comp.lang.ada
 help / color / mirror / Atom feed
* and then... (a curiosity)
@ 2008-08-29 21:06 mockturtle
  2008-08-29 21:47 ` Samuel Tardieu
                   ` (2 more replies)
  0 siblings, 3 replies; 93+ messages in thread
From: mockturtle @ 2008-08-29 21:06 UTC (permalink / raw)


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.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-29 21:06 and then... (a curiosity) mockturtle
@ 2008-08-29 21:47 ` Samuel Tardieu
  2008-08-30 21:28   ` Maciej Sobczak
  2008-08-29 22:28 ` Adam Beneschan
  2008-09-02  3:41 ` Steve
  2 siblings, 1 reply; 93+ messages in thread
From: Samuel Tardieu @ 2008-08-29 21:47 UTC (permalink / raw)


> 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?

Sometimes, you want to ensure that both sides of the boolean operator
have been evaluated. Here is an example:

  --  Send the message to the log and return True if it
  --  has been logged at least at one place succesfully.

  function Log (Message : String) return Boolean is
  begin
     return Log_To_Network (Message) or Log_To_Disk (Message);
  end Log;

 Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-29 21:06 and then... (a curiosity) mockturtle
  2008-08-29 21:47 ` Samuel Tardieu
@ 2008-08-29 22:28 ` Adam Beneschan
  2008-08-30  1:06   ` Jeffrey R. Carter
  2008-08-30 11:21   ` Dmitry A. Kazakov
  2008-09-02  3:41 ` Steve
  2 siblings, 2 replies; 93+ messages in thread
From: Adam Beneschan @ 2008-08-29 22:28 UTC (permalink / raw)


On Aug 29, 2:06 pm, mockturtle <framefri...@gmail.com> wrote:
> 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?

Aside from Samuel's comment (sometimes you want both sides evaluated),
there are some very important differences.  "and" is a predefined
function and can be used wherever a function can (you can rename it,
pass it as parameter for a generic formal function, etc.).  Besides
the "and" on Booleans, there are predefined "and" functions on arrays
of Booleans and on modular types [both of those do bitwise AND's].
You can define your own "and" on other types if you like.  Like every
other function, the use of "and" requires that all (both) of its
arguments be evaluated.  The language also defines "or", "xor", and
"not" with similar properties.

"and then" is not a function, however, and has none of these
properties.

To make "and" [and "or"] on two Booleans behave like the short-circuit
form would introduce a major inconsistency into the language.

                                -- Adam





^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-29 22:28 ` Adam Beneschan
@ 2008-08-30  1:06   ` Jeffrey R. Carter
  2008-08-30 11:21   ` Dmitry A. Kazakov
  1 sibling, 0 replies; 93+ messages in thread
From: Jeffrey R. Carter @ 2008-08-30  1:06 UTC (permalink / raw)


Adam Beneschan wrote:
> 
> "and then" is not a function, however, and has none of these
> properties.
> 
> To make "and" [and "or"] on two Booleans behave like the short-circuit
> form would introduce a major inconsistency into the language.

In addition to the other reasons, there's the question of processor 
optimization. Although we have a sequential view of how code is executed, modern 
processors do all sorts of strange optimizations, such as speculative execution, 
that violate that sequential view. It's my understanding that the short-circuit 
forms can prevent such optimizations. Apparently, code that may evaluate only 
one of the 2 expressions can actually be slower than code that must evaluate both.

-- 
Jeff Carter
"If I could find a sheriff who so offends the citizens of Rock
Ridge that his very appearance would drive them out of town ...
but where would I find such a man? Why am I asking you?"
Blazing Saddles
37



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-29 22:28 ` Adam Beneschan
  2008-08-30  1:06   ` Jeffrey R. Carter
@ 2008-08-30 11:21   ` Dmitry A. Kazakov
  2008-08-30 15:35     ` Peter C. Chapin
  1 sibling, 1 reply; 93+ messages in thread
From: Dmitry A. Kazakov @ 2008-08-30 11:21 UTC (permalink / raw)


On Fri, 29 Aug 2008 15:28:16 -0700 (PDT), Adam Beneschan wrote:

> "and then" is not a function, however, and has none of these
> properties.

It could be made a function if Ada had lazy arguments.

I am unsure if the arguments of "and" are eager. You are a language lawyer,
I am not. But I used to think that the eagerness of evaluation is rather
unspecified, so that the compiler is free "not to care," when it optimizes
the code, as Jeff Carter has pointed out.

So basically, provided the above is correct, the choice was motivated by
least strong precondition (=unspecified eagerness), rather than by choosing
between eager and lazy evaluation.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-30 11:21   ` Dmitry A. Kazakov
@ 2008-08-30 15:35     ` Peter C. Chapin
  2008-09-02 15:06       ` Adam Beneschan
  0 siblings, 1 reply; 93+ messages in thread
From: Peter C. Chapin @ 2008-08-30 15:35 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> I am unsure if the arguments of "and" are eager. You are a language lawyer,
> I am not. But I used to think that the eagerness of evaluation is rather
> unspecified, so that the compiler is free "not to care," when it optimizes
> the code, as Jeff Carter has pointed out.

I thought all function arguments must be evaluated, but that it is
unspecified in which order this evaluation is done.

Peter



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-29 21:47 ` Samuel Tardieu
@ 2008-08-30 21:28   ` Maciej Sobczak
  2008-08-31  8:28     ` Georg Bauhaus
                       ` (2 more replies)
  0 siblings, 3 replies; 93+ messages in thread
From: Maciej Sobczak @ 2008-08-30 21:28 UTC (permalink / raw)


On 29 Sie, 23:47, Samuel Tardieu <s...@rfc1149.net> wrote:

> Sometimes, you want to ensure that both sides of the boolean operator
> have been evaluated. Here is an example:
>
>   --  Send the message to the log and return True if it
>   --  has been logged at least at one place succesfully.
>
>   function Log (Message : String) return Boolean is
>   begin
>      return Log_To_Network (Message) or Log_To_Disk (Message);
>   end Log;

This is actually a bad example. It might use "or else" and still
retain the semantics as described in the comment above.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-30 21:28   ` Maciej Sobczak
@ 2008-08-31  8:28     ` Georg Bauhaus
  2008-08-31 23:21       ` Ray Blaak
  2008-09-01  8:05     ` Martin Krischik
  2008-09-02 14:50     ` Adam Beneschan
  2 siblings, 1 reply; 93+ messages in thread
From: Georg Bauhaus @ 2008-08-31  8:28 UTC (permalink / raw)


Maciej Sobczak wrote:
> On 29 Sie, 23:47, Samuel Tardieu <s...@rfc1149.net> wrote:
> 
>> Sometimes, you want to ensure that both sides of the boolean operator
>> have been evaluated. Here is an example:
>>
>>   --  Send the message to the log and return True if it
>>   --  has been logged at least at one place succesfully.
>>
>>   function Log (Message : String) return Boolean is
>>   begin
>>      return Log_To_Network (Message) or Log_To_Disk (Message);
>>   end Log;
> 
> This is actually a bad example. It might use "or else" and still
> retain the semantics as described in the comment above.

"At least one" of the logs should, I guess, mean to try both.
I.e., the Log subprogram is not about its return value alone.
"Or" achieves all of that (the semantics).

"Or else" might also establish a strict preference for the
network log. "Or" should not.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-31  8:28     ` Georg Bauhaus
@ 2008-08-31 23:21       ` Ray Blaak
  0 siblings, 0 replies; 93+ messages in thread
From: Ray Blaak @ 2008-08-31 23:21 UTC (permalink / raw)


Georg Bauhaus <rm.tsoh.plus-bug.bauhaus@maps.futureapps.de> writes:
> Maciej Sobczak wrote:
> > On 29 Sie, 23:47, Samuel Tardieu <s...@rfc1149.net> wrote:
> > 
> >> Sometimes, you want to ensure that both sides of the boolean operator
> >> have been evaluated. Here is an example:
> >>
> >>   --  Send the message to the log and return True if it
> >>   --  has been logged at least at one place succesfully.
> >>
> >>   function Log (Message : String) return Boolean is
> >>   begin
> >>      return Log_To_Network (Message) or Log_To_Disk (Message);
> >>   end Log;
> > 
> > This is actually a bad example. It might use "or else" and still
> > retain the semantics as described in the comment above.
> 
> "At least one" of the logs should, I guess, mean to try both.
> I.e., the Log subprogram is not about its return value alone.
> "Or" achieves all of that (the semantics).
> 
> "Or else" might also establish a strict preference for the
> network log. "Or" should not.

This kind of confusion makes me prefer an unambiguous if-then-else statement.

-- 
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.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-30 21:28   ` Maciej Sobczak
  2008-08-31  8:28     ` Georg Bauhaus
@ 2008-09-01  8:05     ` Martin Krischik
  2008-09-01 17:56       ` Ray Blaak
  2008-09-02 14:50     ` Adam Beneschan
  2 siblings, 1 reply; 93+ messages in thread
From: Martin Krischik @ 2008-09-01  8:05 UTC (permalink / raw)


Maciej Sobczak schrieb:
> On 29 Sie, 23:47, Samuel Tardieu <s...@rfc1149.net> wrote:
> 
>> Sometimes, you want to ensure that both sides of the boolean operator
>> have been evaluated. Here is an example:
>>
>>   --  Send the message to the log and return True if it
>>   --  has been logged at least at one place succesfully.
>>
>>   function Log (Message : String) return Boolean is
>>   begin
>>      return Log_To_Network (Message) or Log_To_Disk (Message);
>>   end Log;
> 
> This is actually a bad example. It might use "or else" and still
> retain the semantics as described in the comment above.

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.

Martin

-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-01  8:05     ` Martin Krischik
@ 2008-09-01 17:56       ` Ray Blaak
  2008-09-02  6:53         ` Martin Krischik
  0 siblings, 1 reply; 93+ messages in thread
From: Ray Blaak @ 2008-09-01 17:56 UTC (permalink / raw)


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.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-29 21:06 and then... (a curiosity) mockturtle
  2008-08-29 21:47 ` Samuel Tardieu
  2008-08-29 22:28 ` Adam Beneschan
@ 2008-09-02  3:41 ` Steve
  2008-09-02  7:48   ` stefan-lucks
  2 siblings, 1 reply; 93+ messages in thread
From: Steve @ 2008-09-02  3:41 UTC (permalink / raw)


"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 





^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-01 17:56       ` Ray Blaak
@ 2008-09-02  6:53         ` Martin Krischik
  2008-09-02 14:56           ` Adam Beneschan
  2008-09-02 16:26           ` Ray Blaak
  0 siblings, 2 replies; 93+ messages in thread
From: Martin Krischik @ 2008-09-02  6:53 UTC (permalink / raw)


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



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02  3:41 ` Steve
@ 2008-09-02  7:48   ` stefan-lucks
  2008-09-02  8:57     ` Martin Krischik
  2008-09-03  1:24     ` Stephen Leake
  0 siblings, 2 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-02  7:48 UTC (permalink / raw)


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!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02  7:48   ` stefan-lucks
@ 2008-09-02  8:57     ` Martin Krischik
  2008-09-02 10:50       ` stefan-lucks
  2008-09-03  1:24     ` Stephen Leake
  1 sibling, 1 reply; 93+ messages in thread
From: Martin Krischik @ 2008-09-02  8:57 UTC (permalink / raw)


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



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 10:50       ` stefan-lucks
@ 2008-09-02 10:33         ` Ludovic Brenta
  2008-09-02 13:32           ` stefan-lucks
  2008-09-04  1:05         ` Stephen Leake
  1 sibling, 1 reply; 93+ messages in thread
From: Ludovic Brenta @ 2008-09-02 10:33 UTC (permalink / raw)


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.




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02  8:57     ` Martin Krischik
@ 2008-09-02 10:50       ` stefan-lucks
  2008-09-02 10:33         ` Ludovic Brenta
  2008-09-04  1:05         ` Stephen Leake
  0 siblings, 2 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-02 10:50 UTC (permalink / raw)


[-- Attachment #1: Type: TEXT/PLAIN, Size: 2685 bytes --]

> > (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!  ------

^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 13:32           ` stefan-lucks
@ 2008-09-02 12:53             ` Ludovic Brenta
  2008-09-02 17:32               ` Georg Bauhaus
  2008-09-03 13:14               ` stefan-lucks
  2008-09-02 13:39             ` stefan-lucks
                               ` (4 subsequent siblings)
  5 siblings, 2 replies; 93+ messages in thread
From: Ludovic Brenta @ 2008-09-02 12:53 UTC (permalink / raw)


> 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.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 10:33         ` Ludovic Brenta
@ 2008-09-02 13:32           ` stefan-lucks
  2008-09-02 12:53             ` Ludovic Brenta
                               ` (5 more replies)
  0 siblings, 6 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-02 13:32 UTC (permalink / raw)


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!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 13:32           ` stefan-lucks
  2008-09-02 12:53             ` Ludovic Brenta
@ 2008-09-02 13:39             ` stefan-lucks
  2008-09-02 13:40             ` stefan-lucks
                               ` (3 subsequent siblings)
  5 siblings, 0 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-02 13:39 UTC (permalink / raw)


> > 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!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 13:32           ` stefan-lucks
  2008-09-02 12:53             ` Ludovic Brenta
  2008-09-02 13:39             ` stefan-lucks
@ 2008-09-02 13:40             ` stefan-lucks
  2008-09-02 16:48             ` Dmitry A. Kazakov
                               ` (2 subsequent siblings)
  5 siblings, 0 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-02 13:40 UTC (permalink / raw)


>   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);

      Tmp_B: Boolean := B(Y) -- sorry for the typo!

>   begin
>     if Tmp_A and Tmp_B then ... end if;
>   end;

-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-30 21:28   ` Maciej Sobczak
  2008-08-31  8:28     ` Georg Bauhaus
  2008-09-01  8:05     ` Martin Krischik
@ 2008-09-02 14:50     ` Adam Beneschan
  2 siblings, 0 replies; 93+ messages in thread
From: Adam Beneschan @ 2008-09-02 14:50 UTC (permalink / raw)


On Aug 30, 2:28 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> On 29 Sie, 23:47, Samuel Tardieu <s...@rfc1149.net> wrote:
>
> > Sometimes, you want to ensure that both sides of the boolean operator
> > have been evaluated. Here is an example:
>
> >   --  Send the message to the log and return True if it
> >   --  has been logged at least at one place succesfully.
>
> >   function Log (Message : String) return Boolean is
> >   begin
> >      return Log_To_Network (Message) or Log_To_Disk (Message);
> >   end Log;
>
> This is actually a bad example. It might use "or else" and still
> retain the semantics as described in the comment above.

I don't think the example is bad at all, but the comment might be
ambiguous.  I understood Samuel's point to be that the function logs
to the network if possible, and it logs to disk if possible---ideally
it should log to both places, but we're hoping it logs to at least
one.  If you use "or else" it will never log to both.  That apparently
isn't what is desired.

                                -- Adam






^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02  6:53         ` Martin Krischik
@ 2008-09-02 14:56           ` Adam Beneschan
  2008-09-02 16:28             ` Ray Blaak
  2008-09-02 16:26           ` Ray Blaak
  1 sibling, 1 reply; 93+ messages in thread
From: Adam Beneschan @ 2008-09-02 14:56 UTC (permalink / raw)


On Sep 1, 11:53 pm, Martin Krischik <krisc...@users.sourceforge.net>
wrote:

> > 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.

Yeah, and I don't think COBOL or Fortran guarantee "or else" semantics
either.  I was happy when I first started working in Ada because it
had this.  C has this feature, although like everything else in the
language it was represented in proto-Egyptian hieroglyphics rather
than in English, but this was a new and exciting feature to me.  I
guess Ray must be a young'un who only learned all them durn newfangled
languages and never had to struggle with REEL languages like us
dinosaur REEL programmers did back when we had to put all our programs
on punch cards and then lug them five miles through the snow to the
computer operator, uphill both ways.....

                                   -- Adam



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-08-30 15:35     ` Peter C. Chapin
@ 2008-09-02 15:06       ` Adam Beneschan
  0 siblings, 0 replies; 93+ messages in thread
From: Adam Beneschan @ 2008-09-02 15:06 UTC (permalink / raw)


On Aug 30, 8:35 am, "Peter C. Chapin" <pcc482...@gmail.com> wrote:
> Dmitry A. Kazakov wrote:
> > I am unsure if the arguments of "and" are eager. You are a language lawyer,
> > I am not. But I used to think that the eagerness of evaluation is rather
> > unspecified, so that the compiler is free "not to care," when it optimizes
> > the code, as Jeff Carter has pointed out.
>
> I thought all function arguments must be evaluated, but that it is
> unspecified in which order this evaluation is done.

Correct.  If an argument to a subprogram contains another function
call that has side-effects, that argument must be evaluated, and the
compiler is generating incorrect code if it doesn't (which is *not*
the case with "or else").  I think that if the compiler can determine
that the only possible side effect would be to raise a predefined
exception, the compiler doesn't have to actually do any evaluation---
the code isn't required to perform computations just for the sake of
doing the computations.  I'm not sure how far the predefined-exception
thing goes, though.  If you say

   if X = null or X.ID < 0 then ...    -- "or", not "or else"!

even though the right side is supposed to be evaluated, I suppose that
a compiler could in theory generate code that doesn't bother to
evaluate it if X is null, because there would be no point to reading
that field (assuming no memory-mapped I/O is involved here!!).  I
think that behavior is allowed by the Implementation Permissions in
11.6, but of course it would be quite foolish to write code like this
and rely on the optimization.

                               -- Adam







^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02  6:53         ` Martin Krischik
  2008-09-02 14:56           ` Adam Beneschan
@ 2008-09-02 16:26           ` Ray Blaak
  2008-09-02 20:50             ` Robert A Duff
  1 sibling, 1 reply; 93+ messages in thread
From: Ray Blaak @ 2008-09-02 16:26 UTC (permalink / raw)


Martin Krischik <krischik@users.sourceforge.net> writes:
> 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.

This I also agree with, although I admit being used to the short circuit &&
forms in the C-like languages.

But my point is about having the source code be clearer when both operands are
required to be evaluated, especially when this is a possibility:

> 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.


-- 
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.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 14:56           ` Adam Beneschan
@ 2008-09-02 16:28             ` Ray Blaak
  0 siblings, 0 replies; 93+ messages in thread
From: Ray Blaak @ 2008-09-02 16:28 UTC (permalink / raw)


Adam Beneschan <adam@irvine.com> writes:
> I guess Ray must be a young'un who only learned all them durn newfangled
> languages and never had to struggle with REEL languages like us dinosaur
> REEL programmers did back when we had to put all our programs on punch cards
> and then lug them five miles through the snow to the computer operator,
> uphill both ways.....

Missed the punchcards, fortunately, although I was forced to suffer the use of
paper-only terminals in my first few years of comp sci.

-- 
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.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 13:32           ` stefan-lucks
                               ` (2 preceding siblings ...)
  2008-09-02 13:40             ` stefan-lucks
@ 2008-09-02 16:48             ` Dmitry A. Kazakov
  2008-09-02 17:00             ` Keith Thompson
  2008-09-02 17:20             ` Georg Bauhaus
  5 siblings, 0 replies; 93+ messages in thread
From: Dmitry A. Kazakov @ 2008-09-02 16:48 UTC (permalink / raw)


On Tue, 2 Sep 2008 15:32:40 +0200, stefan-lucks@see-the.signature wrote:

> A short-circuit "and" (instead of "and then") would not remove that choice 
> -- see the "much better style" above. 

Disagree.

I think a far better idea would be to introduce pure functions and
procedures with results. Functions with side effects and access parameters
is an insanity.

It is also worth to consider introduction of commutative, associative,
inverse operations per contract. This would allow the compiler to prevent a
procedure with the result from appearing in a commutative "and". The
evaluation order of non-associative etc operations could be fixed.

Later it would also allow to manage a combinatory explosion variants in
multi-methods ("and", "or", "+", "*" etc).

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 13:32           ` stefan-lucks
                               ` (3 preceding siblings ...)
  2008-09-02 16:48             ` Dmitry A. Kazakov
@ 2008-09-02 17:00             ` Keith Thompson
  2008-09-02 19:15               ` Simon Wright
  2008-09-02 20:37               ` Robert A Duff
  2008-09-02 17:20             ` Georg Bauhaus
  5 siblings, 2 replies; 93+ messages in thread
From: Keith Thompson @ 2008-09-02 17:00 UTC (permalink / raw)


stefan-lucks@see-the.signature writes:
[...]
> 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. 
[...]

(As you said in a later followup, you meant B(Y) rather than B(X).)

I disagree.  The shorter form

    if A(X) and B(Y) then ... end if;

makes the programmer's intent absolutely clear to anyone who knows
what "and" means in Ada.  If I saw the other version my first thought
would be to wonder why the programmer didn't just write "if A(X) and
B(Y)".  After a moment's thought, I'd assume that the order of
evaluation of A(X) and B(Y) is significant.  It would never occur to
me that the long form was used to ensure that both A(X) and B(Y) are
evaluated, since the "and" operator already does that.

All programming languages have their quirks, and none of them exactly
follow mathematical notation (in part because there is no single
mathematical notation).  If you try to write code that will be
understandable to someone who doesn't know the language, you'll end up
with an overly verbose mess that can hardly be understood by someone
who *does* know the language.

If I were doing the equivalent of the above in C, whose logical "and"
operator "&&" does do short-circuit evaluation, I probably would
declare the two temporaries.  In Ada, it's just not necessary.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 13:32           ` stefan-lucks
                               ` (4 preceding siblings ...)
  2008-09-02 17:00             ` Keith Thompson
@ 2008-09-02 17:20             ` Georg Bauhaus
  5 siblings, 0 replies; 93+ messages in thread
From: Georg Bauhaus @ 2008-09-02 17:20 UTC (permalink / raw)


stefan-lucks@see-the.signature schrieb:

> 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. 
> 

> 
> But do you really dispute that following the mathematical conventions 
> as much as possible would improve readability? 

I agree with all of the above. However, after having seen much suffering
from what people think are mathematical conventions used in programs,
I think mathematical conventions should be verboten.

Mathematical conventions are, unfortunately, *much* too vague
to be good guidance. Most of the time they don't apply
in computer programs. On the contrary, digital computers started
their lives for exactly this reason: mathematics had
no formalized steps and finite sets of numbers were uncommon.

Mathematical assumptions make us think that Integer is an integer,
which it isn't!  As you have explained, there is no _|_ in the
set of mathematical integers.

A mathematics for computer programs would be different.
Not like "high school operators" between "high school numbers".


--
Georg Bauhaus
Y A Time Drain  http://www.9toX.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 12:53             ` Ludovic Brenta
@ 2008-09-02 17:32               ` Georg Bauhaus
  2008-09-03 13:14               ` stefan-lucks
  1 sibling, 0 replies; 93+ messages in thread
From: Georg Bauhaus @ 2008-09-02 17:32 UTC (permalink / raw)


Ludovic Brenta schrieb:
>> 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.

There is no order, but still the trouble is that mathematics
is not usually about evaluation at all. The process of
evaluating is not explicitly present in the mathematical
meaning of "and". It does not build on "process" or "procedure".

*

Another issue with "and then" short-circuits apparears
in some "elsif"s:

if This_Thing and then Another_Thing then

elsif This_Thing and then Yet_Another_Thing then

... more of the same ...

else
  -- this catches, errhhm, how many of which of
  -- the alternatives and when?
end if


Nest instead and an "unambiguous if-then-else statement"
removes the need of low-level source code optimization
such as too many short-circuits. Makes your fuses blow :) :)

--
Georg Bauhaus
Y A Time Drain  http://www.9toX.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 17:00             ` Keith Thompson
@ 2008-09-02 19:15               ` Simon Wright
  2008-09-02 20:37               ` Robert A Duff
  1 sibling, 0 replies; 93+ messages in thread
From: Simon Wright @ 2008-09-02 19:15 UTC (permalink / raw)


Keith Thompson <kst-u@mib.org> writes:

> If you try to write code that will be understandable to someone who
> doesn't know the language, you'll end up with an overly verbose mess
> that can hardly be understood by someone who *does* know the language.

A sad but all too common situation!



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 17:00             ` Keith Thompson
  2008-09-02 19:15               ` Simon Wright
@ 2008-09-02 20:37               ` Robert A Duff
  2008-09-02 20:58                 ` Jeffrey R. Carter
  2008-09-03  0:11                 ` Randy Brukardt
  1 sibling, 2 replies; 93+ messages in thread
From: Robert A Duff @ 2008-09-02 20:37 UTC (permalink / raw)


Keith Thompson <kst-u@mib.org> writes:

> follow mathematical notation (in part because there is no single
> mathematical notation).  If you try to write code that will be
> understandable to someone who doesn't know the language, you'll end up
> with an overly verbose mess that can hardly be understood by someone
> who *does* know the language.
>
> If I were doing the equivalent of the above in C, whose logical "and"
> operator "&&" does do short-circuit evaluation, I probably would
> declare the two temporaries.  In Ada, it's just not necessary.

Perhaps I agree, but this discussion is (at least in part) about
language design, not just how to write good Ada (or good C or whatever).

At AdaCore, we always say "and then", never "and".  I don't like that
style (but of course I obey it, because obeying coding conventions is a
good thing in itself).

It seems to me, side effects on globals in the operands of "and" or
"and then" are just plain Bad.  The only distinction is whether the
right-hand operand makes sense when the left-hand one is False, as in
"X /= null and then X.all....".

- Bob



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 16:26           ` Ray Blaak
@ 2008-09-02 20:50             ` Robert A Duff
  2008-09-03 12:35               ` Brian Drummond
  2008-09-03 21:01               ` Vinzent Hoefler
  0 siblings, 2 replies; 93+ messages in thread
From: Robert A Duff @ 2008-09-02 20:50 UTC (permalink / raw)


Ray Blaak <rAYblaaK@STRIPCAPStelus.net> writes:

> Martin Krischik <krischik@users.sourceforge.net> writes:
>> 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.
>
> This I also agree with, although I admit being used to the short circuit &&
> forms in the C-like languages.
>
> But my point is about having the source code be clearer when both
> operands are required to be evaluated, especially when this is a
> possibility:

It seems to me that two cases come up in practise, for "A and [then] B".
Either I don't care which gets evaluated first, and don't care whether
or not both get evaluated, because there are no important side effects
(that's "A and B"), or I care about order (that's "A and then B").

I never see cases where it is important that A and B both be evaluated.

Counterexamples, please?  ;-)  Realistic ones, I mean.

- Bob



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 20:37               ` Robert A Duff
@ 2008-09-02 20:58                 ` Jeffrey R. Carter
  2008-09-02 21:08                   ` Robert A Duff
  2008-09-02 22:34                   ` Santiago Urueña
  2008-09-03  0:11                 ` Randy Brukardt
  1 sibling, 2 replies; 93+ messages in thread
From: Jeffrey R. Carter @ 2008-09-02 20:58 UTC (permalink / raw)


Robert A Duff wrote:
> 
> At AdaCore, we always say "and then", never "and".  I don't like that
> style (but of course I obey it, because obeying coding conventions is a
> good thing in itself).

I've noticed that. What is the justification for it? I presume that, being 
compiler writers, AdaCore has some specialized knowledge that led them to make 
that choice.

-- 
Jeff Carter
"C++: The power, elegance and simplicity of a hand grenade."
Ole-Hjalmar Kristensen
90



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 20:58                 ` Jeffrey R. Carter
@ 2008-09-02 21:08                   ` Robert A Duff
  2008-09-03 12:24                     ` Pascal Obry
  2008-09-02 22:34                   ` Santiago Urueña
  1 sibling, 1 reply; 93+ messages in thread
From: Robert A Duff @ 2008-09-02 21:08 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.acm.org> writes:

> Robert A Duff wrote:
>> At AdaCore, we always say "and then", never "and".  I don't like that
>> style (but of course I obey it, because obeying coding conventions is a
>> good thing in itself).
>
> I've noticed that. What is the justification for it? I presume that,
> being compiler writers, AdaCore has some specialized knowledge that led
> them to make that choice.

No, as far as I know (being fairly new to AdaCore), there's no
specialized compiler knowledge that led to that choice.  It's just a
style choice.  Programmers on the project agreed that "and then"-always
is the best idea stylistically, and now that's just the way it's done.

- Bob



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 20:58                 ` Jeffrey R. Carter
  2008-09-02 21:08                   ` Robert A Duff
@ 2008-09-02 22:34                   ` Santiago Urueña
  2008-09-03  5:56                     ` Robert A Duff
  1 sibling, 1 reply; 93+ messages in thread
From: Santiago Urueña @ 2008-09-02 22:34 UTC (permalink / raw)


> I've noticed that. What is the justification for it? I presume that, being
> compiler writers, AdaCore has some specialized knowledge that led them to make
> that choice.
>
I think that the idea is to always use "and then" / "or else" when
there is a function call because maybe thanks to lazy evaluation some
of those calls can be avoided. In contrast, the AdaCore style guide
suggest using plain "and" / "or" operators when just boolean flags are
involved because it is usually faster to evaluate all the variables
than using lazy evaluation.

Branches and jumps instructions really hurt performance in modern
processors, so when just a set of boolean variables must be evaluated
it is faster to read all of them instead of generating some branches.
When function calls are involved you will have those jump instructions
anyway, so it is better to use lazy evaluation to avoid the overhead
of the function call.

--
Santiago Urueña-Pascual <suruena@gmail.com>



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 20:37               ` Robert A Duff
  2008-09-02 20:58                 ` Jeffrey R. Carter
@ 2008-09-03  0:11                 ` Randy Brukardt
  1 sibling, 0 replies; 93+ messages in thread
From: Randy Brukardt @ 2008-09-03  0:11 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wccprnm708a.fsf@shell01.TheWorld.com...
...
> At AdaCore, we always say "and then", never "and".  I don't like that
> style (but of course I obey it, because obeying coding conventions is a
> good thing in itself).

I can't speak for AdaCore, but we (and me personally) have a similar 
convention. It originated in code quality concerns: on the original 8086, 
"and then" could be optimized far better than "and" (because the former is 
branching, and all conditionals on the 8086 required branching; the latter 
requires Boolean values, which had to be created out of branching). These 
days, it's mostly premature optimization.

Note that I avoid the convention in two cases: where a bunch of Boolean 
values are involved (no excess branching is needed), and in rare cases when 
I need both operands evaluated. And I always comment expressions where the 
order is significant or evaluation is significant.

                              Randy.





^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02  7:48   ` stefan-lucks
  2008-09-02  8:57     ` Martin Krischik
@ 2008-09-03  1:24     ` Stephen Leake
  2008-09-03  3:31       ` tmoran
  2008-09-03 13:22       ` stefan-lucks
  1 sibling, 2 replies; 93+ messages in thread
From: Stephen Leake @ 2008-09-03  1:24 UTC (permalink / raw)


stefan-lucks@see-the.signature writes:

> 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". 

It can also be read "if B is false, the result is false, regardless of
 A".

Which is precisely why the Ada semantics are what they are; 

    in some unspecified order: evaluate A, evaluate B
    compute 'and' of result

> So short-circuit evaluation is a natural 

By 'natural' I suspect you really mean 'what I'm used to from
experience'.

That's valid, but it's not like it's built into the human genome, or
dicated by the laws of physics. It's more of a cultural issue, and
therefore it varies from programmer to programmer.

> and good thing for a programming language, 

Why is it "good"?

Being the same as what you are used to makes it easy. But when
comparing languages, you need more than that. 

Something like:

    Given two sets of typical programmers, one thoroughly familiar
    with language Red, which has C-like boolean operator semantics,
    and the other thoroughly familiar with language Green, which has
    Ada-like boolean operator semantics, the number of errors made in
    using boolean operators is higher in Red than Green.

or vice-versa :). I haven't seen anyone make a claim like that.

Then you need to get the sets of programmers from China, India, and
Serbia to be really valid :).

> 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.)

Ah, but you can! That's what speculative execution gives you. Ada
allows for that, under user control. In C, you must use nested 'if' to
achieve control.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-03  1:24     ` Stephen Leake
@ 2008-09-03  3:31       ` tmoran
  2008-09-03 13:22       ` stefan-lucks
  1 sibling, 0 replies; 93+ messages in thread
From: tmoran @ 2008-09-03  3:31 UTC (permalink / raw)


After determining whether "and/and then" or "and/and also" is better,
perhaps this discussion could continue and determine whether
adjectives should appear before or after nouns in human languages.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 22:34                   ` Santiago Urueña
@ 2008-09-03  5:56                     ` Robert A Duff
  2008-09-03  6:55                       ` Santiago Urueña
  2008-09-03 14:14                       ` Adam Beneschan
  0 siblings, 2 replies; 93+ messages in thread
From: Robert A Duff @ 2008-09-03  5:56 UTC (permalink / raw)


Santiago Urue�a <suruena@gmail.com> writes:

> suggest using plain "and" / "or" operators when just boolean flags are
> involved because it is usually faster to evaluate all the variables
> than using lazy evaluation.

I don't buy that argument, because the semantics of "A and B and C"
are identical to the semantics of "A and then B and then C" (when A, B,
and C are Boolean variables), so the compiler is free to generate
identical code for both.  If efficiency is important in this case,
the compiler should be trained to make it efficient, and the programmer
shouldn't have to worry about it.

Your point for (non-inlined) function calls is valid, though -- the
compiler can't be expected to know what's in the function in general.

- Bob



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-03  5:56                     ` Robert A Duff
@ 2008-09-03  6:55                       ` Santiago Urueña
  2008-09-03 14:14                       ` Adam Beneschan
  1 sibling, 0 replies; 93+ messages in thread
From: Santiago Urueña @ 2008-09-03  6:55 UTC (permalink / raw)


> I don't buy that argument, because the semantics of "A and B and C"
> are identical to the semantics of "A and then B and then C" (when A, B,
> and C are Boolean variables), so the compiler is free to generate
> identical code for both.  If efficiency is important in this case,
> the compiler should be trained to make it efficient, and the programmer
> shouldn't have to worry about it.
>
Yes, I suppose that's why at AdaCore the convention is to use always
short-circuit boolean operators, because gnat can generate the
optimized code anyway for just boolean flags.

> Your point for (non-inlined) function calls is valid, though -- the
> compiler can't be expected to know what's in the function in general.
>
It is interesting that in Spark the compiler can always optimize these
two cases completely, because the functions are always pure. Idea:
pragma Profile (Spark)

Having said that, even if the performance can be improved, I don't
like that rule neither because then when the maintainer sees an "and
then" operator she cannot know whether it is just for performance
reasons or you really want to avoid some side effects (unless some
comments are added).

I agree that those micro-optimizations should be done by the compiler,
so even if the programmer doesn't write the short-circuit operators
when function calls are involved, the compiler should be smart enough
to generate lazy evaluation (if the functions are pure).

Cheers,



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 21:08                   ` Robert A Duff
@ 2008-09-03 12:24                     ` Pascal Obry
  0 siblings, 0 replies; 93+ messages in thread
From: Pascal Obry @ 2008-09-03 12:24 UTC (permalink / raw)
  To: Robert A Duff


My experiences shows that the "and then" is almost always what you want.
An example is when dealing with access types:

   if Ptr /= null and then Ptr.X = 8 then

You really want to evaluate Ptr.X only if Ptr is not null.

I could verify but I do not remember having used "and" at all in fact.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 20:50             ` Robert A Duff
@ 2008-09-03 12:35               ` Brian Drummond
  2008-09-03 15:56                 ` Robert A Duff
  2008-09-03 21:01               ` Vinzent Hoefler
  1 sibling, 1 reply; 93+ messages in thread
From: Brian Drummond @ 2008-09-03 12:35 UTC (permalink / raw)


On Tue, 02 Sep 2008 16:50:34 -0400, Robert A Duff
<bobduff@shell01.TheWorld.com> wrote:

>Ray Blaak <rAYblaaK@STRIPCAPStelus.net> writes:
>
>> Martin Krischik <krischik@users.sourceforge.net> writes:
>>> 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.
>>
>> This I also agree with, although I admit being used to the short circuit &&
>> forms in the C-like languages.
>>
>> But my point is about having the source code be clearer when both
>> operands are required to be evaluated, especially when this is a
>> possibility:
>
>It seems to me that two cases come up in practise, for "A and [then] B".
>Either I don't care which gets evaluated first, and don't care whether
>or not both get evaluated, because there are no important side effects
>(that's "A and B"), or I care about order (that's "A and then B").
>
>I never see cases where it is important that A and B both be evaluated.
>
>Counterexamples, please?  ;-)  Realistic ones, I mean.

Given the speed penalty for branches, there are circumstances where it
is faster to evaluate both cases than branch around one. In that sense,
it would be important (for performance, rather than semantics) to
evaluate both cases. But that is properly the compiler's decision to
make.

I don't think that's what you meant; I believe you meant "important for
semantics"

But it does illustrate that (I) "and then" (short circuit form, order
guaranteed) and (II) "and" (short circuit permitted, but not guaranteed,
order not guaranteed) are properly separate operations.

For cases such as the logging example (semantics require both to be
evaluated) my personal choice would be to explicitly evaluate both, and
combine their evaluation results, as elsewhere in this thread. 

Is my understanding of Ada correct in expecting this is the only way to
guarantee evaluation of both? ( i.e. Ada handles "and" as (II) above)

- Brian



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-03 13:14               ` stefan-lucks
@ 2008-09-03 12:44                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 93+ messages in thread
From: Dmitry A. Kazakov @ 2008-09-03 12:44 UTC (permalink / raw)


On Wed, 3 Sep 2008 15:14:15 +0200, stefan-lucks@see-the.signature wrote:

>>> 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".
> 
> Well, if "False and F(X)" is allowed to raise an exception, this is even 
> worse (more far away from mathematical purity) than if "False and F(X)" is 
> just false -- whatever F(X) would do.

Well, it depends. Consider:

   function F (...) return Boolean; -- May raise Some_Error exception

This breaks the contract that promises a *Boolean* result. Mathematically
it means that the result is not Boolean but a value from some other type
Boolean_Ex is (False, True, Some_Error_Fired). Here Some_Error_Fired is an
ideal "value" of Some_Error being propagated. But then "and" is also broken
in its arguments and the result. In particular for "and" defined on
Boolean_Ex and returning Boolean_Ex, the theorem

   False and X <=> X

does not hold anymore. Therefore it cannot be implied. A similar logic
applies to side effects. You just do the Cartesian product of the effect
and the written set of values. This becomes the "true" set of values.

As somebody already pointed out. People using "and" on arguments with side
effects, are fooling themselves and those who are to read the program.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 12:53             ` Ludovic Brenta
  2008-09-02 17:32               ` Georg Bauhaus
@ 2008-09-03 13:14               ` stefan-lucks
  2008-09-03 12:44                 ` Dmitry A. Kazakov
  1 sibling, 1 reply; 93+ messages in thread
From: stefan-lucks @ 2008-09-03 13:14 UTC (permalink / raw)


> > 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".

Well, if "False and F(X)" is allowed to raise an exception, this is even 
worse (more far away from mathematical purity) than if "False and F(X)" is 
just false -- whatever F(X) would do.


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-03  1:24     ` Stephen Leake
  2008-09-03  3:31       ` tmoran
@ 2008-09-03 13:22       ` stefan-lucks
  1 sibling, 0 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-03 13:22 UTC (permalink / raw)


> > 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.)
> 
> Ah, but you can! That's what speculative execution gives you. Ada
> allows for that, under user control. In C, you must use nested 'if' to
> achieve control.

AFAIK, you cannot write "if (A>0) and (B/A<100) then ..." and then trust 
that no constraint_error is raised if A=0 in Ada. 

On the other hand, im Mathematics, such expressions are quite usual. 

-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-03  5:56                     ` Robert A Duff
  2008-09-03  6:55                       ` Santiago Urueña
@ 2008-09-03 14:14                       ` Adam Beneschan
  1 sibling, 0 replies; 93+ messages in thread
From: Adam Beneschan @ 2008-09-03 14:14 UTC (permalink / raw)


On Sep 2, 10:56 pm, Robert A Duff <bobd...@shell01.TheWorld.com>
wrote:
> Santiago Urueña <suru...@gmail.com> writes:
> > suggest using plain "and" / "or" operators when just boolean flags are
> > involved because it is usually faster to evaluate all the variables
> > than using lazy evaluation.
>
> I don't buy that argument, because the semantics of "A and B and C"
> are identical to the semantics of "A and then B and then C" (when A, B,
> and C are Boolean variables),

*Almost* true.  It isn't true when some of those Boolean variables
have 'Address clauses that cause them to be mapped to hardware I/O
registers!!  But I know what you meant.  I'd go so far as to say a
good compiler should generate the exact same code when the arguments
are (normal, non-volatile) Boolean variables whether or not you use
"and" or "and then", and similarly "or" or "or else".  It should just
pick whatever is fastest.

                                -- Adam




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-03 12:35               ` Brian Drummond
@ 2008-09-03 15:56                 ` Robert A Duff
  2008-09-04 22:09                   ` Brian Drummond
  0 siblings, 1 reply; 93+ messages in thread
From: Robert A Duff @ 2008-09-03 15:56 UTC (permalink / raw)


Brian Drummond <brian_drummond@btconnect.com> writes:

> On Tue, 02 Sep 2008 16:50:34 -0400, Robert A Duff
> <bobduff@shell01.TheWorld.com> wrote:
>>It seems to me that two cases come up in practise, for "A and [then] B".
>>Either I don't care which gets evaluated first, and don't care whether
>>or not both get evaluated, because there are no important side effects
>>(that's "A and B"), or I care about order (that's "A and then B").
>>
>>I never see cases where it is important that A and B both be evaluated.
>>
>>Counterexamples, please?  ;-)  Realistic ones, I mean.
>
> Given the speed penalty for branches, there are circumstances where it
> is faster to evaluate both cases than branch around one. In that sense,
> it would be important (for performance, rather than semantics) to
> evaluate both cases. But that is properly the compiler's decision to
> make.
>
> I don't think that's what you meant; I believe you meant "important for
> semantics"

Yes, that's what I meant.  And I would like the compiler to worry about
efficiency for me, although I admit that's not always feasible.

> But it does illustrate that (I) "and then" (short circuit form, order
> guaranteed) and (II) "and" (short circuit permitted, but not guaranteed,
> order not guaranteed) are properly separate operations.
>
> For cases such as the logging example (semantics require both to be
> evaluated) my personal choice would be to explicitly evaluate both, and
> combine their evaluation results, as elsewhere in this thread. 
>
> Is my understanding of Ada correct in expecting this is the only way to
> guarantee evaluation of both? ( i.e. Ada handles "and" as (II) above)

No.  Ada guarantees that both arguments of "and" are evaluated.
Of course if the compiler knows that evaluation has no effect, it
doesn't need to generate any code -- that would be the case for
"X > 0", for example.  Ada allows the two operands to be evaluated
in either order (but not in parallel, if that matters).

So in the example you mention, "F(...) and G(...)" where the bodies of F
and G write some output to a log file, both outputs will be written --
in some order, but not intermixed.

- Bob



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 20:50             ` Robert A Duff
  2008-09-03 12:35               ` Brian Drummond
