On Thu, 2024-01-11 at 01:44 -0500, Paul Smith wrote: > I've implemented a new capability for conditional assignments (not > pushed yet). > > After these changes, a "?" can precede any type of assignment > operation, not just "=", and make it conditional (that is, it only > takes effect if the variable is not already set). > > There is one question I wanted to ask for opinions on: what should we > do with the "?+=" operator?
Having thought about this more the answer seems obvious. Better would be to say that BOTH "?" AND "+" are modifiers to assignment statements, and that you can have only one of them; this makes sense since either you want to set a value if it doesn't exist or you want to append to a value that does exist, but not both. Thus, the "base" assignment operators would be "=", ":=", "::=" (for POSIX), and ":::=". Then you could prefix any of those with either "?" so the assignment only happens if the variable is not defined, or "+" so the assignment is appended to any existing value. So we would allow assignments like "+=", "+:=", "+::=", "+:::=" as well as the "?" variants. This is useful because something like "+:=" has long been requested. So the new confusion becomes, what happens if you use "+" to append to an existing variable that has a different type? Due to decades of history (and, to be honest, significant technical incentive), we have to say that in this case: bar = xx biz = yy FOO := $(bar) FOO += $(biz) bar = 1 biz = 2 FOO is a simply-expanded variable and $(biz) is expanded immediately even though it uses a "+=" assignment, and FOO is "xx yy". But then, what do we say about this case: bar = xx biz = yy FOO = $(bar) FOO +:= $(biz) bar = 1 biz = 2 ? There appear to be two options: Either we could follow the example of "+=" and say that the assignment type in "+:=" only takes effect if the variable doesn't already have a type but if it does that type is preserved, so in the above example FOO would continue to be recursively expanded in spite of "+:=", so FOO has a value of "$(bar) $(biz)" and $(FOO) gives "1 2". Or we could say that "+=" is a special case where we follow the type of the existing variable, but for the other operators we first expand the right hand side then append the result regardless of the original type. So in the above example FOO is still a recursive variable, BUT $(baz) is expanded immediately before appending so the value of FOO would be "$(bar) yy" and $(FOO) gives "1 yy". Neither of these is great, in that they both will cause people to be surprised, in different situations. Given that, I'm leaning more towards the second option above, which leaves "+=" as a special case but seems more useful and less confusing overall. Comments welcome. -- Paul D. Smith <psm...@gnu.org> Find some GNU make tips at: https://www.gnu.org http://make.mad-scientist.net "Please remain calm...I may be mad, but I am a professional." --Mad Scientist