February 11, 2003 Re: Expression eval order, why unordered ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | Burton Radons wrote:
> I'm not going to defend K&R's decision, regardless of why they made it (I'll ask Ritchie). It was the right one to say that this code was bad, it was the wrong one to say that this code was C. It was before lint was a part of the compiler, after all. Now that those dark days are behind us, the language should reflect the current art.
Here's what Ritchie says. Searching on "eh zed language" gives me a bunch of Canadian dialect matches. :-) FOLDOC implies they're both dead (last references in the 70's).
I'm not opposed to the change in itself. My opposition is to using it; it should be like precedence below the BEDMAS level, defined for portability but not intended for use. So I think that if we make this change, code which depends upon evaluation order should still be banned, but if you accidentally have a complex side-effect dependency, your code won't act weird on different platforms.
--
Once the decision was made to allow assignments
(and other alterations) within expressions, the question
is what they mean. The fact is that every language
except the most purely functional has to deal
with the issue in some way. C puts it more
in-the-face than others (e.g. with ++ and --),
but when you think about what f()+f() might
do in just about any language with global
state or I/O, it comes up.
In the case of C, the definition is reasonably clear
that func(++c * ++c) is undefined (although
this particular case is likely to yield consistent
results).
There are languages (e.g. at least one of the B or C-based Waterloo
languages, Eh and Zed) that insist on strict left-to-right
evaluation within an expression so that things
like x[i++] = i, undefined in C, become defined.
C decided not to do that, although the evidence
from there was that not many possibilities for
optimization were lost. (But I don't think they
had an aggressive optimizer).
|
February 11, 2003 Re: Expression eval order, why unordered ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | Burton Radons wrote: > Burton Radons wrote: > >> I'm not going to defend K&R's decision, regardless of why they made it (I'll ask Ritchie). It was the right one to say that this code was bad, it was the wrong one to say that this code was C. It was before lint was a part of the compiler, after all. Now that those dark days are behind us, the language should reflect the current art. > > > Here's what Ritchie says. Searching on "eh zed language" gives me a bunch of Canadian dialect matches. :-) FOLDOC implies they're both dead (last references in the 70's). Whoops, I just made the quotes confusing. The above is me talking. > I'm not opposed to the change in itself. My opposition is to using it; it should be like precedence below the BEDMAS level, defined for portability but not intended for use. So I think that if we make this change, code which depends upon evaluation order should still be banned, but if you accidentally have a complex side-effect dependency, your code won't act weird on different platforms. The above is me talking. > -- > > Once the decision was made to allow assignments > (and other alterations) within expressions, the question > is what they mean. The fact is that every language > except the most purely functional has to deal > with the issue in some way. C puts it more > in-the-face than others (e.g. with ++ and --), > but when you think about what f()+f() might > do in just about any language with global > state or I/O, it comes up. > > In the case of C, the definition is reasonably clear > that func(++c * ++c) is undefined (although > this particular case is likely to yield consistent > results). > > There are languages (e.g. at least one of the B or C-based Waterloo > languages, Eh and Zed) that insist on strict left-to-right > evaluation within an expression so that things > like x[i++] = i, undefined in C, become defined. > C decided not to do that, although the evidence > from there was that not many possibilities for > optimization were lost. (But I don't think they > had an aggressive optimizer). The above is Ritchie talking. |
February 13, 2003 Re: Expression eval order, why unordered ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Wynn | On Sun, 9 Feb 2003 07:48:25 -0000, Mike Wynn <mike.wynn@l8night.co.uk> wrote: > that veiw depends on what you think operators do > > with this same logic the code `func() + other()` is also undefined `other()` > may be called before `func()` > (these is nothing in the docs to say the order is defined, thus it is > undefined (that is in the docs)) It's only undefined if the program has different behavior depending on which function is called first. > a() + b() * c() the only thing defined is b() * c() is performed before the > + and both function calls before * > but c() may be called before b(); Not even that is defined; a() could be evaluated first, but the result not used for anything until the results of b() and c() have been computed and multiplied. > In know , op and , in func call are different because c pushes param in > reverse order. > I don't belive that is enough of a reason to make the eval order undefined. > the , operator when outside a func call does force order, it is defined as > such. The , operator outside of a function or a for statement is evil, and good code shouldn't depend on order-of-evaluation in the latter case either. > basically to write robust code that will perform correctly no matter which > compiler is used, the programmer has to break the program up into simple > statements > func() * func2(); has to become tmp = func(); tmp *= func2(); Only if calling func2() first would cause a problem. If it does, you *should* write it that way, regardless of the languages order-of-evaluation rules, since it makes it clear to someone reading the code that there is a dependency. > It may be my simple view of the world, and use of single cpu sisd machines that leads me to view all programs as a set of single threads of execution, I do not see what is gained by thinking of func( c++, c++ ) as two concurrent increments it has not value so why consider it ? That particular case doesn't buy much, however more complex expressions could. For example, if you have func(foo(), bar()), and bar() is inlineable but foo() isn't, the compiler may want to inline (part of) bar() before foo() is called, due to it pairing well with other previous instructions. If you force foo() to be evaluated first, the compiler can't do that. > the whole rest > of the program has a defined order, why treat expressions so differently. > the whole point about eval order is - when there is a dependancy order is > defined. > func( c++, b++ ) is conceptually concurrent (no dependancy) even if eval > order is defined. Yes, but it's not always easy for the compiler to tell if there is a dependency (especially if functions are involved). > I find it natural to read and understand the eval order of Java code, and can not understand why people are adverse to such a simple concept especially as it is benificial, unordered eval is determental, by its nature you can not know what it happening, that is never good. Ordered eval is detrimental in that it can produce slower code, and makes legal an obfuscation. The only benefit is to make bad code more deterministic, but there are still plenty of other ways that bad code can be non-deterministic (especially if threads or pointers are used), so it doesn't really solve that problem either. -Scott |
February 14, 2003 Re: Expression eval order, why unordered ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@directvinternet.com> wrote in message news:b24f8d$1jbv$1@digitaldaemon.com... > This is why I like D's (to-be-implemented-in-future) array operation feature, where operations can be performed on entire arrays. This doesn't guarantee any order of operation, and is implicitly parallelizable. The more we get away from pointers and start telling the compiler what we want the end results to be, in broad terms, rather than telling it every little detail of how to perform the operation, the better the compiler will be able > to generate optimal code. The restrictions on array slice overlap behavior > give the compiler the option of parallelizing slice operations. Yes. > When you write a for loop, you're building in dependence on the order of traversal, which is bad for parallelism. The compiler would have to prove that no iteration depends on the results of any other iteration before it can parallelize the loop. That's why I'm considering the "foreach" loop construct to not define the iteration order. In theory, if the array you're foreach'ing over has 1000 elements in it, the code could farm out each iteration to a separate processor (for a 1000 processor machine <g>), and the entire operation could be done in parallel. |
February 14, 2003 Re: Expression eval order, why unordered ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | "Burton Radons" <loth@users.sourceforge.net> wrote in message news:b24pfp$1op1$1@digitaldaemon.com... > Scott Wood wrote: > > BTW, I didn't see anything in the D spec about pointer/array aliasing (though I may have missed it), apart from a prohibition on overlapping array slice copies; what are D's semantics for this? > > There's no support at this point. One thing we could do is figure out which sets of arrays being operated on could have a much faster loop if they weren't aliased. Compile both versions, and select the SIMD version at runtime if they don't overlap. This could use profiling information to see whether it was beneficial, whether other sets of arrays used in the loop were unaliased instead of the ones we optimised, and whether we always got small arrays so shouldn't do any SIMD or loop optimisation. > > I don't know what Walter's thoughts on the matter are, though; I hope he weighs in, as I've wanted to know what he's thought of "restrict" for some time now. I'd rather adopt the noalias rule and allow more advanced compilers to be able to massively parallelize operations. |
February 14, 2003 Re: Expression eval order, why unordered ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | "Burton Radons" <loth@users.sourceforge.net> wrote in message news:b24q49$1p1f$1@digitaldaemon.com... > So then you agree with the way D is currently setup; code which is undefined is invalid code and should not compile. When Walter writes that identifying these errors is a "quality of implementation issue", he's not meaning noticing that "func (c ++, ++ c);" is shit code (which is easy), he's meaning that "*c = d ++;" is conditionally undefined. Incredibly complex compilers might be able to recognise it's undefined even though there's no casual way to do so, or could make runtime checks; asking all compilers to do this would be unreasonable and a good way to ensure that there are no conforming implementations of the language. You're right. |
Copyright © 1999-2021 by the D Language Foundation