Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Type Conversion Matrix (TAKE 2)

11 views
Skip to first unread message

Michael Lazzaro

unread,
Apr 24, 2003, 2:00:55 PM4/24/03
to perl6-l...@perl.org

Updated: I've now separated things into various levels of 'lossyness',
to more clearly show the relationships between types.

It is possible that we may want to allow some 'groups' of conversions,
and disallow others. Note, for example, that perhaps each symbol could
represent autocoercions that could be turned on/off by pragma.

+: Automatic conversion, conversion is not lossy
*: undefness and properties will be lost
N: numeric range or precision may be lost [1]
F: numeric (float) conversion -- conversion to int is lossy
S: string conversion -- if string is not *entirely* numeric, is lossy
J: junction type; coercing to non-junction type may be lossy


FROM -> str Str int Int num Num bit Bit bool Bool Scalar
TO: str - * + * + * + * + * *J
Str + - + + + + + + + + J
int S *S - *N F *NF + * + * *J
Int S S + - F F + + + + J
num S *S + * - *N + * + * *J
Num S S + + + - + + + + J
bit S *S N *N N *N - * + * *J
Bit S S N N N N + - + + J
bool S *S N *N N *N + * - * *J
Bool S S N N N N + + + - J
Scalar + + + + + + + + + + -


[1] Int and Num are expected to deal with BigInt and BigNums
automagically. This is why Int --> int and Num --> num can lose
range/precision.

If anyone has opinions on which of these should or should not be
allowed, by all means let 'er rip. I note, for example, that Num -->
int conversion is perhaps the most 'dangerously' lossy of the bunch...

MikeL

Smylers

unread,
Apr 27, 2003, 9:49:23 AM4/27/03
to perl6-l...@perl.org
Michael Lazzaro writes:

> FROM -> str Str int Int num Num bit Bit bool Bool Scalar

C<bool>?

My recollection was that Larry stated that there will not be a boolean
type, so that there will not be a C<true> constant, so that people will
not be able to write C<if $x == true> in place of C<if $x>.

I thought that C<bit> was then suggested as a way to have efficient
storage of single-bit flags without introducing a boolean type.

So, has there been a change and is there now a C<bool> type? If so is
there a third equality operator for comparing them, or will C<true> and
C<false> have numeric (or string) values -- and if so how do we avoid
the C<if $x == true> problem?

And if C<bool> now exists, is there any purpose in C<bit> continuing to
exist as a distinct type?

Smylers

Paul

unread,
Apr 28, 2003, 9:44:39 AM4/28/03
to Smylers, perl6-l...@perl.org

--- Smylers <Smy...@stripey.com> wrote:
> Michael Lazzaro writes:
>
> > FROM -> str Str int Int num Num bit Bit bool Bool Scalar
>
> C<bool>?

You're not the first with that rection. :)

> My recollection was that Larry stated that there will not be a
> boolean type, so that there will not be a C<true> constant, so
> that people will not be able to write C<if $x == true> in place
> of C<if $x>.

Either Austin or Luke pointed out that C<true> isn't a keyword, it's
just a property/trait on something that gets assigned some
appropriate-but-not-universal value. Accordingly, you could test C<if
$x.true> but not C<if $x == true> because independantly, true has no
value (unless you macro it ir something, in which case it has any value
you want).



> I thought that C<bit> was then suggested as a way to have efficient
> storage of single-bit flags without introducing a boolean type.

Yup.

> So, has there been a change and is there now a C<bool> type?

Wasn't there a Bool and a bool in S6?

> If so is there a third equality operator for comparing them,

nope.

> or will C<true> and C<false> have numeric (or string) values --

as traits/proprties, yes. As keywords, no.

> and if so how do we avoid the C<if $x == true> problem?

See above. :)
(This is exactly the gyration I went through, lol...)

> And if C<bool> now exists, is there any purpose in C<bit>
> continuing to exist as a distinct type?
> Smylers

Actually, yes. Even if it's an *exact* synonym for bool, they are each
somewhat connotatively and contextually distinct. Even if I knew they
were the same, I'd use Bool for conditions, and Bit for binary digits
intended as, for example, indexes of *very short* arrays. :)


__________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo.
http://search.yahoo.com

Smylers

unread,
Apr 28, 2003, 2:42:13 PM4/28/03
to perl6-l...@perl.org
Paul writes:

> --- Smylers <Smy...@stripey.com> wrote:
>
> > My recollection was that Larry stated that there will not be a
> > boolean type, so that there will not be a C<true> constant, so
> > that people will not be able to write C<if $x == true> in place
> > of C<if $x>.
>
> Either Austin or Luke pointed out that C<true> isn't a keyword, it's
> just a property/trait on something that gets assigned some
> appropriate-but-not-universal value. Accordingly, you could test C<if
> $x.true> but not C<if $x == true> because independantly, true has no
> value (unless you macro it ir something, in which case it has any value
> you want).

But if there's a boolean type then the only possible values that can be
stored in a variable of that type are C<true> and C<false>. So those
values must exist to some extent, surely?

And there's nothing to stop C<if $x == $true>.

> Wasn't there a Bool and a bool in S6?

So there is. Obviously I didn't read it carefully enough.

> > If so is there a third equality operator for comparing them,
>
> nope.

So if you have:

my bool $x;
my bool $y;

what's the preferred way to test if those two variables are currently
set to identical values? Using C<==> would work if things of type
C<bool> in numeric context are coerced to some numeric values.

But whichever two numbers are chosen, it'd be possible to have two
C<int> variables each of which are treated as true in a boolean context,
but only one of which compares C<==> equally with a boolean variable
that's holding a true value.

Smylers

Luke Palmer

unread,
Apr 28, 2003, 8:10:06 PM4/28/03
to Smy...@stripey.com, perl6-l...@perl.org

You can always check boolean equivalence with:

unless $x ^^ $y {...}

But that's beside the point. And I have nothing to say that isn't.

Luke

Paul

unread,
Apr 28, 2003, 8:50:39 PM4/28/03
to Smylers, perl6-l...@perl.org

--- Smylers <Smy...@stripey.com> wrote:
> Paul writes:
>
> > --- Smylers <Smy...@stripey.com> wrote:
> >
> > > My recollection was that Larry stated that there will not be a
> > > boolean type, so that there will not be a C<true> constant, so
> > > that people will not be able to write C<if $x == true> in place
> > > of C<if $x>.
> >
> > Either Austin or Luke pointed out that C<true> isn't a keyword,
> > it's just a property/trait on something that gets assigned some
> > appropriate-but-not-universal value. Accordingly, you could test
> > C<if $x.true> but not C<if $x == true> because independantly, true
> > has no value (unless you macro it ir something, in which case it
> > has any value you want).
>
> But if there's a boolean type then the only possible values that can
> be stored in a variable of that type are C<true> and C<false>. So
> those values must exist to some extent, surely?

Not necessarily. If bool (lowercase) is a synonym for bit (sic) then
the value will be that the bit in question is either on or off, which
is a pretty fair representation of true and false, if you ask me....but
that doesn't mean that 1 is true and 0 is false. What's to stop you
from flipping them, aside from convention? But don't do that....

Still, I think that the main purpose of a [Bb]oolean type is for it's
internal magic. Assign anything to it, and it eveluates that something
into a true or false based on some algorithm, and then sets itself
accordingly. It might even preserve the original value, but the
important thing is that it return a sensible value I<in Boolean
*context*>.

I doubt Boolean types will get used so much, though. They'll be used,
for certain, but more importantly they will likely be used as the
defining type in conversions using boolean context. That way

if $x { foo() }

works.

> And there's nothing to stop C<if $x == $true>.

What's the value of $true? No such critter, unless you make one.
Knock the $ off and it's probably a syntax error. Not a keyword. :)

Again, these are *exactly* the gyrations I went through just last week.


> > Wasn't there a Bool and a bool in S6?
>
> So there is. Obviously I didn't read it carefully enough.
>
> > > If so is there a third equality operator for comparing them,
> >
> > nope.
>
> So if you have:
>
> my bool $x;
> my bool $y;
>
> what's the preferred way to test if those two variables are currently
> set to identical values? Using C<==> would work if things of type
> C<bool> in numeric context are coerced to some numeric values.

Use something like

if $x.true == $y.true { $well.isIt() }

The .true() method will likely return a standardized (bitwise?) 1 or 0
(just at a guess), so if they both return the same value, and it's that
value that is being compared. If you want to know if they're both true,
just say

if $x and $y { veracity() }

but I assume your question above was to compre likeness, not veracity.

> But whichever two numbers are chosen, it'd be possible to have two
> C<int> variables each of which are treated as true in a boolean
> context, but only one of which compares C<==> equally with a boolean
> variable that's holding a true value.
>
> Smylers


Which is why you don't want to say what values.

my Str $s = "foo";
my Int $i = 1;

if $s and $i { goody() }

These are both boolean true, but if you say

if $s == true { oops () } # error -- true isn't a keyword.

it goes boom. You could say

if $s.true == $i.true { same() }

and same() would fire if both were true, or both were false.
my Str $x = "foo";
my Int $y = 0;

if $x.true == $y.true { same() } # these wouldn't be the same

Am I on the right track here?

Paul

unread,
Apr 28, 2003, 9:08:43 PM4/28/03
to Luke Palmer, Smy...@stripey.com, perl6-l...@perl.org

--- Luke Palmer <fibo...@babylonia.flatirons.org> wrote:
> You can always check boolean equivalence with:
>
> unless $x ^^ $y {...}
>
> But that's beside the point. And I have nothing to say that isn't.
>
> Luke

Ok, Lucy, 'splain.

Que eso ^^?

I've seen you guys tossing that one around, and have no idea where it
came from. Musta missed it in one of the line-noisier sections,
lol....

Luke Palmer

unread,
Apr 28, 2003, 9:26:04 PM4/28/03
to Hod...@writeme.com, Smy...@stripey.com, perl6-l...@perl.org
> --- Luke Palmer <fibo...@babylonia.flatirons.org> wrote:
> > You can always check boolean equivalence with:
> >
> > unless $x ^^ $y {...}
> >
> > But that's beside the point. And I have nothing to say that isn't.
> >
> > Luke
>
> Ok, Lucy, 'splain.
>
> Que eso ^^?

It's exclusive or; i.e. true when the truth values of its operands are
different. I could have also written it:

unless $x xor $y {...}

> I've seen you guys tossing that one around, and have no idea where it
> came from. Musta missed it in one of the line-noisier sections,
> lol....

I don't believe we've tossed this one around much at all. We've
tossed the single ^ around, which is the junctive synonym for one() (a
junctive sort of xor, kindof).

Luqui

Smylers

unread,
Apr 30, 2003, 2:30:33 PM4/30/03
to perl6-l...@perl.org
Paul writes:

> --- Smylers <Smy...@stripey.com> wrote:
>
> > But if there's a boolean type then the only possible values that can
> > be stored in a variable of that type are C<true> and C<false>. So
> > those values must exist to some extent, surely?
>
> Not necessarily. If bool (lowercase) is a synonym for bit (sic) then
> the value will be that the bit in question is either on or off, which
> is a pretty fair representation of true and false, if you ask me....but
> that doesn't mean that 1 is true and 0 is false. What's to stop you
> from flipping them, aside from convention?

What's to stop you is that in a numeric context numbers in Perl that
don't have a specific C<but false> or C<but true> trait[*0] are false
when they are 0 and true otherwise. That's going to have to be the same
for C<bit> in order for C<if $x> to work sanely.

> > And there's nothing to stop C<if $x == $true>.
>
> What's the value of $true? No such critter, unless you make one.

That was my intention by adding in the C<$> -- whatever value Perl is
using to represent truth in

> Knock the $ off and it's probably a syntax error. Not a keyword. :)

That's why I put the C<$> on there.

> Again, these are *exactly* the gyrations I went through just last
> week.

Oh good -- you'll be able to tell me how long they go on for then. (And
surely it also follows that anything completely stupid I say isn't my
fault: I'm just going along the track that Paul's set for me.)

> > So if you have:
> >
> > my bool $x;
> > my bool $y;
> >
> > what's the preferred way to test if those two variables are currently
> > set to identical values? Using C<==> would work if things of type
> > C<bool> in numeric context are coerced to some numeric values.
>
> Use something like
>
> if $x.true == $y.true { $well.isIt() }

How does that help at all? In general .true will return the boolean
truth value of a variable (which is only going to be useful outside
boolean contexts, since in a boolean context that's what you get
anyway). But for a variable of type C<bool>, its truth value is also
its main piece of data, so I don't see how your line above could (given
my definitions above) ever be different from the simpler:

if $x == $y { $well.isIt() }

In both cases we're getting a pair of boolean values then coercing each
of them to numbers and comparing them for numeric equality -- by
extension of your logic that the way to find the truth of a boolean
value is to append C<.true> we'd end up with:

if $x.true.true.true == $y.true.true.true { $well.isIt() }

> The .true() method will likely return a standardized (bitwise?) 1 or 0
> (just at a guess),

Right, but that leads into:

> > But whichever two numbers are chosen, it'd be possible to have two
> > C<int> variables each of which are treated as true in a boolean
> > context, but only one of which compares C<==> equally with a boolean
> > variable that's holding a true value.
>

> Which is why you don't want to say what values.

But you just did, above. And if you have to convert them to integers in
order to compare them then it's trivial to convert them to integers and
print them out or store them in other variables: there's no way that
Perl 6 could keep its canonical 'true' value a secret.

> my Str $s = "foo";

> my Int $i = 1; <Snip>


>
> Am I on the right track here?

I don't know about the 'right' track, but that wasn't what I'm concerned
about -- your example didn't feature any variables of type C<bool>, the
very thing that I'm currently unsure about!

my int $a = 1;
my int $b = 2
my bool $true = 1 is const;

if $a == $true { };
if $b == $true { };

The C<==> is coercing C<$true> into being numeric, and so the test in
the second example evaluates to false, which is probably not what the
programmer intended. If there were a boolean-compare operator then
C<$a> and C<$b> would instead be coerced to boolean values and both
expressions would evaluate to true.

That's what I'm unsure about. (And I'm fairly sure it's also cases like
this that caused Larry not to be in favour of a boolean type.)

Smylers

Austin Hastings

unread,
May 1, 2003, 11:38:56 AM5/1/03
to Smylers, perl6-l...@perl.org

--- Smylers <Smy...@stripey.com> wrote:
> Paul writes:
>
> > --- Smylers <Smy...@stripey.com> wrote:
> >
> > > But if there's a boolean type then the only possible values that
> can
> > > be stored in a variable of that type are C<true> and C<false>. So
> > > those values must exist to some extent, surely?
> >
> > Not necessarily. If bool (lowercase) is a synonym for bit (sic)
> then
> > the value will be that the bit in question is either on or off,
> which
> > is a pretty fair representation of true and false, if you ask
> me....but
> > that doesn't mean that 1 is true and 0 is false. What's to stop you
> > from flipping them, aside from convention?
>
> What's to stop you is that in a numeric context numbers in Perl that
> don't have a specific C<but false> or C<but true> trait[*0] are false
> when they are 0 and true otherwise. That's going to have to be the
> same
> for C<bit> in order for C<if $x> to work sanely.

Sure, but that doesn't mean that bool $x has to store 1/0 for
true/false -- it IS true/false, so it could use 0/1 instead. (After
all, most conditional branches have a shorter span than unconditional
ones.

> > > And there's nothing to stop C<if $x == $true>.
> >
> > What's the value of $true? No such critter, unless you make one.
>
> That was my intention by adding in the C<$> -- whatever value Perl is
> using to represent truth in
>
> > Knock the $ off and it's probably a syntax error. Not a keyword. :)
>
> That's why I put the C<$> on there.

Sure:

my bool $true = 1; # Convert from 1 (num) to TRUE (boolean)
my bool $false = 0;

But now you have to wonder about "default" context -- if I say

if ($x == $true)

Does it convert $x to boolean, or $true to num? Alternatively, you
could write all your code with C<?> boolean context specifiers.

>
> > Again, these are *exactly* the gyrations I went through just last
> > week.
>
> Oh good -- you'll be able to tell me how long they go on for then.
> (And surely it also follows that anything completely stupid I say
> isn't my fault: I'm just going along the track that Paul's set for
> me.)

"Stupid is as stupid does, Lt. Dan."

> > > So if you have:
> > >
> > > my bool $x;
> > > my bool $y;
> > >
> > > what's the preferred way to test if those two variables are
> currently
> > > set to identical values? Using C<==> would work if things of
> type
> > > C<bool> in numeric context are coerced to some numeric values.
> >
> > Use something like
> >
> > if $x.true == $y.true { $well.isIt() }
>
> How does that help at all? In general .true will return the boolean
> truth value of a variable (which is only going to be useful outside
> boolean contexts, since in a boolean context that's what you get
> anyway). But for a variable of type C<bool>, its truth value is also
> its main piece of data, so I don't see how your line above could
> (given
> my definitions above) ever be different from the simpler:
>
> if $x == $y { $well.isIt() }
>

Wait!

"How do I know if two boolean values are the same or different?"

Stop me if you've heard this one before, but:

if ($a && $b) { print "They're both true!"; }

if (!$a && !$b) { print "They're both false!"; }

if ($a ^^ $b) { print "They're different!"; }

if !($a ^^ $b) { print "They're identical"; }

I suppose you could define infix:!^^ to save some typing.

> In both cases we're getting a pair of boolean values then coercing
> each of them to numbers and comparing them for numeric equality -- by
> extension of your logic that the way to find the truth of a boolean
> value is to append C<.true> we'd end up with:
>
> if $x.true.true.true == $y.true.true.true { $well.isIt() }
>
> > The .true() method will likely return a standardized (bitwise?) 1
> or 0
> > (just at a guess),
>
> Right, but that leads into:
>
> > > But whichever two numbers are chosen, it'd be possible to have
> two
> > > C<int> variables each of which are treated as true in a boolean
> > > context, but only one of which compares C<==> equally with a
> boolean
> > > variable that's holding a true value.
> >
> > Which is why you don't want to say what values.
>
> But you just did, above. And if you have to convert them to integers
> in order to compare them then it's trivial to convert them to
> integers and print them out or store them in other variables:
> there's no way that Perl 6 could keep its canonical 'true' value
> a secret.

It's working so far. :-)

>
> > my Str $s = "foo";
> > my Int $i = 1; <Snip>
> >
> > Am I on the right track here?
>
> I don't know about the 'right' track, but that wasn't what I'm
> concerned about -- your example didn't feature any variables of type
> C<bool>, the very thing that I'm currently unsure about!
>
> my int $a = 1;
> my int $b = 2
> my bool $true = 1 is const;
>
> if $a == $true { };
> if $b == $true { };
>
> The C<==> is coercing C<$true> into being numeric, and so the test in
> the second example evaluates to false, which is probably not what the
> programmer intended. If there were a boolean-compare operator then
> C<$a> and C<$b> would instead be coerced to boolean values and both
> expressions would evaluate to true.

Not what the programmer intended, and just as likely to produce a
warning if C<use strict> is enabled -- after all, you're comparing
across types.

Warning: Boolean used in numeric comparison context. Possible domain
error at line 5.

> That's what I'm unsure about. (And I'm fairly sure it's also cases
> like this that caused Larry not to be in favour of a boolean type.)

Doctor, doctor - it hurts when I move my arm like this!

=Austin

Paul

unread,
May 1, 2003, 12:32:38 PM5/1/03
to Smylers, perl6-l...@perl.org
> > > But if there's a boolean type then the only possible values that
> > > can be stored in a variable of that type are C<true> and
C<false>.
> > > So those values must exist to some extent, surely?
> >
> > Not necessarily. If bool (lowercase) is a synonym for bit (sic)
> > then the value will be that the bit in question is either on or
off,
> > which is a pretty fair representation of true and false, if you ask
> > me....but that doesn't mean that 1 is true and 0 is false. What's
to
> > stop you from flipping them, aside from convention?
>
> What's to stop you is that in a numeric context numbers in Perl that
> don't have a specific C<but false> or C<but true> trait[*0] are false
> when they are 0 and true otherwise. That's going to have to be the
> same for C<bit> in order for C<if $x> to work sanely.

Not necessarily. Don't get me wrong: I *HOPE* they don't do something
that wierd! But if a boolean context checks a value's boolean-ness
explicitly, then it's under the hood, and they could do anything they
want. C<if $x> is an explicit boolean context, so it might compile down
to a call to C<if $x.true>, which could return whatever the runtime
expects.

You can't even really say they're false for 0 and true otherwise. "" is
false, and undef, too. On the other hand, "\0" (NULL) is true in P5.

My point is merely that, while I'd much rather have a predictable and
sane implementation, it isn't *required* for predictable and sane
*behavior*.

> > > And there's nothing to stop C<if $x == $true>.
> >
> > What's the value of $true? No such critter, unless you make one.
>
> That was my intention by adding in the C<$> -- whatever value Perl is
> using to represent truth in

I know. I'm just saying ("parroting" from Luke/Austin/Mike/whomever,
actually, and no pun intended by that :) that there doesn't have to be
an absolute value for true. Look at it this way: assume any bool checks
the value being tested against a hash of known false's. If it isn't
there, it must be true. TA-DAA! :) Then the true method on any given
object can be overridden like C<method true($me){1}> with "but true",
or C<method true($me){0}> for "but false".

