Implementing the inline schema function begin () using the schema itself, does the same code behave differently in MIT-SCHEME and Racket?

I read the r5rs schema standard and find that begin () is actually library syntax, which means it can be defined by the schema itself, and the standard gives an implementation at the end of the standard.

I followed r5rs prior to implemented begin () using define-syntax as shown below:

(define-syntax mybegin
  (syntax-rules ()
                ((mybegin expr) expr)
                ((mybegin expr1 expr2 ...)
                 (let ((x expr1))
                   (mybegin expr2 ...)))))

      

and then i tried to implement it with a function, here is my code:

(define begin-func
  (lambda (expr1 expr2)
    ((lambda (x) expr2) expr1)))

      

here are my test cases:

(define x 3)
(define y 3)
(mybegin
  (set! x 4)
  (set! x 5))
(begin-func
  (set! y 4)
  (set! y 5))

      

I ran my code in MIT-SCHEME and Racket using #lang scheme, x is 5 in MIT-SCHEME and Racket, however y is 4 in MIT-SCHEME, but 5 in Racket

So here's my question:

  • Is it true that we could implement begin () using pure functional diagram?
  • Is there something wrong in my code, both the code using the macro and the code using the function?
  • Why does the same code behave differently in MIT-SCHEME and Racket?
+3


source to share


1 answer


begin

is a special form that evaluates each element in order and evaluates the most recent expression. You will never need begin

a purely functional diagram, but in a functional form, you can get similar functionality as begin

in a diagram, which does not have begin

a special form or is embedded in forms lambda

or relatives. This is just one exception and define

within it. define

at the beginning of the top level will be defined globally, while the mock will use procedures to get the score in order, and define

will then only become a local binding, which dies when the procedure goes out of scope.

begin

must be defined as syntax, because if you follow a procedure like:

(define (mybegin . args)
  ...)

      



All arguments when called mybegin

will be evaluated in a specific implementation order. The report says that the evaluation must be consistent so that you don't see that one implementation gets 4 once and 5 more, but you will see that each one happens every time for the same procedure. This did not guarantee that the evaluation would be performed in the same order and on two different procedures, but many Scheme implementations usually do it in the same order.

Racket always evaluates the arguments in order, which is good because the report says you can do it however you want, while MIT at least sometimes evaluates in reverse order.

+3


source







All Articles