Re: Re: Lisp Macros in Mathematica (Re: If Scheme is so

*To*: mathgroup at smc.vnet.net*Subject*: [mg102560] Re: [mg102545] Re: Lisp Macros in Mathematica (Re: If Scheme is so*From*: David Bakin <davidbak at gmail.com>*Date*: Fri, 14 Aug 2009 05:58:10 -0400 (EDT)*References*: <b0g665llur83sj9dnumktjvnipacj7bgrt@4ax.com>

David, I like your ideas. I wouldn't object to better macro facilities in Mathematica, including what you suggest (if done right) and quoting/quasiquoting. (I also wouldn't object (in fact, I would applaud) moving to real lexcial scoping rather than Module, but that's a different story.) I also understand what you were saying about performance. The issue, you know, is that Mathematica doesn't have a compiler in the sense that a (typical) Lisp implementation does. (It has Compile[], but that isn't really the same.) In a (typical) Lisp system macro expansion is done after the program is input and before it is run, at the compile phase. Thus (as I see you know), the macro expansions are done once, then the generated code is executed multiple times, therefore you don't get a performance hit from multiple macro expansions. Using Hold*, pattern matching, and rule replacement as I suggest would mean, in Mathematica, that it was done repeatedly at interpretation time, so I presume you're right, there is a performance hit. (I'm not really experienced enough at Mathematica to know how much of a hit that is.) Your solutions sound like reasonable workarounds to the lack of a proper macro facility, to a point. The point being, that if they aren't integrated fully into the notebook interface, the macro-expanded definition will be what Mathematica knows about and what it will later tell you if you try to display the defintion of your functions. Lisp systems don't have that problem - if you ask later what the value of your function is you'll get the pre-macro expanded version that you expect. (Though I think you could work around that problem to some extent with the use of the pre-output hooks - I forget what they are but I know Mathematica has them - to rewrite function definitions back to pre-macro-expanded state before displaying them. Not sure if that would be a full solution, e.g., what would be saved to a notebook after you did a macro-expansion via an alternate to := or the use of $Pre or $PreRead.) So I'm not sure what the answer is for the original poster. Maybe: Yes, you can do powerful macro-like things in Mathematica very easily - but they come with a performance tax you might not expect if you're used to Lisp systems. On Thu, Aug 13, 2009 at 12:20 AM, David Bailey <dave at removedbailey.co.uk>wrote: > David Bakin wrote: > > It is very easy to make what Lisp calls "special forms". You use HoldAll > or > > related attributes to create your own "special forms", then manipulate > the > > arguments in their full form (aka S-expressions), evaluating things when > you > > wish. > > > > As far as I am aware you do not get reader syntax like quotes and > > quasiquotes that make Lisp macros easy to write. But depending on what > > you're trying to do you may not need them. With Mathematica you get full > > pattern matching on arguments (not just destructuring) and rule-based > > programming, and everything else that Mathematica provides. You may find > > these features are even more effective than quoting and quasiquoting in > > writing macros. > > > > BTW, Mathematica does not need a separate defmacro call that basically > means > > "define this function such that you don't evaluate any arguments, but > when I > > return the result, you evaluate it". That is because 1) To get the first > > part you add the HoldAll attribute to your function name, and 2) > Mathematica > > automatically evaluates the result returned by any/all functions, until > > there's nothing more to evaluate (which is an important difference > between > > the Lisp REPL and the Mathematica REPL). > > > > If I understand what you mean, then surely this is missing the point. > > Let's take a specific example. Suppose you have a vector of data > representing conditions in a reaction vessel, and you define functions > such as: > > pH[x_]:=x[[17]]; > > This is a function, and could be used to access the relevant component > of a vector, but not to change that value. However, if you code in that > style, you will sacrifice a lot of performance for the sake of clarity. > > One way to solve that problem, is to define another operator for use in > defining functions instead of SetDelayed (:=). This lets you make > substitutions on the held form of the RHS before the DownValue is > created - so you code pH[vec] but execute vec[[17]] . > > Alternatively, you could use $Pre or $PreRead, but since these do not > work on code loaded by Get or Needs, I don't find this approach general > enough. > > As I said before, I think a built-in macro mechanism would be a valuable > addition to Mathematica. > > David Bailey > http://www.dbaileyconsultancy.co.uk > >