Yes, that makes true and false look like 1 and 0, but that's because
they are the simplest and easiest and most readable and obvious values.
It could as easily have returned "TRUE" and undef();

> > Knock the $ off and it's probably a syntax error. Not a keyword. :)
>
> That's why I put the C<$> on there.

I know, I know, lol.... Which is why I used it to make the point;
because it's obvious that you already thought about it.

> > Again, these are *exactly* the gyrations I went through just last
> > week.
>
> Oh good -- you'll be able to tell me how long they go on for then.

Your mileage may vary. ;o]

> (And surely it also follows that anything completely stupid I say
> isn't my fault: I'm just going along the track that Paul's set for
> me.)

LOL!!! Hey, it isn't stupid. Well, your isn't, anyway. ;op



> > > So if you have:
> > >
> > > my bool $x;
> > > my bool $y;
> > >
> > > what's the preferred way to test if those two variables are
> > > currently set to identical values? Using C<==> would work if
> > > things of type C<bool> in numeric context are coerced to some
> > > numeric values.
> >
> > Use something like
> >
> > if $x.true == $y.true { $well.isIt() }
>
> How does that help at all? In general .true will return the boolean
> truth value of a variable (which is only going to be useful outside
> boolean contexts, since in a boolean context that's what you get
> anyway). But for a variable of type C<bool>, its truth value is also
> its main piece of data, so I don't see how your line above could
> (given my definitions above) ever be different from the simpler:
>
> if $x == $y { $well.isIt() }
>
> In both cases we're getting a pair of boolean values then coercing
> each of them to numbers and comparing them for numeric equality -- by
> extension of your logic that the way to find the truth of a boolean
> value is to append C<.true> we'd end up with:
>
> if $x.true.true.true == $y.true.true.true { $well.isIt() }

No, the == is what's being evaluated in the boolean context there. It
is applying a numeric context on it's args. What you asked was are the
boolean values of $x and $y the same, so C<$x.true == $y.true> eval's
C<1 == 1> or C<0 == 0> as true, and C<1 == 0> or C<0 == 1> as false.

If you wanted to know if both were true, C<if $x and $y> would be the
way to go, but that's not what you asked for.

> > The .true() method will likely return a standardized (bitwise?) 1
> > or 0 (just at a guess),
>
> Right, but that leads into:
>
> > > But whichever two numbers are chosen, it'd be possible to have
> > > two C<int> variables each of which are treated as true in a
> > > boolean context, but only one of which compares C<==> equally
> > > with a boolean variable that's holding a true value.
> >
> > Which is why you don't want to say what values.
>
> But you just did, above.

There's a difference between saying "1 is true" and saying "true is 1".
Think syllogisms, and the difference between deductive and indictive
reasoning. In Perl, C<false> is a defined set; C<true> is defined as
"not false". Those *are* the canonical definitions. False has a *set*
of empirical values, and true is *everything* else.

> And if you have to convert them to integers in order to compare them
> then it's trivial to convert them to integers and print them out or
> store them in other variables: there's no way that Perl 6 could keep
> its canonical 'true' value a secret.

So what happens when the true value was "foo" and you convert it to an
integer 0? :)

> > my Str $s = "foo";
> > my Int $i = 1; <Snip>
> >
> > Am I on the right track here?
>
> I don't know about the 'right' track, but that wasn't what I'm
> concerned about -- your example didn't feature any variables of type
> C<bool>, the very thing that I'm currently unsure about!

Sorry. I actually did that on purpose as an attempt to simplify.
It apparently didn't help, lol....

My point there is that there is very seldom any reason to have a
C<bool> "type". It's more there for context. Yes, there are resons
occasionally, but they are likely rare.

> my int $a = 1;
> my int $b = 2
> my bool $true = 1 is const;
>
> if $a == $true { };
> if $b == $true { };

But you already know here that the second one will be false, because $b
is 2. Your example might be better to say C<my bool $true = $b>,
because if there is some universal value then $b should be converted in
the assignment context, but that still doesn't mean that C<true> is any
specific value. I'd expect that assignment to set $true to 1, because
unless you specify otherwise I'd expect it to be a single bit, and I'd
expect the boolean context to evaluate the truth of $b, and set that
bit on or off accordingly. I'd also expect the same behavior from

my $a = "foo";
my bool $true = $a;

or even from

my $b = "\0"; # a null byte, all 0 bits....
my bool $true = $b; # should set $true to 1!



> The C<==> is coercing C<$true> into being numeric, and so the test in
> the second example evaluates to false, which is probably not what the
> programmer intended. If there were a boolean-compare operator then
> C<$a> and C<$b> would instead be coerced to boolean values and both
> expressions would evaluate to true.

The boolean compare operator is spelled kinda funny:

my bool $true = $b;
if $true { .... # :)

In other words, you don't need one, precicely because there is no
preordained explicit single value for true. There are false, and then
there are everything else.

> That's what I'm unsure about. (And I'm fairly sure it's also cases
> like this that caused Larry not to be in favour of a boolean type.)

You've got a good grasp of the problem.
Now just walk around and look at it from the other end.
It's not that bad. :)

Paul

unread,
May 1, 2003, 12:58:47 PM5/1/03
to perl6-l...@perl.org

--- Paul <ydb...@yahoo.com> wrote:
> Think syllogisms, and the difference between deductive and indictive

lol -- I love it when my fingers are wittier than I.
That was supposed to be "deductive and inductive", but deduction
implies detectives working on an idictment, lol....

Or maybe the fingers were trying to type "indicative"; that isn't as
funny, but then again, they are just fingers.... :)

Dave Whipp

unread,
May 2, 2003, 12:00:53 AM5/2/03
to perl6-l...@perl.org
Austin Hastings wrote:

> But now you have to wonder about "default" context -- if I say
>
> if ($x == $true)
>
> Does it convert $x to boolean, or $true to num? Alternatively, you
> could write all your code with C<?> boolean context specifiers.

We could always use a junction:

$true.toNum # none(0)
$true.toScalar # none(0, "0", "", undef)

should cover it.

But looking at that brings up an interesting issue: how do junctions
collapse? Numerically, or stringically?

1 | 2 #==> 1 | 2
1 | 1 #==> 1
1 | "1" # ???


Dave.

Luke Palmer

unread,
May 2, 2003, 12:08:28 AM5/2/03
to da...@whipp.name, perl6-l...@perl.org

AHA! See, here's *another* case of the need for generic equality!
(Fortuanately, I needn't beg this case any longer, because I seem to
be on the same side of the fence as Larry regarding this issue)

So, assuming Junctions determine equality with the C<equal> operator:

1 | "1" #==> 1

Supposing C<equal> considers 1 equal to "1", which it ought to.

Oh, your idea of having C<true> be a junction is brilliant. Finally,
people can say:

Int $x = whatever;
if $x == true {...}

And always get what they want.

That's not to say I want it in the language. It's just a neat idea.

Luke

> Dave.

Smylers

unread,
May 1, 2003, 4:20:09 PM5/1/03
to perl6-l...@perl.org
Paul, Austin: I hope you don't mind me combining your messages, since
you've been making similar points.

Austin Hastings <austin_...@yahoo.com> writes:

> --- Smylers <Smy...@stripey.com> wrote:


>
> > Paul writes:
> >
> > > If bool (lowercase) is a synonym for bit (sic) then the value will
> > > be that the bit in question is either on or off, which is a pretty
> > > fair representation of true and false, if you ask me....but that
> > > doesn't mean that 1 is true and 0 is false. What's to stop you
> > > from flipping them, aside from convention?
> >
> > What's to stop you is that in a numeric context numbers in Perl that
> > don't have a specific C<but false> or C<but true> trait[*0] are
> > false when they are 0 and true otherwise. That's going to have to
> > be the same for C<bit> in order for C<if $x> to work sanely.
>

> Sure, but that doesn't mean that bool $x has to store 1/0 for
> true/false -- it IS true/false, so it could use 0/1 instead.

Of course it could. But C<bit> is a numeric type so has to use 0 for
false. Taking Paul's hypothesis that C<bool> is a synonym for C<bit>,
C<bool> would have to be that way round too else they wouldn't be
synonyms!

Paul <ydb...@yahoo.com> writes:

> But if a boolean context checks a value's boolean-ness explicitly,
> then it's under the hood, and they could do anything they want.
> C<if $x> is an explicit boolean context, so it might compile down to a
> call to C<if $x.true>, which could return whatever the runtime
> expects.

Yes; there's no problem with any of that in boolean context. The
problems are where a C<bool> is used in a numeric context.

> my bool $true = 1; # Convert from 1 (num) to TRUE (boolean)
>

> But now you have to wonder about "default" context -- if I say
>
> if ($x == $true)
>
> Does it convert $x to boolean, or $true to num?

The C<==> provides numeric context, so C<$true> gets treated as a
number. So that test only succeeds if C<$x> contains _the_ canonical
'true' value, not merely a value that'd be true in boolean context.

What booleans do in numeric context is exactly what I'm
concerned about here, and I think that's what Larry was objecting to in
the first place -- since I forked this subthread I've now found the
article from Larry I had in mind:

http://groups.google.co.uk/groups?hl=en&lr=&ie=UTF-8&selm=Pine.LNX.4.44.0210311952540.18773-100000%40london.wall.org

Paul <ydb...@yahoo.com> writes:

> Look at it this way: assume any bool checks the value being tested
> against a hash of known false's. If it isn't there, it must be true.
> TA-DAA!

With you so far -- that's what boolean context does in Perl 5.

> Then the true method on any given object can be overridden like
> C<method true($me){1}> with "but true", or C<method true($me){0}> for
> "but false".

Ah. So the C<.true> method could be overriden to return something that
isn't of type C<bool>? Oh; that isn't something I hadn't considered.
If I do:

my $b = $a.true;

then even though I haven't typed C<$b> I'd still expect it only to
contain a boolean value.

> Yes, that makes true and false look like 1 and 0, but that's because
> they are the simplest and easiest and most readable and obvious
> values. It could as easily have returned "TRUE" and undef();

So if two objects each override C<.true> separately they could each
return values which in a boolean context are true but which are
different from each other?

Austin Hastings <austin_...@yahoo.com> writes:

> > > Use something like
> > >
> > > if $x.true == $y.true { $well.isIt() }
> >

> > How does that help at all? ... I don't see how your line above
> > could ever be different from the simpler:


> >
> > if $x == $y { $well.isIt() }
>

> "How do I know if two boolean values are the same or different?"
>

> if !($a ^^ $b) { print "They're identical"; }

I understand how both work, but why bother doing either of them -- a
simple C<==> test seems to do anything that either of your versions will
do so long as C<bool> coerces to a number, so far as I can tell? Am I
missing an advantage of adding in the C<.true>s or using xor?

Paul <ydb...@yahoo.com> writes:

> There's a difference between saying "1 is true" and saying "true is
> 1". Think syllogisms, and the difference between deductive and
> indictive reasoning. In Perl, C<false> is a defined set; C<true> is
> defined as "not false". Those *are* the canonical definitions. False
> has a *set* of empirical values, and true is *everything* else.

Sure. Are you suggesting that in numeric context a C<bool> that
currently evaluates to true should randomly coerce to any non-zero
number?

> > I don't know about the 'right' track, but that wasn't what I'm
> > concerned about -- your example didn't feature any variables of type
> > C<bool>, the very thing that I'm currently unsure about!
> >

> > my int $a = 1;
> > my int $b = 2
> > my bool $true = 1 is const;
> >
> > if $a == $true { };
> > if $b == $true { };
> >

> > The C<==> is coercing C<$true> into being numeric, and so the test
> > in the second example evaluates to false, which is probably not what
> > the programmer intended. If there were a boolean-compare operator
> > then C<$a> and C<$b> would instead be coerced to boolean values and
> > both expressions would evaluate to true.

Austin Hastings <austin_...@yahoo.com> writes:

> Not what the programmer intended, and just as likely to produce a
> warning if C<use strict> is enabled -- after all, you're comparing
> across types.
>
> Warning: Boolean used in numeric comparison context. Possible domain
> error at line 5.

Ah, good. It's possible that such a warning would resolve all the
issues I have with C<bool>. (That would of course make C<bool> not an
exact synonym for C<bit>, since C<bit> is clearly numeric and it'd be
valid to do a numeric comparison on it.)

(Austin, I take it that you aren't actually suggesting that all
comparisons between things of different types would yield warnings --
there wouldn't seem to be much point in a warning when comparing an
integer with a float, for example.)

> > That's what I'm unsure about. (And I'm fairly sure it's also cases
> > like this that caused Larry not to be in favour of a boolean type.)
>

> Doctor, doctor - it hurts when I move my arm like this!

Well, yes, obviously there'd never be any need to write code like that.
But that doesn't stop people. When teaching programming languages I've
encountered many, many students who when they have to write a test for a
variable being true or being false want to write [in no particular
langage]:

If x == True
If y == False

rather than:

If x
If Not y

In languages that don't have keywords for true and false such people
often like to declare their own constants (or variables) to use for
these. To some extent I have sympathy for this -- I can see why
somebody would want to write:

has_kids = True

rather than:

has_kids = 1

because the former makes it much clearer that it is a boolean value
(whether the whatever-it-is has kids) rather than an integer value (how
many kids it has) that is being assigned.

That's fine for assignment regardless of which value they pick for true,
but there are serious problems if those user-defined true and false
constants start being used in tests.

Having a C<bool> type in Perl enforces the fallacy that there is a
single 'true' value that can be used in such comparisons.

I believe that this code is valid Perl 6 (where the parens are
redundant) and valid PHP 4 (where the braces are redundant):

$true = some_function_which_returns_a_bool_type_which_is_true();
$foo = 42;
if ($foo == $true) { print "foo is true"; }
else { print "foo is false"; }

But the output is different in each case. I think many programmers
would think that C<$foo> is true and therefore would expect the PHP
behaviour of printing that message.

I've no desire to write code like the examples I've posted here. But
when other people do write such code (and they will) I want to be able
to explain to them why it doesn't do what they want (and not just "well
don't do that then"!). A warning as you suggest may suffice -- it's
certainly better than just getting the 'wrong' result at run-time.

Paul <ydb...@yahoo.com> writes:

> My point there is that there is very seldom any reason to have a
> C<bool> "type".

Um ... isn't that where I came in -- asking why we now _do_ have a
C<bool> type?

> It's more there for context.

But why does having a boolean context require also having a boolean
type? Perl 5 manages to have the former without the latter.

Smylers

Dulcimer

unread,
May 2, 2003, 10:29:27 AM5/2/03
to Smylers, perl6-l...@perl.org

--- Smylers <Smy...@stripey.com> wrote:
> Paul, Austin: I hope you don't mind me combining your messages, since
> you've been making similar points.

I think it's a good idea. I hope Piers agrees. :)

But for the peanut gallery, my apologies; this does begin to stack
rather deep. I just want to keep the threads clear.

> Austin Hastings <austin_...@yahoo.com> writes:
> > --- Smylers <Smy...@stripey.com> wrote:
> > > Paul writes:
> > > > If bool (lowercase) is a synonym for bit (sic) then
> > > > the value will be that the bit in question is either
> > > > on or off, which is a pretty fair representation of
> > > > true and false, if you ask me....but that doesn't
> > > > mean that 1 is true and 0 is false. What's to stop
> > > > you from flipping them, aside from convention?
> > >
> > > What's to stop you is that in a numeric context numbers
> > > in Perl that don't have a specific C<but false> or
> > > C<but true> trait[*0] are false when they are 0 and true
> > > otherwise. That's going to have> to be the same for C<bit>
> > > in order for C<if $x> to work sanely.
> >
> > Sure, but that doesn't mean that bool $x has to store 1/0 for
> > true/false -- it IS true/false, so it could use 0/1 instead.
>
> Of course it could. But C<bit> is a numeric type so has to
> use 0 for false. Taking Paul's hypothesis that C<bool> is
> a synonym for C<bit>, C<bool> would have to be that way round
> too else they wouldn't be synonyms!

