On Mon, Jan 23, 2012 at 11:23 AM, Imran Rafique <im...@rafique.org> wrote: > I think the one thing which does bother me though, is the lack of a separate > macro-expansion phase. Sure, fexpr's give you what macro's do, at runtime. > > But one of the key things which make me feel comfortable in any lisp is the > knowledge that I can effectively re-arrange the syntax of certain operation > sequences to forms that I prefer.
You call for a separate macro-expansion phase, but what you really want is the runtime performance. I believe it is possible to achieve this runtime performance without the ugliness that would be introduced with CL style macros. Let me explain the ugliness first, and then the solution. IMHO, CL style macros would be ugly in picolisp because there is no way to tell code from data. Suppose you have a quoted list beginning with a symbol defined as a macro. If it is expanded as a macro, you'll never feel safe when quoting a list that's supposed to be data, but if it's not expanded you won't be able to use quoted lists to pass code into other functions, at least not without feeling the agony of the supposed runtime penalty. In a language where lambda is quote, this would be very sad indeed. There are several additional ugliness aspects I won't mention for the sake of brevity, just think CL vs PicoLisp. Now, the proposed solution: Picolisp style FEXPRs have the ability to not only read the argument list unevaluated, but also modify it. These modifications are preserved in the loaded code until next time the function is called from the same place in the code. This is how 'job' environments work. Picolisp style FSUBRs (a C compiled function) on the other hand can read and modify the entire form. This allows them to modify not only the argument list (the cdr of the form) but also the functional expression of the form (the car). I propose this ability is given to FEXPRs as well. A macro would then be a function that alters the car and cdr of it's own form and then evaluates it. This type of macro will work inside quoted code without disturbing quoted data, since it will expand the first time it is executed. I believe this method would preserve the simplicity of picolisp, since macros are not introduced explicitly - only the possibility of rolling your own macro engine is added. This addition to the language would also open up many interesting possibilities other than macro engines. I have used this technique before (in picolisp, with an ugly workaround,) to achieve some things with this type of... let's call it "lexical reflection". In short, it would give FEXPR's a power they now lack compared to FSUBR's. If this ability is given to FEXPR's, anyone could make their own 'defmacro'. Macro expansion would still occur once every runtime, but not more than once. Also, unnecessary macro expansions (of forms that won't be executed anyway) will never occur. Example of a form-altering function (not tested, of course): (de loop X (set *FORM 'prog) (con *FORM (apply circ X)) (eval *FORM)) This defines an eternal loop as a macro expanding to a prog carrying a circular body. I don't necessarily propose this feature is introduced with a variable *FORM as in the example above, but any other way I can think of seems just as ugly. -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe