-----BEGIN PGP SIGNED MESSAGE----- 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])]) =>hi =>1-2 m4_mapall_sep([m4_echo], [-], [[[1]], [[2]]m4_errprintn([hi])]) =>hi =>1hi =>-2 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]) =>bye =>hi =>0 m4_list_cmp([m4_errprintn([hi])0], [m4_errprintn([hi])0]) =>0 forloop (three times, and still an awkward order): m4_list_cmp([m4_errprintn([hi])0], [m4_errprintn([bye])0]) =>hi =>hi =>bye =>bye =>bye =>hi =>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 [EMAIL PROTECTED] -----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 iEYEARECAAYFAkiuGD8ACgkQ84KuGfSFAYD/qwCePtjw1to33RAJfCQR0Z6jyoJc lboAmwf24qtp9RLv41Yi3gffddVkx49t =BV+v -----END PGP SIGNATURE-----
