Vision for the D language - stabilizing complexity?

burjui via Digitalmars-d digitalmars-d at puremagic.com
Sun Jul 10 11:40:39 PDT 2016


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.


More information about the Digitalmars-d mailing list