Expand Messages
• I (and many others) haven t posted here in a while, but I thought I d give it a shot... :) In many languages, logic operators and and or have been
Message 1 of 24 , Nov 23, 2008
I (and many others) haven't posted here in a while, but I thought I'd
give it a shot... :)

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"

Mike
• ... What the hey, I ll bite. It s bad practice. You re conflating different ideas- for example nil/null and false. Which becomes a problem if the programmer
Message 2 of 24 , Nov 23, 2008
On Sun, 23 Nov 2008, Mike wrote:

> I (and many others) haven't posted here in a while, but I thought I'd
> give it a shot... :)
>
> 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.

What the hey, I'll bite.

It's bad practice. You're conflating different ideas- for example
nil/null and false. Which becomes a problem if the programmer needs to
differentiate the idea- for example, consider a function that can return
null as an error case, or 0 as a valid response, and the caller wants to
determine whether the call succeeded or not. Anyone who has done much
perl programming knows exactly the problem I'm talking about. This
becomes even worse in maintainance when the semantics of the called
function is changed, and now the maintainer needs to divine not only what
the program used to do, but also what the originally programmer (now
raising goats in Uganda) meant for it to do.

I've come to believe in two rules a programming language should follow to
make life easier for the programmer:

1) If there is one thing, and only one thing, the programmer can mean by a
given code construct, then the programmer shouldn't have to specify it-
even if it means the compiler/runtime has to do work to figure out what
the one thing is, and

2) If there is more than one thing the programmer might mean by a given
code construct, then the compiler/runtime shouldn't guess or default, the
*compiler* should figure that out and make the programmer specify what is
meant (as a corollary, it should be easy for the programmer to resolve the
ambiguity).

The first rule is simply an application of the DRY principal- Don't Repeat
Yourself. The more often the programmer has to specify the information,
the more likely the programmer is to screw it up- and then not catch the
screw up. Humans can't pay attention to boilerplate and ceremony, they
zone out and miss minor things. The human shouldn't have to repeat
themselves, or spell things out that the compiler can figure out
unambiguously what is meant.

The second rule comes from the fact that computers are stupid. If the
computer has to guess what the programmer meant, then the computer is
going to guess wrong- and Murphy, Lord of Entropy, will gaurentee that the
computer will guess wrong in the worst possible way and at the worst
possible time. And the more complicated is the procedure for the compiler
to "guess" what the programmer meant, and the more likely it is that the
compiler "guesses" right, the more unexpected (and therefor deadly) it is
when the compiler gets it wrong. Assume that sometimes I'll want it one
way, and sometimes another, and that if the compiler isn't sure, it should

Brian
• Replying to myself is bad etiquette, I know, but a new though just occurred to me. There is a logical fallacy a lot of people fall into that goes like this:
Message 3 of 24 , Nov 23, 2008
Replying to myself is bad etiquette, I know, but a new though just
occurred to me.

There is a logical fallacy a lot of people fall into that goes like this:
we're playing a game. I have a shuffled deck of cards- some blue, some
red. We both know that the deck is 70% blue cards and 30% red cards.
Now, just before I turn the card over to show is it red or blue, you bet-
red or blue. If you're right, you win, if you're wrong, you lose. It's a
fair game, I'm not stacking the bet, it's impossible to predict what color
the next card is other than it's a 70% chance it's blue. The deck is
shuffled after every hand, so card counting doesn't help. What strategy
do you play?

Most people play a mix of about 70% blue and 30% red- in other words, they
try to make their betting pattern resemble the sequence of cards drawn.
But this is actually a suboptimal betting strategy if you're trying to
maximize the amount of time you win. It's obvious, once you think about
it, that if you bet blue a fraction p of the time (0 <= p <= 1, so p=0
means you always bet red, and p = 1 means you always bet blue), then the
fraction of times you will win the game is:
0.7p + 0.3(1-p)
It's easy to prove that this is at it's maximum at p=1, i.e. you should
always bet blue.

Now this applies to the discussion because it's the poor compiler (and/or
runtime) playing this game. It sees a given construct in which the
programmer may mean A, or may mean B. The compiler needs to make a bet
which behavior the programmer meant- and a wrong guess means a bug. The
best bet for the compiler then, rather than being clever and guess what
the programmer meant, is to just pick the most likely meaning, and hope
for the best. This is an argument against having complicated algorithms
(aka magic) tha the computer uses to determine what the meaning of a
construct should be.

what *upside* is there to having the computer guess? Imagine the above
the game described above, except for two things- one is, by bet I mean you
have to pony up \$1. If you guess right, you keep you dollar, but if you
guess wrong, you lose the dollar. How often to do play the game? The
correct answer is "not at all"- there's no upside for you. So why play
that game at all?

