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

Type Conversion Matrix, Pragmas (TAKE 4)

17 views
Skip to first unread message

Michael Lazzaro

unread,
Jun 10, 2003, 3:04:14 PM6/10/03
to perl6-l...@perl.org

Seeing as how lots of folks are on the road, and you can hear the
on-list crickets chirping, I'm not sure if anything can be
accomplished, but I'll repost this as one of those perennial
things-which-really-need-to-be-decided-because-lots-of-stuff-is-
dependant-on-it-in-terms-of-basic-A2-examples-and-best-practices.

Namely, how the most basic Perl6 types interact with each other, and
what types can and can't be converted automatically, and the whole
philosophy behind this: is it supposed to be silent, and DWIMmy? Is it
supposed to be pedantic enough to prohibit "lossy" conversions? Is
there more than one level of strictness? Who controls it -- the
caller, or the callee?


(i) ---- Type Matrix ----

The following matrix depicts the basic P6 scalar types, and the "kinds"
of conversions that may/must take place between them. Key is as
follows:

+: Automatic conversion, conversion is not lossy
*: undefness and properties will be lost
N: numeric range or precision may be lost (esp. bigints, bignums)
F: numeric (float) conversion -- conversion to int is lossy
S: string conversion -- if string is not *entirely* numeric, is lossy
B: boolean conversion -- loses all but true/false
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 B *B B *B B *B - * + * *J
Bit B B B B B B + - + + J
bool B *B B *B B *B + * - * *J
Bool B B B B B B + + + - J
Scalar + + + + + + + + + + -


(ii) ---- Initial Assumptions ----

I previously proposed simplifying the matrix using the following Big
Assumptions. This was not universally agreed upon, however: it may be
that these assumptions are controlled by pragma (see next section). I
include them here separately for reference.

*: (undefness and properties lost)

Using/converting an uppercase type as/to a lowercase (primitive)
type is silently allowed. If you're sending an Int to something that
requires an C<int>, you know that the 'something' can't deal with the
undef case anyway -- it doesn't differentiate between undef and zero.
Thus, you meant to do that: it's an "intentionally destructive"
narrowing, and the C<undef> becomes a C<0>.

my Int $a = undef;
my int $b = $a; # $b is now C<0>, NOT C<undef>


B: (conversion to boolean)

Converting to/from a bit or bool value is silently allowed. The
Perl5 rules for "truth" are preserved, such that:

my bool $b = undef; # $b is C<0>
my bool $b = 0; # $b is C<0>
my bool $b = 1; # $b is C<1>
my bool $b = -5; # $b is C<1>
my bool $b = 'foo'; # $b is C<1>

Converting a C<bit> or C<bool> to any other type always results in C<0>
or C<1> for numeric conversions, or C<'0'> or C<'1'> for string
conversions.


J: (scalar junctive to typed scalar)

A scalar junctive, e.g. an "untyped" scalar, can always be silently
used as and/or converted to a more specific primitive type. This will
quite frequently result in the loss of information; for example, saying:

my $a = 'foo';
my int $b = $a; # $b is now C<0>

works, but silently sets $b to 0, because the numeric value of C<'foo'>
is C<0 but true>.

This means that using untyped scalars gets you back to Perl5 behavior
of 'silently' accepting pretty much any conversion you can think of.

my str $a = 'foo';
my $b = $a;
my int $c = $a; # COMPILE TIME ERROR
my int $c = $b; # OK

If you are using typed variables to enforce strict conversions, you
probably want to be warned if you are using any untyped variables,
anywhere. Something like:

use strict types;


(iii) ---- Simplified Matrix ----

The above assumptions result in a simplified conversion matrix, as
follows:

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

Leaving three "tricky" types of conversions to be dealt with.


(iv) ---- Pragma-Controlled Conversions ----

Given the above, and given the fact that our general answer to
everything is to Use A Pragma ;-), we have the following tentative list
of needed pragmas. For each possibility, we need to be able to declare
that a given implicit type conversion will be silently allowed, will
result in a warning, or will result in an exception.

A (very) rough proposed pragma form, for the sake of argument, is:

use strict conversions; # all on (exceptions)
no strict conversions; # all off

