[Top][All Lists]

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

Re: O(n) patches and side effects

From: Eric Blake
Subject: Re: O(n) patches and side effects
Date: Thu, 21 Aug 2008 19:37:03 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20080708 Thunderbird/ Mnenhy/

Hash: SHA1

According to Ralf Wildenhues on 8/21/2008 5:12 PM:
> Hi Eric,
> I'm looking through a bunch of the O(n) patches, and asking myself:
> The fact that rescanning is avoided (by one means for m4-1.4.x and
> another in m4-1.6.x), does that add a slight backward incompatibility
> if the macro arguments contains side-effects?  I'm thinking of stuff
> like m4_syscmd and esyscmd that could affect external state; aren't
> they possibly run a different number of times now?  If yes, can we
> also think of internal side effects that may matter to users, like
> redefinitions or so?

Good question (and in hacker terminology, that's a compliment).  Many of
the list macros keep their arguments quoted throughout (for example,
m4_case), or unquote exactly once per iteration (for example,
m4_transform), giving identical behavior for both algorithms.  The only
thing we have to worry about are the cases where a macro gets a quoted
list but then expands it before iterating over the elements.  For the most
part, these macros should see ALL side effects exactly once, up front,
before any of the list elements are evaluated, and none of my recent
patches changed that:

m4_foreach([i], [[1], [2]m4_errprintn([hi])], [i])
=> hi
=> 12

But after auditing all of the macros in foreach.m4, I noticed the
following exceptions: In m4 2.61, m4_map and m4_map_sep evaluated their
list twice, but in current git, both algorithms for these macros only
evaluate the list once (this is a subtle change in semantics, but unlikely
to break anything, and certainly more consistent with m4_foreach).
Unfortunately, the my new macro m4_mapall_sep currently evaluates its list
twice (for both algorithms):

m4_map_sep([m4_echo], [-], [[[1]], [[2]]m4_errprintn([hi])])
m4_mapall_sep([m4_echo], [-], [[[1]], [[2]]m4_errprintn([hi])])

Even worse, side effects in m4_list_cmp depend on the underlying algorithm
and on the lists being compared:

recursive (usually once, but in an awkward order, but sometimes not at all):
m4_list_cmp([m4_errprintn([hi])0], [m4_errprintn([bye])0])
m4_list_cmp([m4_errprintn([hi])0], [m4_errprintn([hi])0])

forloop (three times, and still an awkward order):
m4_list_cmp([m4_errprintn([hi])0], [m4_errprintn([bye])0])

Hmm, I guess that means I should beef up the testsuite, as well as
patching these misfits to guarantee exactly one expansion of side effects.
Then the manual should indeed call this out as a design rule of thumb when
working with quoted lists - all side effects in the list are expanded
once, up front, before the list elements are visited.  Thanks for the report!

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