Careful! C<bit> isn't a numeric type, it's a C<bit> type. I'd probably
use it in a numeric context. That doesn *not* mean it uses 0 for false
-- careful with the wording here, it's the heart of the issue -- it
means that it *probably* uses 0 as false, since 0 is already *A* false
value, and so wouldn't require any special magic. Why add magic when it
already works? Likewise, its other possible value is 1, which is a
valid true, so it works as-is, B<in a boolean context>. That's not
using it as a number, though.

Using it as a bool, you're just using the wrong syninym for the right
functionality, which is OK, but I wouldn't recommend it. It's
confusing. :)

In either case, it doesn't mean true is 1 and false is zero; it just
takes advantage of the fact that 1 is true and 0 is false. See? the
order of phrasing makes all the difference, here.

> Paul <ydb...@yahoo.com> writes:
> > But if a boolean context checks a value's boolean-ness
> > explicitly, then it's under the hood, and they could do
> > anything they want. C<if $x> is an explicit boolean context,
> > so it might compile down to a call to C<if $x.true>,
> > which could return whatever the runtime expects.
>
> Yes; there's no problem with any of that in boolean context. The
> problems are where a C<bool> is used in a numeric context.

"Then don't do that."
No, seriously, if a bool and a bit are synonymous, then in a numeric
context a bool should return the 1 and 0 you expect. That does NOT mean
true IS 1 and false IS 0. It just means that if you evaluate a true
bool in a numeric context you're actually not using a bool, you're
using a bit, so it gives you its 1, as a false bool in numeric context
would likely give you its zero.

Do it this way: show me an example where you would want a bool value,
then use it in a numeric (bit) context. Look at your example, and tell
me where it requires that C<true> have a single canonical value for all
of the language. There's a disjuncture there. One doesn't require the
other.

> > my bool $true = 1; # Convert from 1 (num) to TRUE (boolean)
> > But now you have to wonder about "default" context -- if I say
> > if ($x == $true)
> > Does it convert $x to boolean, or $true to num?
>
> The C<==> provides numeric context, so C<$true> gets treated as a
> number. So that test only succeeds if C<$x> contains _the_ canonical
> 'true' value, not merely a value that'd be true in boolean context.

You can't jump that far. The only test that succeeds is if $x contains
a value that evaluates in a numeric context to the same value to which
$true evaluates in a numeric context. $true could as easily be $y here.
Your example converts both to numerics, then compares the result.



> What booleans do in numeric context is exactly what I'm
> concerned about here, and I think that's what Larry was objecting to
> in the first place -- since I forked this subthread I've now found
the
> article from Larry I had in mind:
>
http://groups.google.co.uk/groups?hl=en&lr=&ie=UTF-8&selm=Pine.LNX.4.44.0210311952540.18773-100000%40london.wall.org

Bullseye! As the Larry said, there'sno bool type, only boolean context.
the C<bool> is just a sysnonym for C<bit>, "syntactic sugar". What
bools will do in a numeric context is yield their underlying numbers,
which will *most likely* be 0 and 1.

So your concern is the difference between bit and Bit, maybe? Could I
say

my bool $b = 0 but true; #?

That would be "unwise", but if lowercase types allow that sort of
thing, then C<print $b if $b> would print 0. I'm pretty certain you
could do that with a Bool (or a Bit, for that matter....ewww).



> Paul <ydb...@yahoo.com> writes:
> > Look at it this way: assume any bool checks the value being tested
> > against a hash of known false's. If it isn't there, it must be
> > true. TA-DAA!
>
> With you so far -- that's what boolean context does in Perl 5.

Exactly.

> > Then the true method on any given object can be overridden like
> > C<method true($me){1}> with "but true", or C<method true($me){0}>
> > for "but false".
>
> Ah. So the C<.true> method could be overriden to return something
> that isn't of type C<bool>? Oh; that isn't something I hadn't
> considered.

lol -- me niether, but it works, as long as it evaluates to what you
meant.

> If I do:
>
> my $b = $a.true;
>
> then even though I haven't typed C<$b> I'd still expect it only to
> contain a boolean value.

Careful near that edge.....
$b is a plain scalar. Personally, I'd expect $a.true to return a
literal, which in this context would become a scalar. It would still
evaluate the same in a boolean context, but there's a subtle
difference.



> > Yes, that makes true and false look like 1 and 0, but that's
> > because they are the simplest and easiest and most readable
> > and obvious values. It could as easily have returned "TRUE"
> > and undef();
>
> So if two objects each override C<.true> separately they could each
> return values which in a boolean context are true but which are
> different from each other?

Very much so. You could make true return an incrementing count, or the
Gettysburg Address. I wouldn't do so unless there was a compelling
reason, but sometimes there is.

Maybe you want your object to return a full-blown array when true,
which contains a list of the reasons it *is* true. That would be ok.

> Austin Hastings <austin_...@yahoo.com> writes:
> > > > Use something like
> > > > if $x.true == $y.true { $well.isIt() }
> > > How does that help at all? ... I don't see how your line above
> > > could ever be different from the simpler:
> > > if $x == $y { $well.isIt() }
> > "How do I know if two boolean values are the same or different?"
> > if !($a ^^ $b) { print "They're identical"; }
>
> I understand how both work, but why bother doing either of them
> -- a simple C<==> test seems to do anything that either of your
> versions will do so long as C<bool> coerces to a number, so far
> as I can tell? Am I missing an advantage of adding in the
> C<.true>s or using xor?

Hmm... I think I see a problem here, too. What if one returns 1 for
true, and the other returns an array of times it was checked? The array
evaluates in this numeric context to its length. If it's been checked 6
times, C<$x == $y> is false, C<$x.true == $y.true> is also false. C<$a
^^ $b>, on the other hand, is an actual boolean operator, so it would
be true. (Thanks, Austin, that finally clicked. :)

So, there's another lesson to be learned: while you *CAN* override
.true
to return some nonstandard value, "Don't do that" unless you have a
*compelling* reason!

> Paul <ydb...@yahoo.com> writes:
>
> > There's a difference between saying "1 is true" and saying
> > "true is 1". Think syllogisms, and the difference between

> > deductive and inductive reasoning. In Perl, C<false> is a


> > defined set; C<true> is defined as "not false". Those *are*
> > the canonical definitions. False has a *set* of empirical
> > values, and true is *everything* else.
>
> Sure. Are you suggesting that in numeric context a C<bool> that
> currently evaluates to true should randomly coerce to any non-zero
> number?

lol -- no, no. I'm only saying that you can't make the assumption that
every true is a 1. I think it should be by FAR the most common value,
and that any time it isn't there should be great big neon signs posted
saying "NO SWIMMING -- HERE THERE BE DRAGONS", but that you can't
assume without considerable risk. That's all. 1 isn't even *always*
true: consider C<my $x = 1 but false;>.

P6 is really going to be a mind-expanding language, to put it politely.

> > > I don't know about the 'right' track, but that wasn't
> > > what I'm concerned about -- your example didn't feature
> > > any variables of type C<bool>, the very thing that I'm
> > > currently unsure about!
> > > my int $a = 1;
> > > my int $b = 2
> > > my bool $true = 1 is const;
> > > if $a == $true { };
> > > if $b == $true { };
> > > The C<==> is coercing C<$true> into being numeric, and
> > > so the test in the second example evaluates to false,
> > > which is probably not what the programmer intended.
> > > If there were a boolean-compare operator then C<$a> and
> > > C<$b> would instead be coerced to boolean values and both
> > > expressions would evaluate to true.
>
> Austin Hastings <austin_...@yahoo.com> writes:
> > Not what the programmer intended, and just as likely to
> > produce a warning if C<use strict> is enabled -- after all,
> > you're comparing across types.
> >
> > Warning: Boolean used in numeric comparison context. Possible
> > domain error at line 5.

[note: C<use warnings> will likely carp as above.
C<use strict> will more likely bail entirely. :) ]

> Ah, good. It's possible that such a warning would resolve
> all the issues I have with C<bool>. (That would of course
> make C<bool> not an exact synonym for C<bit>, since C<bit>
> is clearly numeric and it'd be valid to do a numeric comparison
> on it.)

Interesting point. That would, in fact, make it *not* an "exact"
synonym.... So is that going to be magic in the bool type? Or is it
reasonable to build that directly into the bit? I'd say not for bit,
since it is likely to be used as a number. On the other hand, if you
have an explicit bit type and try to assign it some inappropriate value
such as a 2, will it gripe about that?



> (Austin, I take it that you aren't actually suggesting that all
> comparisons between things of different types would yield warnings --
> there wouldn't seem to be much point in a warning when comparing an
> integer with a float, for example.)

As a point of order, I'd usually agree, but there might be times when
you'd *want* it to scream. 1.99999999999 isn't 2, after all....



> > > That's what I'm unsure about. (And I'm fairly sure it's
> > > also cases like this that caused Larry not to be in favour
> > > of a boolean type.)
> >
> > Doctor, doctor - it hurts when I move my arm like this!
>
> Well, yes, obviously there'd never be any need to write
> code like that. But that doesn't stop people. When teaching
> programming languages I've encountered many, many students
> who when they have to write a test for a variable being true
> or being false want to write [in no particular langage]:
> If x == True
> If y == False
> rather than:
> If x
> If Not y

I think that's valid in some languages.
I try not to use those languages. :)
Also, this is the sort of thing we need to be teaching them NOT to do.

> In languages that don't have keywords for true and false such
> people often like to declare their own constants (or variables)
> to use for these. To some extent I have sympathy for this --
> I can see why somebody would want to write:
> has_kids = True
> rather than:
> has_kids = 1
> because the former makes it much clearer that it is a boolean
> value (whether the whatever-it-is has kids) rather than an
> integer value (how many kids it has) that is being assigned.

Agreed, though this is a slightly different case. Either works here
with no particular problem, though it might be teaching both good and
bad habits....

> That's fine for assignment regardless of which value they pick
> for true, but there are serious problems if those user-defined
> true and false constants start being used in tests.

Exactly.

> Having a C<bool> type in Perl enforces the fallacy that there is a
> single 'true' value that can be used in such comparisons.

I can definitely see why you're concerned. I screwed it up with the
C<$x.true == $y.true> example, above, and I was being careful to avoid
exactly that problem. :)



> I believe that this code is valid Perl 6 (where the parens are
> redundant) and valid PHP 4 (where the braces are redundant):
>
> $true = some_function_which_returns_a_bool_type_which_is_true();
> $foo = 42;
> if ($foo == $true) { print "foo is true"; }
> else { print "foo is false"; }
>
> But the output is different in each case. I think many programmers
> would think that C<$foo> is true and therefore would expect the PHP
> behaviour of printing that message.

Hmm.... I wonder if this might be worth some magic in boolean contexts?
Would that be a Greater Evil?



> I've no desire to write code like the examples I've posted here.
> But when other people do write such code (and they will) I want
> to be able to explain to them why it doesn't do what they want
> (and not just "well don't do that then"!). A warning as you
> suggest may suffice -- it's certainly better than just getting
> the 'wrong' result at run-time.

AMEN.



> Paul <ydb...@yahoo.com> writes:
> > My point there is that there is very seldom any reason to
> > have a C<bool> "type".
>
> Um ... isn't that where I came in -- asking why we now _do_ have a
> C<bool> type?

lol -- was it? :)

> > It's more there for context.
>
> But why does having a boolean context require also having a boolean
> type? Perl 5 manages to have the former without the latter.

Dunno. I was =>ass<=uming it was because the context system implicitly
used the type system in some sort of casting mechanism. If that's not
the case, I'd say I'd have to agree with you. If someone wants a bool
type, they could add that bit of syntactic sugar with macro that
changes bool to bit for the parser.

Maybe someone will write a module that implements boolean magic as an
extension. Then we could strip it from the hypothetical "core" and
simplify a bit? (No pun intended...) I'd say every ounce of complexity
that goes in should be well founded, and every ounce we can omit saves
the design and development team some headache and heartache and an hour
or three with their children....

Dulcimer

unread,
May 2, 2003, 10:52:41 AM5/2/03
to Luke Palmer, da...@whipp.name, perl6-l...@perl.org

--- Luke Palmer <fibo...@babylonia.flatirons.org> wrote:
> > Austin Hastings wrote:
> > > But now you have to wonder about "default" context -- if I say
> > > if ($x == $true)
> > > Does it convert $x to boolean, or $true to num? Alternatively,
> > > you could write all your code with C<?> boolean context
> > > specifiers.
> >
> > We could always use a junction:
> >
> > $true.toNum # none(0)
> > $true.toScalar # none(0, "0", "", undef)
> >
> > should cover it.
> >
> > But looking at that brings up an interesting issue: how do
> > junctions collapse? Numerically, or stringically?

I prefer "stringifically". :)

> > 1 | 2 #==> 1 | 2
> > 1 | 1 #==> 1
> > 1 | "1" # ???
>
> AHA! See, here's *another* case of the need for generic equality!
> (Fortuanately, I needn't beg this case any longer, because I seem to
> be on the same side of the fence as Larry regarding this issue)

Er?



> So, assuming Junctions determine equality with the C<equal> operator:
>
> 1 | "1" #==> 1
>
> Supposing C<equal> considers 1 equal to "1", which it ought to.

So

0 | "foo" # ==>0?



> Oh, your idea of having C<true> be a junction is brilliant. Finally,
> people can say:
>
> Int $x = whatever;
> if $x == true {...}
>
> And always get what they want.

um, did I miss something?
Was the suggestion that true be a junction, or tha a junction be used
to clarify in cases where it mattered?



> That's not to say I want it in the language. It's just a neat idea.

Ah. Good. :)

Luke Palmer

unread,
May 2, 2003, 11:00:32 AM5/2/03
to Hod...@writeme.com, da...@whipp.name, perl6-l...@perl.org
> --- Luke Palmer <fibo...@babylonia.flatirons.org> wrote:
> > > Austin Hastings wrote:
> > > > But now you have to wonder about "default" context -- if I say
> > > > if ($x == $true)
> > > > Does it convert $x to boolean, or $true to num? Alternatively,
> > > > you could write all your code with C<?> boolean context
> > > > specifiers.
> > >
> > > We could always use a junction:
> > >
> > > $true.toNum # none(0)
> > > $true.toScalar # none(0, "0", "", undef)
> > >
> > > should cover it.
> > >
> > > But looking at that brings up an interesting issue: how do
> > > junctions collapse? Numerically, or stringically?
>
> I prefer "stringifically". :)
>
> > > 1 | 2 #==> 1 | 2
> > > 1 | 1 #==> 1
> > > 1 | "1" # ???
> >
> > AHA! See, here's *another* case of the need for generic equality!
> > (Fortuanately, I needn't beg this case any longer, because I seem to
> > be on the same side of the fence as Larry regarding this issue)
>
> Er?

The generic equality operator, which returns true if its operands are
the same type and the same value, and false otherwise. And true in
some special cases like "54321" and 54321.

I begged for this across many messages, and finally Larry mentioned a
desire for it in one of his posts. I was happy :)



> > So, assuming Junctions determine equality with the C<equal> operator:
> >
> > 1 | "1" #==> 1
> >
> > Supposing C<equal> considers 1 equal to "1", which it ought to.
>
> So
>
> 0 | "foo" # ==>0?

Nope.

0 | "foo" # ==> 0 | "foo"

The generic equality had better not consider those two things equal!
Just because the latter converts into the former means nothing about
their equality relationship.

> > Oh, your idea of having C<true> be a junction is brilliant. Finally,
> > people can say:
> >
> > Int $x = whatever;
> > if $x == true {...}
> >
> > And always get what they want.
>
> um, did I miss something?
> Was the suggestion that true be a junction, or tha a junction be used
> to clarify in cases where it mattered?

Well, I interpreted it as true itself being a junction. Except it was
called $true.

Luke

Austin Hastings

unread,
May 2, 2003, 11:53:16 AM5/2/03
to Smylers, perl6-l...@perl.org
One of the few things that REALLY pisses me off is typing up a response
and having Yahoo drop my text and prompt me to sign in again.

This is the second attempt. I apologize if it's not quite as good as
the first would have been.



> Paul, Austin: I hope you don't mind me combining your messages, since
> you've been making similar points.

Okay by me, but you'll have to make your peace with Piers...

> Of course it could. But C<bit> is a numeric type so has to use 0 for
> false. Taking Paul's hypothesis that C<bool> is a synonym for
C<bit>,
> C<bool> would have to be that way round too else they wouldn't be
> synonyms!

Having C<bool> and C<bit> be synonyms is (quoting Piers, I think) a
vile idea.

> Paul <ydb...@yahoo.com> writes:
>
> > But if a boolean context checks a value's boolean-ness explicitly,
> > then it's under the hood, and they could do anything they want.
> > C<if $x> is an explicit boolean context, so it might compile down
to
> > a call to C<if $x.true>, which could return whatever the runtime
> > expects.
>
> Yes; there's no problem with any of that in boolean context. The
> problems are where a C<bool> is used in a numeric context.
>
> > my bool $true = 1; # Convert from 1 (num) to TRUE (boolean)
> >
> > But now you have to wonder about "default" context -- if I say
> >
> > if ($x == $true)
> >
> > Does it convert $x to boolean, or $true to num?
>
> The C<==> provides numeric context, so C<$true> gets treated as a
> number. So that test only succeeds if C<$x> contains _the_ canonical
> 'true' value, not merely a value that'd be true in boolean context.

You're basing your assumptions on (1) Perl5 and (2) the absence of a
fully-supported boolean type. I'd expect that if we have booleans,
we'll have support for them. That should include a slew of multimethods
so that

multi *infix:==(Bool, Scalar) {...}
multi *infix:==(Scalar, Bool) {...}

do the right thing.

> What booleans do in numeric context is exactly what I'm
> concerned about here, and I think that's what Larry was objecting to
in
> the first place -- since I forked this subthread I've now found the
> article from Larry I had in mind:
>
>
http://groups.google.co.uk/groups?hl=en&lr=&ie=UTF-8&selm=Pine.LNX.4.44.0210311952540.18773-100000%40london.wall.org
>

Larry subsequently backed off a little bit in the same thread. However,
he did express the same reservations as you regarding the notion of
constant values.

> Paul <ydb...@yahoo.com> writes:
> > Then the true method on any given object can be overridden like
> > C<method true($me){1}> with "but true", or C<method true($me){0}>
for
> > "but false".
> Ah. So the C<.true> method could be overriden to return something
that
> isn't of type C<bool>? Oh; that isn't something I hadn't considered.
> If I do:
>
> my $b = $a.true;
>
> then even though I haven't typed C<$b> I'd still expect it only to
> contain a boolean value.

This ties back to the discussion of multiple dispatch of methods, and
to return-type-as-signature. As things currently stand, however, it
seems that