@ 2008-09-03 21:01               ` Vinzent Hoefler
  1 sibling, 0 replies; 93+ messages in thread
From: Vinzent Hoefler @ 2008-09-03 21:01 UTC (permalink / raw)


On Tue, 02 Sep 2008 16:50:34 -0400, Robert A Duff wrote:

> Ray Blaak <rAYblaaK@STRIPCAPStelus.net> writes:
> 
>> Martin Krischik <krischik@users.sourceforge.net> writes:
>>> 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.
>>
>> This I also agree with, although I admit being used to the short circuit &&
>> forms in the C-like languages.
>>
>> But my point is about having the source code be clearer when both
>> operands are required to be evaluated, especially when this is a
>> possibility:
> 
> It seems to me that two cases come up in practise, for "A and [then] B".
> Either I don't care which gets evaluated first, and don't care whether
> or not both get evaluated, because there are no important side effects
> (that's "A and B"), or I care about order (that's "A and then B").
> 
> I never see cases where it is important that A and B both be evaluated.
> 
> Counterexamples, please?  ;-)  Realistic ones, I mean.

Hmm. Digging in *really* old (Turbo-Pascal) sourcecode, I found an old map
editor:

Example #1:

-- 8< --
    {$IFOPT B+} {$DEFINE OPTB} {$B-} {$ENDIF}
    for i := 0 to TESTFUNCS - 1 do
      b := b and MapTest[i](Contents);
    {$IFDEF OPTB} {$UNDEF OPTB} {$B+} {$ENDIF}
-- 8< --

MapTest is a list of procedures I wanted to execute to check the validity
of an edited map prior to exporting it.

#2:

-- 8< --
      {$IFOPT B-} {$DEFINE OPTB} {$B+} {$ENDIF}
      repeat
        P := Message (Desktop, evBroadCast, cmClose, @C);
      until ((P = NIL) or (C = cmCancel));
      {$IFDEF OPTB} {$UNDEF OPTB} {$B-} {$ENDIF}
-- 8< --

Not quite sure, why I did it here. Seems, more than 10 years ago, I lacked
commenting properly. ;)

Finally #3 (and one of those MapTest functions mentioned above, so one can
see why I did it):

-- 8< --
{$A+,B-,D+,E-,F+,G+,I+,L+,N-,O+,R-,S-,V+,X-}
{    ^^ important!!!}

[...]

function AtLeastOneActor;
var
  b : boolean;
  i,
  j : byte;

begin
  b := False;

  for i := 1 to 62 do
  for j := 1 to 62 do
    b := b or (X.mpObj_Data[i][j].odActors <> 0);

  AtLeastOneActor := b or SaveMsgBox (NOACTOR);
end; {AtLeastOneActor}
-- 8< --

(Uh, bad code, literal constants...)

So, maybe I would generally write it different today, but for an example,
it is as real as it gets.


Vinzent.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-02 10:50       ` stefan-lucks
  2008-09-02 10:33         ` Ludovic Brenta
@ 2008-09-04  1:05         ` Stephen Leake
  2008-09-04  6:45           ` stefan-lucks
  1 sibling, 1 reply; 93+ messages in thread
From: Stephen Leake @ 2008-09-04  1:05 UTC (permalink / raw)


stefan-lucks@see-the.signature writes:

>> > (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

What is the "logic level"?

I you mean "abstract Boolean logic, like in college", then there is no
such thing as Constraint_Error, nor side effects. So of course it
gives you a bad understanding of programming languages.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04  1:05         ` Stephen Leake
@ 2008-09-04  6:45           ` stefan-lucks
  2008-09-04  7:35             ` Dmitry A. Kazakov
  2008-09-04  7:39             ` Karel Th�nissen
  0 siblings, 2 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-04  6:45 UTC (permalink / raw)


> > True. But, at the logic level, the Ada-statement
> 
> What is the "logic level"?
> 
> I you mean "abstract Boolean logic, like in college", then there is no
> such thing as Constraint_Error, nor side effects. So of course it
> gives you a bad understanding of programming languages.

Actually, there is Constraint_Erorr, though under a different name. ;-)

If your Boolean function is allowed to raise an exception, this is the 
same as returning "undefined" in three-valued logic, as I pointed out in 
another posting in this mail.

This is the point I had been trying to make in all my postings to this 
thread: "False and Undefined" is False, not Undefined! Thus, "if X/=0 and 
Y/X<100" should go into the else-branch, instead of raising an exception.
The shortcut version "if X/=0 and then Y/X<100" does exactly the right 
thing. 

Perhaps that is the reason why people at AdaCore always write "and then" 
instead of "and". 


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04  6:45           ` stefan-lucks
@ 2008-09-04  7:35             ` Dmitry A. Kazakov
  2008-09-04 12:04               ` stefan-lucks
  2008-09-04  7:39             ` Karel Th�nissen
  1 sibling, 1 reply; 93+ messages in thread
From: Dmitry A. Kazakov @ 2008-09-04  7:35 UTC (permalink / raw)


On Thu, 4 Sep 2008 08:45:03 +0200, stefan-lucks@see-the.signature wrote:

>>> True. But, at the logic level, the Ada-statement
>> 
>> What is the "logic level"?
>> 
>> I you mean "abstract Boolean logic, like in college", then there is no
>> such thing as Constraint_Error, nor side effects. So of course it
>> gives you a bad understanding of programming languages.
> 
> Actually, there is Constraint_Erorr, though under a different name. ;-)
> 
> If your Boolean function is allowed to raise an exception, this is the 
> same as returning "undefined" in three-valued logic, as I pointed out in 
> another posting in this mail.

Why "undefined", it is rather "contradictory" (in four-state Belnap logic)

> This is the point I had been trying to make in all my postings to this 
> thread: "False and Undefined" is False, not Undefined! Thus, "if X/=0 and 
> Y/X<100" should go into the else-branch, instead of raising an exception.
> The shortcut version "if X/=0 and then Y/X<100" does exactly the right 
> thing. 

Well, indeed

    0 /\ _|_ = 0
    0 /\ T = 0

Here 0 = False, 1 = True, _|_ = Uncertain, T = Contradiction. False under
/\ always renders False.

Nevertheless Boolean logic /= Belnap logic, though the former is contained
in the latter. 

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04  6:45           ` stefan-lucks
  2008-09-04  7:35             ` Dmitry A. Kazakov
@ 2008-09-04  7:39             ` Karel Th�nissen
  2008-09-04 12:12               ` stefan-lucks
  1 sibling, 1 reply; 93+ messages in thread
From: Karel Th�nissen @ 2008-09-04  7:39 UTC (permalink / raw)



<stefan-lucks@see-the.signature> schreef in bericht 
news:Pine.LNX.4.64.0809040835270.21815@medsec1.medien.uni-weimar.de...

>> What is the "logic level"?

>> I you mean "abstract Boolean logic, like in college", then there is no
>> such thing as Constraint_Error, nor side effects. So of course it
>> gives you a bad understanding of programming languages.

Exactly. Programming is not mathematics and the resemblance is so close that 
it is dangerous.

> Actually, there is Constraint_Erorr, though under a different name. ;-)

> If your Boolean function is allowed to raise an exception, this is the
> same as returning "undefined" in three-valued logic, as I pointed out in
> another posting in this mail.


> This is the point I had been trying to make in all my postings to this
> thread: "False and Undefined" is False, not Undefined!

That depends on the type of ternary logic that you consider. If the third 
value stands for 'unknown' then:
   false and unknown => false
However, if the third value is used for contradiction, then:
   false and contradiction => contradiction
That is what Ada does with exceptions.

> Thus, "if X/=0 and Y/X<100" should go into the else-branch, instead of 
> raising an exception.
> The shortcut version "if X/=0 and then Y/X<100" does exactly the right
> thing.

That would be a very bad idea. With that in place, an exception raised by a 
simple programming error, /any/ programming error, would give control to the 
else-branch. Nice if the exception is the one that you know that could 
happen, otherwise disasterous. It has become a exception handler in 
disguise, but one that confuses falsity with exceptions. If this is what you 
want you should invent a 3-branched selection statement.

I agree with other posters that the choice between conditional and 
unconditional AND should be explicit and documented. One may not like the 
syntax chosen in Ada, but it is the only sensible design.

Groeten, Karel





^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04  7:35             ` Dmitry A. Kazakov
@ 2008-09-04 12:04               ` stefan-lucks
  2008-09-04 13:00                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 93+ messages in thread
From: stefan-lucks @ 2008-09-04 12:04 UTC (permalink / raw)


> Well, indeed
> 
>     0 /\ _|_ = 0
>     0 /\ T = 0
> 
> Here 0 = False, 1 = True, _|_ = Uncertain, T = Contradiction. False under
> /\ always renders False.
> 
> Nevertheless Boolean logic /= Belnap logic, though the former is contained
> in the latter. 

I never said "Boolean logic", I said "logic", which was ment to include 
multi-valued logic. ;-)


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04  7:39             ` Karel Th�nissen
@ 2008-09-04 12:12               ` stefan-lucks
  2008-09-04 15:13                 ` Georg Bauhaus
                                   ` (3 more replies)
  0 siblings, 4 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-04 12:12 UTC (permalink / raw)


> > Thus, "if X/=0 and Y/X<100" should go into the else-branch, instead of 
> > raising an exception.
> > The shortcut version "if X/=0 and then Y/X<100" does exactly the right
> > thing.
> 
> That would be a very bad idea. With that in place, an exception raised by a 
> simple programming error, /any/ programming error, would give control to the 
> else-branch. 

You misread what I wrote. A statement such as "if Y/X<000" should 
definitively propagate an exception for X=0, and I never said anything 
otherwise.

But when "if X/=0 and Y/X<100" propagates an exception for X=0, as, alas, 
done in Ada, something is logically wrong.


BTW, why do you think that an exception, such as a Constraint_Error, 
should logically count as a contradiction? 

Dividing something by zero is undefined, not a contradiction.


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 12:04               ` stefan-lucks
@ 2008-09-04 13:00                 ` Dmitry A. Kazakov
  2008-09-04 19:05                   ` stefan-lucks
  0 siblings, 1 reply; 93+ messages in thread
From: Dmitry A. Kazakov @ 2008-09-04 13:00 UTC (permalink / raw)


On Thu, 4 Sep 2008 14:04:10 +0200, stefan-lucks@see-the.signature wrote:

>> Well, indeed
>> 
>>     0 /\ _|_ = 0
>>     0 /\ T = 0
>> 
>> Here 0 = False, 1 = True, _|_ = Uncertain, T = Contradiction. False under
>> /\ always renders False.
>> 
>> Nevertheless Boolean logic /= Belnap logic, though the former is contained
>> in the latter. 
> 
> I never said "Boolean logic", I said "logic", which was ment to include 
> multi-valued logic. ;-)

There are many multi-valued logics. But the problem is that taking such a
logic for the base, you need to reconsider everything based on inference.
In such logics inference is sufficiently more difficult, especially when
the results need to be interpreted. The Boolean type is heavily used in the
language. As an example, consider "when others" of a case statement. It
uses the reasoning if X not in A then X in not A (not A = the complement
set of A). But when "in A" is uncertain then its counterpart is too. How
case is supposed to work, then? In fact, especially evident it becomes in
fuzzy logic, in such frameworks you need to keep track on multiple
competing alternatives, because at no point you can discard anything
different from False. On the contrary, in Boolean logic there is only one
right path.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 12:12               ` stefan-lucks
@ 2008-09-04 15:13                 ` Georg Bauhaus
  2008-09-04 15:16                 ` Karel Th�nissen
                                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 93+ messages in thread
From: Georg Bauhaus @ 2008-09-04 15:13 UTC (permalink / raw)


stefan-lucks@see-the.signature schrieb:

> But when "if X/=0 and Y/X<100" propagates an exception for X=0, as, alas, 
> done in Ada, something is logically wrong.

What seems wrong to me is the premise that "and" has a
meaning which is not defined the LRM.

Unfortunately, "and" is the conventional word for this subprogram.
However, switching context to mathematics when the subject
is programming has the obvious effects displayed in this thread.

With Ada requirements in mind (real-time systems,
hardware, predictable execution, ...), then I guess

 Standard."and"(F(X), G(Y))

should normally mean: call subprograms F and G,
just like

  Foo(F(X), G(Y))

should normally mean: call subprograms F and G.
(If at all, deviate from this rule when pragma Pure
applies to F or G and an optimizer is allowed to work.)



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 12:12               ` stefan-lucks
  2008-09-04 15:13                 ` Georg Bauhaus
@ 2008-09-04 15:16                 ` Karel Th�nissen
  2008-09-04 15:42                   ` Dmitry A. Kazakov
  2008-09-04 19:27                   ` stefan-lucks
  2008-09-04 16:33                 ` Dmitry A. Kazakov
  2008-09-05 13:26                 ` Robert A Duff
  3 siblings, 2 replies; 93+ messages in thread
From: Karel Th�nissen @ 2008-09-04 15:16 UTC (permalink / raw)


<stefan-lucks@see-the.signature> schreef in bericht 
news:Pine.LNX.4.64.0809041404570.22581@medsec1.medien.uni-weimar.de...

>> > Thus, "if X/=0 and Y/X<100" should go into the else-branch, instead of
>> > raising an exception.
>> > The shortcut version "if X/=0 and then Y/X<100" does exactly the right
>> > thing.

>> That would be a very bad idea. With that in place, an exception raised by 
>> a
>> simple programming error, /any/ programming error, would give control to 
>> the
>> else-branch.

> You misread what I wrote. A statement such as "if Y/X<000" should
> definitively propagate an exception for X=0, and I never said anything
> otherwise.

So if I understand you correctly this time, the raising (or not) of an 
exception for "if Y/X<000" should in your view depend on the context where 
it is used: /do not raise/ inside branching conditions of a certain pattern, 
but /do raise/ when used as an ordinary statement. I fear that you 
underestimate the complexities of putting that smartness in a compiler and 
you overestimate the abilities of the ordinary programmers to understand 
what is going on.

No, I do not think I misread. Your writing was not precise: you wrote

   "if X/=0 and Y/X<100" should go into the else-branch, instead of raising 
an exception.

But in Ada it does not go to the else-branche for X=0. So you are proposing 
a language change, and I point out that that would be a vey bad idea.

We cannot expect the compiler to be so smart to distinguish exceptions that 
are avoidable if the left operand had been evaluated first (as with 
conditional boolean operators) from the other exceptions in general. So the 
only viable options are: not doing it like this at all (my choice) or 
picking the else branche for all exceptions. That would make it in invisible 
exception handler. Bad, bad, bad. And as noted above, it would also 
introduce context sensitivity whether exceptions should be raised or not. 
Again very bad.

And if you do want conditional evaluation, you choose 'and then'. What is 
wrong with it? Okay, it is wordy, but the formantics in Ada are very 
precise. That is more important than 5 characters saved.

Maybe you meant 'and' in your example in a more abstract sense without 
providing the precision is demanded by Ada. Unfortunately, you expressed it 
as valid Ada.

> But when "if X/=0 and Y/X<100" propagates an exception for X=0, as, alas,
> done in Ada, something is logically wrong.

So you do think that it should not raise an exception and go to the 
else-branche????? Now what do you want? You contradict yourself. Or this the 
reason you came up with the context dependent interpretation of source code? 
The problem is probably that you use the words 'and' and 'should' in two 
different ways. Seems to be the whole point of this discussion.

How much intelligence do you expect from a compiler? And even if the 
compiler where that smart, would we mere programmers understand what was 
going on. How smart should the compiler be? Should it also start using 
inference, perhaps using whole program analysis?

Computing just is not standard logic. Simple boolean logic will not help us 
out and we should stop looking at mathematics and logic as the holy grail in 
computing. It is a different subject.

> BTW, why do you think that an exception, such as a Constraint_Error,
> should logically count as a contradiction?
>
> Dividing something by zero is undefined, not a contradiction.

That again shows my point that mathematics and computing are two different 
beasts. A mathematician will put the pencil done and stop immediately when 
asked to do an undefined operation, such as a division by zero. That just is 
not an option if you are flying 1000 km/h. Then you raise an exception and 
try to make the best of it, probably working from an unknown or even 
corrupted state, regaining control over the machine and bringing the 
passengers to safety.

If the mathematician were to continue anyway and tried to find his way out 
like our software, he could easily obtain contradicitonary results. This 
should be compared with invariants that are broken because of the reaching 
of an undefined operation/ raising an exception in software.

Comparing undefined/raising an exception allowed because they share the 
property: that the result is neither true nor false:

   false AND raisingAnException => raisingAnException
   false AND contradictionary      => contradictionary

Remember that I introduced this point about contradictions where someone 
(you?) equated ternary logic with Kleene's logic. There are other ternary 
logics.

Just to be nitpicking: coming from a DbC-background, a division by zero 
should raise a *violation* of contract, not an exception. A violation indeed 
is a contraction with the explicitly stated contracts. After a violation 
anything goes.

*Exceptions* should be used for things that can be expected, but that should 
be very rare and that are to hard to handle using standard control 
structures. Think of printers that break down, or network failures.

Groeten, Karel 





^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 15:16                 ` Karel Th�nissen
@ 2008-09-04 15:42                   ` Dmitry A. Kazakov
  2008-09-04 19:27                   ` stefan-lucks
  1 sibling, 0 replies; 93+ messages in thread
From: Dmitry A. Kazakov @ 2008-09-04 15:42 UTC (permalink / raw)


On Thu, 4 Sep 2008 17:16:05 +0200, Karel Th�nissen wrote:

> Just to be nitpicking: coming from a DbC-background, a division by zero 
> should raise a *violation* of contract, not an exception. A violation indeed 
> is a contraction with the explicitly stated contracts. After a violation 
> anything goes.

This contradiction is not the contradiction T of multi-valued logic.
Violation of DbC is a contradiction in the interpretation of a formula F.
It tells that F is incorrect <=> F is not a language statement. On the
contrary, the symbol T (or an exception propagation) is itself correct, it
is a language term.

Whether division by zero is illegal (a contract violation) or T
(exceptional), is a question of type language/design. Ada uses the latter,
because the former would make illegal programs compilable, which nobody
wants.
 
> *Exceptions* should be used for things that can be expected, but that should 
> be very rare and that are to hard to handle using standard control 
> structures. Think of printers that break down, or network failures.

Yes.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 12:12               ` stefan-lucks
  2008-09-04 15:13                 ` Georg Bauhaus
  2008-09-04 15:16                 ` Karel Th�nissen