use strict conversions allow => << cv1 cv2 ... >>; # selected
conversions are allowed
use strict conversions warn => << cv1 cv2 ... >>; # selected
conversions give warnings
use strict conversions fail => << cv1 cv2 ... >>; # selected
conversions give exceptions


S: (string to numeric)

Any given string may not be entirely numeric. In P5, a string like
'1234foo' numifies to 1234, but you don't always want that ...
sometimes, you want to throw an error if the string isn't 'cleanly' a
number. Proposed pragma variants (exact P6 pragma syntax unknown):

use strict conversions allow => << str_to_num >>; # which is the
default?
use strict conversions warn => << str_to_num >>;
use strict conversions fail => << str_to_num >>;

F: (float to int)

Historically, accidentally using a float as an int can be a
significant source of errors. Proposed pragma variants:

use strict conversions allow => << num_to_int >>; # which is the
default?
use strict conversions warn => << num_to_int >>;
use strict conversions fail => << num_to_int >>;

N: (numeric range)

This one is a giant pain. Converting, say, an Int to an int will,
in fact, fail to do the right thing if you're in BigInt territory, such
that the number would have to be truncated to fit in a standard <int>.
But 99% of the time, you won't be working with numbers like that, so it
would seem a horrible thing to disallow Int --> int and Num --> num
conversions under the remote chance you *might* be hitting the range
boundary. Then again, it would seem a horrible thing to hit the range
boundary and not be informed of that fact. Thus, deciding the default
state here will be a challenge:

use strict conversions allow => << Int_to_int >>; # which is the
default?
use strict conversions warn => << Int_to_int >>;
use strict conversions fail => << Int_to_int >>;

use strict conversions allow => << Num_to_num >>; # which is the
default?
use strict conversions warn => << Num_to_num >>;
use strict conversions fail => << Num_to_num >>;


(v) ---- Alternative Pragma Form ----

An alternative pragma form could possibly allow finer control over
every individual possible conversion. The disadvantage of this form is
that it would be very difficult to "correctly" set each of the >100
cells of the matrix, or even the 14 "critical" cells that most often
change:

use strict conversions allow {
str => int,
str => Int,
str => num,
str => Num,
Str => int,
Str => Int,
Str => num,
Str => Num,
Int => int,
num => int,
num => Int,
Num => int,
Num => Int,
Num => num,
};


(vi) ---- Conversions of User Defined Types/Classes ----

It may be useful to allow the same level of pragma-based control for
user-defined types and classes. For example, a given class Foo may
wish to be "silently" convertable to an C<int>. One proposed syntax to
declare the method of coercion/conversion might be:

class Foo {
...

to int {...} # or C<as int {...}>?
}

However, users of such a class could adjust the warning level of the
given conversion using the alternate syntax given above (v):

use strict conversions warn { Foo => int };

----

Comments?

MikeL

Tim Bunce

unread,
Jun 11, 2003, 8:48:12 AM6/11/03
to Michael Lazzaro, perl6-l...@perl.org
On Tue, Jun 10, 2003 at 12:04:14PM -0700, Michael Lazzaro wrote:
>
> *: (undefness and properties lost)
>
> Using/converting an uppercase type as/to a lowercase (primitive)
> type is silently allowed. If you're sending an Int to something that
> requires an C<int>, you know that the 'something' can't deal with the
> undef case anyway -- it doesn't differentiate between undef and zero.
> Thus, you meant to do that: it's an "intentionally destructive"
> narrowing, and the C<undef> becomes a C<0>.
>
> my Int $a = undef;
> my int $b = $a; # $b is now C<0>, NOT C<undef>

I'm not sure what "silently allowed" means here (compile time perhaps?)
but I'd certainly want that to generate the traditional "Use of undefined
value" warning (controlable via the perl6 equiv of the warnings pragma,
but defaulting to enabled).


> F: (float to int)
>
> Historically, accidentally using a float as an int can be a
> significant source of errors. Proposed pragma variants:
>
> use strict conversions allow => << num_to_int >>; # which is the default?
> use strict conversions warn => << num_to_int >>;
> use strict conversions fail => << num_to_int >>;