class Antisocial {
method true { return sqrt(-1); }
}

would be legitimate.

(BTW: What is the yorn value of 'Nan'? The default rule says that it
must be true, since it is some numeric value other than 0.)

> > Yes, that makes true and false look like 1 and 0, but that's
because
> > they are the simplest and easiest and most readable and obvious
> > values. It could as easily have returned "TRUE" and undef();
>
> So if two objects each override C<.true> separately they could each
> return values which in a boolean context are true but which are
> different from each other?

By extension from the above, yes.

> Austin Hastings <austin_...@yahoo.com> writes:
>
> > > > Use something like
> > > >
> > > > if $x.true == $y.true { $well.isIt() }
> > >
> > > How does that help at all? ... I don't see how your line above
> > > could ever be different from the simpler:
> > >
> > > if $x == $y { $well.isIt() }
> >
> > "How do I know if two boolean values are the same or different?"
> >
> > if !($a ^^ $b) { print "They're identical"; }
>
> I understand how both work, but why bother doing either of them -- a
> simple C<==> test seems to do anything that either of your versions
> will do so long as C<bool> coerces to a number, so far as I can tell?

> Am I missing an advantage of adding in the C<.true>s or using xor?

I think you're missing two points. First, convert-to-num is a needless
operation. Second, the && ^^ || operators are the natural operators for
boolean values.

You could convert nums to strings and then call strcmp, but why would
you?

Granted, I'd like to say "if ($a == $b)" and have it be meaningful. But
the two-valued yorn system that we use for programming isn't
necessarily compatible with a good logical type.

> Sure. Are you suggesting that in numeric context a C<bool> that
> currently evaluates to true should randomly coerce to any non-zero
> number?

That's an interesting possibility. I hope it doesn't become true.

> > > I don't know about the 'right' track, but that wasn't what I'm
> > > concerned about -- your example didn't feature any variables of
> > > type C<bool>, the very thing that I'm currently unsure about!
> > >
> > > my int $a = 1;
> > > my int $b = 2
> > > my bool $true = 1 is const;
> > >
> > > if $a == $true { };
> > > if $b == $true { };
> > >
> > > The C<==> is coercing C<$true> into being numeric, and so the
test
> > > in the second example evaluates to false, which is probably not
> what
> > > the programmer intended. If there were a boolean-compare
operator
> > > then C<$a> and C<$b> would instead be coerced to boolean values
and
> > > both expressions would evaluate to true.

C<infix:?==> ?

> Austin Hastings <austin_...@yahoo.com> writes:
>
> > Not what the programmer intended, and just as likely to produce a
> > warning if C<use strict> is enabled -- after all, you're comparing
> > across types.
> >
> > Warning: Boolean used in numeric comparison context. Possible
domain
> > error at line 5.
>
> Ah, good. It's possible that such a warning would resolve all the
> issues I have with C<bool>. (That would of course make C<bool> not
an
> exact synonym for C<bit>, since C<bit> is clearly numeric and it'd be
> valid to do a numeric comparison on it.)

See above: bool and bit should not be synonyms.

> (Austin, I take it that you aren't actually suggesting that all
> comparisons between things of different types would yield warnings --
> there wouldn't seem to be much point in a warning when comparing an
> integer with a float, for example.)

I'm still up in the air about this. I'd like there to be some version
of "gcc -Wall -ansi -pedantic" available, but I'm not sure hoe much of
it should hide behind which pragma.

> > > That's what I'm unsure about. (And I'm fairly sure it's also
cases
> > > like this that caused Larry not to be in favour of a boolean
type.)
> >
> > Doctor, doctor - it hurts when I move my arm like this!
>
> Well, yes, obviously there'd never be any need to write code like
that.
> But that doesn't stop people. When teaching programming languages
I've
> encountered many, many students who

... are students ...

> To some extent I have sympathy for this -- I can see why somebody
would
> want to write:
> has_kids = True
> rather than:
> has_kids = 1
> because the former makes it much clearer that it is a boolean value
> (whether the whatever-it-is has kids) rather than an integer value
(how
> many kids it has) that is being assigned.

And Perl does promise to make easy things easy.

> That's fine for assignment regardless of which value they pick for
> true, but there are serious problems if those user-defined true and
> false constants start being used in tests.
>
> Having a C<bool> type in Perl enforces the fallacy that there is a
> single 'true' value that can be used in such comparisons.

Except that if we have a special type, we can make it not be a fallacy.

> I believe that this code is valid Perl 6 (where the parens are
> redundant) and valid PHP 4 (where the braces are redundant):
>
> $true = some_function_which_returns_a_bool_type_which_is_true();
> $foo = 42;
> if ($foo == $true) { print "foo is true"; }
> else { print "foo is false"; }
>
> But the output is different in each case. I think many programmers
> would think that C<$foo> is true and therefore would expect the PHP
> behaviour of printing that message.

Not sure about that -- I'd expect the C behavior, since that was my
formative language.

> I've no desire to write code like the examples I've posted here. But
> when other people do write such code (and they will) I want to be
able
> to explain to them why it doesn't do what they want (and not just
"well
> don't do that then"!). A warning as you suggest may suffice -- it's
> certainly better than just getting the 'wrong' result at run-time.

Agreed.

> Paul <ydb...@yahoo.com> writes:
>
> > My point there is that there is very seldom any reason to have a
> > C<bool> "type".
>
> Um ... isn't that where I came in -- asking why we now _do_ have a
> C<bool> type?
>
> > It's more there for context.
>
> But why does having a boolean context require also having a boolean
> type? Perl 5 manages to have the former without the latter.

It doesn't.

My point is that if we're going to do a logic type, we should do a
logic type. I'd much rather see a Lukasiewiczian (Lukasonian) than a
Boolean type.

Perhaps that should be the name:

my Lukasonian $x;

This way, if you're not aware enough to know how to spell it, there's
little chance you'll mix it up by mistake with other types :-) :-) :-).

Maybe I'll write another brobdignagian proposal next week.

=Austin

Dulcimer

unread,
May 2, 2003, 12:42:18 PM5/2/03
to Austin_...@yahoo.com, Smylers, perl6-l...@perl.org
> > The C<==> provides numeric context, so C<$true> gets treated
> > as a number. So that test only succeeds if C<$x> contains
> > _the_ canonical 'true' value, not merely a value that'd be
> > true in boolean context.
>
> You're basing your assumptions on (1) Perl5 and (2) the absence
> of a fully-supported boolean type. I'd expect that if we have
> booleans, we'll have support for them. That should include a
> slew of multimethods so that
>
> multi *infix:==(Bool, Scalar) {...}
> multi *infix:==(Scalar, Bool) {...}
>
> do the right thing.

Ah. That makes sense. Of course, I'm a rebel without a clue. I'll agree
with almost anything....

That does seem a good solution, but what about

multi *infix:==(Str,Str) {...} # ?

Ugh. I presume it should be written, but I also presume it should
convert its opeands to numbers, and maybe gripe a lot under the
appropriate pragmata.

> [...]

> This ties back to the discussion of multiple dispatch of methods, and
> to return-type-as-signature. As things currently stand, however, it
> seems that
> class Antisocial {
> method true { return sqrt(-1); }
> }

> would be legitimate.

And antisocial. :)



> (BTW: What is the yorn value of 'Nan'? The default rule says that it
> must be true, since it is some numeric value other than 0.)

1) what is a "yorn" value?
2) must it? Nan is "*not* a number", so how can it be a number other
than 0? I'd call it false. I'd also say Inf is true, and might even
argue that Inf is a cool possibility for a "standard" true value. :)
Not a *good* idea, just a semi-cool one. Well, ok, so it's warming fast
in the sun....but I'd still say Inf was true.



> > Am I missing an advantage of adding in the C<.true>s or using xor?
>
> I think you're missing two points. First, convert-to-num is a
> needless operation. Second, the && ^^ || operators are the natural
> operators for boolean values. You could convert nums to strings and
> then call strcmp, but why would you?

i.e., don't assume a boolean test checks for some arbitrary number. :)

> Granted, I'd like to say "if ($a == $b)" and have it be meaningful.
> But the two-valued yorn system that we use for programming isn't
> necessarily compatible with a good logical type.

Not without some magic.

> > . . . . If there were a boolean-compare operator then C<$a>


> > and C<$b> would instead be coerced to boolean values and
> > both expressions would evaluate to true.
>
> C<infix:?==> ?

I assume that's C<infix:==> ?



> See above: bool and bit should not be synonyms.

I'm coming around to this view fast, and with a lot of momentum.

> > That's fine for assignment regardless of which value they pick for
> > true, but there are serious problems if those user-defined true and
> > false constants start being used in tests.
> >
> > Having a C<bool> type in Perl enforces the fallacy that there is a
> > single 'true' value that can be used in such comparisons.
>
> Except that if we have a special type, we can make it not be a
> fallacy.

I still don't like that idea much....
I'm not so sure why anymore.

You are saying that you might actually like for there to be literal
values for true and false? <grumblemumblethinkingaboutit....>

I think I'd strongly prefer for there to be *standard* values for
true/false, but not explicit literals that are the *only* possible
values for true/false. Still, as long as the runtime can convert
intelligently on the fly without too much overhead, I have to say I
really don't care that much in the long run. Just so

%false = ( 0 => true, undef => true, "" => true );
(0 == 1) == (%false{undef});

Hell, I could see that even allowing

use false qw/ :standard NULL NaN "boo!" /;

Unfortunately, that would also allow

use false qw/ 7 /;

I assume it would be smart enough not to allow

use false true;

tho.

> My point is that if we're going to do a logic type, we should do a
> logic type. I'd much rather see a Lukasiewiczian (Lukasonian) than a
> Boolean type. Perhaps that should be the name:
>
> my Lukasonian $x;
>
> This way, if you're not aware enough to know how to spell it, there's
> little chance you'll mix it up by mistake with other types :-) :-)

Now THAT I can agree with. :)

> Maybe I'll write another brobdignagian proposal next week.

DOWN WITH LITTLE-ENDIANS! ;op

Dave Whipp

unread,
May 2, 2003, 1:08:53 PM5/2/03
to Luke Palmer, Hod...@writeme.com, perl6-l...@perl.org

My suggestion was that a bool/Bool, <em>when coerced to another
type</em>, could become a junction in the target type.

We can ignore any performance implications, because it is always
possible to avoid this default behavior if you don't want/need it
(e.g. the ??:: operator; or simply use boolean context).

As various people have said, the values for true/false used
internally by a Boolean type need not be exposed to the outside
world: you're either using the Bool type itself, or it is being
coerced to other types. Neither case will violate encapsulation.


Dave.

Austin Hastings

unread,
May 2, 2003, 3:43:55 PM5/2/03
to Hod...@writeme.com, perl6-l...@perl.org

--- Dulcimer <ydb...@yahoo.com> wrote:
> Ah. That makes sense. Of course, I'm a rebel without a clue. I'll
> agree with almost anything....

You said it, not me. ;-)

>
> That does seem a good solution, but what about
>
> multi *infix:==(Str,Str) {...} # ?
>
> Ugh. I presume it should be written, but I also presume it should
> convert its opeands to numbers, and maybe gripe a lot under the
> appropriate pragmata.

Easier just to C<die "You meant to say 'eq', right?";>

> 1) what is a "yorn" value?

Yes-OR-No

> 2) must it? Nan is "*not* a number", so how can it be a number other
> than 0?

It's a defined part of the floating point space, and probably a full
citizen of Num space as well. Ergo, it's a number.

> > > Am I missing an advantage of adding in the C<.true>s or using
> xor?
> >
> > I think you're missing two points. First, convert-to-num is a
> > needless operation. Second, the && ^^ || operators are the natural
> > operators for boolean values. You could convert nums to strings and
> > then call strcmp, but why would you?
>
> i.e., don't assume a boolean test checks for some arbitrary number.

That's the point -- historically, the ^^ && || (well, not ^^) have
checked for "just any number" because they've been using the 'C'
semantics for truth/falsehood. But if you work in an environment where
logical values are treated as first class citizens, then you encounter
a different culture of usage.

I think it's possible to arrange a reasonable compromise, such that we
don't lose too much of either side. Once again, Perl-as-Orphanage:
there's always room for one more.

> > Granted, I'd like to say "if ($a == $b)" and have it be meaningful.
> > But the two-valued yorn system that we use for programming isn't
> > necessarily compatible with a good logical type.
>
> Not without some magic.

Not even then. Any system which allows "true", "false", and "undef"
(which even the most rudimentary Bool would have to do) either
qualifies undef as false (WAY undesirable) or has to reconcile the fact
that:

my Logical $l;

if (!$l) { print "No"; }
unless ($l) { print "No"; }

may do surprising things.

> > > . . . . If there were a boolean-compare operator then C<$a>
> > > and C<$b> would instead be coerced to boolean values and
> > > both expressions would evaluate to true.
> >
> > C<infix:?==> ?
>
> I assume that's C<infix:==> ?

No, it was meant to be the ?== operator -- suggestive of the boolean
context prefix already mentioned by @Larry several times.

> > > That's fine for assignment regardless of which value they pick
> > > for true, but there are serious problems if those user-defined
> > > true and false constants start being used in tests.
> > >
> > > Having a C<bool> type in Perl enforces the fallacy that there is
> > > a single 'true' value that can be used in such comparisons.
> >
> > Except that if we have a special type, we can make it not be a
> > fallacy.
>
> I still don't like that idea much....
> I'm not so sure why anymore.

Progress.

> You are saying that you might actually like for there to be literal
> values for true and false? <grumblemumblethinkingaboutit....>
>
> I think I'd strongly prefer for there to be *standard* values for
> true/false, but not explicit literals that are the *only* possible
> values for true/false. Still, as long as the runtime can convert
> intelligently on the fly without too much overhead, I have to say I
> really don't care that much in the long run. Just so

Just about. What I'm saying is that if there is a Logic type, there
will be literal values for that type. The Logic type is NOT the same as
a number. Get rid of that. So it's legitimate to talk about conversion
to and fro.

What's more, however, the Logic type and the Boolean context don't have
to be tightly coupled.

I can easily see folks defining a 9-valued logic type to do VHDL stuff.
That doesn't mean we need to have
if...elsa...elsb...elsc...elsd...else...elsf...elsg...elsh...elsi
keyword -- we simply clarify that in control-flow terms, there's

condition-matched
condition-not-matched

in the traditional Boolean style. But in Logic there's other
possibilities:

(MVL)
undef
unknown
provably-unknowable
provably-unprovable
tentatively-true
tentatively-false
true
false

or

(VHDL)
uninitialized
unknown
logic 0 (driven)
logic 1 (driven)
high impedance
weak 1
logic 0 (read)
logic 1 (read)
don't care

or just

(Lukasonian)
undef
null
true
false


> I assume it would be smart enough not to allow
> use false true;
> tho.

That falls under the heading of "developers can do whatever they want".

> > My point is that if we're going to do a logic type, we should do a
> > logic type. I'd much rather see a Lukasiewiczian (Lukasonian) than
> > a Boolean type. Perhaps that should be the name:
> >
> > my Lukasonian $x;
> >
> > This way, if you're not aware enough to know how to spell it,
> > there's
> > little chance you'll mix it up by mistake with other types :-) :-)
>
> Now THAT I can agree with. :)
>
> > Maybe I'll write another brobdignagian proposal next week.
>
> DOWN WITH LITTLE-ENDIANS! ;op

Nothing against Intel, here.

=Austin

Dulcimer

unread,
May 2, 2003, 4:37:54 PM5/2/03
to Austin_...@yahoo.com, perl6-l...@perl.org
> > Ah. That makes sense. Of course, I'm a rebel without a clue. I'll
> > agree with almost anything....
>
> You said it, not me. ;-)

lol -- yes, I did.... Hey, wait a sec... ;o]

> > That does seem a good solution, but what about
> >
> > multi *infix:==(Str,Str) {...} # ?
> >
> > Ugh. I presume it should be written, but I also presume it should
> > convert its opeands to numbers, and maybe gripe a lot under the
> > appropriate pragmata.
>
> Easier just to C<die "You meant to say 'eq', right?";>

Easier, but is it more appropriate?
I'd rather see something that DWIMs, but WIM is up for grabs.
Personally, I'd say

my $x = "1";
my $y = "1";
if ($x == $y) { print "this should work."; }
my Str $a = "1";
my Str $b = "1";
if ($a == $b) { print "should this work?"; }

If that's the whole code, I'd say let it work as you'd predict.
If under C<use warnings>, try to make it wark, but gripe loudly.
If under C<use strict>, die horribly cursing the coder's birth.

> > 1) what is a "yorn" value?
>
> Yes-OR-No

Duh.



> > 2) must it? Nan is "*not* a number", so how can it be a number
> > other than 0?
>
> It's a defined part of the floating point space, and probably a full
> citizen of Num space as well. Ergo, it's a number.

I understand, and it's a valid point, but I'm not sure what represents
the principle of least surprise, here. Personally, I'd just add it to
the list of false values.

> > > > Am I missing an advantage of adding in the C<.true>s or using
> > > > xor?
> > >
> > > I think you're missing two points. First, convert-to-num is a
> > > needless operation. Second, the && ^^ || operators are the
> > > natural operators for boolean values. You could convert nums
> > > to strings and then call strcmp, but why would you?
> >
> > i.e., don't assume a boolean test checks for some arbitrary number.
>
> That's the point -- historically, the ^^ && || (well, not ^^) have
> checked for "just any number" because they've been using the 'C'
> semantics for truth/falsehood. But if you work in an environment
> where logical values are treated as first class citizens, then you
> encounter a different culture of usage.
>
> I think it's possible to arrange a reasonable compromise, such that
> we don't lose too much of either side. Once again, Perl-as-Orphanage:
> there's always room for one more.

lol.... reason enough for a little magic, I suppose.
Because *THAT* follows the principle of least surprise.

> > > Granted, I'd like to say "if ($a == $b)" and have it be
> > > meaningful. But the two-valued yorn system that we use
> > > for programming isn't necessarily compatible with a good
> > > logical type.
> >
> > Not without some magic.
>
> Not even then. Any system which allows "true", "false", and "undef"
> (which even the most rudimentary Bool would have to do) either
> qualifies undef as false (WAY undesirable)

Why is that so undesirable?

> or has to reconcile the fact that:
>
> my Logical $l;
>
> if (!$l) { print "No"; }
> unless ($l) { print "No"; }
>
> may do surprising things.

I'm apparently being dense. I see "NoNo". What's the surprise?



