Hi Alex,

> I just wanted to say that your "1st try" is not a solution to the
> task.

well, the task doesn't say that the environment must be represented as
an alist, or does it?

> As I said, I completely understood your code. SYMBOL-MACROLET is analog
> to 'job'.

No it is not, it allows me to implement job to work like in picolisp.

> This makes it impossible to abstract away the 'job' and put it into a
> library, as is the case in the PicoLisp GUI.

What do you mean?  I wrote job as a separate defmacro, it's completely
self contained, it does the same thing as in picolisp and one can move
it into any file one wishes.

> SYMBOL-MACROLET is a way to _bypass_ the restrictions of lexical scope.
> It is in CL for the same reason as there are "special" (dynamically
> bound) variables: Such features are needed. But they are there to
> circumvent the lexical paradigm.

Yes.  It is there to override the meaning of symbols that would
otherwise be understood to represent variables (lexical or special).

> But: Can you use closures with environments read from a database, or
> communicated across an RPC call?

Unlikely, not portably, only if the implementation somehow exposes that.
Or at least it is not normaly done.  But for example, I can see the
closed over variables in debugger so maybe there would be a way of doing
that.  But you can use SYMBOL-MACROLET to use custom environment, to
look up the values wherever you want.

> I didn't say there is any magic. It is just practical.

It is indeed:-D

> convenient. That's what it is all about in PicoLisp. Keep it simple! You
> can do everything in CL you can do in Pil, of course, but it usually
> looks bigger and uglier (check the other CL solutions in RosettaCode).

True, but that is not inherent feature of Common Lisp I think, it's more
related to the tastes of those programmers.

>> > With that, a Picolisp call like
>> >
>> >    (job <environment>
>> >       <body> )
>> >
>> > becomes to
>> >
>> >    (funcall
>> >       (job (var1 var2 var3 ...)
>> >          <body> )
>> >       <environment> )
>> >
>> > which does not really taste like simply executing some code body
>> > within an environment. This might explain why first class environments
>> > are not an issue in CL.
>> 
>> You missed the most important part, the SYMBOL-MACROLET part.  That
>> changes the meaning of the var1... symbols from "symbol representing a
>> variable" to "symbol representing access to something".
>
> That's picky. Syntacially, (job (var1 var2 var3 ...) is like 'let' or 'lambda'
>
>    (let ((var1 <val1>) (var2 <val2>))
>       <body> )
>
>    (funcall (lambda (x y) (* x y)) <val1> <val2>)

No, that would not work because you could not modify the environment in
the <body> for the same reason it would not work in PicoLisp.

With the definition of job like this:

(defmacro job (env &body body)
  (let ((x (gensym))
        (args (find-free-variables body)))
    `(let ((,x ,env))
       (symbol-macrolet (,@(mapcar (lambda (y) `(,y (cdr (assoc ',y ,x)))) 
args))
         ,@body))))

code like this:

(job e
   (format t "~4d" n)
      (unless (= 1 n)
         (incf cnt)
         (setq n (if (= 1 (logand 1 n)) (1+ (* n 3)) (/ n 2)))))

would expand to something like:

(let ((#:G1234 e))
   (format t "~4d" (cdr (assoc 'n e)))
      (unless (= 1 (cdr (assoc 'n e)))
         (incf (cdr (assoc 'cnt e)))
         (setf (cdr (assoc 'n e))
            (if (= 1 (logand 1 (cdr (assoc 'n e))))
               (1+ (* (cdr (assoc 'n e)) 3))
               (/ (cdr (assoc 'n e)) 2)))))

So in fact, there are no (lexical or special) variables n and cnt at
all.

Cheers,

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

Reply via email to