I don't see a problem with compile time warnings by default *if*
there's an easy way for the developers to express the fact that
they know what they're doing (easier, that is, than wrapping the
assignment in a { use strict conversions allow ... } block).
Something like a cast function would fit: $int = int($num);


> N: (numeric range)
>
> This one is a giant pain. Converting, say, an Int to an int will,
> in fact, fail to do the right thing if you're in BigInt territory, such
> that the number would have to be truncated to fit in a standard <int>.
> But 99% of the time, you won't be working with numbers like that, so it
> would seem a horrible thing to disallow Int --> int and Num --> num
> conversions under the remote chance you *might* be hitting the range
> boundary. Then again, it would seem a horrible thing to hit the range
> boundary and not be informed of that fact. Thus, deciding the default
> state here will be a challenge:
>
> use strict conversions allow => << Int_to_int >>; # which is the default?
> use strict conversions warn => << Int_to_int >>;
> use strict conversions fail => << Int_to_int >>;
>
> use strict conversions allow => << Num_to_num >>; # which is the default?
> use strict conversions warn => << Num_to_num >>;
> use strict conversions fail => << Num_to_num >>;

Same as above. I could live with a compile time warning if it's
trivial to silence it for a particular assignment.

But I'd also like separate control over the detection and behaviour
of underflow / overflow / loss of precision etc at runtime.
So if I assign an int a value that's too big (from a Int, or Num,
or untyped scalar), I would like to know about it. Similarly for num.


> (v) ---- Alternative Pragma Form ----
>
> An alternative pragma form could possibly allow finer control over
> every individual possible conversion. The disadvantage of this form is
> that it would be very difficult to "correctly" set each of the >100
> cells of the matrix, or even the 14 "critical" cells that most often
> change:

Perhaps it would be better to think in terms of "styles of coding"
or "policies", and aim to meet those needs with simple pragmas
(implemented on top of a more general mechanism).

Basically, do both. The simple forms could just be an interface to
the more general.


> (vi) ---- Conversions of User Defined Types/Classes ----
>
> It may be useful to allow the same level of pragma-based control for
> user-defined types and classes. For example, a given class Foo may
> wish to be "silently" convertable to an C<int>. One proposed syntax to
> declare the method of coercion/conversion might be:
>
> class Foo {
> ...
>
> to int {...} # or C<as int {...}>?
> }
>
> However, users of such a class could adjust the warning level of the
> given conversion using the alternate syntax given above (v):
>
> use strict conversions warn { Foo => int };

For
my int $int = $foo;

isn't the int() method (vtable entry) called on $foo? (effectively)
So the $foo object is asked to provide an int for assigment to $int.
So the Foo class gets to decide how to do that.

In which case what you're proposing requires either
- the compiler to write the code to pass extra flags to the int method
- the compiler to write call a different int method (eg, int_warn())
- for the int method to look at the calling context to get flags

Please correct me if I'm wrong (which I could easily be as I've not
been following any of thise closely).

I think this is an important topic because it may reflect back on
how the specific Int/Num/Str classes should also be handled.

Tim [quite possibly talking nonsense]

Michael Lazzaro

unread,
Jun 11, 2003, 2:00:40 PM6/11/03
to Tim Bunce, perl6-l...@perl.org

On Wednesday, June 11, 2003, at 05:48 AM, Tim Bunce wrote:
>> (vi) ---- Conversions of User Defined Types/Classes ----
>>
>> It may be useful to allow the same level of pragma-based control for
>> user-defined types and classes. For example, a given class Foo may
>> wish to be "silently" convertable to an C<int>. One proposed syntax
>> to
>> declare the method of coercion/conversion might be:
>>
>> class Foo {
>> ...
>>
>> to int {...} # or C<as int {...}>?
>> }
>>
>> However, users of such a class could adjust the warning level of the
>> given conversion using the alternate syntax given above (v):
>>
>> use strict conversions warn { Foo => int };
>
> For
> my int $int = $foo;
>
> isn't the int() method (vtable entry) called on $foo? (effectively)
> So the $foo object is asked to provide an int for assigment to $int.
> So the Foo class gets to decide how to do that.

