Re: Type Conversion Matrix, Pragmas (TAKE 4)

2003-06-16 Thread Michael Lazzaro
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, CInt 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 
CInt 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 C7 but 
false.  So if a value is Cbut false, it stays Cbut 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



Re: Type Conversion Matrix, Pragmas (TAKE 4)

2003-06-16 Thread David Storrs
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, CInt 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 
 CInt 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 C7 but 
 false.  So if a value is Cbut false, it stays Cbut 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., Cfoo 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


Re: Type Conversion Matrix, Pragmas (TAKE 4)

2003-06-16 Thread Austin Hastings

--- David Storrs [EMAIL PROTECTED] 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, CInt 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 Cprint $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 
  CInt 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., Cfoo 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 C0 but all(false, prime).

=Austin



Re: Type Conversion Matrix, Pragmas (TAKE 4)

2003-06-16 Thread Michael Lazzaro
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
CInt 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., Cfoo 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 CScalar 'foo' but purple to an Int, resulting 
in CInt 0 but purple
  - assigns CInt 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



Re: Type Conversion Matrix, Pragmas (TAKE 4)

2003-06-16 Thread David Storrs
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 C0 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


Re: Type Conversion Matrix, Pragmas (TAKE 4)

2003-06-13 Thread David Storrs
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 C0
 
 works, but silently sets $b to 0, because the numeric value of C'foo'  
 is C0 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:  Callow 


 F: (float to int)

My vote for default:  Cwarn 


 N: (numeric range)

My vote for default:  Callow 

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 Cint.  One proposed syntax to  
 declare the method of coercion/conversion might be:
 
  class Foo {
  ...
 
  to int {...}  # or Cas 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


Re: Type Conversion Matrix, Pragmas (TAKE 4)

2003-06-11 Thread Tim Bunce
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 Cint, 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 Cundef becomes a C0.
 
   my Int $a = undef;
   my int $b = $a; # $b is now C0, NOT Cundef

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 Cint.  One proposed syntax to  
 declare the method of coercion/conversion might be:
 
 class Foo {
 ...
 
 to int {...}  # or Cas 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]


Re: Type Conversion Matrix, Pragmas (TAKE 4)

2003-06-11 Thread Michael Lazzaro
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 Cint.  One proposed syntax 
to
declare the method of coercion/conversion might be:

class Foo {
...
to int {...}  # or Cas 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