m4-discuss
[Top][All Lists]
Advanced

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

Re: Link time


From: Eric Blake
Subject: Re: Link time
Date: Thu, 15 Jan 2009 07:29:09 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.19) Gecko/20081209 Thunderbird/2.0.0.19 Mnenhy/0.7.5.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to address@hidden on 1/13/2009 11:11 PM:
> I am not sure if the subject heading is appropriately un-ugly enough; 
> there is more than enough out there on the subject of m4.
> Here are a few border-line awesome uses of m4:
> http://www.seindal.dk/rene/gnu/m4lib/

This used to be the m4 home page, before it migrated to savannah.  These
pages are still maintained in git (for that matter, they can only be
generated with a git snapshot, as it uses features not present in any
stable m4 release).

> http://uszla.me.uk/space/essays/m4Y
(and the prereq page, http://uszla.me.uk/space/essays/m4HOP/)

Interesting essay.  I hesitate to link to it from the manual, because it
has some robustness problems.  For starters, it claims that pushdef and
popdef are GNU extensions (this is false - those macros are required by
POSIX, and the example of lambdalite also works on Solaris and BSD m4).

Then it details a recursive re-implementation of length (obviously, you
would use the builtin len instead of this implementation in production,
but it serves as a great teaching tool); however, this implementation uses
substr under the hood, which is not robust to nested quoting occurring in
the argument, nor to the fact that substr returns its output unquoted and
thus subject to another layer of expansion.  For example, given the
definition in the article:

define(`length',`dnl
ifelse($1, `', 0, `dnl
eval(1+length(substr($1,1)))`'dnl
')`'dnl
')`'dnl

note that it reports length(`divnum') is 1 (assuming your current
diversion is 0), rather than 6.

[also, from an efficiency standpoint, that invokes a lot of dnl which can
slow down expansion; I would have written it:

define(`length',
  `ifelse(`$1', `', `0',
    `eval(`1+'length(substr(`$1',`1')))')')
]

However, I am not opposed to documenting the underlying concepts.  In
fact, note that I have already done a portion of just that (in the
eventual m4 1.4.13 manual), for macros that define other macros (although
I used a single invocation of a helper macro with literal arguments of $1
rather than two invocations of changequote in order to define a literal $1
into the target macro), and for a currying operation (although I did it
without resorting to pushdef and popdef; this is also the implementation
of m4_curry that is now present in autoconf's m4sugar):

http://git.savannah.gnu.org/gitweb/?p=m4.git;a=commitdiff;h=f3cbea82

so all that this essay really adds is the notion of a Y-combinator
operation.  So I will probably go ahead and see about adding more to the
manual to mention the concept of a Y-combinator macro (although I plan on
couching it in terms of factorial, rather than length).

> http://209.85.173.101/translate_c?hl=en&sl=ja&u=http://ya.maya.st/d/200703a.html&prev=/search%3Fq%3Dcurry%2Bm4%2BAND%2B%2522(*)define%2522%26start%3D20%26hl%3Den%26rlz%3D1G1GGLQ_ENUS241%26sa%3DN&usg=ALkJrhjp32n1_vh_FSwBXHu_DiAmJsrAVg#d20070306
> www.cs.stir.ac.uk/~kjt/research/pdf/expl-m4.pdf

There are some m4 constructs listed there, but even after the google
translation, I am not quite sure what you found in there that piqued your
interest.

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

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAklvSDUACgkQ84KuGfSFAYD3fgCgxVY1GHuIa49Vi84odeNamYNd
IHoAoLMU493UUZnzitsoFCKXE/1Pr9m9
=UT7h
-----END PGP SIGNATURE-----




reply via email to

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