Hi Tomas,

> > What I mean is to separate the _activation_ of an environment from its
> > _execution_. In PicoLisp, the call to 'job' (the activation of the
> > environment) can be in a library, not only the definition.
> >
> > Only this makes it possible, for example, to store code fragments like
> > (foo X Y) as event handlers, button actions or update managers in GUI
> > components. The library (i.e. the 'form' function) maintains
> > environments in all forms and dialogs, and activates them as necessary
> > before running those handlers and actions in the form's context.
> >
> > SYMBOL-MACROLET can't do that. It always encapsulates the
> > environment's activation _and_ the code body. And your defmacro'd
> > 'job' must therefor expand in the application domain.
> I'm not sure I understand, especially the last sentence.  That's what
> the macros do, they expand during compilation time, maybe be in

The following example is conceived, a normal application would not use
'X' and 'Y' in that way, but other parts of the form's runtime
environment are indeed following this schema. But this example may show
what I mean by "separating activation of an environment from its

   # Activation
      (job (: env)   # Here must be SYMBOL-MACROLET, as 'env' contains
         ... )       # 'X' and 'Y' (unknown to 'form'). There is no body
                     # visible using 'X' or 'Y', that's only in the app
   # Execution
      (de myButton ()       # The button assumes to run in a certain environment
         (gui '(+Rid +Able +Button)
            '(and X Y)      # Enable/disable expression
            '(foo X Y) ) )  # Action expression

   # Usage
      (gui '(+TextField) ...) # The application code sets up the environment
      (gui '(+TextField) ...)

Three different files are involved. "lib/form.l" is the system library
building forms and dialogs, "myApp/gui.l" is the application's library
which defines a button to be used in several parts of the application.

In the usage, the variables 'X' and 'Y' are free. You can't handle that

> application domain whatever that is.  But then one could argue that
> fexprs evaluate in application domain at runtime.

Yes. Dynamically.

> > To bring it to the point: First class environments are _useless_ if
> > you cannot separate activation and execution. If activation and
> > execution are in the same place, you can as well just pass a list of
> > values (without the symbols) and use 'let' or function application to
> > bind them to the symbols locally.
> >
> > This explains perhaps why they are not an issue in other programming
> > languages. At least not in lexically scoped languages.
> >
> > I think I have to write an article in the PicoLisp Wiki to explain all
> > that better.
> >From http://picolisp.com/5000/!wiki?firstClassEnvironments I understand
> that activation means binding/copying the values from the assoc list to
> the value cells of the symbols.  And after execution, the values are
> copied back to the assoc list and original bindings are restored, if I
> understand correctly.


> Say I have this code which is same as in picolisp (except the additional
> explicit argument to job which we agreed could be implemented in Common
> Lisp by walking the sexp expression body, but lets keep it simple for
> now):

Yes. But that's not the point. As I said, you don't need first class
environments at all if you must carry the variables explicitly with you.
You can simply use a 'let' or a 'lambda'.

> I could implement 'job' like this:
> 1 (defmacro job (env args &body body)
> 2   (let ((x (gensym)))
> 3     `(let ((,x ,env))
> 4        (let (,@(mapcar (lambda (a) `(,a (cdr (assoc ',a ,x)))) args))
> 5          (prog1 (progn ,@body)
> 6            ,@(mapcar (lambda (a) `(setf (cdr (assoc ',a ,x)) ,a)) args))))))

You see? You don't separate 'job' from the 'body'.

In "lib/form.l" in PicoLisp, the body to 'job' is the huge body of the
form generating code. The application level code isn't even loaded at
that time, and is different for each form or dialog invoked.

Of course, you can handle some kind of environment in that way. But you
won't do that practically, because it is clumsy and not helpful, and
doesn't provide the convenience it has in PicoLisp. In Common Lisp, it
doesn't lend itself to that way, resulting in a different programming
style (I don't say this is bad, that's a matter of taste).

> > But it also confirms my initial statement, that proper first class
> > environments (handling creation, activation and execution
> > independently) cannot be done with pure lexical binding.
> True, not with pure lexical binding.  There are two dimensions to the
> problem here: one goes along the fexpr/macro/function axis and the other
> along dynamic/lexical scope axis.  And first class environments like in
> PicoLisp can be done with lexical bindings if you use macros.

The issue of fexprs vs. macros is another one, we talked about that.

Note that the PicoLisp style of building many GUI functions like
'action', 'form', down to '<h1>', '<table>' and '<row>' would not be
feasible with macros, at least not efficiently, because these functions
are nesting extremely deep on a typical page. If they were all macros,
you would ge a really _huge_ code explosion, if each of these macros
gets expanded.

> > These examples don't show the separation of activation and execution,
> > as this cannot be simply done in an isolated example. For a real-world
> > use case, take a look at the top-level GUI function in
> > "@lib/form.l". The relevant part can be reduced to
> That's not helpful for understanding the issue, it should be possible to
> write very simple example.  All the http noise could be taken away as it

I hope I could do that with the example above.

- Alex
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

Reply via email to