[erlang-questions] Lisp syntax for Erlang
YC
yinso.chen@REDACTED
Wed Dec 5 21:03:16 CET 2007
On Dec 4, 2007 6:33 PM, Robert Virding <rvirding@REDACTED> wrote:
> 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.
>
> 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:
>
Sorry - my turn of being unclear - to me a lispy syntax for erlang is *not
necessarily* a lisp, and hence why I made the distinction. I know you are
not implementing CL or Scheme, hence I raise the point of either following
erlang's design or leverage their (CL or scheme's) designs (which you mostly
have done except a few places). But fair enough - you want a lisp that
compiles to erlang.
%% Erlang => ErlangInLisp
> > A + 1, => (+ A 1)
> > A = 5. => (= A 5).
> >
>
> This will become a (let ((a 5)) ... ). Let will be extended to match
>
I like the (let ...) form as well. I did find I write assignment code
because the order is important, so (let* ...) form might be necessary as
well - but that could be just me.
> [foo | bar] => (| foo bar)
> >
>
> (cons 'foo 'bar)
>
> Pid ! Data => (! Pid Data)
> >
>
> (send pid data) ;Using symbols can sometimes be harder to read
>
If you offer macro it's fine either way - I think termite uses ! for send.
I do like erlang/haskell here for their terse syntax - cons gets unwieldy if
there are many of them - .e.g (cons 'a (cons 'b (cons 'c 'd))) vs [a,b,c |
d].
As yours but quoted:
> (case a
> ('foo #('bar))
> ('bar #('foo 'bar)))
>
The one I wrote was scheme's version. It can match multiple bindings with
one clause, but that can make it harder to transform into erlang.
>
> 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))))
>
To me this is where the basic lisp language doesn't offer as much as
erlang. Ability to match on the function head is a very nice syntactic
sugar - it *just* look better than case statements, especially with
recursions.
In scheme with pattern matching lib (below is PLT scheme) one can write
(require (lib "match.ss"))
(define foo
(match-lambda ;; or match-lambda* that can have different arities
(1 2)
('abc #(foo bar))))
So with macros you can get pattern matching back, but why hide it in the
first place?
> 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.
>
Given you want a lisp instead of just lispy syntax - it makes sense.
I do think it's about symbol lookup rather than parsing. Erlang uses
upper/lower case to distinguish between which symbol table you need to
lookup - that's a shorthand, I guess. You can certainly have only one
symbol table for the most current bindings without distinguish between cases
or keywords - that's closer to a lisp/1 :)
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.
>
This is where I think the module-call style overlaps with apply/3.
Consider the following calls
Direct local call: fun1(A1, A2, A3).
Direct module call: mod:fun1(A1, A2, A3).
Indirect (Fun) local call: F1 = fun fun1/3, F1(A1, A2, A3).
Indirect module call: F1 = fun mod:fun1/3, F1(A1, A2, A3).
Apply/2 local: apply(fun fun1/3, [A1, A2, A3]).
Apply/3 module: apply(mod, fun1, [A1, A2, A3]).
In all but one case (apply/3), we are working with the function object
directly (either with a direct syntax or creating a Fun reference). I.e.,
the only place we lookup the function via atoms and evaluate it at the same
time is in apply/3.
The (module-call ...) is basically equivalent to apply/3 - you pass in atom
for mod & fun and with that it looks up the function object AND evaluate the
function at the same time.
That's why I said it's tedious to do so for all module calls as it basically
means we are writing apply for all module calls.
To map against erlang - your lisp can "lookup and return" the function
object for use, say:
(fun 'fun1) ;; returns local #<function: fun1>
(: fun1) ;;; shorthand - the same as fun1, so this form is unnecessary
(fun 'mod 'fun1) ;;; returns #<function: mod fun1>
(: mod fun1) ;; for short hand as you say
;;; honestly - mod:fun1 isn't that bad if you allow : to be a package
separator as in CL. I generally end up faking it in scheme anyways.
Then the above becomes:
(fun a1 a2 a3) ;;; same for indirect call
((: mod fun1) a1 a2 a3) ;; same for indirect call
(apply (: mod fun1) (list a1 a2 a3)) ;;; apply/2
(apply 'mod 'fun1 (list a1 a2 a3)) ;;; apply/3
It looks similar but has a different semantic and IMHO more closely
correspond to erlang.
Lastly - I think your idea is interesting and the above are my 2 cents of
input to your goal, hopefully it helps more than it hurts :)
p.s. did you see Mark Feely's scheme to erlang? It might provide some
inspirations.
http://www.erlang.org/pipermail/erlang-questions/2007-June/027057.html
Cheers,
yc
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20071205/937caf9f/attachment.htm>
More information about the erlang-questions
mailing list