[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Side effects

This page is part of the web mail archives of SRFI 93 from before July 7th, 2015. The new archives for SRFI 93 contain all messages, not just those from before July 7th, 2015.

I believe the current specification allows either (1 1 2) or (1 2 1).  We
know for sure that the expansion of bar is done exactly once, before the
expansion of either foo form, and we know that each foo form is expanded
exactly once.  We don't know in which order the foo forms will be
expanded, however, since the order in which the variable definition rhs
expressions and body expressions are expanded is unspecified.

> This seems academic, but I do think the differences could conceivably lead to 
> difficulties in macros that rely on side effects to register compile-time 
> information, as in record or object systems.  For example, if BAR were
> a record definition, I would probably feel most comfortable if I could rely on 
> the expression being epanded atomically (the first behaviour above).

With the current specification, the transformer for a record definition
would be invoked before any subsequent forms are seen, and any direct side
effects of the transformer would happen before any subsequent forms (and
earlier variable definition rhs expressions) are expanded.  This seems
like a useful and sufficient guarantee to allow one to do the kinds of
things one usually wants to do with record and object definitions.

On the other hand, a straight left-to-right expansion algorithm would
prevent certain forms of mutual recursion among variable and syntax
definitions.  To use your object-system example, this might prevent two
class definitions from interacting fully.  For example, consider:

  (define-class C1
    (method M1 () --- (make C2) ---))
  (define-class C2
    (method M2 () --- (make C1) ---))

Assume the transformer for define-class sets up the information necessary
for make to create instances of a class, either by some side effect or by
inserting something into its output.  If the expander fully expands the C1
definition before the C2 definition, the information for creating
instances of C2 will not be available when the vtable definition for class
C1---and hence the expression (make C2) in method M1---is expanded.  In
place of (make C2) and (make C1) you can imagine object switch forms, setf
forms for ivars, etc.