> > > > . . . . If there were a boolean-compare operator then C<$a>
> > > > and C<$b> would instead be coerced to boolean values and
> > > > both expressions would evaluate to true.
> > >
> > > C<infix:?==> ?
> >
> > I assume that's C<infix:==> ?
>
> No, it was meant to be the ?== operator -- suggestive of the
> boolean context prefix already mentioned by @Larry several times.

Ah. Ok, but I think I'd rather see C<?$x == ?$y> do something sensible.
Then again, C<$x ?== $y> looks less noisy. Give me a few minutes; I
could get used to it. I presume it would put both it's operands in a
boolean context?

multi *infix:?== (Bool $x, Bool $y) { $x and $y ?? 1 :: 0; } # ?

> > > > Having a C<bool> type in Perl enforces the fallacy that there
> > > > is a single 'true' value that can be used in such comparisons.
> > >
> > > Except that if we have a special type, we can make it not be a
> > > fallacy.
> >
> > I still don't like that idea much....
> > I'm not so sure why anymore.
>
> Progress.

LOL!! >:o]

> > You are saying that you might actually like for there to be literal
> > values for true and false? <grumblemumblethinkingaboutit....>
> >
> > I think I'd strongly prefer for there to be *standard* values for
> > true/false, but not explicit literals that are the *only* possible
> > values for true/false. Still, as long as the runtime can convert
> > intelligently on the fly without too much overhead, I have to say I
> > really don't care that much in the long run. Just so
>
> Just about. What I'm saying is that if there is a Logic type,
> there will be literal values for that type. The Logic type is
> NOT the same as a number. Get rid of that. So it's legitimate
> to talk about conversion to and fro.

Ok, but the P5 list of false values constitute a list of literal
values. P5's truth is "not false". I'm trying to get my head around the
idea that P6 might do that differently, and honestly evaluate it rather
than give a knee-jerk reactionary response, or just repeat something I
hear.

Conversion doesn't bother me. I'm just contemplating potential
convolution of code.

> What's more, however, the Logic type and the Boolean context don't
> have to be tightly coupled.

Okie..... so long as boolean context always returns true or false, for
some consistent definition of true and false.



> I can easily see folks defining a 9-valued logic type to do VHDL
> stuff.

VHDL?

> That doesn't mean we need to have
> if...elsa...elsb...elsc...elsd...else...elsf...elsg...elsh...elsi
> keyword --

Lord, no!

> we simply clarify that in control-flow terms, there's
>
> condition-matched
> condition-not-matched
>
> in the traditional Boolean style.

With you so far, aside from not being able to de-acronymify VHDL. :)

> But in Logic there's other possibilities:
>
> (MVL)

Multi Value Logical??

> undef
> unknown
> provably-unknowable
> provably-unprovable
> tentatively-true
> tentatively-false
> true
> false

Ok, these are great if you need them, but I doubt I ever will need
provavbly-unprovable in three programs I write at this job. I'd rather
have that functionality abstracted out to a module unless it can be
*very* easily incorporated in a way that is *completely* transparent to
the rest of my code.



> or
>
> (VHDL)
> uninitialized
> unknown
> logic 0 (driven)
> logic 1 (driven)
> high impedance
> weak 1
> logic 0 (read)
> logic 1 (read)
> don't care

Same response.



> or just
>
> (Lukasonian)
> undef
> null
> true
> false

What's the functional difference here between null and undef?
I presume it's the same sort of difference you'd get by testing
JavaScript objects? Again, I think the only times I'm likely to need to
differentiate is if the language imposes a lack of transparency.

I can see where it would matter, but maybe I'm just not qualified to
judge it, because I virtually never use these values. Then again, there
*have* been times I've wanted to split things into different categories
of data that *don't* have a valid values. But I'm weak on theory here.
Break it down for me into a pragmatic case example?

> > I assume it would be smart enough not to allow
> > use false true;
> > tho.
>
> That falls under the heading of "developers can do whatever they
> want".

lol -- "Don't do that!" :)
In this case I might have to disagree.
Something THAT freaky should NOT be easy. Rewrite the parser or some
module that does what at least *appears* to be Deep Black Magic, but
you shouldn't be able to do this without really hacking *something*.
That's just wrong.

> > > Maybe I'll write another brobdignagian proposal next week.
> >
> > DOWN WITH LITTLE-ENDIANS! ;op
>
> Nothing against Intel, here.

Depends on the OS. ;oD

Dave Whipp

unread,
May 3, 2003, 12:50:48 AM5/3/03
to perl6-l...@perl.org
Dulcimer wrote:
>>or has to reconcile the fact that:
>>
>> my Logical $l;
>>
>> if (!$l) { print "No"; }
>> unless ($l) { print "No"; }
>>
>>may do surprising things.
>
> I'm apparently being dense. I see "NoNo". What's the surprise?

In a 3-state logic, in complement of undef is still undef.

Therefore "!undef" will not evaluate to true, so the first case will not
be taken. However, "undef" is also not true: so the second case will be
taken. So the output will be "No", not "NoNo". Surprised?


>>I can easily see folks defining a 9-valued logic type to do VHDL
>>stuff.
>
> VHDL?

The VHSIC-HDL, if that helps ;)

HDL = Hardware Description Language -- used to design integrated
circuits. Support for such things will definitely be in modules, not the
core. At some point I'll try to embed Parrot into a Verilog (another
HDL) simulator (via VPI, for those who know what that is): but I'm not
sure that things are well enough defined yet


Dave.

Dulcimer

unread,
May 3, 2003, 6:37:39 PM5/3/03
to Dave Whipp, perl6-l...@perl.org

--- Dave Whipp <da...@whipp.name> wrote:
> Dulcimer wrote:
> >>or has to reconcile the fact that:
> >> my Logical $l;
> >> if (!$l) { print "No"; }
> >> unless ($l) { print "No"; }
> >>may do surprising things.
> >
> > I'm apparently being dense. I see "NoNo". What's the surprise?
>
> In a 3-state logic, in complement of undef is still undef.
> Therefore "!undef" will not evaluate to true, so the first case will
> not be taken. However, "undef" is also not true: so the second case
> will be taken. So the output will be "No", not "NoNo". Surprised?

Yes, and while it might be a Godd Thing, I don't think I'd like for
Perl to go that far afield from it's history without strong reasons to
do so. THAT is so far from the principle of least surprise that it
would make a lot of things blow up for a long time before the old
school old hands got the hang of it....

Austin Hastings

unread,
May 5, 2003, 12:34:07 AM5/5/03
to Hod...@writeme.com, perl6-l...@perl.org

> -----Original Message-----
> From: Dulcimer [mailto:ydb...@yahoo.com]
> > Easier just to C<die "You meant to say 'eq', right?";>
>
> Easier, but is it more appropriate?

P5 history has == meaning "numeric context". Str == Str should, thereby,
force toNum conversion and then compare the results. That's almost
guaranteed to be wrong -- there may be times when the user meant to do that,
but (s)he could just as well say +$x == +$y for that 1 case.

The rest of the times, it's a newbie making the classic ==/eq error. DWIM in
that case is to silently call eq. But DTRT is, I claim, do emit a diagnostic
message.

> > > 2) must it? Nan is "*not* a number", so how can it be a number
> > > other than 0?
> >
> > It's a defined part of the floating point space, and probably a full
> > citizen of Num space as well. Ergo, it's a number.
>
> I understand, and it's a valid point, but I'm not sure what represents
> the principle of least surprise, here. Personally, I'd just add it to
> the list of false values.

Depends on the logic system. If we're doing boolean (yorn) logic, then it's
a no. If we're doing something more complete, I'll recommend "undef" or
"null".

> lol.... reason enough for a little magic, I suppose.
> Because *THAT* follows the principle of least surprise.

Aye.

> > > > Granted, I'd like to say "if ($a == $b)" and have it be
> > > > meaningful. But the two-valued yorn system that we use
> > > > for programming isn't necessarily compatible with a good
> > > > logical type.
> > >
> > > Not without some magic.
> >
> > Not even then. Any system which allows "true", "false", and "undef"
> > (which even the most rudimentary Bool would have to do) either
> > qualifies undef as false (WAY undesirable)
>
> Why is that so undesirable?

This goes back to the "array default value" discussion some time ago.

The C<undef> value means "no value set here yet."

What happens if your e-voting machine says

map { $_ ?? ++$yes :: ++$no } %voter_prefs;

given $yes <=> $no
{
when 0 { print "Tie."; }
when $_ < 0 { print "Rejected."; }
when $_ > 0 { print "Approved."; }
}

If C<undef> is in %voter_prefs, presumably because that person hasn't voted
(yet), then you're equating "no response" with "response of no".

This is one of those sub-tile semantic things. The easiest thing to do would
be to look up Lukasewiczian logic, as it relates to, say, the SQL 92
standard. The inclusion of the C<NULL> value, and the C<UNDEFINED>
condition, tie right back to this issue.


> > or has to reconcile the fact that:
> >
> > my Logical $l;
> >
> > if (!$l) { print "No"; }
> > unless ($l) { print "No"; }
> >
> > may do surprising things.
>
> I'm apparently being dense. I see "NoNo". What's the surprise?

As has been pointed out, let's suppose there're canonical C<FALSE> and
C<TRUE> values. In this case:
if (!$x)
means $x != TRUE, while
unless ($x)
means $x == FALSE.

You should be able to see the potential problem, given some of the prior
discussion.

> > > > > . . . . If there were a boolean-compare operator then C<$a>
> > > > > and C<$b> would instead be coerced to boolean values and
> > > > > both expressions would evaluate to true.
> > > >
> > > > C<infix:?==> ?
> > >
> > > I assume that's C<infix:==> ?
> >
> > No, it was meant to be the ?== operator -- suggestive of the
> > boolean context prefix already mentioned by @Larry several times.
>
> Ah. Ok, but I think I'd rather see C<?$x == ?$y> do something sensible.
> Then again, C<$x ?== $y> looks less noisy. Give me a few minutes; I
> could get used to it. I presume it would put both it's operands in a
> boolean context?

Be careful with that word, "Boolean". But to satisfy Smylers, yes.

> multi *infix:?== (Bool $x, Bool $y) { $x and $y ?? 1 :: 0; } # ?

Ahh, no. If $x and $y are both untrue, it should still succeed. You want
C<!($x ^^ $y)> in there.

> > Just about. What I'm saying is that if there is a Logic type,
> > there will be literal values for that type. The Logic type is
> > NOT the same as a number. Get rid of that. So it's legitimate
> > to talk about conversion to and fro.
>
> Ok, but the P5 list of false values constitute a list of literal
> values. P5's truth is "not false". I'm trying to get my head around the
> idea that P6 might do that differently, and honestly evaluate it rather
> than give a knee-jerk reactionary response, or just repeat something I
> hear.
>
> Conversion doesn't bother me. I'm just contemplating potential
> convolution of code.
>
> > What's more, however, the Logic type and the Boolean context don't
> > have to be tightly coupled.
>
> Okie..... so long as boolean context always returns true or false, for
> some consistent definition of true and false.

Not true and false. Matched or not-matched.

Look at regexes, for example:

my Str $x = <>;

if $x ~= /fnord.$/ { show($fear); }

What's the scoop on the regex? It either matched, or it failed-to-match.
That's boolean context. Yes, or not-yes.

Or consider C<if> versus C<given/when>:
if $x == 9 { print "nine." }
versus:
given $x {
when 9 { print "nine."; }
}

In the first case, we've got a "boolean" setup. The second example makes it
more clear: $x could have many values. If it matches THIS PARTICULAR ONE
then do some action: match versus not-match.

So if there's a Logic type, we might say
if $x
as a shortcut for
if $x == true
and conversely we might say
if !$x
as a shortcut for something else.

But logic can be more complex than just yorn, so we need to ask: does !$x
mean ($x != true) or does it mean ($x == false).

> VHDL?
Digital circuit design, that kind of stuff.

> > we simply clarify that in control-flow terms, there's
> > condition-matched
> > condition-not-matched
> > in the traditional Boolean style.
>
> With you so far, aside from not being able to de-acronymify VHDL. :)
>
> > But in Logic there's other possibilities:
> >
> > (MVL)
>
> Multi Value Logical??

Multi-valued logic -- logic that allows "I'm not sure" or some such, in
addition to the old yorn.

> > undef
> > unknown
> > provably-unknowable
> > provably-unprovable
> > tentatively-true
> > tentatively-false
> > true
> > false
>
> Ok, these are great if you need them, but I doubt I ever will need
> provavbly-unprovable in three programs I write at this job. I'd rather
> have that functionality abstracted out to a module unless it can be
> *very* easily incorporated in a way that is *completely* transparent to
> the rest of my code.

Right. But this goes to the point of any C<Logic> type. If it exists, it can
be one of two things:

1- A strict yorn value, in keeping with control-flow logic in the program.

2- Something more sinister.

If it's (1), then there's a whole lot of simplification that has to go on,
and eventually we reach the point where people like Smylers point out "Hey,
this is stupid! Having a yorn Logical type is no gain over keeping scalars
with 0/not-0 in them."

If it's (2), then we first have to ask "What kind of Logical is it?" and
some set of people are going to be unhappy with the result. So the best
possible case there is that we have a Logical type that's very much like the
Num type - it can automatically handle Complex and BigNum and other wierd
crap. We'd want Logical to have semantics that easily expanded to handle
whatever extra states wound up in the domain.

That would make the SQL wonks and the ASIC boogers and the
Goedel-Escher-Bach wankers all deliriously, frantically, ecstatically
ambivalent -- a happy medium.

It runs the risk of confusing newbies, but that's a risk we're all happy
with at some level. Besides, any such first-class type would impose its own
semantics, so that newbies would learn that if you want truth, you say C<if
$x == true>, or whatever.

> > undef
> > null
> > true
> > false
>
> What's the functional difference here between null and undef?

"No answer" versus "not asked"?

Or, put another way, what's the difference between
exists %hash{$key}
and
%hash{$key} != undef
?

> I presume it's the same sort of difference you'd get by testing
> JavaScript objects? Again, I think the only times I'm likely to need to
> differentiate is if the language imposes a lack of transparency.

Have you stopped beating your wife, yet?

> I can see where it would matter, but maybe I'm just not qualified to
> judge it, because I virtually never use these values. Then again, there
> *have* been times I've wanted to split things into different categories
> of data that *don't* have a valid values. But I'm weak on theory here.
> Break it down for me into a pragmatic case example?

Above. Also, any website that collects data, or any income-tax form. The
notion of "nothing to see here" (skip to line 6 if line 4 is less than
$20,000) abounds.

Another classic example:

Suppose you own a website, and it's been around for years. Suppose further
you've got a list of customers/contacts, which amount to millions of email
addresses complete with lots of gooey personal data.

And suppose the Federal Government wherever you happen to be passes a law
that says "We will fine you or throw you in jail if you send spam to anyone
who hasn't opted in." (EU, anyone?)

Further suppose that when you STARTED in this business, while you were
collecting private info and your customers were naive enough to give it
away, you couldn't even SPELL "privacy policy" or "opt in".

Now, you've got 3 million records, about 100,000 of which have answered your
"do you want to opt in to our exciting spam?" question. What do you do?

Now you or I might think "Hey, it's a no-brainer, don't send any spam!" But
your boss is saying "MoneymoNeymoneYmoneymOneymonEymoneyMoney...." and
salivating uncontrollably.


> In this case I might have to disagree.
> Something THAT freaky should NOT be easy. Rewrite the parser or some
> module that does what at least *appears* to be Deep Black Magic, but
> you shouldn't be able to do this without really hacking *something*.
> That's just wrong.

It's not too hard to convert 'C' into something resembling Pascal using the
preprocessor. Just because an idea is stupid doesn't mean you should protect
everyone against it.


=Austin

Piers Cawley

unread,
May 5, 2003, 8:15:18 AM5/5/03
to Austin_...@yahoo.com, Hod...@writeme.com, perl6-l...@perl.org
Austin Hastings <austin_...@yahoo.com> writes:

> --- Dulcimer <ydb...@yahoo.com> wrote:
>> Ah. That makes sense. Of course, I'm a rebel without a clue. I'll
>> agree with almost anything....
>
> You said it, not me. ;-)
>
>>
>> That does seem a good solution, but what about
>>
>> multi *infix:==(Str,Str) {...} # ?
>>
>> Ugh. I presume it should be written, but I also presume it should
>> convert its opeands to numbers, and maybe gripe a lot under the
>> appropriate pragmata.
>
> Easier just to C<die "You meant to say 'eq', right?";>

I would hope not. I'd argue that it should only gripe (with a warning)
if the strings in question are meaningless as numbers (and therefore
evaluate to 0). Under C<use strict 'too_damned_anal'> you might also
want a warning when you do

my Str $bibble = <STDIN>;
my Str $flob = <STDIN>;

...

if $bibble == $flob {...}

but I'm not sure I'd go so far as to recommend it. But then, you all
probably know my views on anal type declarations.

--
Piers

Dulcimer

unread,
May 5, 2003, 8:49:38 PM5/5/03
to perl6-l...@perl.org

--- Austin Hastings <Austin_...@Yahoo.com> wrote:
> > -----Original Message-----
> > From: Dulcimer [mailto:ydb...@yahoo.com]
> > > Easier just to C<die "You meant to say 'eq', right?";>
> >
> > Easier, but is it more appropriate?
>
> P5 history has == meaning "numeric context". Str == Str should,
> thereby, force toNum conversion and then compare the results.

That was my rationale....

> That's almost guaranteed to be wrong -- there may be times when
> the user meant to do that, but (s)he could just as well say
> +$x == +$y for that 1 case.

That's right, you *can* do that in P6! Ok, I'm convinced.



> The rest of the times, it's a newbie making the classic ==/eq error.
> DWIM in that case is to silently call eq. But DTRT is, I claim, do
> emit a diagnostic message.

In which case I agree.

> > > > 2) must it? Nan is "*not* a number", so how can it be a
> > > > number other than 0?
> > >
> > > It's a defined part of the floating point space, and probably a
> > > full citizen of Num space as well. Ergo, it's a number.
> >
> > I understand, and it's a valid point, but I'm not sure what
> > represents the principle of least surprise, here. Personally,
> > I'd just add it to the list of false values.
>
> Depends on the logic system. If we're doing boolean (yorn) logic,
> then it's a no. If we're doing something more complete, I'll
> recommend "undef" or "null".

I'm assuming a YorN truth system, and voting for NaN to be false.
I fully expect to be outvoted on it, though, so I'll get a head start
getting used to the idea. :)