The imagined upside, I think, is that if the compiler mainly gets it
right, the programmer can save some typing by relying on the default
behavior. I'd argue that this is no savings what so ever- because every
time the code is inspected, the programmer has to figure out what the
right thing for that code is, and then figure out what the compiler does-
and then do something if those two things aren't the same. But even if it
is an advantage, that's just an argument for making the disambiguation
cheaper in terms of typing. It like you play the above card game- if you
guess right, you win a penny, guess wrong and lose a dollar. Is that a
game you should play? Heck no- the upside doesn't come near justifying
the cost of the downside.

Brian
• Sorry for the short response, but the question remains... Python, Javascript, Lua, Ruby, all use or and and as: 1 or 2 = 1 1 and 2 = 2 Can there be a
Message 4 of 24 , Nov 23, 2008
Sorry for the short response, but the question remains... Python, Javascript, Lua, Ruby, all use "or" and "and" as:

1 or 2  => 1
1 and 2  => 2

Can there be a short version of and "obj = obj or {}" "obj and obj foo()" which doesn't overload the logic operators?
For example, operators "?" and "nil?" that explicitly compare nil/non-nil:

obj = obj nil? {}  =>  obj = obj or {}
obj ? obj foo()  =>  obj and obj foo()

Syntacticly, do those make sense if you saw them?  Are they any less or more clear than the logical operator versions?

I agree about not letting the compiler play guessing games, but as far as I can tell, the languages above all have the same results when using "and" and "or".  Are you talking about other situations involving truthy/falsey values?

Mike

From: Brian Hurt <bhurt@...>
To: langsmiths@yahoogroups.com
Sent: Sunday, November 23, 2008 5:16:32 PM

On Sun, 23 Nov 2008, Mike wrote:

> I (and many others) haven't posted here in a while, but I thought I'd
> give it a shot... :)
>
> 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.

What the hey, I'll bite.

It's bad practice. You're conflating different ideas- for example
nil/null and false. Which becomes a problem if the programmer needs to
differentiate the idea- for example, consider a function that can return
null as an error case, or 0 as a valid response, and the caller wants to
determine whether the call succeeded or not. Anyone who has done much
perl programming knows exactly the problem I'm talking about. This
becomes even worse in maintainance when the semantics of the called
function is changed, and now the maintainer needs to divine not only what
the program used to do, but also what the originally programmer (now
raising goats in Uganda) meant for it to do.

I've come to believe in two rules a programming language should follow to
make life easier for the programmer:

1) If there is one thing, and only one thing, the programmer can mean by a
given code construct, then the programmer shouldn't have to specify it-
even if it means the compiler/runtime has to do work to figure out what
the one thing is, and

2) If there is more than one thing the programmer might mean by a given
code construct, then the compiler/runtime shouldn't guess or default, the
*compiler* should figure that out and make the programmer specify what is
meant (as a corollary, it should be easy for the programmer to resolve the
ambiguity).

The first rule is simply an application of the DRY principal- Don't Repeat
Yourself. The more often the programmer has to specify the information,
the more likely the programmer is to screw it up- and then not catch the
screw up. Humans can't pay attention to boilerplate and ceremony, they
zone out and miss minor things. The human shouldn't have to repeat
themselves, or spell things out that the compiler can figure out
unambiguously what is meant.

The second rule comes from the fact that computers are stupid. If the
computer has to guess what the programmer meant, then the computer is
going to guess wrong- and Murphy, Lord of Entropy, will gaurentee that the
computer will guess wrong in the worst possible way and at the worst
possible time. And the more complicated is the procedure for the compiler
to "guess" what the programmer meant, and the more likely it is that the
compiler "guesses" right, the more unexpected (and therefor deadly) it is
when the compiler gets it wrong. Assume that sometimes I'll want it one
way, and sometimes another, and that if the compiler isn't sure, it should

Brian

• ... Yes, this is called the coalesce operator. My language, Cobra, has this as a ? b which evals to a unless it s nil, in which case it evals to b .
Message 5 of 24 , Nov 23, 2008
On Sun, Nov 23, 2008 at 7:09 PM, Mike Austin <mike_ekim@...> wrote:
> Sorry for the short response, but the question remains... Python,
> Javascript, Lua, Ruby, all use "or" and "and" as:
>
> 1 or 2 => 1
> 1 and 2 => 2
>
> Can there be a short version of and "obj = obj or {}" "obj and obj foo()"
> which doesn't overload the logic operators?
> For example, operators "?" and "nil?" that explicitly compare nil/non-nil:
>
> obj = obj nil? {} => obj = obj or {}
> obj ? obj foo() => obj and obj foo()

Yes, this is called the "coalesce" operator.

My language, Cobra, has this as "a ? b" which evals to "a" unless it's
nil, in which case it evals to "b". It's short circuit.

C# has the same thing with "a ?? b"

SQL has the same thing with "COALESCE(a, b)"

Groovy does it with "a ?: b"

