[BUG] ?? in True and False

Richard A. O'Keefe ok at cs.otago.ac.nz
Fri Mar 14 00:36:59 UTC 2003


Bill Spight <bspight at pacbell.net> found a hardy perennial:
    true | 10 -> true
    true & 10 -> 10
    false | 10 -> 10
    false & 10 -> false
	
This is one of the traces of Smalltalk's link with Lisp.
Traditionally Lisp has regarded everything except the one "false" value
(spelled NIL) as "true".

In Lisp, (or t 10 -> t
         (or nil 10) -> 10
         (and t 10) -> 10
         (and nil 10) -> nil

Scheme broke with this tradition.  Smalltalk has broken with it in
the control structures, but not in & | and: or:.  Note that

    true  or:  [10]  ==> true
    false or:  [10]  ==> 10
    true  and: [10]  ==> 10
    false and: [10]  ==> false

Given the way that the compiler open-codes #or: and #and:, it could be
quite costly to "fix" #and: and #or:.

As things stand:
(1) &, | are consistent with #and:, #or:
(2) if the result of an expression involving &, |, #and:, #or:
    is used in a control structure (whileFalse[:], whileTrue[:],
    ifTrue:[ifFalse:] ifFalse:[ifTrue:]) it will be checked THEN
    that the result is Boolean, also for #not.
(3) The only cases where there is a net difference is where the
    result is not so used.

	> & aBoolean
	> Evaluating conjunction (AND).  Evaluate the argument.  Then
	> answer true if both the receiver and the argument are true.

This is not a good comment because it leaves what happens if the argument
is _not_ true completely unspecified.  Fix the comment to say that
	true & x => value of x
	false & x => false, x's value computed but ignored.
	
	> | aBoolean
	> Evaluating disjunction (OR).  Evaluate the argument.  Then
	> answer true if either the receiver or the argument is true.

This is not a good comment because it leaves what happens if neither
the receiver nor the argument is true completely unspecified.
Fix the comment to say that
	true | x => true, x's value computed but ignored.
	false | x => value of x.

	There is, if not a requirement that the argument be a Boolean,
	at least that strong suggestion.

Historically, there hasn't been any such requirement.

It's only fair to point out that the ANSI standard DOES have such
a requirement: "operand <boolean> unspecified" in 5.3.3.1, for example.
What's more, ANSI says (5.3.3.3) that (e and: [f]) is "undefined if the
result of sending #value to" the argument "is not a <boolean>".

	Nowhere does it say to return a non-Boolean.

But those method comments don't say NOT to return a non-Boolean, either.
I believe Squeak's behaviour is an allowed extension of ANSI behaviour here.

	As long as we're evaluating the argument, we
	might as well check whether it is a Boolean or not, no?

Benefits:
(1) slightly earlier error reporting.
(2) stricter conformance to ANSI.
Costs:
(3) extra time in &, |, and:, #or:.
(4) extra space in every use of #and:, #or:.
(5) risk of breaking existing code (probably slight)

It really isn't clear that the potential benefits are enough to outweigh
the costs.  Whatever happens, those comments have got to be improved, so
let's do _just_ that.



More information about the Squeak-dev mailing list