> > > > > Granted, I'd like to say "if ($a == $b)" and have it be
> > > > > meaningful. But the two-valued yorn system that we use
> > > > > for programming isn't necessarily compatible with a good
> > > > > logical type.
> > > >
> > > > Not without some magic.
> > >
> > > Not even then. Any system which allows "true", "false", and
> > > "undef" (which even the most rudimentary Bool would have to
> > > do) either qualifies undef as false (WAY undesirable)
> >
> > Why is that so undesirable?
>
> This goes back to the "array default value" discussion some time ago.
>
> The C<undef> value means "no value set here yet."
>
> What happens if your e-voting machine says
> map { $_ ?? ++$yes :: ++$no } %voter_prefs;
> given $yes <=> $no {
> when 0 { print "Tie."; }
> when $_ < 0 { print "Rejected."; }
> when $_ > 0 { print "Approved."; }
> }
>
> If C<undef> is in %voter_prefs, presumably because that person hasn't
> voted (yet), then you're equating "no response" with "response of
no".

Which is a programmer error. That should've been a more sophisticated
test. Yes, that's a pain, but that's programming. Any other system
would still require that you know what you're doing, and the above code
doesn't accomodate undef's at all. Your map is a YorN answer to what
you suggest is a multistate problem. This is a situation where the
current system allows coding it either way reasonably cleanly, I'd say.
I'd've probably said something like
map { $_ ?? ++$yes :: defined
?? ++$no :: ++$novote } %voter_prefs;
if $novote > $threshhold {
die "Too much apathy!"; # or a wait loop, or whatever
} else {


given $yes <=> $no {
when 0 { print "Tie."; }
when $_ < 0 { print "Rejected."; }
when $_ > 0 { print "Approved."; }
}
}

> This is one of those sub-tile semantic things. The easiest thing to


> do would be to look up Lukasewiczian logic, as it relates to, say,
> the SQL 92 standard. The inclusion of the C<NULL> value, and the
> C<UNDEFINED> condition, tie right back to this issue.

I usually interpret UNDEFINED as Perl's NULL, but wouldn't mind having
another toy to play with. :)

> > > or has to reconcile the fact that:
> > > my Logical $l;
> > > if (!$l) { print "No"; }
> > > unless ($l) { print "No"; }
> > > may do surprising things.
> >
> > I'm apparently being dense. I see "NoNo". What's the surprise?
>
> As has been pointed out, let's suppose there're canonical C<FALSE>
> and C<TRUE> values. In this case:
> if (!$x)
> means $x != TRUE, while
> unless ($x)
> means $x == FALSE.
>
> You should be able to see the potential problem, given some of the
> prior discussion.

Which is exactly why I'd tend to vote against some
canonical/empirical/Platonic True and False. I'd rather see it say True
is "not false", and !$x says T = "is $x true" and then returns not-T.

> > > > > > . . . . If there were a boolean-compare operator then C<$a>
> > > > > > and C<$b> would instead be coerced to boolean values and
> > > > > > both expressions would evaluate to true.
> > > > >
> > > > > C<infix:?==> ?
> > > >
> > > > I assume that's C<infix:==> ?
> > >
> > > No, it was meant to be the ?== operator -- suggestive of the
> > > boolean context prefix already mentioned by @Larry several times.
> >
> > Ah. Ok, but I think I'd rather see C<?$x == ?$y> do something
> > sensible.
> > Then again, C<$x ?== $y> looks less noisy. Give me a few minutes; I
> > could get used to it. I presume it would put both it's operands in
> > a boolean context?
>
> Be careful with that word, "Boolean". But to satisfy Smylers, yes.

I was careful, lol....

> > multi *infix:?== (Bool $x, Bool $y) { $x and $y ?? 1 :: 0; } # ?
>
> Ahh, no. If $x and $y are both untrue, it should still succeed. You
> want C<!($x ^^ $y)> in there.

"and" returns true when both operands are false?!?!?!?!?
Ok, Lucy, 'splain.

> > Okie..... so long as boolean context always returns true or false,
> > for some consistent definition of true and false.
>
> Not true and false. Matched or not-matched.

The difference?

> Look at regexes, for example:
>
> my Str $x = <>;
>
> if $x ~= /fnord.$/ { show($fear); }
>
> What's the scoop on the regex? It either matched, or it
> failed-to-match.
> That's boolean context. Yes, or not-yes.

Agreed, and this condition if usually referred to in a boolean standard
manner, using the terms true or false to indicate a condition which
matches prevailing data, or one which does not, respectively. To
reverse your example, a match means you have applied a true description
of the data to the data; a non-match meaqns you have applied a false
description of the data to the data. These are just semantics.



> Or consider C<if> versus C<given/when>:
> if $x == 9 { print "nine." }
> versus:
> given $x {
> when 9 { print "nine."; }
> }
>
> In the first case, we've got a "boolean" setup. The second example
> makes it more clear: $x could have many values. If it matches THIS
> PARTICULAR ONE then do some action: match versus not-match.

Exactly: *each_individual* possibility is still boolean, however. Each,
taken by itself, either matches or does not: is either a true
description of the given data, or a false one.

> So if there's a Logic type, we might say
> if $x
> as a shortcut for
> if $x == true
> and conversely we might say
> if !$x
> as a shortcut for something else.

C<if !$x> had better do exactly the same thing as C<unless $x> or we're
going to lose a lot of potential programmers. I like the language, and
would like to see it supported in the future, so I'd rather keep a
happy professional user base.



> But logic can be more complex than just yorn, so we need to ask: does
> !$x mean ($x != true) or does it mean ($x == false).

If they mean something different, change it. It's broken.
Yes, I realize that means giving up some really cool toys; put them in
a module. Unless I ask for it, don't force feed me added complexity.

> > > undef
> > > unknown
> > > provably-unknowable
> > > provably-unprovable
> > > tentatively-true
> > > tentatively-false
> > > true
> > > false
> >
> > Ok, these are great if you need them, but I doubt I ever will
> > need provavbly-unprovable in three programs I write at this job.
> > I'd rather have that functionality abstracted out to a module
> > unless it can be *very* easily incorporated in a way that is
> > *completely* transparent to the rest of my code.
>
> Right. But this goes to the point of any C<Logic> type. If it exists,
> it can be one of two things:
>
> 1- A strict yorn value, in keeping with control-flow logic in the
> program.
>
> 2- Something more sinister.

Interesting choice of words. :)

> If it's (1), then there's a whole lot of simplification that has to
> go on, and eventually we reach the point where people like Smylers
> point out "Hey, this is stupid! Having a yorn Logical type is no
> gain over keeping scalars with 0/not-0 in them."

I disagree. O boolean object type has magic in it that does stuff for
me. It lets me delegate some of my code simplification. It's a simple
case of the classic advantages you get from object code, as well as a
case of the common object problem -- don't use it unless it adds
something.


> If it's (2), then we first have to ask "What kind of Logical is it?"
> and some set of people are going to be unhappy with the result. So
> the best possible case there is that we have a Logical type that's
> very much like the Num type - it can automatically handle Complex
> and BigNum and other wierd crap. We'd want Logical to have semantics
> that easily expanded to handle whatever extra states wound up in the
> domain.

Agreed, as long as you don't take away my ability to use it to store
good ol' ints, and more importantly, as long as you don't take away my
ability to use Int to *enforce* integer math.

I think you have a great idea.
I suspect it'd make a great module.
I'm not convinced that it's a good replacement for P5's veracity
system.



> That would make the SQL wonks and the ASIC boogers and the
> Goedel-Escher-Bach wankers all deliriously, frantically, ecstatically
> ambivalent -- a happy medium.

LOL!!! Not a ghost of a chance. ;op



> It runs the risk of confusing newbies, but that's a risk we're all
> happy with at some level. Besides, any such first-class type would
> impose its own semantics, so that newbies would learn that if you
> want truth, you say C<if $x == true>, or whatever.

boo, hiss.
Don't go there. I really just don't think we want that particular
system. I don't mind true and false being operators that can make
intelligent decisions that should be no-ops anyway, but not keyword
values. C<if true $x> I could live with; C<if $x == true> should be a
compile crash. :)

> > > undef
> > > null
> > > true
> > > false
> >
> > What's the functional difference here between null and undef?
>
> "No answer" versus "not asked"?

If I know which it is, I asked. :)



> Or, put another way, what's the difference between
> exists %hash{$key}
> and
> %hash{$key} != undef
> ?

Getting tired. Can't parse that. I guess I should stop now.



> > I presume it's the same sort of difference you'd get by testing
> > JavaScript objects? Again, I think the only times I'm likely to
> > need to differentiate is if the language imposes a lack of
> > transparency.
>
> Have you stopped beating your wife, yet?

A boolean "no". :)
If you act incorrectly on that info, it's because you asked the wrong
question. That actually demonstrates the problem pretty well -- PICNIC:

Problem In Chair, Not In Computer.
We can't write code for the coder. It's his job, and his problem. We
try to make it simple.... but bools are pretty simple.

> > I can see where it would matter, but maybe I'm just not qualified
> > to judge it, because I virtually never use these values. Then
again,
> > there *have* been times I've wanted to split things into different
> > categories of data that *don't* have a valid values. But I'm weak
> > on theory here. Break it down for me into a pragmatic case example?
>
> Above. Also, any website that collects data, or any income-tax form.

ack, hiss, lol....
Same problem. I don't intend to solve the ambiguity of others by adding
complexity to the syntax of English. Let them arrange for good answers
by asking the right questions and providing me with an opportunity to
give them reasonable data, and I'll give them reasonable data. If they
FORCE me to answer with a bool, I'll answer with a bool, but then they
shouldn't have done that unless the question is appropriately answered
with a bool. Complicating bools doesn't prevent people from asking
questions stupidly. There are already plenty of tools to ask whether
I'm married first, and then if so (which I ain't) whether I ever beat
my wife (which I di'n't).

> The notion of "nothing to see here" (skip to line 6 if line 4 is less
> than $20,000) abounds.

If $a { } elsif $b { } else { }.
Some think it's ugly, but it's a staple of code.
I ain't scared. :)

> Another classic example:
>
> Suppose you own a website, and it's been around for years. Suppose
> further you've got a list of customers/contacts, which amount to
> millions of email addresses complete with lots of gooey personal
> data.
> And suppose the Federal Government wherever you happen to be passes a
> law that says "We will fine you or throw you in jail if you send spam
> to anyone who hasn't opted in." (EU, anyone?)
> Further suppose that when you STARTED in this business, while you
> were collecting private info and your customers were naive enough
> to give it away, you couldn't even SPELL "privacy policy" or "opt
> in".
>
> Now, you've got 3 million records, about 100,000 of which have
> answered your "do you want to opt in to our exciting spam?" question.
> What do you do?

I go out of business, because if my job depends on spamming people I'd
die of guilt, lol....

> Now you or I might think "Hey, it's a no-brainer, don't send any
> spam!" But your boss is saying
> "MoneymoNeymoneYmoneymOneymonEymoneyMoney...." and
> salivating uncontrollably.

He can wipe his mouth on my resignation. :)

More seriously, the question is boolean. Did they opt in? Then you can
mail them. If not, then you can't. Boss doesn't like it? That doesn't
change the fact that it's still a boolean situation.

> > In this case I might have to disagree.
> > Something THAT freaky should NOT be easy. Rewrite the parser or
> > some module that does what at least *appears* to be Deep Black
> > Magic, but you shouldn't be able to do this without really hacking
> > *something*. That's just wrong.
>
> It's not too hard to convert 'C' into something resembling Pascal
> using the preprocessor. Just because an idea is stupid doesn't mean
> you should protect everyone against it.

Exactly. In fact, if they want to do that, more power to them.
As long as the truth of !x equals the falsity of x, I'll be ok.

Smylers

unread,
May 5, 2003, 6:59:18 PM5/5/03
to perl6-l...@perl.org
Austin Hastings writes:

> > > Granted, I'd like to say "if ($a == $b)" and have it be
> > > meaningful. But the two-valued yorn system that we use for
> > > programming isn't necessarily compatible with a good logical type.
> >
> > Not without some magic.
>
> Not even then. Any system which allows "true", "false", and "undef"
> (which even the most rudimentary Bool would have to do) either
> qualifies undef as false (WAY undesirable) or has to reconcile the fact
> that:
>
> my Logical $l;
>
> if (!$l) { print "No"; }
> unless ($l) { print "No"; }
>
> may do surprising things.

That didn't surprise me (and yes, I did get it right before I read your
explanation to Paul later in this thread). If you have chosen to
declare something as a C<Bool> or whatever then you having knowingly
created a variable which can have three different values. A single test
only makes one distinction therefore two of the three values are going
to be treated in the same way as each other.

If somebody does C<if !$l> without first testing for C<defined $l> then
they have chosen only to be interested in the truth value and to treat
false and C<undef> equivalently.

> Just about. What I'm saying is that if there is a Logic type, there
> will be literal values for that type.

Yes -- if there is a type then there are values of that type and its
silly to pretend that there aren't and claim that there isn't a way of
writing them.

Smylers

Smylers

unread,
May 5, 2003, 6:53:52 PM5/5/03
to perl6-l...@perl.org
Austin Hastings writes:

> > Paul, Austin: I hope you don't mind me combining your messages, since
> > you've been making similar points.
>
> Okay by me, but you'll have to make your peace with Piers...

That's odd -- you and Paul took exactly opposite views on how Piers
would view my post-combining. (Personally I think Piers should just be
happy I changed the subject line on this sub-thread ...)

> > Of course it could. But C<bit> is a numeric type so has to use 0
> > for false. Taking Paul's hypothesis that C<bool> is a synonym for
> > C<bit>, C<bool> would have to be that way round too else they
> > wouldn't be synonyms!
>
> Having C<bool> and C<bit> be synonyms is (quoting Piers, I think) a
> vile idea.

Fair enough -- I was just highlighting the problems I saw with Paul's
proposal (though that thread I quoted before does have Larry saying that
he sees C<bool> as a C<bit>).

> > > my bool $true = 1; # Convert from 1 (num) to TRUE (boolean)

> > > if ($x == $true)
> > >
> > > Does it convert $x to boolean, or $true to num?
> >
> > The C<==> provides numeric context, so C<$true> gets treated as a
> > number. So that test only succeeds if C<$x> contains _the_ canonical
> > 'true' value, not merely a value that'd be true in boolean context.
>
> You're basing your assumptions on (1) Perl5

Well, I was assuming that C<==> still does numeric comparisons, sure. I
don't want to be the person who has to break it to MikeL that the
operator list has changed again ...

> and (2) the absence of a fully-supported boolean type.

I was puzzled as to how C<bool> could work; Paul suggested a way and I
was specifically arguing against that particular way.

> I'd expect that if we have booleans, we'll have support for them. That
> should include a slew of multimethods so that
>
> multi *infix:==(Bool, Scalar) {...}
> multi *infix:==(Scalar, Bool) {...}
>
> do the right thing.

But what is the right thing? Is it "right" for C<==> not always to
compare numerically? If C<==> is going to be able to cope with numbers
and booleans (and presumably strings and booleans) being mixed then
people are much more likely to expect it to compare strings -- and you
can't respond by saying that C<==> is just for numeric comparisons.

> > > > > if $x.true == $y.true { $well.isIt() }
> > > >
> > > > How does that help at all? ... I don't see how your line above
> > > > could ever be different from the simpler:
> > > >
> > > > if $x == $y { $well.isIt() }
> > >
> > > "How do I know if two boolean values are the same or different?"
> > >
> > > if !($a ^^ $b) { print "They're identical"; }
> >
> > I understand how both work, but why bother doing either of them -- a
> > simple C<==> test seems to do anything that either of your versions
> > will do so long as C<bool> coerces to a number, so far as I can tell?
>
> > Am I missing an advantage of adding in the C<.true>s or using xor?
>
> I think you're missing two points. First, convert-to-num is a needless
> operation.

Indeed, which is why I didn't think a numeric C<==> comparison was a
good idea.

> Second, the && ^^ || operators are the natural operators for boolean
> values.

Yes, but it's hardly natural to have to test for equality by doing
not-xor.

> You could convert nums to strings and then call strcmp, but why would
> you?

I wouldn't: I think that if we're going to have a boolean type in the
language then we should have a boolean comparison.

> C<infix:?==> ?

I could live with that.

> > That's fine for assignment regardless of which value they pick for
> > true, but there are serious problems if those user-defined true and
> > false constants start being used in tests.
> >
> > Having a C<bool> type in Perl enforces the fallacy that there is a
> > single 'true' value that can be used in such comparisons.
>
> Except that if we have a special type, we can make it not be a
> fallacy.

