tech-userlevel archive

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

Re: make: new modifyer :Y



On Tue, Nov 08, 2011 at 04:13:19PM +0100, Anthony Mallet wrote:
 > On Tuesday, at 12:45, Aleksey Cheusov wrote:
 > | Anyway, I hope someone with better knowledge of bmake's internals answers
 > | to Anthony's proposal to treat "yes" and "no" in boolean context as 1
 > 
 > I had a 2 minutes look and concluded that this was not trivial to
 > get into that part of the code.  However, I can have a deeper look
 > if there is an interest.

It is perhaps(*) a good idea eventually, but not now -- when/if things
can be bashed into a reasonable state for an interpreter it should be
a straightforward patch, but until then it'll probably make the mess
worse.

(*) The problem, and the thing to think about, is making sure the eval
rules stay sane and sound. The problem with implicit conversions, or
at least implicit conversions that aren't isomorphisms, is that they
can make equality non-transitive; this makes interesting traps for the
unwary both in the implementation and when using the language.

For example, if you promote strings to booleans like this, then
both "Yes" and "yES" are true, so whether one is equal to the other
depends on whether a conversion to boolean is made before comparison.
I'm not having any luck coming up with an example of a way to get
hosed by this, especially given the limited contexts in which make
recognizes or evaluates boolean expressions. But I'm far from
convinced there aren't any such ways.

In a more typical language, you can get hosed as follows. Start off
with a boolean expression:

   (A1 == A2) == (B1 == B2)

So far so good - whatever the variables are this will do the expected
thing. Now let's suppose these comparisons appear a lot, so we factor
them out:

   A = (A1 == A2)
   B = (B1 == B2)
    ...
   A == B

The variables A and B will be (dynamically) typed as boolean and the
final comparison will be done as boolean as well and it will still
behave as expected. But now let's wire down A:

   A = "Yes"
   B = (B1 == B2)
    ...
   A == B

With suitable implicit promotion this still works. Likewise, it still
works if A is left alone and B is wired down. But if you wire them
both down...

   A = "Yes"
   B = "yes"
    ...
   A == B

suddenly the comparison is done as strings and becomes false, and the
program logic fails, probably (by Murphy's Law) in a subtle and
aggravating way.

And it's far from impossible to accidentally wire the two variables
down to different spellings of true; e.g. if you have one in some
equivalent of mk.conf, or if it's become the system default, and the
other is presented on the equivalent of the make command line.

One of the goals/problems in language design is to sort out the
evaluation and typing rules to prevent, or at least minimize, the
existence of this kind of anomalous behavior.

There are various ways to fix this particular example; the important
question is how many other cases like it there are, how many of them
actually matter to make in the specific context of how variables get
expanded/evaluated in make, and how exactly to handle the implicit
string -> boolean conversion to avoid them as much as possible.

Even for booleans this isn't a particularly simple problem...

-- 
David A. Holland
dholland%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index