Re: What you can do with macros in Lisp

From: Pascal Bourguignon (spam_at_thalassa.informatimago.com)
Date: 10/12/03


Date: 12 Oct 2003 16:09:44 +0200

Tim Bradshaw <tfb@cley.com> writes:

> Someone mentioned that there's been the usual futile argumentation
> between Lisp people and you-don't-need-macros-at-all and/or
> you-can-do-it-all-with-HOFs people.
>
> Here's something I'd like to see non-macro people do.
>
> Imagine you have a language with a CASE expression. You're writing
> (or generating: for instance in the output of some kind of FSM system)
> code that has a huge number of large, dense, integer CASE expressions,
> which can obviously be optimised into jump-tables. But your compiler
> won't do this, so your code is spending lots of time testing integers
> repeatedly.
>
> So: implement NCASE, which looks exactly like your language's CASE
> expression, but, if all the keys are numeric and if they pass some
> user-definable test - for instance that there are enough keys and they
> are dense enough in their range, will expand to a jump-table.
> Otherwise it should just expand to the ordinary CASE expression.
>
> Can you do this with macros in Lisp? Yes: in fact I did this ages
> ago, with results I've now put up at
> http://www.tfeb.org/lisp/toys.html#NCASE.
>
> Can you do it any other way (in partiucular: in any way which isn't
> equivalent to writing a macro system...)
>
> --tim
 
Well, as explained in Paul Graham's "On Lisp" in his extended coverage
of LISP macros, if you don't mind the typing (and most importantly the
associated obfuscation by redundant details), you can always replace
macro calls by function calls encapsulating the bodies in closure
lambdas (or even, merely quoting them and let the called function make
a function of these lists).

The most difficult stuff is the manipulation of variables (lexical
scope) and declarations in general. But since LISP is highly
(totally?) dynamic, you can always generate a declaration at run-time
rather than compilation time. Well, perhaps doing compilation-time
stuff at run-time is the equivalent of writing a macro system...

http://lib1.store.vip.sc5.yahoo.com/lib/paulgraham/onlisp.pdf

(defmacro with-var (varname value &body body)
  `(let ((,varname ,value)) ,@body))

(with-var x (* 6 7)
          (format t "x =~D~%" x)
          (format t "2x =~D~%" (* 2 x)))

x =42
2x =84
NIL

(defun f-with-var-1 (varname value body)
  (set varname value) ;; wrong, we're setting a global variable
  (funcall body))

(f-with-var-1 'x (* 6 7)
              (lambda () (format t "x =~D~%" x)
                (format t "2x =~D~%" (* 2 x))))

x =42
2x =84
NIL

(format t "x= ~D~%" x)

x= 42
NIL

(makunbound 'x)

;;X

(defun f-with-var-2 (varname value body)
  ;; cheating or not?
  (eval (list `(lambda (,varname) (progn ,@body)) value)))

(f-with-var-2 'x '(* 6 7)
              '((format t "x =~D~%" x)
                (format t "2x =~D~%" (* 2 x))))

x =42
2x =84
NIL

Of course, if you add the constraint of not having to change the
source and quote everything, it's trivially true that you cannot do
what you're asking without a macro system.

I note that when I program in languages other than LISP, my sources
are covered by comments containing emacs lisp code, followed by some
automatically generated code...

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.


Relevant Pages

  • Re: Programming By The Seat Of Your Pants
    ... the only way I'm going to learn Lisp ... was Python, a better scripting language. ... Not much in the way of libraries. ... then add a macro layer that allows you to write things the way you want to ...
    (comp.lang.lisp)
  • Re: Macro Question: Paraphrasing
    ... Instead, you will need to put some macro around all the forms that need to be processed, and use a code walker to process each subform, a la ... The programming language has its own grammar rules that are simpler and much more consistent than natural language. ... Far from enforcing English grammar rules on Lisp, these ideas entail adding context to arbitrary ordering and paraphrasing awkward expressions. ... The variable clauses resemble dependent clauses, and the main clause represents the independent clause. ...
    (comp.lang.lisp)
  • Re: A "killer" macro
    ... could be included as a feature in another language, ... The "killer" macro, in CL ... of the functional features of Lisp. ... When confronted by fellow programmers with the question "so why is ...
    (comp.lang.lisp)
  • Re: Python gets macros - now XML does too
    ... > I think the main advantage: You use Lisp within a Lisp macro to generate ... > generation part in another language than the description to generate the ... MetaL compiler flow module provides support for level 0 (macro ... Despite currently I only use PHP because I only develop Web ...
    (comp.lang.lisp)
  • Re: What language for pen and paper programming?
    ... Probably most of the languages would look like lisp, ... I probably should have said the language would resemble lisp, ... that syntax tree might just happen to have a one-to-one or nearly ... When executing code by hand the problem is not normally writing out the ...
    (comp.programming)