> Timon Gehr: > >> The problem is that generated/CTFE'd code might produce that kind of >> redundancy. > > Right. > > >> Proving that two sub-expressions are equivalent is a hard task. > > A simple equivalence is enough here: the code with normalized whitespace. > Those tools are probably doing something not much complex than this. > > >> Has anyone ever >> experienced a bug that was hard to find similar to those toy examples? Well, >> maybe >> if(x||y||z||a||b||x||d){/*do stuff*/}, but who writes such code? > > The examples I've shown are present in real code. See the results of the Coccinelle project too.
Okay, I see. Lexical equivalence can catch the infamous copy-paste bugs. An alternative is to never ever copy-paste code. But unfortunately the compiler cannot enforce this, catching only the most trivial cases. I think it might be a good idea though. However, having this feature means requiring one AST compare for every boolean operator. > > >> But if a programmer wants to use it, he has >> to be familiar with its precedence rules (very simple, lower precedence than >> anything but = and ,). > > In computer languages there are plenty simple things that are bug-prone. > > >> I as an excessive user of ?: am very much against it though. > > It's not advisable to use the ?: operator a *lot* :-) I use it whenever I would have to write either if(c) x=y;else x=z; // => x=c?y:z; or if(c) x=z;else y=z; // => c?x:y=z; This reduces code duplication, mostly when x or z are complicated expressions. I do not use it often in larger arithmetical expressions though. Unfortunately, D's conditional operator is not quite as mighty as C++'s (Eg, it cannot throw an exception). On the plus side, it is simple (0.5 p in TDPL, where C++ allocates 1.5 p in the standard to it). I also like g++ style x?:y; > > >> I think requiring parentheses (providing undefined or ambiguous precedence >> rules) >> is ugly. D has done it before and it seems reasonable to do so, but still >> ugly. > > I don't see better solutions given the D Zen contraints. And in this case > adding parentheses may be better than doing nothing. I agree. You usually don't want to do this anyways. > If you have some comments about this bug #1, a good place to add them is here: > http://d.puremagic.com/issues/show_bug.cgi?id=5409 > > >> It also implies that the precedence rules would be a design mistake if not >> for compatibility with C. > > I don't fully understand. The fact that that kind of manual disambiguation is necessary implies that the precedence rules are counter-intuitive to many programmers. Eg if a&b/a<<b would behave more like a*b than a&&b/wtf, I think there would be less precedence related bugs. But of course, this breaks compatibility with C. If however C never existed, the precedence rules would be suboptimal. > > >> What property makes them so bug-prone? > > I am not sure, but I think it encourages a too much compact code style (and > you have to be a bit careful with operator precedence too). Probably there is some optimum for > compactness of C-like code. The sources of the first J interprer is surely too much compact, and some C# code I've seen seems not enough compact to the point of not allowing > an easy read. Afaik the average programmer introduces a new bug every 20 lines of code or so. Therefore, you better get your work done in less than that. ;) @C# comment: I totally agree. And the usual convention to have { waste an entire line of horizontal space does not make this any better. Unfortunately, balancing the compactness in an optimal way is not possible, because the optimum varies between programmers. I appreciate the fact, that in D most likely "very compact" is the optimal choice most of the time. > > >> I think they are quite easy to use. > > Right, the ?: operator is easy to use. > > Thank you for your comments, bye, > bearophile The best feature to crush bugs would still be automated model checking, let's hope good program provers will be available soon =). Timon