Re: Overloaded logic operators

torbenm@pc-003.diku.dk (Torben =?iso-8859-1?Q?=C6gidius?= Mogensen)
Mon, 24 Nov 2008 17:00:59 +0100

          From comp.compilers

Related articles
Overloaded logic operators mike@mike-austin.com (Mike Austin) (2008-11-23)
Re: Overloaded logic operators mailbox@dmitry-kazakov.de (Dmitry A. Kazakov) (2008-11-24)
Re: Overloaded logic operators torbenm@pc-003.diku.dk (2008-11-24)
Re: Overloaded logic operators bc@freeuk.com (Bartc) (2008-11-24)
Re: Overloaded logic operators arnold@skeeve.com (2008-11-25)
Re: Overloaded logic operators mike@mike-austin.com (Mike Austin) (2008-11-25)
Re: Overloaded logic operators mike@mike-austin.com (Mike Austin) (2008-11-25)
Re: Overloaded logic operators mike@mike-austin.com (Mike Austin) (2008-11-25)
Re: Overloaded logic operators lkrupp@pssw.com (Louis Krupp) (2008-11-25)
[9 later articles]
| List of all articles for this month |
From: torbenm@pc-003.diku.dk (Torben =?iso-8859-1?Q?=C6gidius?= Mogensen)
Newsgroups: comp.compilers
Date: Mon, 24 Nov 2008 17:00:59 +0100
Organization: Department of Computer Science, University of Copenhagen
References: 08-11-110
Keywords: design
Posted-Date: 24 Nov 2008 18:00:51 EST

Mike Austin <mike@mike-austin.com> writes:


> In many languages, logic operators "and" and "or" have been overloaded to
> handle more than booleans. For example:
>
> x = x or 0 # if x is nil, 0
> x and x.foo() # if x is not nil, call foo
> x = x > 0 # if x is > 0, x, else false
>
> I'm torn between this being easier for the programmer, or just bad
> practice in general.
>
> It enables you do to tricks like this:
>
> x = -1 < x < 1 or 0
>
> but it also means your booleans are values, and you can't test "if x == true",
> but only "if x != nil"
>
> In languages such as Ruby, Lua, Io, Python and JavaScript, does the
> benefit outweigh the effect of overloaded logic?


Strictly speaking, this is a question of language design and not
compilers, except where the design influences ease of compilation.


Basically, there are two ways I have seen of extending logical operators:


  1. Let the default boolean type be a type with more than two values,
        such as integers, extend operators to all values and define which
        subset corresponds to True and which to False.


  2. Include a null value that is present in all types and let logical
        operators treat the null value a False and all other values as
        True.


Option 1 is chosen by, e.g., C and many versions of BASIC, and logical
operators are typically extended to bitwise operations (though C also
includes sequential logical operators that are not bitwise).
Typically, 0 is treated ad False and all nonzero values as True. This
has the odd implication that AND'ing two True values may give False
and that two True values do not compare as equal. In C, comparison
operators return 1 as True, while in most BASIC variants, -1 is
returned. The latter has the advantage of being the bitwise negation
of 0 (if you use two's complement numbers, which is nearly universal
now). C's sequential operators && and || are more like if-then-else,
with p && q being equivalent to (p ? q : p) and p || q being
equivalent to (p ? p : q).


Option 2 is chosen by some scripting languages and "p and q" is
typically equivalent to "if p == null then p else q" and "p or q"
equivalent to "if p == null then q else p", so very similar to C's
sequential operators. There is, however, no obvious implementation of
logical negation. If the argument is non-null, the result is
obviously null, but if the argument is null, there is no obvious
value. If the language is dynamically typed, you don't even know
which type the result should have. Similarly, comparison operators
should return a non-null value when the comparison yields True. If
you have a boolean type that has exactly one non-null values, you can
use this value in both cases. If you have an Object class (top of the
inheritance hierarchy), this might be used.


Generally, I don't like including null-values in all types, as this
require functions to test for null-values all the time.


> x = x > 0 # if x is > 0, x, else false


This makes > and < assymetrical: x > 0 is not the same as 0 < x, and
they might not even have the same type (unless null/false is included
in all types). It could lead to subtle bugs which get even worse if x
itself might be a null value (what is the value of false==y?).


In any case, I don't see the above as ad-hoc overloading of logical
operators, more like defining them on the Object type and by
inheritance on all other types, which is a kind of overloading, but
not in an ad-hoc fashion.


Torben


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.