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] |
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
Return to the
comp.compilers page.
Search the
comp.compilers archives again.