@ 2008-09-04 16:33                 ` Dmitry A. Kazakov
  2008-09-04 19:31                   ` stefan-lucks
  2008-09-05 13:26                 ` Robert A Duff
  3 siblings, 1 reply; 93+ messages in thread
From: Dmitry A. Kazakov @ 2008-09-04 16:33 UTC (permalink / raw)


On Thu, 4 Sep 2008 14:12:57 +0200, stefan-lucks@see-the.signature wrote:

> BTW, why do you think that an exception, such as a Constraint_Error, 
> should logically count as a contradiction? 
> 
> Dividing something by zero is undefined, not a contradiction.

Undefined is a too vague term.

When a mathematician tells that X/0 > 100 is undefined he usually means
that X/0 > 100 has no interpretation.

But "X/0 > 100 = _|_" has an interpretation. Namely: m(X/0 in ]100,oo[)=1,
m(X/0 not in = ]100,oo[)=1. I.e. it is both possible for X/0 be in ]100,oo[
or in its complement. This is uncertainty.

"X/0 > 100 = T" means that neither is possible (contradiction). This
"contradiction" is closer to an intuitive understanding of X/0 > 100, yet
it is not the standard mathematical meaning of, which is that X/0 > 100 is
not a formula at all.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 13:00                 ` Dmitry A. Kazakov
@ 2008-09-04 19:05                   ` stefan-lucks
  2008-09-04 20:28                     ` Dmitry A. Kazakov
  2008-09-05 14:14                     ` Robert A Duff
  0 siblings, 2 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-04 19:05 UTC (permalink / raw)


> >> Nevertheless Boolean logic /= Belnap logic, though the former is contained
> >> in the latter. 
> > 
> > I never said "Boolean logic", I said "logic", which was ment to include 
> > multi-valued logic. ;-)
> 
> There are many multi-valued logics. 

You are trying to build an overly complex theory, which I am not 
interested in. The issue is very simple:

1. If the A- or the B-part in "if A and B" raises an exception, but the 
   other part is false, the "right thing" (TM) to do would be to transfer 
   control to the else clause (or below "end if", when there is no else). 
   The intermediate result can be viewed as a three-valued logic 
   expression, but the final outcome of the Boolean expression must be 
   Boolean, of course. 

2. If both raise A and B an exception, of if one raises an exception and 
   the other one is true, an exception is propagated. (*)

3. I would be willing to pragmatically sacrifice mathematical purity for a 
   shortcut rule: If A is false, the expression is false, whatever B does. 
   If A raises an exception, of if A is true and B raises an exception, 
   the exception is propagated.
 
----

(*) Funny problem: *Which* exception should be propagated? 
  
   
 


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 15:16                 ` Karel Th�nissen
  2008-09-04 15:42                   ` Dmitry A. Kazakov
@ 2008-09-04 19:27                   ` stefan-lucks
  2008-09-04 19:43                     ` stefan-lucks
  2008-09-04 20:09                     ` Karel Th�nissen
  1 sibling, 2 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-04 19:27 UTC (permalink / raw)


On Thu, 4 Sep 2008,  wrote:

> <stefan-lucks@see-the.signature> schreef in bericht 
> news:Pine.LNX.4.64.0809041404570.22581@medsec1.medien.uni-weimar.de...
> 
> >> > Thus, "if X/=0 and Y/X<100" should go into the else-branch, instead of
> >> > raising an exception.
> >> > The shortcut version "if X/=0 and then Y/X<100" does exactly the right
> >> > thing.
> 
> >> That would be a very bad idea. With that in place, an exception raised by 
> >> a
> >> simple programming error, /any/ programming error, would give control to 
> >> the
> >> else-branch.
> 
> > You misread what I wrote. A statement such as "if Y/X<000" should
> > definitively propagate an exception for X=0, and I never said anything
> > otherwise.
> 
> So if I understand you correctly this time, the raising (or not) of an 
> exception for "if Y/X<000" should in your view depend on the context where 
> it is used: [...]

No, you misread me again. If you had read some earlier posts from me in 
this thread, what I am trying to express is that "and" should better do 
what "and then" actually does. That is it, so simple!

> I fear that you underestimate the complexities of putting that smartness 
> in a compiler and you overestimate the abilities of the ordinary 
> programmers to understand what is going on.

Very strange that the Ada compiler is able to compile stuff if you write 
"and then" instead of "and". Following your point, the designers of Ada 
did overestimate the smartness of compilers. ;-)

Now really, the whole thing seems to work quite well for "and then". And 
in quite a few languages other than Ada for "and".

> No, I do not think I misread. Your writing was not precise: you wrote
> 
>    "if X/=0 and Y/X<100" should go into the else-branch, instead of raising 
> an exception.
> 
> But in Ada it does not go to the else-branche for X=0. So you are proposing 
> a language change, and I point out that that would be a vey bad idea.

I am not trying to propose to change Ada -- regrettably this would break 
compatibility too much. But if it where not for compatibility reasons, I 
would consider to propose that change. 

> We cannot expect the compiler to be so smart to distinguish exceptions that 
> are avoidable if the left operand had been evaluated first (as with 
> conditional boolean operators) from the other exceptions in general. So the 
> only viable options are: not doing it like this at all (my choice) or 
> picking the else branche for all exceptions. 

Strange that the compiler is smart enough to do the right thing if we just 
write "and then" instead of "and". ;-)

> That would make it in invisible exception handler. Bad, bad, bad. And as 
> noted above, it would also introduce context sensitivity whether 
> exceptions should be raised or not. Again very bad.

Where is the context sensitivity about exceptions when you write "and 
then"? 

> And if you do want conditional evaluation, you choose 'and then'. What is 
> wrong with it? Okay, it is wordy, but the formantics in Ada are very 
> precise. That is more important than 5 characters saved.

I could not care less about the five characters. 

But the designers of Ada (and the designers of almost any other language 
out there) have chosen the identifier "and" for a reason. And the reason 
is that the language "and" actually attempts to mimic the mathematical 
"and".

> Maybe you meant 'and' in your example in a more abstract sense without 
> providing the precision is demanded by Ada. Unfortunately, you expressed it 
> as valid Ada.

No, I simply complained about a (minor) design flaw of Ada. 

> > But when "if X/=0 and Y/X<100" propagates an exception for X=0, as, alas,
> > done in Ada, something is logically wrong.
> 
> So you do think that it should not raise an exception and go to the 
> else-branche????? Now what do you want? You contradict yourself. 

Are you trolling? That quote of mine is a repetition, not a contradiction!

> > Dividing something by zero is undefined, not a contradiction.
> 
> That again shows my point that mathematics and computing are two different 
> beasts. A mathematician will put the pencil done and stop immediately when 
> asked to do an undefined operation, such as a division by zero. 

Agreed!

But in a lot of mathematical papers, descriptions of algorithms and the 
like, you actually find expressions like "X/=0 and Y/X<1000". Such an 
expression does have a well-defined meaning, even for X=0. Nobody would 
drop his or here pencil.

BTW, even the order is an issue -- if you write "Y/X<1000 and X/=0" in a 
mathematical paper, that would be logically correct, but you could bet on 
the reviewers asking you to rewrite it to "X/=0 and Y/X<1000".


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 16:33                 ` Dmitry A. Kazakov
@ 2008-09-04 19:31                   ` stefan-lucks
  2008-09-04 19:59                     ` Karel Th�nissen
  2008-09-04 20:17                     ` Dmitry A. Kazakov
  0 siblings, 2 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-04 19:31 UTC (permalink / raw)


On Thu, 4 Sep 2008, Dmitry A. Kazakov wrote:

> "X/0 > 100 = T" means that neither is possible (contradiction). This
> "contradiction" is closer to an intuitive understanding of X/0 > 100, yet
> it is not the standard mathematical meaning of, which is that X/0 > 100 is
> not a formula at all.

Well, "X/=0 and Y/X<100" is a common notation with a well-defined meaning, 
even for X=0 (false, of course). On the other hand an isolated "Y/X<100" 
only has a well-defined meaning if X/=0. 



-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 19:43                     ` stefan-lucks
@ 2008-09-04 19:40                       ` Georg Bauhaus
  2008-09-05  7:00                         ` stefan-lucks
  2008-09-04 20:06                       ` Karel Th�nissen
  1 sibling, 1 reply; 93+ messages in thread
From: Georg Bauhaus @ 2008-09-04 19:40 UTC (permalink / raw)


stefan-lucks@see-the.signature wrote:

> 1. If the A- or the B-part in "if A and B" raises an exception, but the
>    other part is false, the "right thing" (TM) to do would be to transfer
>    control to the else clause (or below "end if", when there is no else).

With all due respect, professor, you are suggesting circumstances
could warrant the automatic assignment of value False to expection
occurrences?



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 19:27                   ` stefan-lucks
@ 2008-09-04 19:43                     ` stefan-lucks
  2008-09-04 19:40                       ` Georg Bauhaus
  2008-09-04 20:06                       ` Karel Th�nissen
  2008-09-04 20:09                     ` Karel Th�nissen
  1 sibling, 2 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-04 19:43 UTC (permalink / raw)


On Thu, 4 Sep 2008, stefan-lucks@see-the.signature wrote:

> On Thu, 4 Sep 2008,  wrote:
> > So if I understand you correctly this time, the raising (or not) of an 
> > exception for "if Y/X<000" should in your view depend on the context where 
> > it is used: [...]
> 
> No, you misread me again. If you had read some earlier posts from me in 
> this thread, what I am trying to express is that "and" should better do 
> what "and then" actually does. That is it, so simple!

To be precise, here is a cut-and-paste from what I wrote in another 
posting:

1. If the A- or the B-part in "if A and B" raises an exception, but the
   other part is false, the "right thing" (TM) to do would be to transfer
   control to the else clause (or below "end if", when there is no else).
   The intermediate result can be viewed as a three-valued logic
   expression, but the final outcome of the Boolean expression must be
   Boolean, of course.

2. If both raise A and B an exception, of if one raises an exception and
   the other one is true, an exception is propagated. 

3. I would be willing to pragmatically sacrifice mathematical purity for a
   shortcut rule: If A is false, the expression is false, whatever B does.
   If A raises an exception, of if A is true and B raises an exception,
   the exception is propagated.

1. and 2. describe some "ideal" behaviour, but 3. describes what the one 
can realistically expect from the compiler. BTW, the compiler would not 
need to be that incredibly smart. If an exception is raised when 
evaluating a Boolean expression, the exception could be handled inernally, 
to finish evaluating the Boolean expression, and re-raised if neccessary. 

-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 19:31                   ` stefan-lucks
@ 2008-09-04 19:59                     ` Karel Th�nissen
  2008-09-05  7:27                       ` stefan-lucks
  2008-09-04 20:17                     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 93+ messages in thread
From: Karel Th�nissen @ 2008-09-04 19:59 UTC (permalink / raw)



<stefan-lucks@see-the.signature> schreef in bericht 
news:Pine.LNX.4.64.0809042128350.25707@medsec1.medien.uni-weimar.de...
> On Thu, 4 Sep 2008, Dmitry A. Kazakov wrote:
>
>> "X/0 > 100 = T" means that neither is possible (contradiction). This
>> "contradiction" is closer to an intuitive understanding of X/0 > 100, yet
>> it is not the standard mathematical meaning of, which is that X/0 > 100 
>> is
>> not a formula at all.
>
> Well, "X/=0 and Y/X<100" is a common notation with a well-defined meaning,
> even for X=0 (false, of course). On the other hand an isolated "Y/X<100"
> only has a well-defined meaning if X/=0.

No, the very fact that we have this discussion shows that it does not have a 
well-defined meaning in computing (outside Ada). And the meaning in two 
valued logic is well-defined, but a different beast.

Claiming 'false of course' is retorics.

And again, you propose a contextual interpretation of "Y/X<100" (for X=0). 
That is totally beyond what program analysis can achieve.

> -- 
> ------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
>               Stefan dot Lucks at uni minus weimar dot de
> ------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------
> 





^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 19:43                     ` stefan-lucks
  2008-09-04 19:40                       ` Georg Bauhaus
@ 2008-09-04 20:06                       ` Karel Th�nissen
  2008-09-05  7:44                         ` stefan-lucks
  1 sibling, 1 reply; 93+ messages in thread
From: Karel Th�nissen @ 2008-09-04 20:06 UTC (permalink / raw)


> On Thu, 4 Sep 2008, stefan-lucks@see-the.signature wrote:
>
>> On Thu, 4 Sep 2008,  wrote:
>> > So if I understand you correctly this time, the raising (or not) of an
>> > exception for "if Y/X<000" should in your view depend on the context
>> > where
>> > it is used: [...]
>>
>> No, you misread me again. If you had read some earlier posts from me in
>> this thread, what I am trying to express is that "and" should better do
>> what "and then" actually does. That is it, so simple!

If that /were the only thing you wrote/, then it would indeed be simple. But
in your earlier posting, /and/ a few lines down in the very post I am
replying to now (as a quote from an earlier posting), you write something
different. See few lines further down.

I personally could life with the idea that in Ada, 'and' would have had
conditional formantics (now  and-then)and some other operator would have
unconditional formantics (now and). That is just swapping tokens at the
lexical level. Fine. What is your point?

> To be precise, here is a cut-and-paste from what I wrote in another
> posting:
>
> 1. If the A- or the B-part in "if A and B" raises an exception, but the
>   other part is false, the "right thing" (TM) to do would be to transfer
>   control to the else clause (or below "end if", when there is no else).
>   The intermediate result can be viewed as a three-valued logic
>   expression, but the final outcome of the Boolean expression must be
>   Boolean, of course.

Thank you, there it is.

Contrary to what you write above, this is /not/ the formantics of and-then
in Ada. In Ada, the conditional boolean operators are not symmetric: "A
and-then B" is not equivalent to "A and-then B". So you are proposing
something new in the language beyond the mere choice of lexemes.

The formantics you propose would be an exception handler that does not
discriminate neither for the type of the exception, nor for the side of the
operator where it was raised. The ambiguity of both sides raising an
exception is handled by rule 2 below.

The formantics you propose would execute the else-branch for *any*
exception, not just the divide by zero in the example, but also overflows
and Gods knows what else. A nice place for bugs to hide. It is even worse
than that: if there is no else-branch, then the execution silently continues
after the end-if. Great. Bugs now go completely undetected. The worst
possible thing you could do for high-integrity software.

> 2. If both raise A and B an exception, of if one raises an exception and
>   the other one is true, an exception is propagated.

Why not follow your own logic and really use a three-valued logic and
introduce a three-branched if-then-else structure with a third branch for
handling "undefined and undefined" or whatever you call it.

> 3. I would be willing to pragmatically sacrifice mathematical purity for a
>   shortcut rule: If A is false, the expression is false, whatever B does.
>   If A raises an exception, of if A is true and B raises an exception,
>   the exception is propagated.

Congratulations, you just reinvented the and-then in Ada.

> 1. and 2. describe some "ideal" behaviour, but 3. describes what the one
> can realistically expect from the compiler. BTW, the compiler would not
> need to be that incredibly smart. If an exception is raised when
> evaluating a Boolean expression, the exception could be handled inernally,
> to finish evaluating the Boolean expression, and re-raised if neccessary.

1+2 may appear ideal for a mathematician, because of the symmetry it
provides. But we are not doing mathematics. I am a professional software
engineer and I do not want my stupid mistakes, that I do make, caught by
contracts that raise all sorts of violations (program exceptions), go
unnoticed because the exception is silently handled in the else-branche or
not at all if there is no such branche.

Ideal behavior is a fata morgana from lala-land. We have to deal with
fallible developers and machinery.

> ------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
>               Stefan dot Lucks at uni minus weimar dot de
> ------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------





^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 19:27                   ` stefan-lucks
  2008-09-04 19:43                     ` stefan-lucks
