Mon, 24 Nov 2008 17:00:59 +0100

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

Post a followup to this message

Return to the
comp.compilers page.

Search the
comp.compilers archives again.