On 4-Jun-07, at 3:03 PM, Luke Gorrie wrote:
"Philip Robinson" chlorophil@gmail.com writes:
On 6/2/07, Joel Reymont joelr1@gmail.com wrote:
What about Scheme on the Erlang VM?
I would *love* a Scheme/Lisp on the Erlang VM.
For a toy starting point see 'lersp' in the Jungerl.
The most fun bit of writing a Scheme interpreter IMO is to write things like lersp/priv/core-macs.ler i.e. to implement 'let', 'case', 'if', etc from a small kernel.
Core Erlang would probably make a nice target language for a Scheme dialect.
I just couldn't resist the challenge and wrote a prototype Scheme to Erlang compiler (named Stoe of course) that is based on the front-end of the Gambit-C Scheme compiler. The code is attached below. It is just a prototype and it only handles a subset of Scheme, but it could be the starting point for a more complete Scheme to Erlang compiler. Stoe supports some of the Termite language and mutation of local variables. Here's a sample usage:
% cat test.scm (define (fib n) (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2)))))
(define (fact n) (if (< n 2) 1 (* n (fact (- n 1)))))
(define (iota n) (iota-2 n '()))
(define (iota-2 i lst) (if (> i 0) (iota-2 (- i 1) (cons i lst)) lst))
(define (tally) (let ((sum 0)) (lambda (x) (set! sum (+ sum x)) sum)))
(define (process n dest) (lambda () (! dest (map (?) (iota n)))))
(define (main) (let ((a (spawn (process 10 (self)))) (b (spawn (process 10 (self)))) (t1 (tally)) (t2 (tally))) (! a fib) (! b fact) (map t1 (?)) (map t2 (?)) (list (t1 0) (t2 0)))) % gsc -i stoe.scm test.scm % cat test.erl -module(test). -export([fib/1,fact/1,iota/1,iota@2d@2/2,tally/0,process/2,main/0]).
fib(N) -> if (N < 2) -> 1; true -> (fib((N - 1)) + fib((N - 2))) end.
fact(N) -> if (N < 2) -> 1; true -> (N * fact((N - 1))) end.
iota(N) -> iota@2d@2(N,[]).
iota@2d@2(I,Lst) -> if (I > 0) -> iota@2d@2((I - 1),[I|Lst]); true -> Lst end.
tally() -> Sum = schemelib:box(0), fun (X) -> schemelib:setbox(Sum,(schemelib:unbox(Sum) + X)), schemelib:unbox(Sum) end.
process(N,Dest) -> fun () -> (Dest ! lists:map(receive Tmp_1 -> Tmp_1 end,iota(N))) end.
main() -> {T2,T1,B,A} = {tally(),tally(),spawn(process(10,self())),spawn (process(10,self()))}, (A ! fun fib/1), (B ! fun fact/1), lists:map(T1,receive Tmp_2 -> Tmp_2 end), lists:map(T2,receive Tmp_3 -> Tmp_3 end), [T1(0),T2(0)].
% erl Eshell V5.5.4 (abort with ^G) 1> c(schemelib.erl). {ok,schemelib} 2> c(test.erl). {ok,test} 3> test:main(). [4037913,231]
Marc