Yep. The general question that has come up before is to what extent
the user of a given class or module should be able to influence the
"strictness" of the interface of that class/module -- without altering
the module, obviously. The general feeling was that people wanted to
be able to do it, because they didn't want to be bound to a particular
CP6AN author's decisions on interface strictness.

The specific issue discussed previously, IIR, was something like this:

class Foo {
method bar(str $s);
}

If you said:

my int $i = 5;
$foo->bar($i);

what should happen? Should bar() convert $i to a str, or give a
compiletime warning or error because it's not a str? And is that
determined by the strictness level of the Foo class, or the strictness
level of the calling code, or --shudder-- possibly both?


> Please correct me if I'm wrong (which I could easily be as I've not
> been following any of thise closely).
>
> I think this is an important topic because it may reflect back on
> how the specific Int/Num/Str classes should also be handled.
>
> Tim [quite possibly talking nonsense]

Talking perfect sense. It's a nasty issue.

MikeL

David Storrs

unread,
Jun 14, 2003, 1:26:24 AM6/14/03
to perl6-l...@perl.org
On Tue, Jun 10, 2003 at 12:04:14PM -0700, Michael Lazzaro wrote:

> J: (scalar junctive to typed scalar)
>
> A scalar junctive, e.g. an "untyped" scalar, can always be silently
> used as and/or converted to a more specific primitive type. This will
> quite frequently result in the loss of information; for example, saying:
>
> my $a = 'foo';
> my int $b = $a; # $b is now C<0>
>
> works, but silently sets $b to 0, because the numeric value of C<'foo'>
> is C<0 but true>.

On the subject of untyped scalars...what does it mean to say that the
conversion is 'lossless'? For example:

my $a = 'foo';
my Int $b = $a; # legal; $b is now 0; is there a warning?
my $c = $b; # is $c 0, or 'foo'?
my Str $d = $a; # no loss
my $a = $d; # no effective change in $a
my $e = $b; # what is $d?

In the above, I would expect that $c is 0 and

my $a = 7 but false;
my Str $b = $e; # ???

What value does $f end up with? (My vote would be '7'.)
Does it have any properties?
Are any warnings emitted?


>
> (iv) ---- Pragma-Controlled Conversions ----
>
> Given the above, and given the fact that our general answer to
> everything is to Use A Pragma ;-), we have the following tentative list
> of needed pragmas. For each possibility, we need to be able to declare
> that a given implicit type conversion will be silently allowed, will
> result in a warning, or will result in an exception.
>
> A (very) rough proposed pragma form, for the sake of argument, is:
>
> use strict conversions; # all on (exceptions)
> no strict conversions; # all off
>
> use strict conversions allow => << cv1 cv2 ... >>; # selected
> conversions are allowed
> use strict conversions warn => << cv1 cv2 ... >>; # selected
> conversions give warnings
> use strict conversions fail => << cv1 cv2 ... >>; # selected
> conversions give exceptions

Seems generally, but I'd like to see this be organized into
hierarchies, like Perl 5 (recent versions) warnings: the Numeric
group would control every form of numeric conversion, the
Truncation subgroup would control everything in the Numeric group
that could end up truncating data (e.g. int -> short), etc.

> S: (string to numeric)

My vote for default: C<allow>


> F: (float to int)

My vote for default: C<warn>


> N: (numeric range)

My vote for default: C<allow>

I also suggest adding an extra pragma:

use rangechecking warn => << Int_to_int >>;
use rangechecking warn => << Num_to_num >>;
use rangechecking fail => << Int_to_int >>;
use rangechecking fail => << Num_to_num >>;

This lets you trade speed for safety on a lexically-scoped basis.


> (vi) ---- Conversions of User Defined Types/Classes ----
>
> It may be useful to allow the same level of pragma-based control for
> user-defined types and classes. For example, a given class Foo may
> wish to be "silently" convertable to an C<int>. One proposed syntax to
> declare the method of coercion/conversion might be:
>
> class Foo {
> ...
>
> to int {...} # or C<as int {...}>?
> }
>
> However, users of such a class could adjust the warning level of the
> given conversion using the alternate syntax given above (v):
>
> use strict conversions warn { Foo => int };


