Hi Tomas, > > 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?
No, but the environment must encapsulate symbols _and_ values, not just values. Just a list of values doesn't make an environment. > > 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. This is not what I'm talking about. 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. 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. > > 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. You are right. I'm always surprised (since the times I cooperated with COBOL programmers) how some people prefer verbose code, but I should not judge about it. Still, most of that verbosity is inherent in CL, and you can't avoid it. So it was more the taste of the original language designers. > (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. Right. But now you avoided the issue of variable bindings all together, so that we cannot talk of an "environment" here any longer. And, as ever, it doesn't separate the activation and execution of the environment. As far as the RosettaCode task is concerned (which doesn't need that separation), this would be the cleanest solution so far. 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. Cheers, - Alex -- UNSUBSCRIBE: mailto:[email protected]?subject=Unsubscribe
