[erlang-questions] Scheme on the Erlang VM

Marc Feeley <>
Tue Jun 5 23:18:29 CEST 2007


On 5-Jun-07, at 8:45 AM, Torbjorn Tornkvist wrote:

> Did the cool Scheme hack from Marc Freeley really turn up in the
> erlang-questions list?
>
> If not, then you'll find the post here:
>
> http://article.gmane.org/gmane.lisp.scheme.gambit/1463/match=scheme
>
> --Tobbe
> (Ps. I saw it as I read the list via gmane, but others didn't
> apparently, and it isn't in trapexit.org)

Seems my post was rejected (due to the attachment?) and  
article.gmane.org is down.  So here is an alternate link (which  
includes the attachment):

   https://webmail.iro.umontreal.ca/pipermail/gambit-list/2007-June/ 
001466.html

Here's the text part of my post:

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/@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) ->
   @2(N,[]).

@2(I,Lst) ->
   if (I > 0) -> @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




More information about the erlang-questions mailing list