Adding to the 'hierarchical pragmas' idea that I mentioned above...how
about a 'to_int' group, which controlled any type (user defined or
system) that was attempted to convert itself to an int? The
extensions are obvious.


--Dks

Michael Lazzaro

unread,
Jun 16, 2003, 1:15:57 PM6/16/03
to David Storrs, perl6-l...@perl.org

On Friday, June 13, 2003, at 10:26 PM, David Storrs wrote:
> On the subject of untyped scalars...what does it mean to say that the
> conversion is 'lossless'? For example:

I've been using the word to mean that a conversion is "lossless" if,
for a particular A-->B conversion, you can recreate the typed value A
*completely* from B, including value, definedness, and properties.

So if you can say A-->B-->A, and always get _exactly_ the same thing in
A that you started with, for _any_ valid starting value of A, it's
"lossless". Which is darn rare, looking at the matrix, because of
range issues, etc.

> my $a = 'foo';
> my Int $b = $a; # legal; $b is now 0; is there a warning?
> my $c = $b; # is $c 0, or 'foo'?

0, I think. Or specifically, C<Int 0>. (I've been operating under the
assumption that an "untyped scalar" doesn't _remove_ the type of
something, it just can store values of _any_ type, and is by default
much more generous about autoconverting them for you, so that you could
use $c as an Int, int, Num, num, Str, str, etc., without warning or
error... but internally, it's actually still storing the value as an
C<Int 0>, because that's what you assigned to it.)


> my Str $d = $a; # no loss
> my $a = $d; # no effective change in $a
> my $e = $b; # what is $d?

$d? Still a Str, I would think. And $e would be Int 0, same as $c

> In the above, I would expect that $c is 0 and
>
> my $a = 7 but false;
> my Str $b = $e; # ???
>
> What value does $f end up with? (My vote would be '7'.)

My understanding is that properties go with the values, (just like
traits go with the variables), so I would expect $f to be C<7 but
false>. So if a value is C<but false>, it stays C<but false> until you
say otherwise.

> Are any warnings emitted?

Yeah, I dunno. I think we need somebody smart to tell us at this
point. I have no idea how close or how far we are on our musings about
pragmas and defaults... I sure hope somebody does. :-)

MikeL

Austin Hastings

unread,
Jun 16, 2003, 2:47:35 PM6/16/03
to David Storrs, perl6-l...@perl.org

--- David Storrs <dst...@dstorrs.com> wrote:

> On Mon, Jun 16, 2003 at 10:15:57AM -0700, Michael Lazzaro wrote:
> >
> > On Friday, June 13, 2003, at 10:26 PM, David Storrs wrote:
> >
> > > my $a = 'foo';
> > > my Int $b = $a; # legal; $b is now 0; is there a warning?
> > > my $c = $b; # is $c 0, or 'foo'?
> >
> > 0, I think. Or specifically, C<Int 0>.
>
> So then conversion from Scalar to Int is not lossless, and
> (by extension) conversions from Scalar to any other LargeCapPrimitive
> are presumably not lossless either.

Not *guaranteed* lossless. Indeed, how could they be?

I suppose you could construct your scalar as:

my $a = "foo";
my Int $b = $a;

$b == 0 but Scalar("foo");

such that you may reconstruct the Scalarness. But that seems like
trouble waiting to happen -- propagating the value means that
eventually someone calls C<print $b3> and gets "foo" instead of "0".

Unless operator semantics strip extended-value-attributes, so that $b
== 0 but Scalar("foo") while C<$c = $b + 1> == 1 but Scalar("1");

Frankly, I prefer to regard Scalar->Int as a narrowing conversion and
accept the lossage.

