Prev: Lisp sucks!
Next: grabbing key presses
From: Pillsy on 17 Nov 2009 11:25 On Nov 17, 9:48 am, Pillsy <pillsb...(a)gmail.com> wrote: [...] > (let ((closed (closed "BACKING-"))) > (defmacro foo (name &rest args) > (setf (get closed name) (stuff-from-foo-args args)) > (generate-foo-expansion name args closed)) > (defmacro bar (name &rest args) > (setf (get closed name) (stuff-from-bar-args args)) > (generate-bar-expansion name args closed))) > Is there something horribly wrong with this approach? Well, one thing that's potentially horribly wrong with the approach is its dependence on compile-time side-effects. This problem seems pretty avoidable if all you want to do is establish a private chanell that can be accessed by your expansions; that may not be enough for your purposes. But if it is, there's always (let ((closed (gensym "CLOSED-"))) (defmacro foo (name &rest stuff) `(progn (setf (get ',closed ',name) ,(mangle-foo-args args)) ,(foo-expand name args closed))) (defmacro bar (name &rest stuff) `(progn (setf (get ',closed ',name) ,(mangle-bar-args args)) ,(foo-expand name args closed)))) Cheers, Pillsy
From: Spiros Bousbouras on 17 Nov 2009 11:41 On 11 Nov, 08:31, "Tobias C. Rittweiler" <t...(a)freebits.de.invalid> wrote: > Spiros Bousbouras <spi...(a)gmail.com> writes: > > (let ((a 0)) > > (defmacro memory (&rest body) > > (prog2 > > (incf a) > > `(symbol-macrolet ((cell ,a)) > > ,@body) > > (decf a)))) > > (Mind Thoms Russ' response!) > > > In any case, it seems that if one wants to have macros share > > information (apart from trivial cases perhaps) then this cannot be > > achieved behind the scenes so to speak. What I mean behind the scenes > > is the way you would do it with functions: > > > (let ((a)) > > (defun foo ... > > (defun bar ...) > > > Any changes to a one function makes the other knows about but the > > rest of the code is ignorant about a. With macros however one has to > > put any changes to the shared information in the code the macro > > produces thereby leaking what ought to be internal implementation. > > Where is it leaking? In my code above nothing is leaking but my code doesn't do what I want. In the solutions posted by the two Pascals a symbol-macro cell is introduced in the global environment. That's what's leaking. In Pascal B.'s solution also the dynamic variable *cell* is leaking. > Because you can introspectively look at a macro's > expansion? The ability to expand macros is a good thing. As I said in my opening post , if Lisp had a minimal-compile function (which in a sense would be a stronger version of macroexpand) , I could do what I want in a clean and more elegant manner. Actually I find it surprising that it doesn't. minimal-compile would be more or less something which does more than macroexpand but less than eval. > Do you consider reflection to be "blemish" in general? Not at all. The problem here is lack of the right kind of "reflection". > > I consider this a blemish in Lisp. > > Impenetrable encapsulation is only longed for by the timid. :-) Timid or not , if one wants impenetrable encapsulation the language should let them achieve it unless it conflicts with something else. And the issues here are elegance , practicality and even speed of compilation. -- Never attribute to conspiracy what can adequately be explained by shared attitudes.
From: Tamas K Papp on 17 Nov 2009 12:11 On Tue, 17 Nov 2009 08:41:28 -0800, Spiros Bousbouras wrote: > On 11 Nov, 08:31, "Tobias C. Rittweiler" <t...(a)freebits.de.invalid> > wrote: >> Where is it leaking? > > In my code above nothing is leaking but my code doesn't do what I want. > In the solutions posted by the two Pascals a symbol-macro cell is > introduced in the global environment. That's what's leaking. In Pascal > B.'s solution also the dynamic variable *cell* is leaking. As Pascal said, you can put *cell* in another package. End of story. >> Because you can introspectively look at a macro's expansion? > > The ability to expand macros is a good thing. As I said in my opening > post , if Lisp had a minimal-compile function (which in a sense would be > a stronger version of macroexpand) , I could do what I want in a clean > and more elegant manner. Actually I find it surprising that it doesn't. > minimal-compile would be more or less something which does more than > macroexpand but less than eval. > >> Do you consider reflection to be "blemish" in general? > > Not at all. The problem here is lack of the right kind of "reflection". > >> > I consider this a blemish in Lisp. >> >> Impenetrable encapsulation is only longed for by the timid. :-) > > Timid or not , if one wants impenetrable encapsulation the language > should let them achieve it unless it conflicts with something else. And > the issues here are elegance , practicality and even speed of > compilation. I don't see how you would gain elegance, practicality or even speed in this case. But fortunately, your problem might have a solution soon. Stroustrup is rumored to be working on a new language with impenetrable encapsulation. The problem with C++ was that even though it has private slots, the programmer would _know_ that they are there and be tempted to access them using devious tricks. They might even reside on the same hard disk as some other code! The new language, tentatively called Objective StraitJacket, will offer the following method to deal with that: The code is written to a hard disk, which put in sealed triple metal container (made of gold, silver, and iron). A river is temporarily diverted at a random location to bury the container. The workers, who would still know the location, are then shot by archers. The archers are eaten by wild boars. The boars are then read the operator precedence rules of C++, until they die of sheer exasperation. Until then, you just have to hide symbols in packages. Cheers, Tamas
From: Tobias C. Rittweiler on 17 Nov 2009 13:01 Spiros Bousbouras <spibou(a)gmail.com> writes: > On 11 Nov, 08:31, "Tobias C. Rittweiler" wrote: > > > Spiros Bousbouras <spi...(a)gmail.com> writes: > > > > > In any case, it seems that if one wants to have macros share > > > information (apart from trivial cases perhaps) then this cannot be > > > achieved behind the scenes so to speak. What I mean behind the scenes > > > is the way you would do it with functions: > > > > > (let ((a)) > > > (defun foo ... > > > (defun bar ...) > > > > > Any changes to a one function makes the other knows about but the > > > rest of the code is ignorant about a. With macros however one has to > > > put any changes to the shared information in the code the macro > > > produces thereby leaking what ought to be internal implementation. > > > > Where is it leaking? > > In my code above nothing is leaking but my code doesn't do what I > want. In the solutions posted by the two Pascals a symbol-macro cell > is introduced in the global environment. That's what's leaking. In > Pascal B.'s solution also the dynamic variable *cell* is leaking. Pascal Costanza's example contained a global symbol macro, though you don't need it. Are internally used functions to implement other functions also an example of leaking? Or variables? They all introduce stuff into the global environment. What's the difference? > > Because you can introspectively look at a macro's expansion? > > The ability to expand macros is a good thing. As I said in my opening > post , if Lisp had a minimal-compile function (which in a sense would > be a stronger version of macroexpand) , I could do what I want in a > clean and more elegant manner. Actually I find it surprising that it > doesn't. minimal-compile would be more or less something which does > more than macroexpand but less than eval. It's commonly called MACROEXPAND-ALL. Look into the different SWANK backends how it could be implemented on many implementations. > > Do you consider reflection to be "blemish" in general? > > Not at all. The problem here is lack of the right kind of > "reflection". MACROEXPAND-ALL can be useful, yeah. > > > I consider this a blemish in Lisp. > > > > Impenetrable encapsulation is only longed for by the timid. :-) > > Timid or not , if one wants impenetrable encapsulation the language > should let them achieve it unless it conflicts with something else. > And the issues here are elegance , practicality and even speed of > compilation. How does MACROEXPAND-ALL help the speed of compilation? Using it, the implementation has to walk the syntax tree twice. Do you know that it can in fact lead to an _impairment_ of runtime speed because implementation which would previously implement some macros as special forms cannot do so? -T.
From: Pascal Costanza on 17 Nov 2009 15:15
Spiros Bousbouras wrote: > On 11 Nov, 00:40, Pascal Costanza <p...(a)p-cos.net> wrote: >> Spiros Bousbouras wrote: >> >>> (let ((a 0)) >>> (defmacro memory (&rest body) >>> (prog2 >>> (incf a) >>> `(symbol-macrolet ((cell ,a)) >>> ,@body) >>> (decf a)))) >>> His phrasing above and the example gave me the impression that he was >>> saying that all assignments are dangerous even if the effects of the >>> assignment do not persist after the macroexpansion function has >>> finished executing. If that's what he meant then I do find it >>> surprising. For example I don't see what could go wrong with my code >>> above regardless of how many times the macro gets expanded. >> I didn't read your code carefully enough, so I indeed didn't notice that >> the side effect didn't persist. However, this code could still create >> problems, for example when a user tries to macroexpand some particular >> form while some other code is compiled in a background thread, and two >> invocations of 'memory are thus expanded at the same time. > > Is there any established way for how such parallel > expansion/compilation is supposed to work ? Intuitively it seems to > me that in the scenario you're describing the implementation ought to > create one copy of a for the compilation and another for any > expansions which are not part of the compilation. If it doesn't do > that what makes you think that even your code will work correctly ? > There may be clashes with the use of new-cell-value. Huh? new-cell-value is lexically bound, so it's guaranteed to have its own binding per invocation. >>> In any case, it seems that if one wants to have macros share >>> information (apart from trivial cases perhaps) then this cannot be >>> achieved behind the scenes so to speak. What I mean behind the scenes >>> is the way you would do it with functions: >>> (let ((a)) >>> (defun foo ... >>> (defun bar ...) >>> Any changes to a one function makes the other knows about but the >>> rest of the code is ignorant about a. With macros however one has to >>> put any changes to the shared information in the code the macro >>> produces thereby leaking what ought to be internal implementation. I >>> consider this a blemish in Lisp. >> You can hide the shared information in a package. > > You can but still I find it kludgy. You already have the datum in a > variable i.e. in memory but in order to share it with a different > invocation of the macro you have to "print" it and then read it back > in again. Very ugly. Apart from aesthetics there's another issue : > "Practical Common Lisp" says in footnote 4 of chapter 4 : "Not all > Lisp objects can be written out in a way that can be read back in". > What if it is such an object you want to share ? This all has absolutely nothing to do with printing and reading. Pascal -- My website: http://p-cos.net Common Lisp Document Repository: http://cdr.eurolisp.org Closer to MOP & ContextL: http://common-lisp.net/project/closer/ |