If we have a boolean comparison operator then I don't think a canonical
true value is needed (though I suppose it may be for Luke's 'generic
comparison').

> > I believe that this code is valid Perl 6 (where the parens are
> > redundant) and valid PHP 4 (where the braces are redundant):
> >
> > $true = some_function_which_returns_a_bool_type_which_is_true();
> > $foo = 42;
> > if ($foo == $true) { print "foo is true"; }
> > else { print "foo is false"; }
> >
> > But the output is different in each case. I think many programmers
> > would think that C<$foo> is true and therefore would expect the PHP
> > behaviour of printing that message.
>
> Not sure about that -- I'd expect the C behavior, since that was my
> formative language.

I don't know much C but I didn't think it had a boolean type, and that
even if it did there'd be an error for trying to compare things of
wildly differing types. I suppose that makes three different possible
behaviours for that code.

> My point is that if we're going to do a logic type, we should do a
> logic type. I'd much rather see a Lukasiewiczian (Lukasonian) than a
> Boolean type.

I'm not entirely convinced about that, but I'd feel happier about having
something that definitely is distinct from boolean and so not as
confusable with it.

Smylers

Smylers

unread,
May 5, 2003, 6:37:33 PM5/5/03
to perl6-l...@perl.org
Dulcimer writes:

> --- Smylers <Smy...@stripey.com> wrote:
>
> > Paul, Austin: I hope you don't mind me combining your messages,
> > since you've been making similar points.
>
> I think it's a good idea. I hope Piers agrees. :)

And I hope he doesn't mind you changing your name halfway through a
thread ...

> Careful! C<bit> isn't a numeric type, it's a C<bit> type.

Isn't it? I'd assumed that a bit was like an integer only much smaller,
and that it's valid to do arithmetic on things of type C<bit>.

> > The problems are where a C<bool> is used in a numeric context.
>
> "Then don't do that."

I expect I wouldn't, but people are going to try it and it needs to do
something sane.

> Do it this way: show me an example where you would want a bool value,
> then use it in a numeric (bit) context.

I can't think of one. Does it matter? I've provided examples where
people might think they want to use a C<bool> in a generic numeric
context.

> > > my bool $true = 1; # Convert from 1 (num) to TRUE (boolean)
> > > But now you have to wonder about "default" context -- if I say
> > > if ($x == $true)
> > > Does it convert $x to boolean, or $true to num?
> >
> > The C<==> provides numeric context, so C<$true> gets treated as a
> > number. So that test only succeeds if C<$x> contains _the_ canonical
> > 'true' value, not merely a value that'd be true in boolean context.
>
> You can't jump that far. The only test that succeeds is if $x contains
> a value that evaluates in a numeric context to the same value to which
> $true evaluates in a numeric context.

Yup. But if I started by declaring C<$true> as a C<bool> and storing a
true value in it then C<$x> is being compared with the numeric
representation of the canonical true value.

> Your example converts both to numerics, then compares the result.

Exactly, which is why I'm bothered about how these conversions go.

> So your concern is the difference between bit and Bit, maybe?

Oh, no -- I've been sufficiently occupied puzzling over how C<bool> can work
sensibly that I haven't even consider C<Bit> and C<Bool> yet.

> > So if two objects each override C<.true> separately they could each
> > return values which in a boolean context are true but which are
> > different from each other?
>
> Very much so. You could make true return an incrementing count, or the
> Gettysburg Address. I wouldn't do so unless there was a compelling
> reason, but sometimes there is.
>
> Maybe you want your object to return a full-blown array when true,
> which contains a list of the reasons it *is* true. That would be ok.

So why bother writing a function which claims to return a boolean but
then overloads it with a string, integer, or array? At the moment
people simply write functions that return strings, integers, or arrays.
Users of those functions can test the return values in boolean contexts,
taking advantage of the fact that empty strings, zero, and empty arrays
evaluate to false.

But because the return values don't claim to be booleans nobody would
try to compare them as booleans. Returning a string from one function
and a count from another but claiming that they are both booleans just
sounds daft to me.

> > > > > Use something like
> > > > > if $x.true == $y.true { $well.isIt() }
> > > > How does that help at all? ... I don't see how your line above
> > > > could ever be different from the simpler:
> > > > if $x == $y { $well.isIt() }
> > > "How do I know if two boolean values are the same or different?"
> > > if !($a ^^ $b) { print "They're identical"; }
> >
> > I understand how both work, but why bother doing either of them
> > -- a simple C<==> test seems to do anything that either of your
> > versions will do so long as C<bool> coerces to a number, so far
> > as I can tell? Am I missing an advantage of adding in the
> > C<.true>s or using xor?
>
> Hmm... I think I see a problem here, too.

I wasn't trying to identify a problem here -- I was just wondering what
your and Austin's more complicated ways of comparing two C<bool>s had
over the simple way. I'm still wondering.

> So, there's another lesson to be learned: while you *CAN* override
> .true to return some nonstandard value, "Don't do that" unless you
> have a *compelling* reason!

Can you give an example of a compelling reason?


> > Are you suggesting that in numeric context a C<bool> that currently
> > evaluates to true should randomly coerce to any non-zero number?
>
> lol -- no, no. I'm only saying that you can't make the assumption that
> every true is a 1.

Which is why comparing them using a numeric comparison operator causes
problems.

> > (Austin, I take it that you aren't actually suggesting that all
> > comparisons between things of different types would yield warnings
> > -- there wouldn't seem to be much point in a warning when comparing
> > an integer with a float, for example.)
>
> As a point of order, I'd usually agree, but there might be times when
> you'd *want* it to scream. 1.99999999999 isn't 2, after all....

Yes; I hadn't thought of that. I suppose it depends on the type of
comparison -- checking that a float is less than an integer strikes me
as something that should always be allowed even if testing for equality
isn't.

> > When teaching programming languages I've encountered many, many
> > students who when they have to write a test for a variable being
> > true or being false want to write [in no particular langage]:
> > If x == True
> > If y == False
> > rather than:
> > If x
> > If Not y
>
> I think that's valid in some languages. I try not to use those
> languages. :)

There are definitely languages where that's valid.

> Also, this is the sort of thing we need to be teaching them NOT to do.

Yes. (And my preferred way of teaching them not to do this in Perl 5 is
by being able to state categorically that there isn't a boolean type,
and there isn't a canonical true value.)

But even so it needs to do something reasonable for those that are on
the learning curve.

> > I believe that this code is valid Perl 6 (where the parens are
> > redundant) and valid PHP 4 (where the braces are redundant):
> >
> > $true = some_function_which_returns_a_bool_type_which_is_true();
> > $foo = 42;
> > if ($foo == $true) { print "foo is true"; }
> > else { print "foo is false"; }
> >
> > But the output is different in each case. I think many programmers
> > would think that C<$foo> is true and therefore would expect the PHP
> > behaviour of printing that message.
>
> Hmm.... I wonder if this might be worth some magic in boolean
> contexts? Would that be a Greater Evil?

Personally I like having a simple rule that C<==> always does numeric
comparison.

What do you mean by "boolean contexts" (and indeed "magic") here? You
can't mean that C<==> should booleanize its arguments simply because the
C<if> is providing a boolean context -- that would make C<if 2 == 3>
evaluate to true.

So what would denote the boolean context for these purposes -- one of
the operands being a C<bool>? It sounds like a slippery slope to me.

> > But why does having a boolean context require also having a boolean
> > type? Perl 5 manages to have the former without the latter.
>
> Dunno. I was =>ass<=uming it was because the context system implicitly
> used the type system in some sort of casting mechanism.

I can't immediately see why internals like that should require an effect
on the visible language.

> If that's not the case, I'd say I'd have to agree with you. If someone
> wants a bool type, they could add that bit of syntactic sugar with
> macro that changes bool to bit for the parser.

It was my being unconvinced as to the need for a boolean type which
prompted this thread. After so many posts of me merely having thoughts
you'd had a week previously I'm glad you've finally come round to my
view!

Smylers

Austin Hastings

unread,
May 6, 2003, 11:40:59 AM5/6/03
to Smylers, perl6-l...@perl.org

--- Smylers <Smy...@stripey.com> wrote:
> Austin Hastings writes:
>
> > > Paul, Austin: I hope you don't mind me combining your messages,
> since
> > > you've been making similar points.
> >
> > Okay by me, but you'll have to make your peace with Piers...
>
> That's odd -- you and Paul took exactly opposite views on how Piers
> would view my post-combining. (Personally I think Piers should just
> be happy I changed the subject line on this sub-thread ...)

He's very sensitive, you know ... ;-)

> > > Of course it could. But C<bit> is a numeric type so has to use 0
> > > for false. Taking Paul's hypothesis that C<bool> is a synonym
> for
> > > C<bit>, C<bool> would have to be that way round too else they
> > > wouldn't be synonyms!
> >
> > Having C<bool> and C<bit> be synonyms is (quoting Piers, I think) a
> > vile idea.
>
> Fair enough -- I was just highlighting the problems I saw with Paul's
> proposal (though that thread I quoted before does have Larry saying
> that he sees C<bool> as a C<bit>).

Considering the shirt he's wearing in his "stock Larry picture", it
boggles my mind how many people believe Larry always gets things right
the first time.

> > > > my bool $true = 1; # Convert from 1 (num) to TRUE (boolean)
> > > > if ($x == $true)
> > > >
> > > > Does it convert $x to boolean, or $true to num?
> > >
> > > The C<==> provides numeric context, so C<$true> gets treated as a
> > > number. So that test only succeeds if C<$x> contains _the_
> > > canonical 'true' value, not merely a value that'd be true in
> > > boolean context.
> >
> > You're basing your assumptions on (1) Perl5
>
> Well, I was assuming that C<==> still does numeric comparisons, sure.
> I don't want to be the person who has to break it to MikeL that the
> operator list has changed again ...

:-)
But hold on to that idea: that == does numeric comparisons.

> > I'd expect that if we have booleans, we'll have support for them.
> > That should include a slew of multimethods so that
> >
> > multi *infix:==(Bool, Scalar) {...}
> > multi *infix:==(Scalar, Bool) {...}
> >
> > do the right thing.
>
> But what is the right thing? Is it "right" for C<==> not always to
> compare numerically? If C<==> is going to be able to cope with
> numbers and booleans (and presumably strings and booleans) being
> mixed then people are much more likely to expect it to compare
> strings -- and you can't respond by saying that C<==> is just for
> numeric comparisons.

Why not? If C<==> is the numifying comparator, as it traditionally has
been, then it should numify and compare. In which case, as someone has
pointed out, there are several possibilities:

1- Convert "true" -> 1, and "false" -> 0.
2- Convert "true" -> none(0), and "false" -> 0.

If, on the other hand, == is more dwimish, then we need to decide which
takes precedence: num->logic or logic->num. That is, if I say C<$i ==
$p>, does the Int get easily converted to yorn, or does the predicate
get converted to Int?

> > > > > > if $x.true == $y.true { $well.isIt() }
> > > > > How does that help at all? ... I don't see how your line
> > > > > above could ever be different from the simpler:
> > > > > if $x == $y { $well.isIt() }
> > > > "How do I know if two boolean values are the same or
> > > > different?"

> > > > if !($a ^^ $b) { print "They're identical"; }
> > >
> > > I understand how both work, but why bother doing either of them
> > > -- a simple C<==> test seems to do anything that either of your
> > > versions will do so long as C<bool> coerces to a number, so far
> > > as I can tell?

> > I think you're missing two points. First, convert-to-num is a
> > needless operation.
> Indeed, which is why I didn't think a numeric C<==> comparison was a
> good idea.
>
> > Second, the && ^^ || operators are the natural operators for
> boolean
> > values.
>
> Yes, but it's hardly natural to have to test for equality by doing
> not-xor.

Why is that?

I mean, if you had to perform this very same operation in Perl5, how
would you do it?

You certainly couldn't use ==, since that's a numeric conversion and
(unless you've already defined canonical true/false for your vars)
there's no single true value.

So you'd wind up saying ($x && $y) || (!$x && !$y), which if you had
the ^^ operator and a set of logic tables available, you'd realize
translates directly to !($x ^^ $y).

> > You could convert nums to strings and then call strcmp, but why
> > would you?
> I wouldn't: I think that if we're going to have a boolean type in the
> language then we should have a boolean comparison.
> > C<infix:?==> ?
> I could live with that.

OTOH, if we have a boolean type, and the boolean type has canonical
true/false/etc values, then there's no reason not to have == overloaded
to do that -- but it depends on defining the type. Otherwise we're back
at "any num (but one) could be true" and the situation above.

> > > That's fine for assignment regardless of which value they pick
> > > for true, but there are serious problems if those user-defined
> > > true and false constants start being used in tests.
> > >
> > > Having a C<bool> type in Perl enforces the fallacy that there is
> > > a single 'true' value that can be used in such comparisons.
> >
> > Except that if we have a special type, we can make it not be a
> > fallacy.
>
> If we have a boolean comparison operator then I don't think a
> canonical true value is needed (though I suppose it may be for
> Luke's 'generic comparison').

Depends on what you're looking for. If you have a boolean comparison
operator, you can implement boolean ops using Scalar type, provided you
always keep in the back of your mind that this isn't really boolean,
and remember to override and extend and insert boolean context sigils
in the right places.

> > > I believe that this code is valid Perl 6 (where the parens are
> > > redundant) and valid PHP 4 (where the braces are redundant):
> > >
> > > $true =
> some_function_which_returns_a_bool_type_which_is_true();
> > > $foo = 42;
> > > if ($foo == $true) { print "foo is true"; }
> > > else { print "foo is false"; }
> > >
> > > But the output is different in each case. I think many
> > > programmers would think that C<$foo> is true and therefore
> > > would expect the PHP behaviour of printing that message.
> >
> > Not sure about that -- I'd expect the C behavior, since that was my
> > formative language.
>
> I don't know much C but I didn't think it had a boolean type, and
> that even if it did there'd be an error for trying to compare
> things of wildly differing types. I suppose that makes three
> different possible behaviours for that code.

C and Perl5 share common logical behavior. The == operator is a
non-logical compare between compatible types (only). So the comparable
version would declare foo to be false, unless there was a special bool
type whose "true" value stored 42 in an int.

> > My point is that if we're going to do a logic type, we should do a
> > logic type. I'd much rather see a Lukasiewiczian (Lukasonian) than
> > a Boolean type.
>
> I'm not entirely convinced about that, but I'd feel happier about
> having something that definitely is distinct from boolean and so
> not as confusable with it.

Death to Boole!

(And no, I don't want to call it 'Ada'. On the other hand, since Paul
seems bewildered by the notion of a logical type where the !true
doesn't mean false, and yes can sometimes mean no, perhaps we could
call it 'Ladylike'. :-) :-) :-)

=Austin

Austin Hastings

unread,
May 6, 2003, 11:50:44 AM5/6/03
to Smylers, perl6-l...@perl.org

--- Smylers <Smy...@stripey.com> wrote:
> Austin Hastings writes:
>
> > > > Granted, I'd like to say "if ($a == $b)" and have it be
> > > > meaningful. But the two-valued yorn system that we use for
> > > > programming isn't necessarily compatible with a good logical
> type.
> > >
> > > Not without some magic.
> >
> > Not even then. Any system which allows "true", "false", and "undef"
> > (which even the most rudimentary Bool would have to do) either
> > qualifies undef as false (WAY undesirable) or has to reconcile the
> fact
> > that:
> >
> > my Logical $l;
> >
> > if (!$l) { print "No"; }
> > unless ($l) { print "No"; }
> >
> > may do surprising things.
>
> That didn't surprise me (and yes, I did get it right before I read
> your explanation to Paul later in this thread).

I expect that anyone who went through the "default value for arrays"
thread would get this automatically.

> If you have chosen
> to declare something as a C<Bool> or whatever then you having
> knowingly created a variable which can have three different values.
> A single test only makes one distinction therefore two of the three
> values are going to be treated in the same way as each other.

That's a really good explanation, if it becomes true. I hope Mike &
company use it.

> If somebody does C<if !$l> without first testing for C<defined $l>
> then they have chosen only to be interested in the truth value and to
> treat false and C<undef> equivalently.

Yep.

> > Just about. What I'm saying is that if there is a Logic type, there
> > will be literal values for that type.
>
> Yes -- if there is a type then there are values of that type and its
> silly to pretend that there aren't and claim that there isn't a way
> of writing them.

Thank you.


Austin Hastings

unread,
May 6, 2003, 11:55:57 AM5/6/03
to Smylers, perl6-l...@perl.org