>
> > (I've been operating under the
> > assumption that an "untyped scalar" doesn't _remove_ the type of
> > something, it just can store values of _any_ type, and is by
> default
> > much more generous about autoconverting them for you, so that you
> could
> > use $c as an Int, int, Num, num, Str, str, etc., without warning or
>
> > error... but internally, it's actually still storing the value as
> an
> > C<Int 0>, because that's what you assigned to it.)
>

> Seems reasonable.
>
> <pedantic> Although I would assume that it would store and pull the
> value from an Int slot, then create a new value of the "converted to"
> type, and use that. </pedantic>

This goes back to Damian's point some months ago that function call
arguments are pass-by-reference and the limitations that imposes on
automatic conversion/coercion.

In essence, because we say:

sub foo(Int $arg) {...}

foo($a);

The parameter to foo has to be type compatible with Int, or the
compiler will have to automatically instantiate a temp and convert in
one or more directions. Currently, I believe the pendulum has swung
towards "must be type compatible or you get an error."

> A better example of what I was driving at would be this:
>
> my $a = 'foo' but purple;


> my Int $b = $a;
>

> In other words: I've just created an untyped Scalar. This Scalar is
> (presumably in it's Str slot) storing a string value which happens
> to have a property set on it (i.e., C<foo but purple). Now I assign
> this Str to an Int. String values get converted when assigned to
> Ints. Are we converting and assigning THE IDENTICAL VALUE or are we
> creating a new value (whose value, in a numeric context, is
> considered equivalent) and assigning that? In the first case, I
> would expect that the property would be preserved. In the latter
> case, I would expect it NOT to be preserved.

My preference is:
$temp = "foo";
$temp.setProperty(purple);
$a = $temp;
$temp = Str_to_Int($a); # 0, no property.
$b = $temp;

Although it occurs to me that there might be such a thing as "Int
properties" and "Str properties", and maybe the conversion propagates
the appropriate ones.

That is:

my $a = "foo" but $purple ;
$a but= false;
$a but= prime;
$a but= charset("UTF8");
$a but= encoding("text/utf8");

my Int $b = $a;

At this point, $b would be C<0 but all(false, prime)>.

=Austin

David Storrs

unread,
Jun 16, 2003, 2:04:19 PM6/16/03
to perl6-l...@perl.org
On Mon, Jun 16, 2003 at 10:15:57AM -0700, Michael Lazzaro wrote:
>
> On Friday, June 13, 2003, at 10:26 PM, David Storrs wrote:
>
> > my $a = 'foo';
> > my Int $b = $a; # legal; $b is now 0; is there a warning?
> > my $c = $b; # is $c 0, or 'foo'?
>
> 0, I think. Or specifically, C<Int 0>.

So then conversion from Scalar to Int is not lossless, and


(by extension) conversions from Scalar to any other LargeCapPrimitive
are presumably not lossless either.

> (I've been operating under the

> assumption that an "untyped scalar" doesn't _remove_ the type of
> something, it just can store values of _any_ type, and is by default
> much more generous about autoconverting them for you, so that you could
> use $c as an Int, int, Num, num, Str, str, etc., without warning or
> error... but internally, it's actually still storing the value as an
> C<Int 0>, because that's what you assigned to it.)

Seems reasonable.

<pedantic> Although I would assume that it would store and pull the
value from an Int slot, then create a new value of the "converted to"
type, and use that. </pedantic>

> > my Str $d = $a; # no loss
> > my $a = $d; # no effective change in $a
> > my $e = $b; # what is $d?
>
> $d? Still a Str, I would think. And $e would be Int 0, same as $c

I obviously had either a typo or a braino on the last line there. I
have no idea what I was trying to ask.

> > What value does $f end up with? (My vote would be '7'.)
>
> My understanding is that properties go with the values, (just like
> traits go with the variables), so I would expect $f to be C<7 but
> false>. So if a value is C<but false>, it stays C<but false> until you
> say otherwise.

A better example of what I was driving at would be this:

my $a = 'foo' but purple;

my Int $b = $a;

In other words: I've just created an untyped Scalar. This Scalar is


(presumably in it's Str slot) storing a string value which happens
to have a property set on it (i.e., C<foo but purple). Now I assign
this Str to an Int. String values get converted when assigned to
Ints. Are we converting and assigning THE IDENTICAL VALUE or are we
creating a new value (whose value, in a numeric context, is considered
equivalent) and assigning that? In the first case, I would expect
that the property would be preserved. In the latter case, I would
expect it NOT to be preserved.


--Dks


OT afterthought: In the past, whenever we've gotten embroiled in one
of these thorny, knotty issues, @Larry has pulled a stunningly
beautiful, elegant rabbit out of their hats. And when I thought that,
I had this vision of a single quantum rabbit simultaneously coming out
of multiple hats with widely divergent spatial coordinates....

Michael Lazzaro

unread,
Jun 16, 2003, 3:00:21 PM6/16/03
to David Storrs, perl6-l...@perl.org

On Monday, June 16, 2003, at 11:04 AM, David Storrs wrote:
> On Mon, Jun 16, 2003 at 10:15:57AM -0700, Michael Lazzaro wrote:
>> (I've been operating under the
>> assumption that an "untyped scalar" doesn't _remove_ the type of
>> something, it just can store values of _any_ type, and is by default
>> much more generous about autoconverting them for you, so that you
>> could
>> use $c as an Int, int, Num, num, Str, str, etc., without warning or
>> error... but internally, it's actually still storing the value as an
>> C<Int 0>, because that's what you assigned to it.)
>
> Seems reasonable.
>
> <pedantic> Although I would assume that it would store and pull the
> value from an Int slot, then create a new value of the "converted to"
> type, and use that. </pedantic>

Yeah, I would think so.


> A better example of what I was driving at would be this:
>
> my $a = 'foo' but purple;
> my Int $b = $a;
>
> In other words: I've just created an untyped Scalar. This Scalar is
> (presumably in it's Str slot) storing a string value which happens
> to have a property set on it (i.e., C<foo but purple). Now I assign
> this Str to an Int. String values get converted when assigned to
> Ints. Are we converting and assigning THE IDENTICAL VALUE or are we
> creating a new value (whose value, in a numeric context, is considered
> equivalent) and assigning that? In the first case, I would expect
> that the property would be preserved. In the latter case, I would
> expect it NOT to be preserved.

I am almost positive that the assignment would perform a copy/clone of
the original value, but would preserve the properties while doing so.

So if we try to assign C<'foo' but purple> to the Int $b, it:
- clones a new Scalar C<'foo' but purple>, but...
- identifies the copied C<'foo' but purple> as being a Scalar, not an
Int, so...
- converts the copied C<Scalar 'foo' but purple> to an Int, resulting
in C<Int 0 but purple>
- assigns C<Int 0 but purple> to $b.

... or something like that. But I would expect that the property
_would_ be preserved... my gut feeling is that otherwise, they'd be
_way_ to easy to accidentally lose, yes?


> OT afterthought: In the past, whenever we've gotten embroiled in one
> of these thorny, knotty issues, @Larry has pulled a stunningly
> beautiful, elegant rabbit out of their hats. And when I thought that,
> I had this vision of a single quantum rabbit simultaneously coming out
> of multiple hats with widely divergent spatial coordinates....

Yeah. What I wouldn't give for a quantum bunny, right about now. It's
not even that type conversion is a particularly difficult issue, it's
just so *very* all-encompassing that it's got to be done precisely,
because it chains through everything else about the language... what
happens when calling subroutines, what happens in the multimethod
dispatcher, what simple lines of code do or don't give big honkin'
errors, etc...

MikeL

David Storrs

unread,
Jun 16, 2003, 4:35:24 PM6/16/03
to perl6-l...@perl.org
On Mon, Jun 16, 2003 at 11:47:35AM -0700, Austin Hastings wrote:
>
> Although it occurs to me that there might be such a thing as "Int
> properties" and "Str properties", and maybe the conversion propagates
> the appropriate ones.
>
> That is:
>
> my $a = "foo" but $purple ;
> $a but= false;
> $a but= prime;
> $a but= charset("UTF8");
> $a but= encoding("text/utf8");
>
> my Int $b = $a;
>
> At this point, $b would be C<0 but all(false, prime)>.
>
> =Austin


Yeek. That gives me the screaming willies. Let's either have it
preserve all the properties or none, but please don't make me remember
a big list of which properties exist for which types...and oh, btw,
did I happen to overload/modify that? Did any of the modules I'm
using? Where do user defined properties (if those still exist) fit
in?


--Dks

0 new messages