MathGroup Archive 2009

[Date Index] [Thread Index] [Author Index]

Search the Archive

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


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>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

  • Prev by Date: Re: How to get plot Exclusions for a numerical function?
  • Next by Date: Re: Problem with a 1st order IV ODE (nonlinear)
  • Previous by thread: Re: ListLogLinearPlot with two y-axis
  • Next by thread: Newcomer Question