views:

101

answers:

5

Long story short I am trying to replicate the Sleeping barber problem in Erlang.

In my solution I decided that for all the processes that are waiting I would put them into a list. Then, once it was that processes turn, I would take that PID off of the list.

Unfortunately when I call

length(myListOfPids).

it fails, as an example:

length([<0.46.0>]).
* 2: syntax error before: '<'

is there a way to store PID's so that I can recall them and use them normally? i.e.

PID ! message

... just in case it matters here is the actual error I recieve when running my program:

=ERROR REPORT==== 1-Jul-2010::05:50:40 ===
Error in process <0.44.0> with exit value:
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]}

barber1 is my module, waitingRoom is the function that keeps track of which processes are waiting

+5  A: 

Entering Pids by typing them does not work for me either. Is that the only problem?

With code:

-module(test).
-export([loop/0]).

loop() ->
    receive
        {hello} ->
            io:format("Hello world!~n"),
            loop()
end.

I get:

 Eshell V5.7.5  (abort with ^G)
 1> Pid = spawn(fun test:loop/0).
 <0.35.0>
 2> L = [Pid].
 [<0.35.0>]
 3> length(L). 
 1
Koistinen
+3  A: 

The problem is that while <0.46.0> is the way that a PID gets printed, it can't be entered this way. You can use list_to_pid("<0.46.0>") instead. Of course, once you do have a PID (created in this way, returned from spawn, etc.), it can be stored in a list and retrieved like any other Erlang term.

Alexey Romanov
+6  A: 

You can also construct a Pid from it's three components using pid/3.

1> length([pid(0,35,0)]).

Be aware that using any of these techniques for constructing Pid goes wrong if you construct a pid on a different node than the one it was created on.

The problem your program is having is different.

{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]}

A call to erlang:length/1 created a badarg. The third element of {erlang,length,[<0.46.0>]} is the list of arguments passed to erlang:length. So that's equivalent to:

1> erlang:length(pid(0,46,0)).

where you intended:

1> erlang:length([pid(0,46,0)]).

(Annoyingly, the erlang shell now hides erlang's internal representation of errors from you. Replacing the above error with:

** exception error: bad argument in function length/1 called as length(<0.35.0>)

which is much easier to understand but less useful because it gets in the way of learning the essential skill of interpreting erlang errors yourself.)

cthulahoops
A: 
I GIVE TERRIBLE ADVICE
+5  A: 

This error message:

=ERROR REPORT==== 1-Jul-2010::05:50:40 ===
Error in process <0.44.0> with exit value:
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]}

means that you were calling length(<0.46.0>), not length([<0.46.0>]) (ignoring for the moment that PIDs can only be written, not read). In the stack trace the topmost function will have the list of arguments. Since length takes one argument, this list has a single argument: you are taking the length of a PID, which obviously fails, since only lists have lengths.

legoscia