--- Austin Hastings <austin_...@yahoo.com> wrote:
> > > > -- a simple C<==> test seems to do anything that either of your
> > > > versions will do so long as C<bool> coerces to a number, so far
> > > > as I can tell?
> >
> > Yes, but it's hardly natural to have to test for equality by doing
> > not-xor.
>
> Why is that?
>
> I mean, if you had to perform this very same operation in Perl5, how
> would you do it?
>
> You certainly couldn't use ==, since that's a numeric conversion and
> (unless you've already defined canonical true/false for your vars)
> there's no single true value.
>
> So you'd wind up saying ($x && $y) || (!$x && !$y), which if you had
> the ^^ operator and a set of logic tables available, you'd realize
> translates directly to !($x ^^ $y).

It occurs to me, in spiteful pique, that I can blow Paul's head off one
more time by pointing out that

$x <=> $y

should be non-zero when the two values are identical.

=Austin

(That would be "implies and is implied by", not the tripartite
difference operator.)

Michael Lazzaro

unread,
May 6, 2003, 1:48:36 PM5/6/03
to perl6-l...@perl.org
About C<bool>:

The assumption behind the C<bool> type -- at least, if it's what I
understand it to be -- is that it is a type representing the results of
a boolean operation, typically a comparision. To wit:

($i > 5)

returns a value of type C<bool>, containing some internal
representation of true or false. So you can say:

my bool $c = ($i > 5);
if $c {...}

and it will be the same thing as saying:

if ($a > 5) {...}

Given that, the C<bool> type really is a Boolean type, and not a more
generic logic type. Not to say that we couldn't use generic or
Luckowackyann logic types, but all the Perl conditionals like C<if>
operate in a two-state, true/false system. So in accordance with P5
(and basic comprehension issues), 'undef' and 'false' are the same
thing.

Likewise, because C<bool> is used -only- as a boolean, it can be
represented 'numerically' as 1/0, and 'stringically' as '1'/'0', and
while it _will_ have internal representations of true/false, in the
same way any value will, it is fair to say that the parser does not
need keywords representing those values, because they can be inferred
from numeric 1/0:

my bool $c = 1;

In fact, I'd rather say C<bool $c = 1> than C<bool $c = TRUE>,
personally.

I am not sure what the use of a promoted C<Bool> type would be, other
than a container for properties; but certainly if you can say:

my Bool $c = 0 but true;

it should set the value to true (if it doesn't give an error), and
should be result in _exactly_ the same C<$c> as if you said:

my Bool $c = 1 but true;

e.g. unlike all other builtin types, a C<bool> or C<Bool> should not
store any value other than it's own trueness.

It is possible, I suppose, that Bool could implement tristate
true/false/undef logic, but I cannot imagine that working well in
conjunction with the primitive C<bool>.

Now, as far as N-state logic, it would be neat to have modules that
implemented such behavior. They could even interact with Perl
internals like C<if>:

use Tristate;
my Tristate $c = undef;

if $c {...}

because if C<if> is a multimethod, your module could extend C<if> to
know how to deal with Tristates. Same with the comparision operators,
assuming multimethods can dispatch based on return type.

So I think we really can have an assortment of logic types... but I
think it would be a mistake to incorporate _any_ of those logic types,
other than the standard boolean true/false, as the default Perl
behavior for conditionals.

(Also, in passing, note that the default storage for C<bool>, and even
C<bit>, will _not_ be a single bit, in all likelihood. For speed, a
C<bool> would probably be stored as a native-sized int, as would,
ironically, a C<bit>... it would only be when using them in an C<Array>
or struct-like thingy that the storage would be compressed.)

The only difference I can surmise between a C<Bit> and a C<Bool> is
that it would presumably be possible to meaningfully say C<my Bit = 0
but true>, but not C<my Bool = 0 but true>. I think the distinction is
an important one, however. The context for

($i > 5)

should return C<bool>, not C<bit>, and you should certainly say

my bool $c = ($i > 5);

instead of

my bit $c = ($i > 5);

for sheer the sake of clarity, if nothing else.


FWIW, I envision the moderately-surprising behaviors of C<Bool> to be:

my Bool $bool;

$bool = 1; # TRUE
$bool = '1'; # TRUE
$bool = 'foo'; # TRUE

$bool = 0; # FALSE
$bool = '0'; # FALSE
$bool = ''; # FALSE
$bool = undef; # FALSE

$bool = 1 but false; # FALSE
my int $i = $bool; # 0 (a bool is only true/valse, not a
value!)

$bool = 0 but true; # TRUE
my int $i = $bool; # 1

$bool = 1 but false;
if $bool { die }; # false; doesn't die

$bool = 0 but true;
if $bool { die }; # true; dies


Whereas the moderately-surprising C<Bit> can store 1/0 _and_
truth/falseness:

my Bit $bit;

$bit = 1; # 1
$bit = '1'; # 1
$bit = 'foo'; # 1

$bit = 0; # 0
$bit = '0'; # 0
$bit = ''; # 0
$bit = undef; # undef (or 0, for primitive C<bit>)

$bit = 1 but false; # 1
my int $i = $bit; # 1 (a bit is a value, not true/false)

$bit = 0 but true; # 0
my int $i = $bit; # 0

$bit = 1 but false;
if $bit { die }; # false; doesn't die

$bit = 0 but true;
if $bit { die }; # true; dies


MikeL

Dulcimer

unread,
May 6, 2003, 8:02:29 PM5/6/03
to Smylers, perl6-l...@perl.org
> > > Paul, Austin: I hope you don't mind me combining your messages,
> > > since you've been making similar points.
> >
> > I think it's a good idea. I hope Piers agrees. :)
>
> And I hope he doesn't mind you changing your name halfway through a
> thread ...

That's an issue? Hey, it's easy to change it back....

> > Careful! C<bit> isn't a numeric type, it's a C<bit> type.
>
> Isn't it? I'd assumed that a bit was like an integer only much
> smaller, and that it's valid to do arithmetic on things of type
> C<bit>.

<nodnodnod> 0 and 1 ARE numbers....



> > > The problems are where a C<bool> is used in a numeric context.
> >
> > "Then don't do that."
>
> I expect I wouldn't, but people are going to try it and it needs to
> do something sane.

Depends on whether there is actually a declarable boolean type.
It's been said in many posts that bool isn't a type, it's a context.


I could live with that.

> > Do it this way: show me an example where you would want a bool


> > value, then use it in a numeric (bit) context.
>
> I can't think of one. Does it matter? I've provided examples where
> people might think they want to use a C<bool> in a generic numeric
> context.

my @Res_Bus_Accts;
my bool $is_bus;
for (@someData) {
$is_bus = see_if_bus_acct();
calc_bus_stuff() if $is_bus; # 1
@Res_Bus_Accts[$is_bus]++; # 2
}

I'd rather just use a bit or a common scalar in a boolean context at 1,
and as an index at 2, so this isn't exactly a pressing argument. It is,
however, a definite possibility that needs to be considered.

> > > > my bool $true = 1; # Convert from 1 (num) to TRUE (boolean)
> > > > But now you have to wonder about "default" context -- if I say
> > > > if ($x == $true)
> > > > Does it convert $x to boolean, or $true to num?
> > >
> > > The C<==> provides numeric context, so C<$true> gets treated
> > > as a number. So that test only succeeds if C<$x> contains
> > > _the_ canonical 'true' value, not merely a value that'd be
> > > true in boolean context.
> >
> > You can't jump that far. The only test that succeeds is if $x
> > contains a value that evaluates in a numeric context to the same
> > value to which $true evaluates in a numeric context.
>
> Yup. But if I started by declaring C<$true> as a C<bool> and
> storing a true value in it then C<$x> is being compared with
> the numeric representation of the canonical true value.

Not if there isn't a canonical true value. That could lead to
headaches, but it still isn't required. A bool should *be* a state of
truth, when evaluated in a boolean context, but using it in a numeric
context is just a bad idea. Have the compiler squawk if any sort of
warnings are appropriate stricture is engaged, otherwise assume the
person knew what they were doing and let them shoot themselves in the
foot.

> > Your example converts both to numerics, then compares the result.
>
> Exactly, which is why I'm bothered about how these conversions go.
>
> > So your concern is the difference between bit and Bit, maybe?
>
> Oh, no -- I've been sufficiently occupied puzzling over how C<bool>
> can work sensibly that I haven't even consider C<Bit> and C<Bool>
yet.

It can only work sensibly when used sensibly.
Don't declare a type unless you mean for it to be that type.
Don't use a bool for anything other than a bool.

You wouldn't declare a pointer to a character in C to store a general
integer value (I hope). It's the same thing.

> > > So if two objects each override C<.true> separately they could
> > > each return values which in a boolean context are true but which
> > > are different from each other?
> >
> > Very much so. You could make true return an incrementing count,
> > or the Gettysburg Address. I wouldn't do so unless there was a
> > compelling reason, but sometimes there is.
> >
> > Maybe you want your object to return a full-blown array when true,
> > which contains a list of the reasons it *is* true. That would be
> > ok.
>
> So why bother writing a function which claims to return a boolean but
> then overloads it with a string, integer, or array? At the moment
> people simply write functions that return strings, integers, or
> arrays.

As I said, I think it's a bad idea. Don't do it unless you mean to do
exactly that. I don't think people will, in general, but if they need
to, they can.

There's also the possibility that a smart fellow could write .true to
look at it's context and behave appropriately. In a boolean context, it
should return the simplest and most sane response, probably a constant,
or maybe a bit. For any othercircumstance, you're taking your sanity
into your own hands to muck around with it, but that's what Perl's all
about. "Don't do that (unless you meant to)."

> Users of those functions can test the return values in boolean
> contexts, taking advantage of the fact that empty strings, zero,
> and empty arrays evaluate to false.
>
> But because the return values don't claim to be booleans nobody
> would try to compare them as booleans. Returning a string from
> one function and a count from another but claiming that they are
> both booleans just sounds daft to me.

Agreed. Don't claim they are bools if they aren't.
They don't have to be. Testing a scalar in boolean context works fine,
and I suspect a scalar literal 1 will be a very common default for
truth. One shouldn't assume a type just because of a context.

> > Hmm... I think I see a problem here, too.
>
> I wasn't trying to identify a problem here -- I was just wondering
> what your and Austin's more complicated ways of comparing two
> C<bool>s had over the simple way. I'm still wondering.

One of mine had a mistake. :)

> > So, there's another lesson to be learned: while you *CAN* override
> > .true to return some nonstandard value, "Don't do that" unless you
> > have a *compelling* reason!
>
> Can you give an example of a compelling reason?

Nope! And that's my point. Don't do it.
But somebody somewhere might. I hope they're very careful.
And I hope I don't have to use that module.

> > > Are you suggesting that in numeric context a C<bool> that
> > > currently evaluates to true should randomly coerce to any
> > > non-zero number?
> >
> > lol -- no, no. I'm only saying that you can't make the assumption
> > that every true is a 1.
>
> Which is why comparing them using a numeric comparison operator
> causes problems.

Exactly.

> > > (Austin, I take it that you aren't actually suggesting that all
> > > comparisons between things of different types would yield
> > > warnings -- there wouldn't seem to be much point in a warning
> > > when comparing an integer with a float, for example.)
> >
> > As a point of order, I'd usually agree, but there might be times
> > when you'd *want* it to scream. 1.99999999999 isn't 2, after
all....
>
> Yes; I hadn't thought of that. I suppose it depends on the type of
> comparison -- checking that a float is less than an integer strikes
> me as something that should always be allowed even if testing for
> equality isn't.

I don't see an immediate propblem with that, though I'd hope to
abstract the problem out to a more generic solution than a casefor
every circumstance. (And I'm waiting for someone to point out the
problem I don't see with that.)

> > Also, this is the sort of thing we need to be teaching them
> > NOT to do.
>
> Yes. (And my preferred way of teaching them not to do this in Perl
> 5 is by being able to state categorically that there isn't a boolean
> type, and there isn't a canonical true value.)

Gets a little more complicated when only one of those statements is
correct, lol....

> But even so it needs to do something reasonable for those that are
> on the learning curve.

<nodnodnod>

> Personally I like having a simple rule that C<==> always does
> numeric comparison.

At face value, so do I. There might be exceptions, but I want to know
what they are.

> What do you mean by "boolean contexts" (and indeed "magic") here?

Bools are Yes-or-No situations. C<if $x> doesn't care what the actual
value of $x is, just whether or not the veracity rules make that
statement a Yes or a No; is it true or false; does it describe a
matching condition or not. For a simple case like this one, it gets
tricky, lol.... You have to define more sophisticated veracity rules
than 1 and 0. Maybe the context creates a temporary boolean object than
could only accept 1 or 0, and assigns to it using complex internal
conversion/coercion rules, and then evaluates that object, but I hope
not. I still prefr a list of falses, and everything else is true, like
P5.

> You can't mean that C<==> should booleanize its arguments simply
> because the C<if> is providing a boolean context -- that would make
> C<if 2 == 3> evaluate to true.

lol -- I could, but you're right, I don't. :)
I look at that as several layers of context. C<if> puts the return from
the == in boolean context, though it always returns a boolean value
anyway -- either it's operands are numerically the same, or they
aren't. the == puts its operands into numeric context, completely aside
from the greater context of the if; 2 and 3 aren't being evaluated by
the if. The == is. 2 and 3 are only being evaluated by the ==.

> So what would denote the boolean context for these purposes -- one of
> the operands being a C<bool>? It sounds like a slippery slope to me.

No, boolean context means the expression is expected to return a true
or a false. The == above is in boolean context -- B<but the numbers are
*not*>. :) The if doesn't care what you're comparing. It only looks at
the result of the comparison. The == wants to know the exact value of
each operands, and decides for itself what boolean state to return to
the if. That's why we *have* a == operator.



> > > But why does having a boolean context require also having a
> > > boolean type? Perl 5 manages to have the former without the
> > > latter.
> >
> > Dunno. I was =>ass<=uming it was because the context system
> > implicitly used the type system in some sort of casting mechanism.
>
> I can't immediately see why internals like that should require an
> effect on the visible language.

My thought is that they won't. @LarryNco will figure out some
reasonable middle ground, and the users will say "oh, do it *this*
way..."

> > If that's not the case, I'd say I'd have to agree with you.
> > If someone wants a bool type, they could add that bit of
> > syntactic sugar with macro that changes bool to bit for the
> > parser.
>
> It was my being unconvinced as to the need for a boolean type
> which prompted this thread. After so many posts of me merely
> having thoughts you'd had a week previously I'm glad you've
> finally come round to my view!

lol -- have I?
I think I'm too ambivalent to agree completely.
But maybe not. ;o]

Paul

Dulcimer

unread,
May 6, 2003, 8:31:27 PM5/6/03
to Austin_...@yahoo.com, Smylers, perl6-l...@perl.org
> > But what is the right thing? Is it "right" for C<==> not always to
> > compare numerically? If C<==> is going to be able to cope with
> > numbers and booleans (and presumably strings and booleans) being
> > mixed then people are much more likely to expect it to compare
> > strings -- and you can't respond by saying that C<==> is just for
> > numeric comparisons.
>
> Why not? If C<==> is the numifying comparator, as it traditionally
> has been, then it should numify and compare. In which case, as
> someone has pointed out, there are several possibilities:
>
> 1- Convert "true" -> 1, and "false" -> 0.
> 2- Convert "true" -> none(0), and "false" -> 0.

Or maybe "true" -> none(%false), and "false" -> any(%false)

> If, on the other hand, == is more dwimish, then we need to decide
> which takes precedence: num->logic or logic->num. That is, if I say
> C<$i == $p>, does the Int get easily converted to yorn, or does the
> predicate get converted to Int?

I'd still like to hold to the premise that we don't need/want/have a
boolean *Type*. Even if you have some convoluted mess like
C<if(($a==$b)== $c)>, the return from will be *a* true or *a* false,
and the most likely cases are 1 and 0. In a boolean context, 1 or 0
make fine sense, but here they're being compared numerically against
another value...but hey! 1 and 0 make fine sense as numbers, too!

So what if it were C<if(($a eq $b)== $c)>?
Let's assume
my $a = "foo";
my $b = "bar";
my $c = 0;

If you're using appropriate warnings and/or strictures, I bet you'll
get a message about using strings in a numeric context. If P6 does what
P5 did, $a eq $b should return '', which isn't a number.

If it can coerce, '' will become 0, and since $c is zero, the
expression will evaluate to true. Complex and possibly painful, but
flexible and Perl-ish. What's wrong with that?

It still doesn't need a boolean type.

> > > Second, the && ^^ || operators are the natural operators for
> > > boolean values.
> >
> > Yes, but it's hardly natural to have to test for equality by doing
> > not-xor.
>
> Why is that?
>
> I mean, if you had to perform this very same operation in Perl5, how
> would you do it?
>
> You certainly couldn't use ==, since that's a numeric conversion and
> (unless you've already defined canonical true/false for your vars)
> there's no single true value.
>
> So you'd wind up saying ($x && $y) || (!$x && !$y), which if you had
> the ^^ operator and a set of logic tables available, you'd realize
> translates directly to !($x ^^ $y).

While true, and a lovely example of the sort of abstraction programmers
are paid for, it would be nice to have a simpler operation...so we
macro that into some new toy such as a é operator, lol....



> > > C<infix:?==> ?
> > I could live with that.
>
> OTOH, if we have a boolean type, and the boolean type has canonical
> true/false/etc values, then there's no reason not to have ==
> overloaded to do that -- but it depends on defining the type.
> Otherwise we're back at "any num (but one) could be true" and the
> situation above.

I'd rather have ?== (or é :)
On the gripping hand, "keep the ramp low".
Tell people "these things are false. Anything else is true."
That's not too complex, and still flexible as all hell.



> > > > That's fine for assignment regardless of which value they pick
> > > > for true, but there are serious problems if those user-defined
> > > > true and false constants start being used in tests.
> > > >
> > > > Having a C<bool> type in Perl enforces the fallacy that there
> > > > is a single 'true' value that can be used in such comparisons.
> > >
> > > Except that if we have a special type, we can make it not be a
> > > fallacy.
> >
> > If we have a boolean comparison operator then I don't think a
> > canonical true value is needed (though I suppose it may be for
> > Luke's 'generic comparison').
>
> Depends on what you're looking for. If you have a boolean comparison
> operator, you can implement boolean ops using Scalar type, provided
> you always keep in the back of your mind that this isn't really
> boolean, and remember to override and extend and insert boolean
> context sigils in the right places.

Which gives control back to the programmer, maintains maximum
flexibility, and keeps the ramp low. And since we've already
established not-xor as a good boolean equality, especially if macro'd
to something pretty, I think maybe we've killed the problem, lol....

So, does anybody have the latest word on whether there really is a
boolean type?

> > > My point is that if we're going to do a logic type, we should
> > > do a logic type. I'd much rather see a Lukasiewiczian
(Lukasonian)
> > > than a Boolean type.
> >
> > I'm not entirely convinced about that, but I'd feel happier about
> > having something that definitely is distinct from boolean and so
> > not as confusable with it.
>
> Death to Boole!

I can live with that. >:op

> (And no, I don't want to call it 'Ada'. On the other hand, since Paul
> seems bewildered by the notion of a logical type where the !true
> doesn't mean false, and yes can sometimes mean no, perhaps we could
> call it 'Ladylike'. :-) :-) :-)

LOL!!! If that were the case, then !false would not necessarily mean
true, and no would sometimes also mean yes, but if you ever mistakenly
assume you have a case where one means the other your compiler would
carp at you tesily and then refuse to respond for a few days. :)

Dulcimer

unread,
May 6, 2003, 8:37:27 PM5/6/03
to Smylers, perl6-l...@perl.org
> > Just about. What I'm saying is that if there is a Logic type, there
> > will be literal values for that type.
>
> Yes -- if there is a type then there are values of that type and its
> silly to pretend that there aren't and claim that there isn't a way
> of writing them.

Agreed -- but for a type to have acceptable values does not inherently
mean that you can infer which value something has because of it's type;
you can only inferwhat set of values are allowed. My (perhaps flawed)
understanding of boolean is that the value is either true or false.
P5's interpretation of that is that "these shall be false" and all
others true. Thus, if you know a P5 $x is boolean true, or even false,
you still don't know which value it might have in some other context.

If $x is false, it could be undef, or '', or 0, or "0".....
If it's true, it can't be those, but might be NULL.....

either way, you know it's true, or it's false. That doesn't mean you
can say "it's a 1".

Why can't P6 be the same?

Dulcimer

unread,
May 6, 2003, 8:41:11 PM5/6/03
to Austin_...@yahoo.com, Smylers, perl6-l...@perl.org
> It occurs to me, in spiteful pique, that I can blow Paul's head off
> one more time by pointing out that
>
> $x <=> $y
>
> should be non-zero when the two values are identical.
>
> (That would be "implies and is implied by", not the tripartite
> difference operator.)

lol....er?

If it isn't the numeric equivelent of cmp, then I am ignorant.
Why would it be nonzero?

Hey, I'm always up for an education, even at the cost of a little
scalp. ;o]

Michael Lazzaro

unread,
May 7, 2003, 1:40:44 PM5/7/03
to Hod...@writeme.com, Austin_...@yahoo.com, Smylers, perl6-l...@perl.org

On Tuesday, May 6, 2003, at 05:31 PM, Dulcimer wrote:
> I'd still like to hold to the premise that we don't need/want/have a
> boolean *Type*. Even if you have some convoluted mess like
> C<if(($a==$b)== $c)>, the return from will be *a* true or *a* false,
> and the most likely cases are 1 and 0. In a boolean context, 1 or 0

Plz see my last (...long...) message re: this subject... the reason for
a boolean type would be that, indeed, we specifically have a boolean
context, but no way to express that context.

An expression like

(2 < 3) # what 'type' does this op return?

clearly _has_ a return type -- so what is it? The result of that
operation is _not_ a string, or an integer, or a float. It's truth or
falseness. So unless we have a bool type, we cannot accurately express
what type the expression C<(2 < 3)> returns. Personally, it seems a
bigger hack to state that the result of a boolean test is an integer
than to say the result of a boolean test is, in fact, a boolean.

multi *infix:< ($a, $b) returns bool {...}
multi *infix:> ($a, $b) returns bool {...}
multi *infix:== ($a, $b) returns bool {...}
...etc...

I must admit I still don't see the problem presented by:

my bool $true = (2 < 3);
if (7 == $true) {...}

I agree that a programming newbie -- someone with no prior history in C
or C-like languages whatsoever -- _could_ write that... but in our
C-like language, they'd be wrong, and for consistent and clearly
definable reasons. In P6, C<==> compares two values numerically. The
conditional will be false, because the numeric value of 7 is not equal
to the numeric value of boolean truth, which is C<1>.

It is true, I can go either way on whether or not there should be TRUE
and FALSE keywords in the language. We certainly don't _need_ them,
but if we don't have them, people will probably immediately make them.

But especially if C<Bool> really acts like I posited in my last message
-- e.g., it is _not_ simply a synonym of C<Bit>, but an
otherwise-valueless container storing truth or falseness, I very much
like the idea of having it around.

MikeL

0 new messages