On Sunday, 10 July 2016 at 11:21:49 UTC, Walter Bright wrote:
On 7/9/2016 7:44 PM, Ola Fosheim Grøstad wrote:
Scheme is a simple functional language which is easy to extend.

If they have to extend it, it isn't Scheme anymore.

You misunderstand the meaning of "extend" in respect to Scheme due to your lack of experience with it. Macros are the way of extending Scheme, you don't need to hack the compiler for that.

From Wikipedia:
---------------
Invocations of macros and procedures bear a close resemblance — both are s-expressions — but they are treated differently. When the compiler encounters an s-expression in the program, it first checks to see if the symbol is defined as a syntactic keyword within the current lexical scope. If so, it then attempts to expand the macro, treating the items in the tail of the s-expression as arguments without compiling code to evaluate them, and this process is repeated recursively until no macro invocations remain. If it is not a syntactic keyword, the compiler compiles code to evaluate the arguments in the tail of the s-expression and then to evaluate the variable represented by the symbol at the head of the s-expression and call it as a procedure with the evaluated tail expressions passed as actual arguments to it.
---------------

For example, an "if expression" is written as follows:

; Returns either settings or an error, depending on the condition
(if (authenticated)
  (load-settings)
  (error "cannot load settings, authentication required"))

Either branch is an expression, and the false-branch can be omitted (then a Scheme's "null" equivalent will be returned instead). If you need a "block", a sequence of expressions, you could write this:

(if (authenticated)
  (begin
    (display "loading settings")
    (load-settings))
  (begin
    (display "something went wrong")
    (error "cannot load settings, authentication required")))

When you specify true-branch only, it's tedious to wrap your sequence in "begin" expression. But you can write a "when" macro, which takes a condition and a sequence of expressions and generates the code for you:

(define-syntax when
  (syntax-rules ()
    ((when pred exp exps ...)
      (if pred (begin exp exps ...)))))

Now you can use it just as an ordinary "if":

(when (authenticated)
  (save-settings)
  (display "Saved settings"))

What about the false-branch-only "if"?

(define-syntax unless
  (syntax-rules ()
    ((unless pred exp exps ...)
      (if (not pred) (begin exp exps ...)))))

(unless (dead)
  (display "walking")
  (walk))

The only syntax Scheme has is S-expressions, which are used to represent both data and code, so there's nothing to be extended in the language itself. You just write a macro that generates the code you want. Macros are effectively AST transformers, it just happens so that in Scheme everything is represented in S-expressions, so the code you write is already the AST.

So if you "extend" Scheme by writing a macro, it's still Scheme. You can think of macros as of D string mixins, but without the ugly stringiness.

Reply via email to