[erlang-questions] Lisp syntax for Erlang

David Mercer dmercer@REDACTED
Wed Dec 5 18:37:25 CET 2007


On Tuesday, December 04, 2007, Robert Virding wrote:

What I want is something which *is* lisp even though it a lisp which has
been designed to work seamlessly together with *normal* Erlang. So it is
more than just wrapping ( ... ) around expressions after converting them
into prefix form. So, for example, there are no syntactic variables, you
quote things which you don't want to evaluate. So to comment some of you
examples: 

 

I like your idea.  Is your idea to compile Lersp to Erlang or straight to
the virtual machine (BEAM files?)?

 

Cheers,

 

David

 

  _____  

From: erlang-questions-bounces@REDACTED
[mailto:erlang-questions-bounces@REDACTED] On Behalf Of Robert Virding
Sent: Tuesday, December 04, 2007 20:34
To: YC
Cc: Denis; Erlang-Questions (E-mail)
Subject: Re: [erlang-questions] Lisp syntax for Erlang

 

On 04/12/2007, YC <yinso.chen@REDACTED> wrote:

 

IMHO, the issues above arise from the goal being unclear: is it a lispy
syntax for erlang or is it a lisp in erlang? 


I have tried to be clear, but obviously not succeeded. I am going to do a
lisp syntax for Erlang, not implement CL or Scheme which, by the way, is
*very* difficult on the BEAM today. That is the main problem as I have to
invent lisp constructions which match into Erlang. 

If it's a lispy syntax, IMO a prefix<->infix transformer can handle a lot of
cases (below uses vector for tuples): 


What I want is something which *is* lisp even though it a lisp which has
been designed to work seamlessly together with *normal* Erlang. So it is
more than just wrapping ( ... ) around expressions after converting them
into prefix form. So, for example, there are no syntactic variables, you
quote things which you don't want to evaluate. So to comment some of you
examples: 

 

%% Erlang => ErlangInLisp 
A + 1, => (+ A 1) 
A = 5. => (= A 5).


This will become a (let ((a  5)) ... ). Let will be extended to match

 

[foo | bar] => (| foo bar) 


(cons 'foo 'bar) 

 

Pid ! Data => (! Pid Data) 


(send pid data)    ;Using symbols can sometimes be harder to read

 

A = {foo, bar}. => (= A #(foo bar)) %% or (= A {foo bar}) (either works
fine, but vector version appears more uniform and in spirit of lisp) 


(let ((a #('foo 'bar))) ... )    ;or '#(foo bar) here 

 

fun(A) -> A + 1. => (lambda (A) (+ A 1)) %% I think fun is fine. 


Agree 

 

case A of foo -> {foo}; bar -> {foo, bar} end. => (case A ((foo) bar) ((bar)
#(foo bar)))


As yours but quoted:
(case a
  ('foo #('bar))
  ('bar #('foo 'bar))) 

 

foo(1) -> 2; foo(abc) -> {foo, bar}. => (defun foo ((1) 2) ((abc) #(foo
bar))) 


I was more into:

(defun foo (arg)
  (case arg
    (1 2)
    (abc '#(foo bar)))) 

 

{ok, B} = mod:fun(). => (= #(ok B) (mod:fun))  or  (=  {ok B} ((: mod fun)))


(let ((#('ok b) (: mod fun))) ... )    ;see below 

 

And keep the rest of the erlang syntax such as Camel casing for variable,
pattern matching built-in default, bare words as atoms unless at the the
head of a list (or unless in special syntax such as case), etc. 


One feature of lisp we must keep is that code has he same form as data, *is*
data. That means that if we keep the Camel casing for variables then they
have to parse to something other than symbols. If they don't then we will
forever be parsing symbol names to discern what they are. That is why I
would prefer to use the lisp convention of evaluating everything *except*
that which is quoted. That means even using quotes in patterns. 

 

The issue with (remote-call) is that it's tedious.  Think of having to write
that for all function calls that don't live in the current module namespace.
And it also takes on meaning of apply/3. 

If mod:fun(Args)  is writtten as (remote-call mod fun Args), then how to
write apply/3? 

Should we write apply(mod, fun, Args) as (apply (remote-call mod fun
Args))??  Then it's apply/1. 

Probably better to have remote-call take on the meaning of apply/3. I don't
think all function calls should go through apply. 


My current working model is:

mod:fun(<arg1>, <arg2>, <arg3>)  ==>  (module-call 'mod 'fun <arg1> <arg2>
<arg3>)
Mod:fun(<arg1>, <arg2>, <arg3>)  ==>  (module-call mod 'fun <arg1> <arg2>
<arg3>) 
Mod:Fun(<arg1>, <arg2>, <arg3>)  ==>  (module-call mod fun <arg1> <arg2>
<arg3>)


with (: mod fun <arg1> <arg2> <arg3>) as a macro for the 1st most common
case. It smiles at you because it feels good to be so helpful. 

You will still need apply:

apply(Fun, ArgList)  ==>  (apply fun arglist)
apply(Mod, Fun, ArgList)  ==>  (apply mod fun arglist)

Apply and module-call are proper functions which evaluate their arguments, :
is a macro which doesn't evaluate its first two arguments, the module name
and function name, but does evaluate the function arguments. 

We'll see where it all ends up,

Robert

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20071205/e7db25f7/attachment.htm>


More information about the erlang-questions mailing list