"Paul D. Smith" <[EMAIL PROTECTED]> writes: >%% Philip Guenther <[EMAIL PROTECTED]> writes: > > pg> It would greatly increase the expressiveness of GNU make's macro > pg> expansion if it was possible to define recursive macro functions. > pg> For example, here's a function that performs calculates the > pg> transitive closure of a set of dependencies: > > pg> # If $(firstword) is car, this is cdr: > pg> rest = $(wordlist 1,$(words ${1}),${1}) > > pg> tclose = $(if ${1},$(firstword ${1}) \ > pg> $(call tclose,$(sort ${DEP_$(firstword ${1})} \ > pg> $(call rest,${1})))) > >Heh. I see your point, but I have to say that your example proves >exactly the amount of danger involved with allowing this: your >definition of "rest" has a bug which causes this series to loop >infinitely! :)
Oops... > pg> Unfortunately, the restriction on recursive macros not referencing > pg> themselves includes references via $(call). I would argue that > pg> GNU make should not try to protect someone from themself if the > pg> write a recursive $(call). Yes, you can trivially write infinite > pg> loops if it's allowed, but the increase in expressiveness is > pg> substantial. > >OK, I buy this argument. As a test I removed the restriction on >recursive variable definitions and (with the above fix) your example >did work as you intended. Neat. > >However, I think the restriction is valid for normal variable >expansions, and most if not all builtin functions. Are there any other >builtins you think would benefit from loosening this restriction? The only other one which could legitimately benefit would be $(foreach), as it's the only other builtin which can change the value of a variable during expansion. That is, just as self-reference in $(call) can be done safely by conditioning the recursion on the values of the argument variables, self-reference in $(foreach) can be done safely by conditioning it on the value of the iteration variable. In fact, I _think_ the following pair of assignments would again implement transitive closure: tclose_ = ${dep} $(foreach dep,${DEP_${dep}},${tclose_}) tclose = $(sort $(foreach dep,${1},${tclose_})) ...but I think that's harder to read than the $(call) version. From the programming language perspective, $(call) is to be prefered as the variable 'reassignment' is part of the recursion machinery, instead of being done in the "parent's" $(foreach). Philip Guenther _______________________________________________ Bug-make mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-make