@ 2008-09-04 20:09                     ` Karel Th�nissen
  2008-09-05  7:25                       ` stefan-lucks
  1 sibling, 1 reply; 93+ messages in thread
From: Karel Th�nissen @ 2008-09-04 20:09 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 6528 bytes --]

>> <stefan-lucks@see-the.signature> schreef in bericht
>> news:Pine.LNX.4.64.0809041404570.22581@medsec1.medien.uni-weimar.de...

>> So if I understand you correctly this time, the raising (or not) of an
>> exception for "if Y/X<000" should in your view depend on the context
>> where
>> it is used: [...]
>
> No, you misread me again. If you had read some earlier posts from me in
> this thread, what I am trying to express is that "and" should better do
> what "and then" actually does. That is it, so simple!

Refuted in another reply.

>> I fear that you underestimate the complexities of putting that smartness
>> in a compiler and you overestimate the abilities of the ordinary
>> programmers to understand what is going on.
>
> Very strange that the Ada compiler is able to compile stuff if you write
> "and then" instead of "and". Following your point, the designers of Ada
> did overestimate the smartness of compilers. ;-)

My objections are targeted at the thing that you propose (elsewhere called
1+2). That beast would either allow bugs to hide, or would require whole
program analysis and perhaps mind-reading capabilties.

> Now really, the whole thing seems to work quite well for "and then". And
> in quite a few languages other than Ada for "and".

If course it works. It is a different thing thing you propose.

>> No, I do not think I misread. Your writing was not precise: you wrote
>>
>>    "if X/=0 and Y/X<100" should go into the else-branch, instead of
>> raising
>> an exception.
>>
>> But in Ada it does not go to the else-branche for X=0. So you are
>> proposing
>> a language change, and I point out that that would be a vey bad idea.
>
> I am not trying to propose to change Ada -- regrettably this would break
> compatibility too much. But if it where not for compatibility reasons, I
> would consider to propose that change.

>> We cannot expect the compiler to be so smart to distinguish exceptions
>> that
>> are avoidable if the left operand had been evaluated first (as with
>> conditional boolean operators) from the other exceptions in general. So
>> the
>> only viable options are: not doing it like this at all (my choice) or
>> picking the else branche for all exceptions.
>
> Strange that the compiler is smart enough to do the right thing if we just
> write "and then" instead of "and". ;-)

You still seem to think that the conditional-and in a programming language
can be symmetric.

>> That would make it in invisible exception handler. Bad, bad, bad. And as
>> noted above, it would also introduce context sensitivity whether
>> exceptions should be raised or not. Again very bad.
>
> Where is the context sensitivity about exceptions when you write "and
> then"?

There is no need in Ada, for the simple reason that the compiler can see the
difference between "A and B" and "A and then B" without knowing anything at
all about the context in which it is used. Therefore, the choice of
formantics is known while parsing that particular expression/ production in
the grammar.

>> And if you do want conditional evaluation, you choose 'and then'. What is
>> wrong with it? Okay, it is wordy, but the formantics in Ada are very
>> precise. That is more important than 5 characters saved.
>
> I could not care less about the five characters.
>
> But the designers of Ada (and the designers of almost any other language
> out there) have chosen the identifier "and" for a reason. And the reason
> is that the language "and" actually attempts to mimic the mathematical
> "and".

Yes, I agree and that is very unfortunate. But while we are at it. The
'designers' of logic made the same mistake: they have chosen an
interpretation that difference from the word "and" in English. Take a
semiologist to explain the difference. The important thing is that the
formantics of the operator be well-defined. That is the case in the various
logics as is the case in Ada (but not in most other programming languages).

>> Maybe you meant 'and' in your example in a more abstract sense without
>> providing the precision is demanded by Ada. Unfortunately, you expressed
>> it
>> as valid Ada.
>
> No, I simply complained about a (minor) design flaw of Ada.
>
>> > But when "if X/=0 and Y/X<100" propagates an exception for X=0, as,
>> > alas,
>> > done in Ada, something is logically wrong.
>>
>> So you do think that it should not raise an exception and go to the
>> else-branche????? Now what do you want? You contradict yourself.
>
> Are you trolling? That quote of mine is a repetition, not a contradiction!
>
>> > Dividing something by zero is undefined, not a contradiction.
>>
>> That again shows my point that mathematics and computing are two
>> different
>> beasts. A mathematician will put the pencil done and stop immediately
>> when
>> asked to do an undefined operation, such as a division by zero.
>
> Agreed!
>
> But in a lot of mathematical papers, descriptions of algorithms and the
> like, you actually find expressions like "X/=0 and Y/X<1000". Such an
> expression does have a well-defined meaning, even for X=0. Nobody would
> drop his or here pencil.
>
> BTW, even the order is an issue -- if you write "Y/X<1000 and X/=0" in a
> mathematical paper, that would be logically correct, but you could bet on
> the reviewers asking you to rewrite it to "X/=0 and Y/X<1000".

Then the author is not using boolean Algebra, but some three valued logic.
Quite possible. Perhaps a logic with:

   false and undefined  <=> undefined and false <=> false

If that is the definition, then that would be possible. But this is not the
na�ve definition from Boolean algebra. This definition must be learned, but
then you could equally well learn both well-defined definitions as from Ada.

But you may still prefer above definition from a three-valued logic. I
agree, the logic is well-defined and mathemtically elegant. However, it is
an engineering disaster. We write millions of lines of code and we must deal
with violations, exceptions, and validations errors. In general exceptions
are a fact of life in computing. And I do not want my exceptions
(violations, errors) to get uncaught because of some interpretation of
boolean operators that sends them to else clause or silently resumes
execution, no matter how elegant the notation for completely correct
programs.

> ------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
>               Stefan dot Lucks at uni minus weimar dot de
> ------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------
>





^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 19:31                   ` stefan-lucks
  2008-09-04 19:59                     ` Karel Th�nissen
@ 2008-09-04 20:17                     ` Dmitry A. Kazakov
  1 sibling, 0 replies; 93+ messages in thread
From: Dmitry A. Kazakov @ 2008-09-04 20:17 UTC (permalink / raw)


On Thu, 4 Sep 2008 21:31:21 +0200, stefan-lucks@see-the.signature wrote:

> On Thu, 4 Sep 2008, Dmitry A. Kazakov wrote:
> 
>> "X/0 > 100 = T" means that neither is possible (contradiction). This
>> "contradiction" is closer to an intuitive understanding of X/0 > 100, yet
>> it is not the standard mathematical meaning of, which is that X/0 > 100 is
>> not a formula at all.
> 
> Well, "X/=0 and Y/X<100" is a common notation with a well-defined meaning, 
> even for X=0 (false, of course). On the other hand an isolated "Y/X<100" 
> only has a well-defined meaning if X/=0.

Hmm, in the texts I can still remember comma was used instead of /\:

   X /= 0, Y/X < 100   (when a set of pairs (X,Y) is specified)

   A, A => B
   --------------     (inference rule)
      B

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 19:05                   ` stefan-lucks
@ 2008-09-04 20:28                     ` Dmitry A. Kazakov
  2008-09-05  6:57                       ` stefan-lucks
  2008-09-05 14:14                     ` Robert A Duff
  1 sibling, 1 reply; 93+ messages in thread
From: Dmitry A. Kazakov @ 2008-09-04 20:28 UTC (permalink / raw)


On Thu, 4 Sep 2008 21:05:02 +0200, stefan-lucks@see-the.signature wrote:

>>>> Nevertheless Boolean logic /= Belnap logic, though the former is contained
>>>> in the latter. 
>>> 
>>> I never said "Boolean logic", I said "logic", which was ment to include 
>>> multi-valued logic. ;-)
>> 
>> There are many multi-valued logics. 
> 
> You are trying to build an overly complex theory,

I though you wanted to expose these values. But see below.

> which I am not interested in.

(You should be interested in making a consistent proposal...)

> The issue is very simple:
>
> 1. If the A- or the B-part in "if A and B" raises an exception, but the 
>    other part is false, the "right thing" (TM) to do would be to transfer 
>    control to the else clause (or below "end if", when there is no else). 
>    The intermediate result can be viewed as a three-valued logic 
>    expression, but the final outcome of the Boolean expression must be 
>    Boolean, of course. 

   0 /\ T = 0  (as you see the theory is very simple)

> 2. If both raise A and B an exception, of if one raises an exception and 
>    the other one is true, an exception is propagated. (*)

   T /\ T = T (ditto)
 
> 3. I would be willing to pragmatically sacrifice mathematical purity for a 
>    shortcut rule:

There is absolutely no reason to sacrifice purity for impurity.

>    If A is false, the expression is false, whatever B does. 
>    If A raises an exception, of if A is true and B raises an exception, 
>    the exception is propagated.

   1 /\ T = T (it works!)

As you see the theory works fine, even if you don't like it.

Anyway now I see what you want. That is (more or less formally):

Boolean'Base is Belnap logical values. All Boolean expressions are
evaluated in Boolean'Base, as it is already done for numeric types. Nothing
drastically new. (Compare also how Float overflow is converted to IEEE
Infinity.) Like universal numbers, Boolean'Base may have no variables
declared.

> (*) Funny problem: *Which* exception should be propagated? 

This is not funny. This one kills the idea, unless you forcefully convert
all exceptions into Constraint_Error, when a non-Boolean value is converted
to Boolean.

But the main problem is that this is not what people want. They do lazy
evaluation in order to control side effects (and exception is considered
rather as a side effect). Your proposal does not deal with eagerness. Yes
the compiler might optimize away evaluation of one of the arguments of
"and" if another is False. But to do so it still needs a proof that there
is no side effects other than an exception. Unlikely to exceptions, you
cannot pack all side effects into T or _|_.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-03 15:56                 ` Robert A Duff
@ 2008-09-04 22:09                   ` Brian Drummond
  0 siblings, 0 replies; 93+ messages in thread
From: Brian Drummond @ 2008-09-04 22:09 UTC (permalink / raw)


On Wed, 03 Sep 2008 11:56:15 -0400, Robert A Duff
<bobduff@shell01.TheWorld.com> wrote:

>Brian Drummond <brian_drummond@btconnect.com> writes:

>> But it does illustrate that (I) "and then" (short circuit form, order
>> guaranteed) and (II) "and" (short circuit permitted, but not guaranteed,
>> order not guaranteed) are properly separate operations.
>>
>> For cases such as the logging example (semantics require both to be
>> evaluated) my personal choice would be to explicitly evaluate both, and
>> combine their evaluation results, as elsewhere in this thread. 
>>
>> Is my understanding of Ada correct in expecting this is the only way to
>> guarantee evaluation of both? ( i.e. Ada handles "and" as (II) above)
>
>No.  Ada guarantees that both arguments of "and" are evaluated.
>Of course if the compiler knows that evaluation has no effect, it
>doesn't need to generate any code -- that would be the case for
>"X > 0", for example. 

In the process it must give up some opportunities for optimisation
(though I suspect, not as many as e.g. mandating the short-circuit form
in a particular order). 
Note: I am not complaining that this is an unreasonable design decision.

- Brian




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05  6:57                       ` stefan-lucks
@ 2008-09-05  6:34                         ` Ray Blaak
  0 siblings, 0 replies; 93+ messages in thread
From: Ray Blaak @ 2008-09-05  6:34 UTC (permalink / raw)


stefan-lucks@see-the.signature writes:
> > This is not funny. This one kills the idea, unless you forcefully convert
> > all exceptions into Constraint_Error, when a non-Boolean value is converted
> > to Boolean.
> 
> If I would actually propose something like that, I would probably propose 
> to raise Program_Error if the exceptions aren't all the same. 

If you have a situation where all operands are evaluated, then the exceptions
raised should only be those from the operand expressions themselves under
normal language rules: Constraint_Error if appropriate, whatever explicit
exception a function raises, etc.

To do anything else gives way to madness. If nothing else, it would be quite
difficult to determine the root cause of an exception, and examining source
code would not give obvious reasons.

The only way out is to have partial evaluation of boolean expressions, so that
you can have guard operands *and* consistent exception rules. But Ada already
has that with "and then" and "or else", so consistently use that if you wish.

The reasons of having "and" and "or" evaluate both operands is a least
consistent and logical according to Ada rules, especially given that they are
semantically function calls.

It's just that for me, if I see a boolean expression, I am by instinct
evaluating the boolean logic, not seeing the side effect of evaluating all
operands. If that needs to be stressed, i.e., is an explicit requirement, I
prefer the code to more clearly spell out that required evaluation, and leave
the boolean combination of the results as a separate step.

-- 
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.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05  7:00                         ` stefan-lucks
@ 2008-09-05  6:35                           ` Ray Blaak
  0 siblings, 0 replies; 93+ messages in thread
From: Ray Blaak @ 2008-09-05  6:35 UTC (permalink / raw)


stefan-lucks@see-the.signature writes:
> But "if False and Function_Call_That_Raises_An_Exception" ideally should 
> not propagate the exception raised in the function call, but evaluate to 
> false.

If the function executes, then of course the exception should be
propogated. Otherwise you have silent errors.

The only way out is to not evaluate the function at all.

But that is just "and then".

-- 
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.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05  7:25                       ` stefan-lucks
@ 2008-09-05  6:37                         ` Ray Blaak
  2008-09-05  8:20                           ` stefan-lucks
  2008-09-05 13:57                         ` Robert A Duff
  1 sibling, 1 reply; 93+ messages in thread
From: Ray Blaak @ 2008-09-05  6:37 UTC (permalink / raw)


stefan-lucks@see-the.signature writes:
> Now, a really ugly issue is that both the evaluation of A and the 
> evaluation of B might raise an exeption, and we cannot re-raise both 
> exceptions. 

They are executed sequentially, in some arbitrary order, so one wins
first. That is the exception that gets propataged

> If not for other reasons, that suffices not to propagate that. 

This is the worst thing to do, for that silently hides error situations.

-- 
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.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05  7:44                         ` stefan-lucks
@ 2008-09-05  6:41                           ` Vinzent Hoefler
  0 siblings, 0 replies; 93+ messages in thread
From: Vinzent Hoefler @ 2008-09-05  6:41 UTC (permalink / raw)


On Fri, 05 Sep 2008 09:44:33 +0200, stefan-lucks wrote:

> I didn't invent or re-invent anything. I just pointed out that the fact 
> that "and then" does, what "and" should do. This is un-intiutive and 
> error-prone.

Well, for me the "and" disguising as "and then" would be unintuitive.
I had the same issues, as you seem to have now, adjusting to C's
IMO "illogical" statements like "if ((NULL != p) && (p->something))"
suddenly being totally valid.

So, the "intuition" obviously depends on the observer. ;)


Vinzent.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 20:28                     ` Dmitry A. Kazakov
@ 2008-09-05  6:57                       ` stefan-lucks
  2008-09-05  6:34                         ` Ray Blaak
  0 siblings, 1 reply; 93+ messages in thread
From: stefan-lucks @ 2008-09-05  6:57 UTC (permalink / raw)


On Thu, 4 Sep 2008, Dmitry A. Kazakov wrote:

> There is absolutely no reason to sacrifice purity for impurity.

Fine! ;-)

> >    If A is false, the expression is false, whatever B does. 
> >    If A raises an exception, of if A is true and B raises an exception, 
> >    the exception is propagated.
> 
>    1 /\ T = T (it works!)
> 
> As you see the theory works fine, even if you don't like it.
> 
> Anyway now I see what you want. That is (more or less formally):
> 
> Boolean'Base is Belnap logical values. All Boolean expressions are
> evaluated in Boolean'Base, as it is already done for numeric types. Nothing
> drastically new. (Compare also how Float overflow is converted to IEEE
> Infinity.) Like universal numbers, Boolean'Base may have no variables
> declared.