HTH,
Chuck
--
http://cobra-language.com/
• ... These rules are operationally meaningless. The compiler has no access to what the programmer means or might mean, only to what he says, which always
Message 6 of 24 , Nov 24, 2008
Brian Hurt scripsit:

> 1) If there is one thing, and only one thing, the programmer can mean by a
> given code construct, then the programmer shouldn't have to specify it-
> even if it means the compiler/runtime has to do work to figure out what
> the one thing is, and
>
> 2) If there is more than one thing the programmer might mean by a given
> code construct, then the compiler/runtime shouldn't guess or default, the
> *compiler* should figure that out and make the programmer specify what is
> meant (as a corollary, it should be easy for the programmer to resolve the
> ambiguity).

what the programmer means or might mean, only to what he says, which always
"means" only one thing to the compiler. Unless the language grammar is
severely broken, ambiguity is purely in the eye of the beholder.

--
Not to perambulate John Cowan <cowan@...>
the corridors http://www.ccil.org/~cowan
during the hours of repose
• ... Lisp, too. Pretty much any language without a separate boolean type that isn t trying to be C-compatible will naturally do the same thing. -- They do not
Message 7 of 24 , Nov 24, 2008
Mike Austin scripsit:

> Sorry for the short response, but the question remains... Python,
> Javascript, Lua, Ruby, all use "or" and "and" as:

Lisp, too. Pretty much any language without a separate boolean type
that isn't trying to be C-compatible will naturally do the same thing.

--
They do not preach John Cowan
that their God will rouse them cowan@...
A little before the nuts work loose. http://www.ccil.org/~cowan
They do not teach
that His Pity allows them --Rudyard Kipling,
to drop their job when they damn-well choose. "The Sons of Martha"
• ... foo() which doesn t overload the logic operators? ... My language uses default operator to achieve this. x default 5 returns 5 if (and only if) the
Message 8 of 24 , Nov 24, 2008
--- In langsmiths@yahoogroups.com, Mike Austin <mike_ekim@...> wrote:
>
> Sorry for the short response, but the question remains... Python,
Javascript, Lua, Ruby, all use "or" and "and" as:
>
> 1 or 2 => 1
> 1 and 2 => 2
>
> Can there be a short version of and "obj = obj or {}" "obj and obj
foo()" which doesn't overload the logic operators?
> For example, operators "?" and "nil?" that explicitly compare
nil/non-nil:
>
> obj = obj nil? {} => obj = obj or {}
> obj ? obj foo() => obj and obj foo()
>

My language uses 'default' operator to achieve this.

"x default 5" returns 5 if (and only if) the value x is nil.

You need to decide, how do you want your operators to convert it's
operands.

Nice example is '+' operator, which is often overloaded for to
concatenate strings. I prefer it to try to convert the operands to
numbers. So "5" + "1" return 51 and not "51".

Rudla
• ... I meant 6 not 51, of course.
Message 9 of 24 , Nov 24, 2008
--- In langsmiths@yahoogroups.com, "rudla.kudla" <rudla@...> wrote:
>
> --- In langsmiths@yahoogroups.com, Mike Austin <mike_ekim@> wrote:
> >
> > Sorry for the short response, but the question remains... Python,
> Javascript, Lua, Ruby, all use "or" and "and" as:
> >
> > 1 or 2 => 1
> > 1 and 2 => 2
> >
> > Can there be a short version of and "obj = obj or {}" "obj and obj
> foo()" which doesn't overload the logic operators?
> > For example, operators "?" and "nil?" that explicitly compare
> nil/non-nil:
> >
> > obj = obj nil? {} => obj = obj or {}
> > obj ? obj foo() => obj and obj foo()
> >
>
> My language uses 'default' operator to achieve this.
>
> "x default 5" returns 5 if (and only if) the value x is nil.
>
> You need to decide, how do you want your operators to convert it's
> operands.
>
> Nice example is '+' operator, which is often overloaded for to
> concatenate strings. I prefer it to try to convert the operands to
> numbers. So "5" + "1" return 51 and not "51".
>

I meant 6 not 51, of course.

>
> Rudla
>
• ... There are languages beyond Python, Javascipt, Lua, and Ruby. And I should ask- what is the meaning of 1 or 2? I could make the cogent argument that the
Message 10 of 24 , Nov 24, 2008
On Sun, 23 Nov 2008, Mike Austin wrote:

> Sorry for the short response, but the question remains... Python, Javascript, Lua, Ruby, all use "or" and "and" as:
>
> 1 or 2 => 1
> 1 and 2 => 2

There are languages beyond Python, Javascipt, Lua, and Ruby.

And I should ask- what is the meaning of 1 or 2? I could make the cogent
argument that the correct result of 1 or 2 is 3- and 1 and 2 is 0. Hint:
bitwise. But on a much deeper level does the expression "1 or 2" have any
real meaning at all?

And consider for a moment:
if (x = 1 or 2) then
...

