spawning from the shell?

100 views
Skip to first unread message

Duncan McGreggor

unread,
Feb 17, 2013, 1:32:48 PM2/17/13
to lisp-flavo...@googlegroups.com
I'm writing up a tutorial on working with processes in LFE -- mostly to teach myself Erlang ;-)

But I got curious about working around the no-function-definition in the shell and figuring out how to spawn a lambda in the REPL... and it's so close, I figure there might *just* be a way to do it. But I keep falling short ;-)

Here's what I've got so far:

Erlang R15B03 (erts-5.9.3.1) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false] [dtrace]

LFE Shell V5.9.3.1 (abort with ^G)
> (set print-result
    (lambda (x)
      (: io format '"Received message: '~s'~n" (list x))))
#Fun<lfe_eval.10.53503600>
> (funcall print-result '"Zaphod was here.")
Received message: 'Zaphod was here.'
ok


Then I try to do the spawn...

> (set pid (spawn 'self 'funcall (list print-result)))
<0.31.0>
>
  =ERROR REPORT==== 17-Feb-2013::10:15:18 ===
       Error in process <0.31.0> with exit value: {undef,[{self,funcall,[#Fun<lfe_eval.10.53503600>],[]}]}


I can't really read Erlang error messages very well yet, but I'm guessing it's "self" that's the problem? (i.e., it's undefined) My hope was that since I could reference the shell with (self) in the REPL, its namespace could also act as a module in the call to spawn ;-)

Any ideas on if it's possible to spawn a lambda from the REPL, and if so, how?

Thanks!

d

Robert Virding

unread,
Feb 17, 2013, 8:39:39 PM2/17/13
to lisp-flavo...@googlegroups.com
Mainly you have been running into erlang. :-)

I can't of course do anything about the actual error values, most are
predefined in the VM/language. They are either atoms or tuples. The
format of the error message I can't do much about without rewriting a
significant parts of OTP, I don't think they have any useful general
hooks.

This error was an 'undef' error meaning that you tried to call an
undefined function or that the module did not exist. In this case you
tried to call the function erlang:funcall/1.

The problem is not 'self' per se but that I think you tried to give it
more meaning than it actually has. It is just the name of a BIF (Built
In Function) which when called returns the pid of the calling process.
So (self) returns something like <0.46.0>. Apart from that it is a
normal atom and you can use it as a variable if you wish. So in the
shell:

LFE Shell V5.9.1 (abort with ^G)
> (set self (self))
<0.30.0>
> self
<0.30.0>
> 'self
self
> (self)
<0.30.0>
>

The BIF spawn/3 starts a new process running a function. Its 1st arg
is a module name, 2nd arg a function name and the 3rd arg a list of
arguments. Spawn creates a new process and returns the pid, the new
process then calls the function specified by the arguments. In your
case the new process tried to make the call:

(: self funcall print-result)

You generally call spawn like (spawn lfe_shell server '(default)).

There is also another version of the BIF spawn, spawn/1 which takes a
lambda (a "fun" in Erlang speak) of arguments as arg where the new
process calls that lambda. So with your print-result you could do:

> (spawn (lambda () (funcall print-result 'bert)))
<0.34.0>
Received message: 'bert'
>

Note I need to wrap print-result as the spawned lambda takes no arguments.

Unfortunately functions with variable no. of args don't exist in
Erlang at all. It is just not possible to do it. So (spawn lambda) and
(spawn mod func arglist) are two different functions. There is also
spawn/2 and spawn/4 which take a node on which to start the process.

This makes it difficult to do some lispy things without LFE
incompatible with vanilla erlang/OTP. For example &rest arguments. If
you want to do something like that you explicitly have to pass a last
argument which is a list. This rubs off on LFE as all LFE functions
are normal vanilla erlang functions. Same applies for lambdas. So you
have to call functions/lambdas with the right number of args.

Sorry this became a bit longer than expected,

Robert
> --
> You received this message because you are subscribed to the Google Groups
> "Lisp Flavoured Erlang" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to lisp-flavoured-e...@googlegroups.com.
> To post to this group, send email to lisp-flavo...@googlegroups.com.
> Visit this group at
> http://groups.google.com/group/lisp-flavoured-erlang?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Duncan McGreggor

unread,
Feb 17, 2013, 9:11:34 PM2/17/13
to lisp-flavo...@googlegroups.com
Thank you! You sir, are dedicated and a gentleman :-) It was highly educational!

Thanks so much,

d

Robert Virding

unread,
Feb 17, 2013, 9:15:03 PM2/17/13
to lisp-flavo...@googlegroups.com
No worries.

On 18 February 2013 03:11, Duncan McGreggor <dun...@cogitat.io> wrote:
> Thank you! You sir, are dedicated and a gentleman :-) It was highly
> educational!

The result of giving many courses. :-)

Robert
Reply all
Reply to author
Forward
0 new messages