> > (*) Funny problem: *Which* exception should be propagated? 
> 
> This is not funny. This one kills the idea, unless you forcefully convert
> all exceptions into Constraint_Error, when a non-Boolean value is converted
> to Boolean.

If I would actually propose something like that, I would probably propose 
to raise Program_Error if the exceptions aren't all the same. 

> But the main problem is that this is not what people want. They do lazy
> evaluation in order to control side effects (and exception is considered
> rather as a side effect). 

Well, exceptions are treated like side effects, but they actually are 
something different. 

E.g., pure functions are free from "real" side effects, but they can still 
raise an exception. Even if you employ the SPARK verifier, you can be sure 
that no Constraint_Error occurs, but you still don't know about 
Storage_Error.




-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 19:40                       ` Georg Bauhaus
@ 2008-09-05  7:00                         ` stefan-lucks
  2008-09-05  6:35                           ` Ray Blaak
  0 siblings, 1 reply; 93+ messages in thread
From: stefan-lucks @ 2008-09-05  7:00 UTC (permalink / raw)


> stefan-lucks@see-the.signature wrote:
> 
> > 1. If the A- or the B-part in "if A and B" raises an exception, but the
> >    other part is false, the "right thing" (TM) to do would be to transfer
> >    control to the else clause (or below "end if", when there is no else).
> 
> With all due respect, professor, you are suggesting circumstances
> could warrant the automatic assignment of value False to expection
> occurrences?

For heaven's sake, no!

But "if False and Function_Call_That_Raises_An_Exception" ideally should 
not propagate the exception raised in the function call, but evaluate to 
false.


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 20:09                     ` Karel Th�nissen
@ 2008-09-05  7:25                       ` stefan-lucks
  2008-09-05  6:37                         ` Ray Blaak
  2008-09-05 13:57                         ` Robert A Duff
  0 siblings, 2 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-05  7:25 UTC (permalink / raw)


On Thu, 4 Sep 2008,  wrote:

> > Very strange that the Ada compiler is able to compile stuff if you write
> > "and then" instead of "and". Following your point, the designers of Ada
> > did overestimate the smartness of compilers. ;-)
> 
> My objections are targeted at the thing that you propose (elsewhere called
> 1+2). That beast would either allow bugs to hide, or would require whole
> program analysis and perhaps mind-reading capabilties.

Firstly, I have been very clear that I didn't "propose" that. 

Secondly, it is easy to implement. Replace "if A and B then ... else ... 
end if" by:

declare 
  T_A := A;
begin
  if T_A then 
    return B; -- may raise an exception
  end if;
exception
  when others =>
    if B -- may raise an exception
    then 
      raise; -- propagate the exception raised by A 
    else
      return False;
    end if;
end;

Hey, do you need mind-reading capabilities for that? I would consider 
this an exercise for Students -- and a really easy one.;-)

Now, a really ugly issue is that both the evaluation of A and the 
evaluation of B might raise an exeption, and we cannot re-raise both 
exceptions. If not for other reasons, that suffices not to propagate that. 
Well, one could raise a Program_Error in that case, but that is ugly 
anyway. But note that even in Ada-as-it-is, it is not defined which of 
both exceptions is raised!

> > is that the language "and" actually attempts to mimic the mathematical
> > "and".
> 
> Yes, I agree and that is very unfortunate. But while we are at it. The
> 'designers' of logic made the same mistake: they have chosen an
> interpretation that difference from the word "and" in English. 

OK, here we disagree. They wanted the "and", because they wanted to mimic 
the mathematical and -- as much as the designers of most other languages. 
As much as integer addition mimics the addition over the integers ... 

> Quite possible. Perhaps a logic with:
> 
>    false and undefined  <=> undefined and false <=> false
> 
> If that is the definition, then that would be possible. But this is not the
> nave definition from Boolean algebra. This definition must be learned, but
> then you could equally well learn both well-defined definitions as from Ada.
> 
> But you may still prefer above definition from a three-valued logic. I
> agree, the logic is well-defined and mathemtically elegant. However, it is
> an engineering disaster. We write millions of lines of code and we must deal
> with violations, exceptions, and validations errors. 

The better it would be to focus on actual violations. Instead of hunting 
an exception raised in fragments such as "if X/=0 and Y/X<Z".


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 19:59                     ` Karel Th�nissen
@ 2008-09-05  7:27                       ` stefan-lucks
  2008-09-05  8:38                         ` Ludovic Brenta
  0 siblings, 1 reply; 93+ messages in thread
From: stefan-lucks @ 2008-09-05  7:27 UTC (permalink / raw)


On Thu, 4 Sep 2008,  wrote:

> And again, you propose a contextual interpretation of "Y/X<100" (for X=0). 
> That is totally beyond what program analysis can achieve.

No, I am not. I claim that the shortcut "and" (which in Ada unfurtunately 
is written as "and then") is the more natural and human-readable 
interpretation of "and" expressions.

-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 20:06                       ` Karel Th�nissen
@ 2008-09-05  7:44                         ` stefan-lucks
  2008-09-05  6:41                           ` Vinzent Hoefler
  0 siblings, 1 reply; 93+ messages in thread
From: stefan-lucks @ 2008-09-05  7:44 UTC (permalink / raw)


On Thu, 4 Sep 2008,  wrote:

> > On Thu, 4 Sep 2008, stefan-lucks@see-the.signature wrote:
> >> No, you misread me again. If you had read some earlier posts from me in
> >> this thread, what I am trying to express is that "and" should better do
> >> what "and then" actually does. That is it, so simple!
[...]
> I personally could life with the idea that in Ada, 'and' would have had
> conditional formantics (now  and-then)and some other operator would have
> unconditional formantics (now and). That is just swapping tokens at the
> lexical level. Fine. What is your point?

That was my point. I don't know why this raised such a lengthy thread. 

> > To be precise, here is a cut-and-paste from what I wrote in another
> > posting:
> >
> > 1. If the A- or the B-part in "if A and B" raises an exception, but the
> >   other part is false, the "right thing" (TM) to do would be to transfer
> >   control to the else clause (or below "end if", when there is no else).
> >   The intermediate result can be viewed as a three-valued logic
> >   expression, but the final outcome of the Boolean expression must be
> >   Boolean, of course.
> 
> Thank you, there it is.

Please don't take me out of context! As I pointed out, there are reasons 
not to do exactly the "right thing" in a pragmatic language. I had been 
very explicit, that if I where proposing a language change (I am not, as 
this would break compatibilty), I would propose the following:

> > 3. I would be willing to pragmatically sacrifice mathematical purity for a
> >   shortcut rule: If A is false, the expression is false, whatever B does.
> >   If A raises an exception, of if A is true and B raises an exception,
> >   the exception is propagated.
> 
> Congratulations, you just reinvented the and-then in Ada.

I didn't invent or re-invent anything. I just pointed out that the fact 
that "and then" does, what "and" should do. This is un-intiutive and 
error-prone. Exceptions may be raised which the programmer would not 
really expect to be raised. 

I described an "ideal" interpretation. You would not need "mind reading" 
capabilities to impleent it, but it would still be too heavy-weight and 
complex. And I pointed out an easy and pragmatic approach which could 
handle the issue, and which is used in quite a few other programming 
languages. 

> 1+2 may appear ideal for a mathematician, because of the symmetry it
> provides. [...]
> 
> Ideal behavior is a fata morgana from lala-land. We have to deal with
> fallible developers and machinery.

Thank you for making my point! 


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05  6:37                         ` Ray Blaak
@ 2008-09-05  8:20                           ` stefan-lucks
  0 siblings, 0 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-05  8:20 UTC (permalink / raw)


> > If not for other reasons, that suffices not to propagate that. 
> 
> This is the worst thing to do, for that silently hides error situations.

Sorry, I meant to write not to *propose* that. So I agree with you.

-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05  7:27                       ` stefan-lucks
@ 2008-09-05  8:38                         ` Ludovic Brenta
  0 siblings, 0 replies; 93+ messages in thread
From: Ludovic Brenta @ 2008-09-05  8:38 UTC (permalink / raw)


Stefan Lucks wrote:
> On Thu, 4 Sep 2008,  wrote:
>
> > And again, you propose a contextual interpretation of "Y/X<100" (for X=0).
> > That is totally beyond what program analysis can achieve.
>
> No, I am not. I claim that the shortcut "and" (which in Ada unfurtunately
> is written as "and then") is the more natural and human-readable
> interpretation of "and" expressions.

Maybe my college years are too far behind but I differ here. When I
see "and", I intuitively think of a _symmetric_ operator with the same
meaning for Booleans as for arrays of Booleans and modular types (i.e.
bitwise, mathematical, pure Boolean-logic "and"). When I see "and
then", I intuitively think of an _asymmetric_ operator which only
evaluates the right hand side if the left-hand side is True.

--
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 12:12               ` stefan-lucks
                                   ` (2 preceding siblings ...)
  2008-09-04 16:33                 ` Dmitry A. Kazakov
@ 2008-09-05 13:26                 ` Robert A Duff
  2008-09-05 13:49                   ` Robert A Duff
  3 siblings, 1 reply; 93+ messages in thread
From: Robert A Duff @ 2008-09-05 13:26 UTC (permalink / raw)


stefan-lucks@see-the.signature writes:

> But when "if X/=0 and Y/X<100" propagates an exception for X=0, as, alas, 
> done in Ada, something is logically wrong.

So what do you think "if Y/X<100 and X/=0" should do in Ada when X = 0?

The original poster asked for "and" to behave like "and then",
which is asymmetric.

- Bob



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05 13:26                 ` Robert A Duff
@ 2008-09-05 13:49                   ` Robert A Duff
  0 siblings, 0 replies; 93+ messages in thread
From: Robert A Duff @ 2008-09-05 13:49 UTC (permalink / raw)


I wrote:

> stefan-lucks@see-the.signature writes:
>
>> But when "if X/=0 and Y/X<100" propagates an exception for X=0, as, alas, 
>> done in Ada, something is logically wrong.
>
> So what do you think "if Y/X<100 and X/=0" should do in Ada when X = 0?

Ah, I see you answered this question elsewhere.  You said 1+2 is what
you prefer, because you believe it to be mathematically elegant,
but you would settle for 3.

Well, that seems inconsistent, to me: you can't argue for 3 ("and"
should behave as "and then" does, and we can presumably eliminate
the "and then" syntax from the language) on the basis that 1+2
is elegant.

- Bob



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05  7:25                       ` stefan-lucks
  2008-09-05  6:37                         ` Ray Blaak
@ 2008-09-05 13:57                         ` Robert A Duff
  1 sibling, 0 replies; 93+ messages in thread
From: Robert A Duff @ 2008-09-05 13:57 UTC (permalink / raw)


stefan-lucks@see-the.signature writes:

> On Thu, 4 Sep 2008,  wrote:
>
>> > Very strange that the Ada compiler is able to compile stuff if you write
>> > "and then" instead of "and". Following your point, the designers of Ada
>> > did overestimate the smartness of compilers. ;-)
>> 
>> My objections are targeted at the thing that you propose (elsewhere called
>> 1+2). That beast would either allow bugs to hide, or would require whole
>> program analysis and perhaps mind-reading capabilties.
>
> Firstly, I have been very clear that I didn't "propose" that. 
>
> Secondly, it is easy to implement.

What is "it" here?  In the below, are you implementing the 1+2 idea,
or the 3 idea?  Neither one seems right (even ignoring the minor
syntax errors)...

>... Replace "if A and B then ... else ... 
> end if" by:
>
> declare 
>   T_A := A;
> begin
>   if T_A then 
>     return B; -- may raise an exception
>   end if;
> exception
>   when others =>
>     if B -- may raise an exception
>     then 
>       raise; -- propagate the exception raised by A 
>     else
>       return False;
>     end if;
> end;

In the above, if B raises an exception the first time, we evaluate B
again (and maybe it raises the exception again, or maybe not).
Surely that's not what you meant!  And the comment 
"propagate the exception raised by A" is wrong, since the
handler doesn't apply to exceptions raised by A.

> Hey, do you need mind-reading capabilities for that?

Yes, I need to read your mind to know what you meant above.  ;-)

>...I would consider 
> this an exercise for Students -- and a really easy one.;-)

;-)

> Now, a really ugly issue is that both the evaluation of A and the 
> evaluation of B might raise an exeption, and we cannot re-raise both 
> exceptions. If not for other reasons, that suffices not to propagate that. 
> Well, one could raise a Program_Error in that case, but that is ugly 
> anyway. But note that even in Ada-as-it-is, it is not defined which of 
> both exceptions is raised!

Sure, that's a little ugly, but in practice it doesn't matter -- the
fact that something went wrong is not lost.

- Bob



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-04 19:05                   ` stefan-lucks
  2008-09-04 20:28                     ` Dmitry A. Kazakov
@ 2008-09-05 14:14                     ` Robert A Duff
  2008-09-05 15:04                       ` Dmitry A. Kazakov
                                         ` (2 more replies)
  1 sibling, 3 replies; 93+ messages in thread
From: Robert A Duff @ 2008-09-05 14:14 UTC (permalink / raw)


stefan-lucks@see-the.signature writes:

>> >> Nevertheless Boolean logic /= Belnap logic, though the former is contained
>> >> in the latter. 
>> > 
>> > I never said "Boolean logic", I said "logic", which was ment to include 
>> > multi-valued logic. ;-)
>> 
>> There are many multi-valued logics. 
>
> You are trying to build an overly complex theory, which I am not 
> interested in. The issue is very simple:
>
> 1. If the A- or the B-part in "if A and B" raises an exception, but the 
>    other part is false, the "right thing" (TM) to do would be to transfer 
>    control to the else clause (or below "end if", when there is no else). 
>    The intermediate result can be viewed as a three-valued logic 
>    expression, but the final outcome of the Boolean expression must be 
>    Boolean, of course. 
>
> 2. If both raise A and B an exception, of if one raises an exception and 
>    the other one is true, an exception is propagated. (*)
>
> 3. I would be willing to pragmatically sacrifice mathematical purity for a 
>    shortcut rule: If A is false, the expression is false, whatever B does. 
>    If A raises an exception, of if A is true and B raises an exception, 
>    the exception is propagated.

Some more questions about 3.

Do you want to say that "and" is not a function (just like "and then" is
not a function)?  So you can't pass "and" as a generic formal parameter,
pass it as a downward closure to an iterator, or rename it?

Or are you saying that if "and" is passed to a generic formal function
called Mumble, then Mumble gets this special property (of not evaluating
its second argument in some cases)?

Do you want that "and" on array-of-Boolean is no longer defined in terms
of "and" on each component pair?  (There's no such thing as "and then"
on arrays.)  Same question for modular "and".  Or maybe just eliminate
these other "and" operators?

Do believe that "0 * F(X)" should return 0, even if F raises
an exception?  Must return 0, or might return 0?

I'm just trying to explore the consequences of this seemingly-simple
language design choice.  It doesn't seem so simple to me.