That construct has a "plain meaning" (at least to me) that just happens to
be not the meaning just about any programming language would assign it.
That's what I was talking about with the compiler guessing wrong what the
meaning of a code phrase is.

>
> Can there be a short version of and "obj = obj or {}" "obj and obj foo()" which doesn't overload the logic operators?
> For example, operators "?" and "nil?" that explicitly compare nil/non-nil:
>
> obj = obj nil? {} => obj = obj or {}
> obj ? obj foo() => obj and obj foo()
>
> Syntacticly, do those make sense if you saw them? Are they any less or
> more clear than the logical operator versions?

What does the or give you, then?

Of course, my day job is coding Ocaml, so I'm weird. Mind you, I'd
strongly recommend learning Ocaml, Haskell, or SML. Among other things,
they have a nice solution to the nullability problem that works real well
in practice.

>
> I agree about not letting the compiler play guessing games, but as far
> as I can tell, the languages above all have the same results when using
> "and" and "or". Are you talking about other situations involving
> truthy/falsey values?

And other languages.

Brian
• ... This is NOT operationally meaningless. It s just very generic. A couple of specific examples help. A classic example of violating rule #2 is the dangling
Message 11 of 24 , Nov 24, 2008
On Mon, 24 Nov 2008, John Cowan wrote:

> Brian Hurt scripsit:
>
>> 1) If there is one thing, and only one thing, the programmer can mean by a
>> given code construct, then the programmer shouldn't have to specify it-
>> even if it means the compiler/runtime has to do work to figure out what
>> the one thing is, and
>>
>> 2) If there is more than one thing the programmer might mean by a given
>> code construct, then the compiler/runtime shouldn't guess or default, the
>> *compiler* should figure that out and make the programmer specify what is
>> meant (as a corollary, it should be easy for the programmer to resolve the
>> ambiguity).
>
> These rules are operationally meaningless. The compiler has no access to
> what the programmer means or might mean, only to what he says, which always
> "means" only one thing to the compiler. Unless the language grammar is
> severely broken, ambiguity is purely in the eye of the beholder.

This is NOT operationally meaningless. It's just very generic.

A couple of specific examples help.

A classic example of violating rule #2 is the dangling else problem. In a
language that has an if clause with an optional else clause, the compiler
can run into a code sequence like:

if expr1 then if expr2 then expr3 else expr4;

At which point it needs to decide which if statement the else goes to- the
inner one or the outer one? Note that the programmer may *intend* a
different meaning than the compiler imparts. So now the compiler has to
guess what is the right thing to do. And this may be the case where
99.999% of the time the card is blue, and the programmer intended the else
to bind to the inner if- but this is (demonstratably) not always true. My
point is that the compiler should guess- there are a number of ways of
eliminating the ambiguity (Python/Haskell's significant whitespace or the
introduction of an endif keyword, are two popular solutions).

And you're right, the compiler has no access to what the programmer
"intends"- but by the same logic, the program doesn't "mean" anything at
all to the compiler/computer- it is just simply a collection of
meaningless transforms on sets of bits. If the program has any meaning at
all, that meaning resides in the brain of a human.

A good example of violating #1 is Java packages. You have to specify, in
every file seperately, what package the class goes in to- and then you
have to place the objects in a directory tree mirroring the package tree.
The same information repeated over and over again- why?

Java started with the laudable goal of eliminating bugs in code by
eliminating the ambiguities- but they went way to far and ended up
introducing massive amounts of redundancy and introducing bugs that way.
The modern scripting languages are going the other way- in the zeal to
eliminate the wastefull and error prone redundancies, they're introducing
massive ambiguities.

My two rules could be easily summarized as no redundancies and no
ambiguities.

