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:email@example.com?subject=Unsubscribe