How can you rewrite “begin” in Scheme?

2019-04-04 14:11发布

问题:

As the Wikipedia article explains, begin in Scheme is a library form that can be rewritten using more fundamental forms like lambda.

But how do you rewrite a begin, especially considering the following?

x
===> error: undefined identifier: x
(begin (define x 28) x)
===> 28
x
===> 28

回答1:

You cannot. The thing is that begin has two roles: one is sequence a bunch of side-effectful expressions, and the other is that it is used to "splice" macro results. The fact that you can use begin with a definition as in the above is a result of this second feature, and you cannot write it yourself.

If you really want to follow the whole story, then you could define begin as the simple macro which makes it do only the sequencing aspect (and it can indeed be implemented as such, though usually it isn't). But, you need to add explicit recognition of begins to splice definitions (toplevel or internal). This means that a macro implementation is fine, but it cannot really be a library because the core expander should know about it. (And because the language is lexically scoped, there is no good way for the core expander to identify begins that are not defined in the core language.)

To summarize all of this, you could say that R5RS is only wrong in classifying begin as "library syntax", since it can't be defined in a library... but even that's not entirely accurate since R5RS defines "library syntax" as just "derived expressions". The real wrong point is, therefore, the fact that one of begins two faces is implemented elsewhere, in the expander (for definition contexts).

Note also that R6RS clarifies the whole deal: the two faces of begin are made explicit, and it is now part of the core language, not a "library form", and not even a derived form.



回答2:

You are still welcome to try writing a version of begin which satisfies its first role: sequencing.

(define-syntax sequencing
  (syntax-rules ()
    [(_ expression) expression]
    [(_ expression expressions ...)
     ((lambda (ignored) (sequencing expressions ...)) expression)]))

Here is the post from which I took that snippet. It provides better context if you are interested, and you might be.



标签: scheme