Brian
• ... Sure. It depends on how (and if) the language in question maps its values into booleans. Given that 1 is true (not the unique true value, but one of the
Message 12 of 24 , Nov 24, 2008
Brian Hurt scripsit:

> And I should ask- what is the meaning of 1 or 2? I could make the cogent
> argument that the correct result of 1 or 2 is 3- and 1 and 2 is 0. Hint:
> bitwise. But on a much deeper level does the expression "1 or 2" have any
> real meaning at all?

Sure. It depends on how (and if) the language in question maps its
values into booleans. Given that 1 is true (not the unique true value,
but one of the true values), as is the case in all the languages mentioned
(plus Lisp), it's reasonable for a short-cutting "or" to return it if
it's the first true value. Scheme has #t and #f as unique booleans,
but all other values are also treated as true, so (or 1 2) is 1.
The recurrence relationship is:

(or) => #t
(or x) => x
(or x y) => if x then y else #f
(or x y z) => if x then (or y z) else #f
...

Scheme's "and" is of course the dual of this.

A language that treats booleans as a distinct type will of course treat
"1 or 2" as a domain error (a type error, if it has static typing).

--
John Cowan cowan@... http://ccil.org/~cowan
It's the old, old story. Droid meets droid. Droid becomes chameleon.
Droid loses chameleon, chameleon becomes blob, droid gets blob back
again. It's a classic tale. --Kryten, Red Dwarf
• ... In one of several directory trees or ZIPfiles which mirror the package tree, is the more correct statement. The reason for that requirement is to permit
Message 13 of 24 , Nov 24, 2008
Brian Hurt scripsit:

> A good example of violating #1 is Java packages. You have to specify, in
> every file seperately, what package the class goes in to- and then you
> have to place the objects in a directory tree mirroring the package tree.
> The same information repeated over and over again- why?

In one of several directory trees or ZIPfiles which mirror the package
tree, is the more correct statement. The reason for that requirement
is to permit the compiler to find a class file (and the source file,
although current compilers don't do that) without having to make an
arbitrary search of the file system.

--
Yes, chili in the eye is bad, but so is your John Cowan
ear. However, I would suggest you wash your cowan@...
hands thoroughly before going to the toilet. http://www.ccil.org/~cowan
• ... Care to expand? -Chuck -- http://cobra-language.com/
Message 14 of 24 , Nov 24, 2008
On Mon, Nov 24, 2008 at 3:40 PM, Brian Hurt <bhurt@...> wrote:
> Of course, my day job is coding Ocaml, so I'm weird. Mind you, I'd
> strongly recommend learning Ocaml, Haskell, or SML. Among other things,
> they have a nice solution to the nullability problem that works real well
> in practice.

Care to expand?

-Chuck
--
http://cobra-language.com/
• Ahh, learn something every day :) What is the operator, if any, for the equivalent of obj and obj.foo() ? One issue of introducing more operators is that you
Message 15 of 24 , Nov 24, 2008
Ahh, learn something every day :)  What is the operator, if any, for the equivalent of "obj and obj.foo()"?

One issue of introducing more operators is that you get the Perl "operator explosion" as I think someone mentioned, and end up with statements like "obj ||= {}".  That's nonsense to anyone that doesn't know Ruby, or at least somewhat confusing.

The Elvis operator - I might just have to use it, what else is cooler than Elvis with his tongue sticking out. :)

Mike

From: Chuck Esterbrook <Chuck.Esterbrook@...>
To: langsmiths@yahoogroups.com
Sent: Sunday, November 23, 2008 7:39:47 PM

On Sun, Nov 23, 2008 at 7:09 PM, Mike Austin <mike_ekim@yahoo. com> wrote:
> Sorry for the short response, but the question remains... Python,
> Javascript, Lua, Ruby, all use "or" and "and" as:
>
> 1 or 2 => 1
> 1 and 2 => 2
>
> Can there be a short version of and "obj = obj or {}" "obj and obj foo()"
> which doesn't overload the logic operators?
> For example, operators "?" and "nil?" that explicitly compare nil/non-nil:
>
> obj = obj nil? {} => obj = obj or {}
> obj ? obj foo() => obj and obj foo()

Yes, this is called the "coalesce" operator.

My language, Cobra, has this as "a ? b" which evals to "a" unless it's
nil, in which case it evals to "b". It's short circuit.

C# has the same thing with "a ?? b"

SQL has the same thing with "COALESCE(a, b)"

Groovy does it with "a ?: b"

HTH,
Chuck
--
http://cobra- language. com/

• Questions - So why did you introduce a default operator vs. using or ? And, why were you more strict about it than your coercive + operator? I ask only
Message 16 of 24 , Nov 24, 2008
Questions -

So why did you introduce a "default" operator vs. using "or"?  And, why were you more strict about it than your coercive "+" operator?  I ask only for enlightenment, not to critique your language :)

Mike

From: rudla.kudla <rudla@...>
To: langsmiths@yahoogroups.com
Sent: Monday, November 24, 2008 1:01:15 PM

--- In langsmiths@yahoogro ups.com, Mike Austin <mike_ekim@. ..> wrote:
>
> Sorry for the short response, but the question remains... Python,
Javascript, Lua, Ruby, all use "or" and "and" as:
>
> 1 or 2 => 1
> 1 and 2 => 2
>
> Can there be a short version of and "obj = obj or {}" "obj and obj
foo()" which doesn't overload the logic operators?
> For example, operators "?" and "nil?" that explicitly compare
nil/non-nil:
>
> obj = obj nil? {} => obj = obj or {}
> obj ? obj foo() => obj and obj foo()
>

My language uses 'default' operator to achieve this.

"x default 5" returns 5 if (and only if) the value x is nil.

You need to decide, how do you want your operators to convert it's
operands.

Nice example is '+' operator, which is often overloaded for to
concatenate strings. I prefer it to try to convert the operands to
numbers. So "5" + "1" return 51 and not "51".

Rudla