- Bob



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05 14:14                     ` Robert A Duff
@ 2008-09-05 15:04                       ` Dmitry A. Kazakov
  2008-09-07 16:45                         ` stefan-lucks
  2008-09-05 15:14                       ` Hyman Rosen
  2008-09-07 16:36                       ` stefan-lucks
  2 siblings, 1 reply; 93+ messages in thread
From: Dmitry A. Kazakov @ 2008-09-05 15:04 UTC (permalink / raw)


On Fri, 05 Sep 2008 10:14:47 -0400, Robert A Duff wrote:
 
> Some more questions about 3.

(The proposal is, as I understood it, IMO workable, but it potentially has
a heavy overhead and it does not solve the problem. It is not the
mathematical interpretation of "and", and its semantics is not better than
one of "and then". Further IMO the problem lies elsewhere. Nevertheless, I
will take the liberty of explaining the semantics, and consequences)
 
> Do you want to say that "and" is not a function (just like "and then" is
> not a function)?  So you can't pass "and" as a generic formal parameter,
> pass it as a downward closure to an iterator, or rename it?

It will be a normal function. Surely this would require a lot of re-work of
the existing compilers, because exception occurrence will become an
extended "Universal_Boolean" value. It will likely mean a lot of
distributed overhead, because an exception which is already underway needs
to be convertible into a value everywhere a "Universal_Boolean" is
expected.

> Or are you saying that if "and" is passed to a generic formal function
> called Mumble, then Mumble gets this special property (of not evaluating
> its second argument in some cases)?

No, all arguments are eagerly evaluated. It is simply so that exception
becomes a legal value of "Universal_Boolean". The exception is raised when
such value is converted to Boolean in the context where a Boolean is
expected. Like in "if". But "and", "or", "xor", "not" operate on
"Universal_Boolean".

> Do you want that "and" on array-of-Boolean is no longer defined in terms
> of "and" on each component pair?  (There's no such thing as "and then"
> on arrays.)  Same question for modular "and".  Or maybe just eliminate
> these other "and" operators?

This is no problem either, because "Universal_Boolean" is not Boolean like
Universal_Integer is not Integer. So the array of Boolean remains what it
was.

> Do believe that "0 * F(X)" should return 0, even if F raises
> an exception?  Must return 0, or might return 0?

That's the case for IEEE numbers. The idea is to replace a potential or
real (shudder) exception propagation with a value, which may or may not
raise the exception later. This value may participate in expressions. It
can even be stored as NaN is. (Though, not in this case.)

BTW, I am not a fan of IEEE numbers. But considering it rationally,
evaluation of expressions in terms of wider ranges or ideal values has some
advantages. After all 1-3+4 is OK for Positive, even if (1-3) is not a
positive.

> I'm just trying to explore the consequences of this seemingly-simple
> language design choice.  It doesn't seem so simple to me.

(I hope Stefan will correct me if I misinterpreted his proposal)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05 14:14                     ` Robert A Duff
  2008-09-05 15:04                       ` Dmitry A. Kazakov
@ 2008-09-05 15:14                       ` Hyman Rosen
  2008-09-05 15:59                         ` Adam Beneschan
  2008-09-07 16:36                       ` stefan-lucks
  2 siblings, 1 reply; 93+ messages in thread
From: Hyman Rosen @ 2008-09-05 15:14 UTC (permalink / raw)


Robert A Duff wrote:
> I'm just trying to explore the consequences of this seemingly-simple
> language design choice.  It doesn't seem so simple to me.

There are two kinds of "and" - the one that's involved in
control flow, and should therefore be short-circuited, and
the one that combines booleans, which is just an arithmetic
function like addition and should therefore not be short-
circuited.

Both C and Ada have this, C through "&&" and "&" and Ada
through "and then" and "and". Given the nature of code,
the control flow variant appears far more often than the
arithmetic one, so I guess some people are disturbed by
the fact that the most common variant is wordier. As a
long-time reader of this newsgroup, I know the mantra that
"Ada is designed for readers, not writers. Shorter is not
necessarily better." :-)

By the way, C++ made the design mistake of allowing && and
|| to be overloaded, whereupon they lose their short-circuit
behavior and become normal evaluate-both-operands functions.
Just awful.



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05 15:14                       ` Hyman Rosen
@ 2008-09-05 15:59                         ` Adam Beneschan
  2008-09-05 16:10                           ` Hyman Rosen
  0 siblings, 1 reply; 93+ messages in thread
From: Adam Beneschan @ 2008-09-05 15:59 UTC (permalink / raw)


On Sep 5, 8:14 am, Hyman Rosen <hyro...@mail.com> wrote:

> By the way, C++ made the design mistake of allowing && and
> || to be overloaded, whereupon they lose their short-circuit
> behavior and become normal evaluate-both-operands functions.
> Just awful.

Hey, at least they haven't allowed the "if" and "while" keywords to be
overloaded.  Yet.  Maybe they'll find a way to overload the curly
braces too.

                                 -- Adam




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05 15:59                         ` Adam Beneschan
@ 2008-09-05 16:10                           ` Hyman Rosen
  0 siblings, 0 replies; 93+ messages in thread
From: Hyman Rosen @ 2008-09-05 16:10 UTC (permalink / raw)


Adam Beneschan wrote:
> Hey, at least they haven't allowed the "if" and "while"
 > keywords to be overloaded.

I take it you haven't seen some of the most fancy expression
template code, then? :-)



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-07 16:36                       ` stefan-lucks
@ 2008-09-07 16:08                         ` Gautier
  0 siblings, 0 replies; 93+ messages in thread
From: Gautier @ 2008-09-07 16:08 UTC (permalink / raw)


stefan-lucks@see-the.signature:

 > I think, there are three options:
 >
 > 1. Differentiate between the control flow "and", and the Boolean 
function
 >    "and". The first has the shortcut property, the second doesn't.
 >
 > (This is the worst option, but it would be the easy one.)

The worst of the three maybe, but not the worst possible ;-). For 
instance Delphi does it a lot worse (really difficult to beat):

http://www.delphibasics.co.uk/RTL.asp?Name=$B

Cheers
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/

NB: For a direct answer, e-mail address on the Web site!



^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05 14:14                     ` Robert A Duff
  2008-09-05 15:04                       ` Dmitry A. Kazakov
  2008-09-05 15:14                       ` Hyman Rosen
@ 2008-09-07 16:36                       ` stefan-lucks
  2008-09-07 16:08                         ` Gautier
  2 siblings, 1 reply; 93+ messages in thread
From: stefan-lucks @ 2008-09-07 16:36 UTC (permalink / raw)


On Fri, 5 Sep 2008, Robert A Duff wrote:

> stefan-lucks@see-the.signature writes:
> 
> > 3. I would be willing to pragmatically sacrifice mathematical purity for a 
> >    shortcut rule: If A is false, the expression is false, whatever B does. 
> >    If A raises an exception, of if A is true and B raises an exception, 
> >    the exception is propagated.
> 
> Some more questions about 3.

Interesting questions! 

I like to point out, that I don't actually *propose* something, I just 
share some unfinished ideas. 

> Do you want to say that "and" is not a function (just like "and then" is
> not a function)?  

Not quite!

> So you can't pass "and" as a generic formal parameter, pass it as a 
> downward closure to an iterator, or rename it?

I think, there are three options:

1. Differentiate between the control flow "and", and the Boolean function 
   "and". The first has the shortcut property, the second doesn't. 

(This is the worst option, but it would be the easy one.)

2. Define the function "and" to operate over a type "Universal_Boolean", 
   similarly to what Dmitry suggested in another posting.

3. Extend the syntax of Ada subprograms to allow teh specification of 
   parameters in lazy evaluation mode. E.g., the function "and" could be 
   specified as follows:
      "function and(A: in Boolean; B: lazy in Boolean) return Boolean;
   Note that A is in eager mode, B in lazy mode. 

My preferred option would be 3., followed by 2. One reason is that I would 
like to have lazy evaluation in Ada, anyway. 

> Or are you saying that if "and" is passed to a generic formal function
> called Mumble, then Mumble gets this special property (of not evaluating
> its second argument in some cases)?

Assuming lazy evaluation in Ada, this would not be a "special property". 
And to pass the shortcut "and" to "Mumble", the first parameter of 
"mumble" must be of mode (eager) in, the second of mode lazy in. So there 
would be no surprise to the programmer.

> Do you want that "and" on array-of-Boolean is no longer defined in terms
> of "and" on each component pair?  (There's no such thing as "and then"
> on arrays.)  Same question for modular "and".  Or maybe just eliminate
> these other "and" operators?

For heaven's sake, no! 

> Do believe that "0 * F(X)" should return 0, even if F raises
> an exception?  Must return 0, or might return 0?

Good question! Given lazy evaluation, we *could* implement "*" that way. 
But the exception could imply that F(X) is infinite, and "0*infinite" is 
undefined. So I don't think we *should* implement "*" that way. Except, 
perhaps, modular types. 

> I'm just trying to explore the consequences of this seemingly-simple
> language design choice.  It doesn't seem so simple to me.

As I wrote before, I wouldn't even think of proposing such things without 
having a plausible idea how to implement such stuff.

-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

* Re: and then... (a curiosity)
  2008-09-05 15:04                       ` Dmitry A. Kazakov
@ 2008-09-07 16:45                         ` stefan-lucks
  0 siblings, 0 replies; 93+ messages in thread
From: stefan-lucks @ 2008-09-07 16:45 UTC (permalink / raw)


On Fri, 5 Sep 2008, Dmitry A. Kazakov wrote:

> On Fri, 05 Sep 2008 10:14:47 -0400, Robert A Duff wrote:
>  
> > Some more questions about 3.
> 
> (The proposal is, as I understood it, IMO workable, but it potentially has
> a heavy overhead and it does not solve the problem. It is not the
> mathematical interpretation of "and", and its semantics is not better than
> one of "and then". Further IMO the problem lies elsewhere. Nevertheless, I
> will take the liberty of explaining the semantics, and consequences)

Once again, I didn't actually *propose* anything. But you described some 
ideas I had very well, Dmitry, thank you. 

> No, all arguments are eagerly evaluated. It is simply so that exception
> becomes a legal value of "Universal_Boolean". The exception is raised when
> such value is converted to Boolean in the context where a Boolean is
> expected. Like in "if". But "and", "or", "xor", "not" operate on
> "Universal_Boolean".

I would consider both the option of introducing lazy evaluation (not as a 
special "compiler magic" thing only for "and", but in general), or 
extending the type Boolean, as described by you.

> (I hope Stefan will correct me if I misinterpreted his proposal)

No problem! You expressed one of the ideas I had in my mind better than I 
would have done it myself. But once again, I didn't make a proposal. I 
just shared some thoughts about the non-shortcut-and (and -or) in "if" 
expressions, which in my experience is a common error-pattern in Ada. 
(Other languages have more and worse traps than Ada, but nevertheless ...)



-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[flat|nested] 93+ messages in thread

end of thread, other threads:[~2008-09-07 16:45 UTC | newest]

Thread overview: 93+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-29 21:06 and then... (a curiosity) mockturtle
2008-08-29 21:47 ` Samuel Tardieu
2008-08-30 21:28   ` Maciej Sobczak
2008-08-31  8:28     ` Georg Bauhaus
2008-08-31 23:21       ` Ray Blaak
2008-09-01  8:05     ` Martin Krischik
2008-09-01 17:56       ` Ray Blaak
2008-09-02  6:53         ` Martin Krischik
2008-09-02 14:56           ` Adam Beneschan
2008-09-02 16:28             ` Ray Blaak
2008-09-02 16:26           ` Ray Blaak
2008-09-02 20:50             ` Robert A Duff
2008-09-03 12:35               ` Brian Drummond
2008-09-03 15:56                 ` Robert A Duff
2008-09-04 22:09                   ` Brian Drummond
2008-09-03 21:01               ` Vinzent Hoefler
2008-09-02 14:50     ` Adam Beneschan
2008-08-29 22:28 ` Adam Beneschan
2008-08-30  1:06   ` Jeffrey R. Carter
2008-08-30 11:21   ` Dmitry A. Kazakov
2008-08-30 15:35     ` Peter C. Chapin
2008-09-02 15:06       ` Adam Beneschan
2008-09-02  3:41 ` Steve
2008-09-02  7:48   ` stefan-lucks
2008-09-02  8:57     ` Martin Krischik
2008-09-02 10:50       ` stefan-lucks
2008-09-02 10:33         ` Ludovic Brenta
2008-09-02 13:32           ` stefan-lucks
2008-09-02 12:53             ` Ludovic Brenta
2008-09-02 17:32               ` Georg Bauhaus
2008-09-03 13:14               ` stefan-lucks
2008-09-03 12:44                 ` Dmitry A. Kazakov
2008-09-02 13:39             ` stefan-lucks
2008-09-02 13:40             ` stefan-lucks
2008-09-02 16:48             ` Dmitry A. Kazakov
2008-09-02 17:00             ` Keith Thompson
2008-09-02 19:15               ` Simon Wright
2008-09-02 20:37               ` Robert A Duff
2008-09-02 20:58                 ` Jeffrey R. Carter
2008-09-02 21:08                   ` Robert A Duff
2008-09-03 12:24                     ` Pascal Obry
2008-09-02 22:34                   ` Santiago Urueña
2008-09-03  5:56                     ` Robert A Duff
2008-09-03  6:55                       ` Santiago Urueña
2008-09-03 14:14                       ` Adam Beneschan
2008-09-03  0:11                 ` Randy Brukardt
2008-09-02 17:20             ` Georg Bauhaus
2008-09-04  1:05         ` Stephen Leake
2008-09-04  6:45           ` stefan-lucks
2008-09-04  7:35             ` Dmitry A. Kazakov
2008-09-04 12:04               ` stefan-lucks
2008-09-04 13:00                 ` Dmitry A. Kazakov
2008-09-04 19:05                   ` stefan-lucks
2008-09-04 20:28                     ` Dmitry A. Kazakov
2008-09-05  6:57                       ` stefan-lucks
2008-09-05  6:34                         ` Ray Blaak
2008-09-05 14:14                     ` Robert A Duff
2008-09-05 15:04                       ` Dmitry A. Kazakov
2008-09-07 16:45                         ` stefan-lucks
2008-09-05 15:14                       ` Hyman Rosen
2008-09-05 15:59                         ` Adam Beneschan
2008-09-05 16:10                           ` Hyman Rosen
2008-09-07 16:36                       ` stefan-lucks
2008-09-07 16:08                         ` Gautier
2008-09-04  7:39             ` Karel Th�nissen
2008-09-04 12:12               ` stefan-lucks
2008-09-04 15:13                 ` Georg Bauhaus
2008-09-04 15:16                 ` Karel Th�nissen
2008-09-04 15:42                   ` Dmitry A. Kazakov
2008-09-04 19:27                   ` stefan-lucks
2008-09-04 19:43                     ` stefan-lucks
2008-09-04 19:40                       ` Georg Bauhaus
2008-09-05  7:00                         ` stefan-lucks
2008-09-05  6:35                           ` Ray Blaak
2008-09-04 20:06                       ` Karel Th�nissen
2008-09-05  7:44                         ` stefan-lucks
2008-09-05  6:41                           ` Vinzent Hoefler
2008-09-04 20:09                     ` Karel Th�nissen
2008-09-05  7:25                       ` stefan-lucks
2008-09-05  6:37                         ` Ray Blaak
2008-09-05  8:20                           ` stefan-lucks
2008-09-05 13:57                         ` Robert A Duff
2008-09-04 16:33                 ` Dmitry A. Kazakov
2008-09-04 19:31                   ` stefan-lucks
2008-09-04 19:59                     ` Karel Th�nissen
2008-09-05  7:27                       ` stefan-lucks
2008-09-05  8:38                         ` Ludovic Brenta
2008-09-04 20:17                     ` Dmitry A. Kazakov
2008-09-05 13:26                 ` Robert A Duff
2008-09-05 13:49                   ` Robert A Duff
2008-09-03  1:24     ` Stephen Leake
2008-09-03  3:31       ` tmoran
2008-09-03 13:22       ` stefan-lucks

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox