[mercury-users] lisp macros

Ralph Becket rafe at cs.mu.OZ.AU
Wed May 29 13:17:25 AEST 2002


Michael Day, Friday, 24 May 2002:
> 
> > Here's a little example from some XML processing I did in Scheme using
> > unhygienic macros:
> > 
> > (defmacro x-define (Id . Body)
> >   `(define (,Id Element Ancestors) ,(list 'quasiquote Body)))
> > (defmacro apply-templates ()
> >   `(process-children Element Ancestors))
> 
> Any tips on how this kind of thing would look in Mercury for people who
> don't know lisp? :)

Basically, backquote `(...) says "take (...) as the literal expansion"
with the proviso "except for ,x which should be replaced with whatever x
evaluates to."

That is, given

	(defmacro foo (x) `(x ,x))
		  |   |   |
		  |   |   body
		  |   arg list
		  macro name
then

	(foo a)
==>	(x a)

since the first x is literal and the second is evaluated in the macro
body.

It is possible to perform structural matching on macros (called
"destructuring" in Lispese); the body is evaluated to produce the macro
expansion.

One could imagine some sort of Mercury pre-processing library in which
Mercury pre-processors could be written.  For example, a preprocessor
compiled for a rule like

:- macro pred_lambda (test(X) :- Body)
	==	(pred(X::in) is semidet :- Body).

would turn things like the following

	Ys = filter((test(X) :- odd(X), prime(X)), Xs),

into

	Ys = filter((pred(X::in) is semidet :- ...), Xs)

[I suppose there's no need for a separate pre-processor - this could be
integrated into the compiler, but if you want to allow some kind of
processing in producing the expansions then things might get
trickier...  On the other hand, if pre-processor A produces macros
expanded by pre-processor B and vice versa, then it isn't clear what the
policy should be.  Perhaps this sort of thing should be forbidden.]

Another example (the syntax here is very sketchy):

:- macro pred_decl io_pred P(Args) is Detism
	==	(pred P(Args ++ [io::di, io::uo]) is Detism).

:- macro pred_decl io_pred P(Args)
	==	(io_pred P(Args) is det).

Then one could write declarations like

	:- io_pred main.

	:- io_pred print_first_result(pred(T)::(pred(out) is cc_multi))
			is cc_multi.

	...

I'm not making any claims that this would be a great thing, however.
I'm undecided.  Part of me is thinking that light-weight higher-order
syntax and support for monadic style would go a long way.

- Ralph
--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list