• I m familiar with other languages also, I just mention the ones below because they have the same semantics. When you say compiler guessing , do you mean the
Message 17 of 24 , Nov 24, 2008
I'm familiar with other languages also, I just mention the ones below because they have the same semantics.  When you say "compiler guessing", do you mean the disconnect between the programmer and the compiler writer, ie. that it's unintuitive?  Or do you mean something that is truly ambiguous and the compiler can't, or wont detect it?

Mike

From: Brian Hurt <bhurt@...>
To: langsmiths@yahoogroups.com
Sent: Monday, November 24, 2008 3:40:52 PM

On Sun, 23 Nov 2008, Mike Austin wrote:

> Sorry for the short response, but the question remains... Python, Javascript, Lua, Ruby, all use "or" and "and" as:
>
> 1 or 2 => 1
> 1 and 2 => 2

There are languages beyond Python, Javascipt, Lua, and Ruby.

And I should ask- what is the meaning of 1 or 2? I could make the cogent
argument that the correct result of 1 or 2 is 3- and 1 and 2 is 0. Hint:
bitwise. But on a much deeper level does the expression "1 or 2" have any
real meaning at all?

And consider for a moment:
if (x = 1 or 2) then
...

That construct has a "plain meaning" (at least to me) that just happens to
be not the meaning just about any programming language would assign it.
That's what I was talking about with the compiler guessing wrong what the
meaning of a code phrase is.

>
> Can there be a short version of and "obj = obj or {}" "obj and obj foo()" which doesn't overload the logic operators?
> For example, operators "?" and "nil?" that explicitly compare nil/non-nil:
>
> obj = obj nil? {} => obj = obj or {}
> obj ? obj foo() => obj and obj foo()
>
> Syntacticly, do those make sense if you saw them? Are they any less or
> more clear than the logical operator versions?

What does the or give you, then?

Of course, my day job is coding Ocaml, so I'm weird. Mind you, I'd
strongly recommend learning Ocaml, Haskell, or SML. Among other things,
they have a nice solution to the nullability problem that works real well
in practice.

>
> I agree about not letting the compiler play guessing games, but as far
> as I can tell, the languages above all have the same results when using
> "and" and "or". Are you talking about other situations involving
> truthy/falsey values?

And other languages.

Brian

• ... For an obj that is a nilable type? You can say exactly that: def compute(t as List ?) if t and t.count print t.count Notice the ? on the type which
Message 18 of 24 , Nov 25, 2008
On Mon, Nov 24, 2008 at 9:55 PM, Mike Austin <mike_ekim@...> wrote:
> Ahh, learn something every day :) What is the operator, if any, for the
> equivalent of "obj and obj.foo()"?

For an obj that is a nilable type? You can say exactly that:

def compute(t as List<of int>?)
if t and t.count
print t.count

Notice the ? on the type which indicates it can be nil. Without ?,
you're saying you really want a List<of int> and nil will not do:

def compute(t as List<of int>)
...

Then if the compiler catches you passing something nilable to that
argument, it's an error. I call this "compile-time nil tracking" and I
find it eliminates 90% or more of the "null reference exceptions" that
I experience in practice with Python and C#.

There is also a parameter check at run-time; necessary because you
might pass nil through Cobra's dynamic binding or reflection or some
unthought of trickery to bypass the compiler.

-Chuck
--
http://cobra-language.com/
• The + and or operator (and most other) behave in similar way. The + operator tries to convert it s operands to numbers. The or operator tries to
Message 19 of 24 , Nov 25, 2008
The '+' and 'or' operator (and most other) behave in similar way.

The '+' operator tries to convert it's operands to numbers.
The 'or' operator tries to convert it to bools (and always returns bool).

If the 'or' converts values to bool, you need separate operator for 'default'.

'Default' has additional property of returning the default value even in case when there is some error evaluating the left operand.
This greatly simplifies handling nil (we call it 'empty') values.

Another reason was, I didn't feel, the meaning of expression 'print x or 5' meant print 5 in case the x is empty,
but rather print whichever value of the two you (you compiler) want.

It's not a format argument, but I thing it is valid, as language designers should apply certain amount of aesthetics when designing the language.

Rudla

Mike Austin wrote:
Questions -

So why did you introduce a "default" operator vs. using "or"?  And, why were you more strict about it than your coercive "+" operator?  I ask only for enlightenment, not to critique your language :)

Mike

From: rudla.kudla <rudla@espace. cz>
To: langsmiths@yahoogro ups.com
Sent: Monday, November 24, 2008 1:01:15 PM

--- In langsmiths@yahoogro ups.com, Mike Austin <mike_ekim@. ..> wrote:
>
> Sorry for the short response, but the question remains... Python,
Javascript, Lua, Ruby, all use "or" and "and" as:
>
> 1 or 2 => 1
> 1 and 2 => 2
>
> Can there be a short version of and "obj = obj or {}" "obj and obj
foo()" which doesn't overload the logic operators?
> For example, operators "?" and "nil?" that explicitly compare
nil/non-nil:
>
> obj = obj nil? {} => obj = obj or {}
> obj ? obj foo() => obj and obj foo()
>

