On 4-Jun-07, at 3:03 PM, Luke Gorrie wrote:
> "Philip Robinson" <chlorophil(a)gmail.com> writes:
>
>> On 6/2/07, Joel Reymont <joelr1(a)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