I'm currently learning some r7rs and I am trying to implement a macro 'begin' as following :
(begin0 expr0 expr1 ... expr2)
With expr being a regular expression (Like (set! x (+ x 1)))
And begin0 as a macro that evaluates all the expression but return only the expr1 result.
For example :
(let ((year 2017))
(begin1 (set! year (+ year 1))
year
(set! year (+ year 1))
year))
It musts return 2018
I've created a begin function first :
(define-syntax begin0
(syntax-rules ()
((begin-0 body-expr-0 body-expr-1 ...)
(let ((tmp body-expr-0)) body-expr-1 ... tmp))))
And now, I'm trying to understand how I can do to return the value of "body-expr-1" ? I've done the following code, but it says that I'm missing some ellipsis and I don't understand how to do it.
(define-syntax begin1
(syntax-rules ()
((begin1 body-expr-0 body-expr-1 ... body-expr-2)
(let ((tmp body-expr-0) body-expr-1 ... tmp)
(cond (eq? tmp body-expr-1)
(begin . tmp))))))
I hope that it is understandable enough, thanks for the answers.
This can be done, but the macro will interfere such that you cannot do all the things with
begin1
as withbegin
.The code that does not work is this:
The reason is obvious. It expands to:
The second
define
will be changed to aletrec
such that the variableglobal2
is only available for the duration of thelet
. I have no fix for this since it requires you to be able to do globaldefine
from a closure.begin1
is rather strange feature. In Racket and perhaps other Scheme dialects we havebegin0
that returns the result of the first expression. This is very useful. eg. here is a counter:And with
begin0
:In Racket
begin0
is a primitive. So it is a form supported in the fully expanded program and thus implemented in C, just likebegin
..