My language uses 'default' operator to achieve this.

"x default 5" returns 5 if (and only if) the value x is nil.

You need to decide, how do you want your operators to convert it's
operands.

Nice example is '+' operator, which is often overloaded for to
concatenate strings. I prefer it to try to convert the operands to
numbers. So "5" + "1" return 51 and not "51".

Rudla

• That reminds me, Dylan has nullable types: slot parent :: false-or ( ); Would you consider C++ references as non-nullable types? Mike
Message 20 of 24 , Nov 25, 2008
That reminds me, Dylan has nullable types:

slot parent :: false-or (<shape>);

Would you consider C++ references as non-nullable types?

Mike

From: John Cowan <cowan@...>
To: langsmiths@yahoogroups.com
Sent: Monday, November 24, 2008 8:49:40 AM

Mike Austin scripsit:

> Sorry for the short response, but the question remains... Python,
> Javascript, Lua, Ruby, all use "or" and "and" as:

Lisp, too. Pretty much any language without a separate boolean type
that isn't trying to be C-compatible will naturally do the same thing.

--
They do not preach John Cowan
that their God will rouse them cowan@...
A little before the nuts work loose. http://www.ccil. org/~cowan
They do not teach
that His Pity allows them --Rudyard Kipling,
to drop their job when they damn-well choose. "The Sons of Martha"

• It s not a format argument, but I thing it is valid, as language designers should apply certain amount of aesthetics when designing the language. I
Message 21 of 24 , Nov 25, 2008
"It's not a format argument, but I thing it is valid, as language designers should apply certain amount of aesthetics when designing the language."

I wholeheartedly agree. :)  That's why I bring i up.  What are your thoughts then, with this expression:

print isAlpha or isBeta

Does it still seem like you're giving the compiler an option?  Maybe it's the fact that without the "if", "or" is kind of kind of hanging out by itself, being indecisive, hah

Mike

From: Rudla Kudla <rudla.kudla@...>
To: langsmiths@yahoogroups.com
Sent: Tuesday, November 25, 2008 12:36:29 AM

The '+' and 'or' operator (and most other) behave in similar way.

The '+' operator tries to convert it's operands to numbers.
The 'or' operator tries to convert it to bools (and always returns bool).

If the 'or' converts values to bool, you need separate operator for 'default'.

'Default' has additional property of returning the default value even in case when there is some error evaluating the left operand.
This greatly simplifies handling nil (we call it 'empty') values.

Another reason was, I didn't feel, the meaning of expression 'print x or 5' meant print 5 in case the x is empty,
but rather print whichever value of the two you (you compiler) want.

It's not a format argument, but I thing it is valid, as language designers should apply certain amount of aesthetics when designing the language.

Rudla

Mike Austin wrote:

Questions -

So why did you introduce a "default" operator vs. using "or"?  And, why were you more strict about it than your coercive "+" operator?  I ask only for enlightenment, not to critique your language :)

Mike

From: rudla.kudla <rudla@espace. cz>
To: langsmiths@yahoogro ups.com
Sent: Monday, November 24, 2008 1:01:15 PM

--- In langsmiths@yahoogro ups.com, Mike Austin <mike_ekim@. ..> wrote:
>
> Sorry for the short response, but the question remains... Python,
Javascript, Lua, Ruby, all use "or" and "and" as:
>
> 1 or 2 => 1
> 1 and 2 => 2
>
> Can there be a short version of and "obj = obj or {}" "obj and obj
foo()" which doesn't overload the logic operators?
> For example, operators "?" and "nil?" that explicitly compare
nil/non-nil:
>
> obj = obj nil? {} => obj = obj or {}
> obj ? obj foo() => obj and obj foo()
>

My language uses 'default' operator to achieve this.

"x default 5" returns 5 if (and only if) the value x is nil.

You need to decide, how do you want your operators to convert it's
operands.

Nice example is '+' operator, which is often overloaded for to
concatenate strings. I prefer it to try to convert the operands to
numbers. So "5" + "1" return 51 and not "51".

Rudla

• ... it s the fact that without the if , or is kind of kind of hanging out by itself, being indecisive, hah ... No, in this case there is not an option. The
Message 22 of 24 , Nov 26, 2008
--- In langsmiths@yahoogroups.com, Mike Austin <mike_ekim@...> wrote:
>
> "It's not a format argument, but I thing it is valid, as language
> designers should apply certain amount of aesthetics when designing the
> language."
>
> I wholeheartedly agree. :) That's why I bring i up. What are your
thoughts then, with this expression:
>
> print isAlpha or isBeta
>
> Does it still seem like you're giving the compiler an option? Maybe
it's the fact that without the "if", "or" is kind of kind of hanging
out by itself, being indecisive, hah
>
> Mike
>

No, in this case there is not an option. The logical expression
"isAlpha or isBeta" should be evaluated and the result printed (in
very same way as if the expression would be "x + y").

Both compiler and the programmer know, what the expression means.

Here is an example, that stresses out the difference between 'or' and
'default':

a = [] -- empty list
b = 1,2,3 -- non empty list

print a default b => 1,2,3
print a or b => true

Rudla
• Another reason to avoid this type of overloading is that it breaks the operator s properties. Or is normally symmetric operator (a or b == b or a). When you
Message 23 of 24 , Nov 26, 2008
Another reason to avoid this type of overloading is that it breaks the
operator's properties.
'Or' is normally symmetric operator (a or b == b or a). When you use
it as default, the symmetry is broken in case none of the operands is
empty (5 or 7 != 7 or 5).

Rudla

--- In langsmiths@yahoogroups.com, Mike Austin <mike_ekim@...> wrote:
>
> "It's not a format argument, but I thing it is valid, as language
> designers should apply certain amount of aesthetics when designing the
> language."
>
> I wholeheartedly agree. :) That's why I bring i up. What are your
thoughts then, with this expression:
>
> print isAlpha or isBeta
>
> Does it still seem like you're giving the compiler an option? Maybe
it's the fact that without the "if", "or" is kind of kind of hanging
out by itself, being indecisive, hah
>
> Mike
>
>
>
>
> ________________________________
> From: Rudla Kudla <rudla.kudla@...>
> To: langsmiths@yahoogroups.com
> Sent: Tuesday, November 25, 2008 12:36:29 AM
>
>
> The '+' and 'or' operator (and most other) behave in similar way.
>
> The '+' operator tries to convert it's operands to numbers.
> The 'or' operator tries to convert it to bools (and always returns
> bool).
>
> If the 'or' converts values to bool, you need separate operator for
> 'default'.
>
> 'Default' has additional property of returning the default value even
> in case when there is some error evaluating the left operand.
> This greatly simplifies handling nil (we call it 'empty') values.
>
> Another reason was, I didn't feel, the meaning of expression 'print x
> or 5' meant print 5 in case the x is empty,
> but rather print whichever value of the two you (you compiler) want.
>
> It's not a format argument, but I thing it is valid, as language
> designers should apply certain amount of aesthetics when designing the
> language.
>
> Rudla
>
>
> Mike Austin wrote:
> Questions -
>
> So why did you introduce a "default" operator vs. using "or"? And, why
> only for enlightenment, not to critique your language :)
>
> Mike
>
>
>
>
> ________________________________
> From: rudla.kudla <rudla@espace. cz>
> To: langsmiths@yahoogro ups.com
> Sent: Monday, November
> 24, 2008 1:01:15 PM
> Subject: [langsmiths]
>
>
> --- In langsmiths@yahoogro ups.com,
> Mike Austin <mike_ekim@ ..> wrote:
> >
> > Sorry for the short response, but the question remains... Python,
> Javascript, Lua, Ruby, all use "or" and "and" as:
> >
> > 1 or 2 => 1
> > 1 and 2 => 2
> >
> > Can there be a short version of and "obj = obj or {}" "obj and obj
> foo()" which doesn't overload the logic operators?
> > For example, operators "?" and "nil?" that explicitly compare
> nil/non-nil:
> >
> > obj = obj nil? {} => obj = obj or {}
> > obj ? obj foo() => obj and obj foo()
> >
>
> My language uses 'default' operator to achieve this.
>
> "x default 5" returns 5 if (and only if) the value x is nil.
>
> You need to decide, how do you want your operators to convert it's
> operands.
>
> Nice example is '+' operator, which is often overloaded for to
> concatenate strings. I prefer it to try to convert the operands to
> numbers. So "5" + "1" return 51 and not "51".
>
>
> Rudla
>
• ... The && and || flavors of or and and aren t symmetrical anyway with respect to undefined expressions. Ada neatly expresses their conditional nature by
Message 24 of 24 , Nov 26, 2008
rudla.kudla scripsit:

> Another reason to avoid this type of overloading is that it breaks the
> operator's properties.
> 'Or' is normally symmetric operator (a or b == b or a). When you use
> it as default, the symmetry is broken in case none of the operands is
> empty (5 or 7 != 7 or 5).

The && and || flavors of 'or' and 'and' aren't symmetrical anyway
with respect to undefined expressions. Ada neatly expresses their
conditional nature by spelling them 'and then' and 'or else'.

--
I am expressing my opinion. When my John Cowan
honorable and gallant friend is called, cowan@...
he will express his opinion. This is http://www.ccil.org/~cowan
the process which we call Debate. --Winston Churchill
Your message has been successfully submitted and would be delivered to recipients shortly.