[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: m4_lambda

From: Eric Blake
Subject: Re: m4_lambda
Date: Mon, 19 Jan 2009 07:04:47 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20081209 Thunderbird/ Mnenhy/

Hash: SHA1

According to Paolo Bonzini on 1/19/2009 4:56 AM:
>> Meanwhile, I'm wondering if it is worth trying to add some syntactic sugar 
>> to 
>> make anonymous macros easier to use.  My initial thoughts (but only lightly 
>> tested) is that something like this would make it easier to write macro 
>> definitions which in turn define other (possibly anonymous) macros:
> This m4_(un)defer seems okay and it makes sense to do it automatically
> within m4_lambda.  But the need to use dquote escapes me, and it seems
> to make m4_lambda close to unusable in practice, except for forwarding
> to another macro in ways more advanced than what m4_curry allows.  Can
> you explain?

I'm starting to lean towards escaping/unescaping with $_1 rather than
$][1, as that needs less changequote.  But the idea is this - when
defining one macro which in turn defines another, you almost always need
at least one intermediate macro to form any literal $1 that will be used
in the secondary definition.  In other words, if you define a macro which
in turn calls m4_lambda, you need some form of escaping to preserve the $1
that should be in the definition of the anonymous macro, rather than
fixing it as your macro's first parameter.

There are multiple ways of doing this, but some are more expensive than
others.  Each of the following show a way to define inner such that the
first parameter passed to m4_echo is the remembered parameter of outer,
and the second word is the first argument of inner:

# use of m4_dquote to construct nested [$1]
[m4_define([inner], [m4_echo([$1], ]m4_dquote([$][1])[)])])

# use of m4_undefer to convert [$_1] to [$1]
[m4_define([inner], m4_undefer([m4_echo([$1], [$_1])]))])

# use of _outer with literal argument $1 substituted in correct place
m4_define([outer], [_outer([$1], [$][1])])
[m4_define([inner], [m4_echo([$1], [$2])])])

When using m4_lambda at the top level, there is no need to automatically
unescape macros; but if most uses of m4_lambda are within another macro
definition, then having a wrapper that does the unescape automatically
does indeed make m4_lambda easier to use.  For efficiency sake, though, I
may end up leaving m4_lambda as is and instead providing a wrapper that
does both the unescape and the m4_lambda, where the wrapper is the tool of
choice inside macro definitions.

Also, note that with the above example, calling outer([$][2]) ends up
defining inner that operates on a second argument, rather than passing a
literal $2 as the first argument to inner's m4_echo.  If you want to fix
the definition of an inner macro to use text provided as an argument to
the outer macro but without the inner macro interpolating $ in the string,
even more escaping/unescaping effort is required.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at
Comment: Using GnuPG with Mozilla -


reply via email to

[Prev in Thread] Current Thread [Next in Thread]