| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#11
| |||
| |||
| Martin Krischik <krischik@users.sourceforge.net> writes: > Actually it is good example - for both: > > 1) Log to both Disk and Network and return true if at least one was > successful: > > Log_To_Network (Message) or Log_To_Disk (Message) > > 2) Log to Network and if that fails log to Disk and return true if at > least one was successful: > > Log_To_Network (Message) or else Log_To_Disk (Message) > > And it shows nicely the why there are two: The programmer can decide > which behaviour he / she wants. My problem is not with the theoretical elegance as such, but rather that "or" vs "or else" is not immediately clear to me. As a multi-language programmer, I am really really used to thinking of boolean or as "if one is true we don't care about the other". This instinct is reenforced both from the current popular languages as well as from formal proof styles in programming methodology. So, I don't like relying the execution of both disjuncts. Sure, I could use "or else" consistently, but I like thinking of boolean or as good old regular boolean or. So, my preference for the first log example (do both, return success of at least one is: declare Network_Logged : Boolean := Log_To_Network(Message); Disked_Logged : Boolean := Log_To_Disk(Message); begin return Network_Logged or Disked_Logged; end; -- Cheers, The Rhythm is around me, The Rhythm has control. Ray Blaak The Rhythm is inside me, rAYblaaK@STRIPCAPStelus.net The Rhythm has my soul. |
|
#12
| |||
| |||
| "mockturtle" <framefritti@gmail.com> wrote in message news:18b41828-bda4-4484-8884-ad62ce1c831d@f36g2000hsa.googlegroups.com... > Dear.all, > today while I was writing in my favorite language > (PERL with C extensions, of course :-)))) I wondered why in Ada the > "shortcut and" is "and then", while the simple "and" has not > a shortcut behaviour. My curiosity stems from the fact that > I am not able to envision any situation where the "non shortcut" > version would preferable, but I immagine that there was some > reason for this choice. Do anyone have any hint? > > Thank you in advance. There are cases where both arguments to an "and" operator should always be used. For example if you have Function A and Functon B involved in a condition: if A(x) and B(y) then ... do something end if; If short circuit evalution is permitted then more complex logic is required to assure that both arguments are evaluated: resultA := A(x); resultB := B(z); if resultA and resultB then ... do something end if; With Ada you can choose whether or not you want short circuit evaluation. If you require short circuit evaluation you must convey that information to the compiler. If you do not require short circuit evaluation you can convey that information as well. The more the compiler knows about your requirements, the greater the potential for optimization. The form used also conveys information about the code to programmers reading the code. Regards, Steve |
|
#13
| |||
| |||
| Ray Blaak schrieb: > Martin Krischik <krischik@users.sourceforge.net> writes: >> Actually it is good example - for both: >> >> 1) Log to both Disk and Network and return true if at least one was >> successful: >> >> Log_To_Network (Message) or Log_To_Disk (Message) >> >> 2) Log to Network and if that fails log to Disk and return true if at >> least one was successful: >> >> Log_To_Network (Message) or else Log_To_Disk (Message) >> >> And it shows nicely the why there are two: The programmer can decide >> which behaviour he / she wants. > > My problem is not with the theoretical elegance as such, but rather that "or" > vs "or else" is not immediately clear to me. > As a multi-language programmer, I am really really used to thinking of boolean > or as "if one is true we don't care about the other". Funny I am not - probably because my first languages where Basic and Pascal - and Basic and Pascal do not guarantee short cut boolean. Modern Basic and Pascal dialects might have it but it is not guaranteed in the language itself. > This instinct is > reenforced both from the current popular languages as well as from formal > proof styles in programming methodology. When I was at Polytechnic first language was PL/1, second Pascal and therefore methodology was different. i.E. Don't rely on the execution order of boolean expressing. > So, I don't like relying the execution of both disjuncts. Sure, I could use > "or else" consistently, but I like thinking of boolean or as good old regular > boolean or. They are not necessarily both executed with plain old OR and AND either. Plain old OR and AND leaves all options open to the optimizer: Out of order execution Common subexpression elimination or dead code elimination. If the optimizer determines that the 2nd expression has no side effects it might optimize it away. But note that raising CONSTRAINT_ERROR is a side effect. So: if X /= null and x.all = 5 then Do_Something; end if; will most likely become: if x = null then raise CONSTRAINT_ERROR; elif x.all = 5 then Do_Something; end if; Or - for a CPU with hardware null pointer detection - it might become: if x.all = 5 then Do_Something; end if; Ada is a language which highly rely on the existence of an optimizer. Unlike the C style languages - the very first C did not have an optimizer and it still show in the syntax and semantic.- One should always remember C's main design goal: compiler must fit's into 8 kb of memory. It explains a lot. Anyway by default Ada leaves all option options open to the optimizer. For example: type Byte is range -128 .. 127; might not actually be a byte - especially when optimized for performance. By default all options are open to the optimizer to make the best of you wish. Only when you start restricting the optimizer with for Byte'Size use 8; you are guaranteed an 8 bit type. You consider this when thinking of "or else" and "and then" - both restrict the optimizer in it's doing and the result might not be faster. Regards Martin -- mailto://krischik@users.sourceforge.net Ada programming at: http://ada.krischik.com |
|
#14
| |||
| |||
| On Mon, 1 Sep 2008, Steve wrote: > If short circuit evalution is permitted then more complex logic is required > to assure that both arguments are evaluated: > > resultA := A(x); > resultB := B(z); > if resultA and resultB then > ... do something > end if; If I actually require to run both functions A and B, I always write something like the above (typically inside a declare ... begin ... end), because I think that makes my intention clearer than by just writing "and" (or "or"). > With Ada you can choose whether or not you want short circuit evaluation. > If you require short circuit evaluation you must convey that information to > the compiler. If you do not require short circuit evaluation you can convey > that information as well. The more the compiler knows about your > requirements, the greater the potential for optimization. True. But the case that you want both expressions to be evaluated is a rare exception. On a *logic* level, "A and B" implies "if A is false, the result is false, regardless of B". So short-circuit evaluation is a natural and good thing for a programming language, and it is regrettable that Ada needs a more complex syntax for this. (Well, "A and B" also implies "if B is false, don't care about A", but in a programming language you can't have it both ways.) But, as others pointed it: IF the default "and" supported short-circuit-evaluation, THEN this "and" could not be an ordinary Ada operator. At the language semantic level, it is much more reasonable to treat "and" like any other operator or function, such as "+" and "-". So the inventors of Ada decided on a special syntax for short-circuit evaluation. But I wish Ada would support some sort of lazy evaluation for subprogram arguments. So long Stefan -- ------ Stefan Lucks -- Bauhaus-University Weimar -- Germany ------ Stefan dot Lucks at uni minus weimar dot de ------ I love the taste of Cryptanalysis in the morning! ------ |
|
#15
| |||
| |||
| stefan-lucks@see-the.signature schrieb: > True. But the case that you want both expressions to be evaluated is a > rare exception. On a *logic* level, "A and B" implies "if A is false, the > result is false, regardless of B". So short-circuit evaluation is a > natural and good thing for a programming language, and it is regrettable > that Ada needs a more complex syntax for this. That's not what I learned in my boolean arithmetic classes. > (Well, "A and B" also > implies "if B is false, don't care about A", but in a programming language > you can't have it both ways.) That is what I learned in my boolean arithmetic classes. It's either way. There is no preference that the left parameter if more important then the right. A Human seeing "A∧0" won't evaluate A. And if you see "f(x)∧g" you would probably evaluate g first as a variable is usually easier to evaluate then a function. And it is what you have in Ada - with plain old "and" and "or" the optimizer is free to do out of order evaluation and dead code elimination which could well lead to B being evaluated first and A being optimized away if B already determines the final result. This - of course - only if the compiler can also determine that A and B have no side effect. Side effect are that little difference between arithmetic and programming. The CONSTRAINT_ERROR in: if X /= null and x.all = 5 then Do_Something; end if; or the global variable which f(x) might change: function f(x:Integer) is begin if x > 10 then g = false; end if; return x > 5; end f; It's all about those side effect which make order of evaluation so important. Otherwise it should not matter. Note that once you add: pragma Inline (f); to the example above things become very interesting for the optimizer ;-) (do remember that the optimizer will use goto without shame). > But, as others pointed it: IF the default "and" supported > short-circuit-evaluation, THEN this "and" could not be an ordinary Ada > operator. At the language semantic level, it is much more reasonable to > treat "and" like any other operator or function, such as "+" and "-". Well again, in my arithmetic classes I learned that a+b is the same and b+a - which includes that the order of evaluation is of no importance. If you want that ∧ operates the same way as + then "a∧b" must be the same as "b∧a". Martin -- mailto://krischik@users.sourceforge.net Ada programming at: http://ada.krischik.com |
|
#16
| |||
| |||
| stefan-lu...@see-the.signature wrote: > True. But, at the logic level, the Ada-statement > > if (X >= A'First) and (X <= A'Last) and (A[X]=Y) then > ... > else > ... > end if; > > should *not* raise a Constraint_Error if X < A'First or X > A'Last, but > instead handle the "else" case. Except that X may be a function returning a different value for each call! > True enough, at the logic level the same should hold for > > if (A(x)=Y) and (X >= A'First) and (X <= A'Last) then ... end if; > > > It's all about those side effect which make order of evaluation so > > important. Otherwise it should not matter. > > The bad thing is that Constraint_Error counts as a valid side effect here. And what would be an "invalid" side effect? > Ideally, the program should check the other branches of the "and" > expression, and only propagate the exception if none of them evaluates to > false without raising an exception of its own. No, because the Constraint_Error (or other exception, or other side effect such as logging, assignment to a variable, etc.) may be intentional! The compiler does not and should not try to read your mind. At least I would find it very disturbing to program in a language that would try to "do what I mean, not what I say". > Consider a programm fragment like > > if X and Y then > ... > end if > > Assume Y raises a Constraint_Error if X is false. This appears to be a > common bug pattern in Ada. I have seen this several times in Ada > sourcecode, and *never* it was the programmer's intention to raise an > exception if X is false ... except when an exception was raised > explicitely in the else branch. Even then, the programmers typically > expected the exception they raised there, not Constraint_Error. I have seen this bug a couple of times and always concluded it was *my* fault and that I should have used "and then" to specify that the order of evaluation was important. In such situation the mathematical "and" (where "X and Y" is strictly equivalent to "Y and X") is not what I want. I definitely like the fact that Ada gives me the choice (short-circuit or full evaluation) and the means ("and" vs. "and then") to express my intent exactly. -- Ludovic Brenta. |
|
#17
| |||
| |||
| > > (Well, "A and B" also > > implies "if B is false, don't care about A", but in a programming language > > you can't have it both ways.) > > That is what I learned in my boolean arithmetic classes. It's either > way. There is no preference that the left parameter if more important > then the right. A Human seeing "A∧0" won't evaluate A. And if you see > "f(x)∧g" you would probably evaluate g first as a variable is usually > easier to evaluate then a function. True. But, at the logic level, the Ada-statement if (X >= A'First) and (X <= A'Last) and (A[X]=Y) then ... else ... end if; should *not* raise a Constraint_Error if X < A'First or X > A'Last, but instead handle the "else" case. True enough, at the logic level the same should hold for if (A(x)=Y) and (X >= A'First) and (X <= A'Last) then ... end if; > It's all about those side effect which make order of evaluation so > important. Otherwise it should not matter. The bad thing is that Constraint_Error counts as a valid side effect here. Ideally, the program should check the other branches of the "and" expression, and only propagate the exception if none of them evaluates to false without raising an exception of its own. Consider a programm fragment like if X and Y then ... end if Assume Y raises a Constraint_Error if X is false. This appears to be a common bug pattern in Ada. I have seen this several times in Ada sourcecode, and *never* it was the programmer's intention to raise an exception if X is false ... except when an exception was raised explicitely in the else branch. Even then, the programmers typically expected the exception they raised there, not Constraint_Error. I admit, we will not get this "ideal" behavoiur in any usable programming language. What happens, e.g., if two different exceptions are raised when evaluating "A and B"? Which exception should be propagated? In the absence of this "ideal" behaviour, a short-circuit behaviour of "and" and "or" would eliminate a common bug pattern in Ada. I would consider it the lesser evil, compared to the current situation. > Note that once you add: > > pragma Inline (f); > > to the example above things become very interesting for the optimizer > ;-) (do remember that the optimizer will use goto without shame). Funny idea! ;-) But at the end, there are lots of gotos ("jumps", "branches") in assembler code, with or without pragma inline or optimisation. -- ------ Stefan Lucks -- Bauhaus-University Weimar -- Germany ------ Stefan dot Lucks at uni minus weimar dot de ------ I love the taste of Cryptanalysis in the morning! ------ |
|
#18
| |||
| |||
| > But do you really dispute that following the mathematical conventions > as much as possible would improve readability? Of course not. That's wgy "and" should have its mathematical meaning - i.e it should not impose an order of evaluation and it should not avoid evaluating its operands. That's what "and then" is for. > A short-circuit "and" (instead of "and then") would not remove that choice > -- see the "much better style" above. But it would break the mathematical purity of "and". -- Ludovic Brenta. |
|
#19
| |||
| |||
| On Tue, 2 Sep 2008, Ludovic Brenta wrote: > stefan-lu...@see-the.signature wrote: > > if (X >= A'First) and (X <= A'Last) and (A[X]=Y) then > > ... > > else > > ... > > end if; > > > > should *not* raise a Constraint_Error if X < A'First or X > A'Last, but > > instead handle the "else" case. > > Except that X may be a function returning a different value for each > call! On the level of formal logic, there isn't really space for side effects. > > The bad thing is that Constraint_Error counts as a valid side effect here. > > And what would be an "invalid" side effect? A "valid" side effect would, e.g., be changing a global variable. On the other hand, a function which raises an exception is essentially a function returning some value outside its domain (but inside an extended domain). This isn't quite like a side-effect -- only Ada pretends it is. > > Ideally, the program should check the other branches of the "and" > > expression, and only propagate the exception if none of them evaluates to > > false without raising an exception of its own. > > No, because the Constraint_Error (or other exception, or other side > effect such as logging, assignment to a variable, etc.) may be > intentional! The compiler does not and should not try to read your > mind. At least I would find it very disturbing to program in a > language that would try to "do what I mean, not what I say". Well, if the program requirements are that the side effects for A and B actually occur, I consider it poor programming style if people just write if A(X) and B(Y) then ... end if; IMHO, much better style is the following: declare Tmp_A: Boolean := A(X); Tmp_B: Boolean := B(X); begin if Tmp_A and Tmp_B then ... end if; end; This makes the programmers intention clear, "if A(X) and B(X)" doesn't. > > Consider a programm fragment like > > > > if X and Y then > > ... > > end if > > > > Assume Y raises a Constraint_Error if X is false. This appears to be a > > common bug pattern in Ada. [...] > I have seen this bug a couple of times and always concluded it was > *my* fault and that I should have used "and then" to specify that the > order of evaluation was important. In such situation the mathematical > "and" (where "X and Y" is strictly equivalent to "Y and X") is not > what I want. Right! But do you really dispute that following the mathematical conventions as much as possible would improve readability? > I definitely like the fact that Ada gives me the choice (short-circuit > or full evaluation) and the means ("and" vs. "and then") to express my > intent exactly. A short-circuit "and" (instead of "and then") would not remove that choice -- see the "much better style" above. In any case, instead of an explicit syntax for short-circuit "and" an explict syntax for the rare non-short-circuit cases would be preferable, perhaps "if A(X) and all B(Y) then ... end if;". -- ------ Stefan Lucks -- Bauhaus-University Weimar -- Germany ------ Stefan dot Lucks at uni minus weimar dot de ------ I love the taste of Cryptanalysis in the morning! ------ |
|
#20
| |||
| |||
| > > And what would be an "invalid" side effect? > > A "valid" side effect would, e.g., be changing a global variable. On the > other hand, a function which raises an exception is essentially a function > returning some value outside its domain (but inside an extended domain). > This isn't quite like a side-effect -- only Ada pretends it is. To be clear, if "function F(...) return Boolean" may raise an exception, such as Constrained_Error, we essentially have a three-valued logic -- the function can return - either "true2, - or "false2, - or raise an exception, which is tantamount to returning "undefined". -- ------ Stefan Lucks -- Bauhaus-University Weimar -- Germany ------ Stefan dot Lucks at uni minus weimar dot de ------ I love the taste of Cryptanalysis in the morning! ------ |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.