Raku / problem-solving

🦋 Problem Solving, a repo for handling problems that require review, deliberation and possibly debate
Artistic License 2.0
70 stars 16 forks source link

uint's confused with int's #154

Closed ToddAndMargo closed 4 months ago

ToddAndMargo commented 4 years ago

Dear Raku,

This is starting to drive me crazy!

When I declare something a unit, please stop changing it to an int. When I declare an unsigned integer, I am doing it for a purpose. uint and int are separate native types as stated in the documentation:

int | Equivalent to Int (with limited range) uint | Equivalent to Int (with limited range) with the unsigned trait

Examples:

> my native D32 is repr('P6int') is Int is nativesize(32) is unsigned { }
(D32)

> my D32 $d = 0xFF44; say D32.^name; say D32.Range;
D32
-Inf^..^Inf 

constant DWORD := uint32;
(uint32)

subset StrOrDword where Str | DWORD;
(StrOrDword)

sub x( StrOrDword $item ) {
*       say "$item is a " ~ $item.^name;
*   }
&x

x( "abc" );
abc is a Str

x( 3 );
Constraint type check failed in binding to parameter '$item'; expected StrOrDword but got Int (3)
in sub x at <unknown file> line 1
in block <unit> at <unknown file> line 1

x( 3.UInt );
Constraint type check failed in binding to parameter '$item'; expected StrOrDword but got Int (3)
in sub x at <unknown file> line 1
in block <unit> at <unknown file> line 1
In another example:

my uint32 $a = 2.1; ===SORRY!=== Error while compiling: Cannot assign a literal of type Rat (2.1) to a native variable of type int. You can declare the variable to be of type Real, or try to coerce the value with 2.1.Int or Int(2.1) ------> my uint32 ⏏$a = 2.1;


And another example:

my uint32 $b = 3; say $b.^name Int

JJ commented 4 years ago

That's called autoboxing, as you said yourself in the email list, pointing to this documentation page. Autoboxing does not mean that something is being changed to something else; every operation you do with it will still be done using the type (in this case representation) assigned. I fail to see what autoboxing has to do with assigning some variable something that can't be assigned to that variable.

my Int $i = 3.1
===SORRY!=== Error while compiling:
Cannot assign a literal of type Rat (3.1) to a variable of type Int. You can declare the variable to be of type Real, or try to coerce the value with 3.1.Int or Int(3.1), or just write the value as 3
------> my Int ⏏$i = 3.1

You can't assigned something of type A to type B unless you coerce it, as the error message helpfully says here. Also, I don't see what's the big deal with autoboxing. You operate with the values in its native form:

> my uint32 $a = 3333; my uint32 $b = 6666; say $a+$b; say ($a+$b).^name
9999
Int

So what? The arithmetic operation will use its uint32 representation. You will also be able to put them into arrays, whatever. Native types are all about representation and low-level operation.

ToddAndMargo commented 4 years ago

JJ,

I do not care. Sorry to be so blunt.

If I declare something and want to know what it is, I want back what I declared it as. And when I ask something what range it is, I want back the range of what I actually declared it as.

When I declare something as an unsigned integer, I want unsigned integer back. Not an integer, not a real, not a string, not a banana, not a rabbit. I want back an what I declared the variable to actually be.

When I declare something as an unsigned integer, I do not want to see the range come back with negative infinity.

.^name and .Range need TO BE ACCURATE.

No participation trophies allow.

-T

treyharris commented 4 years ago

I do not care. Sorry to be so blunt.

“I do not care” would be merely blunt if your demand was reasonable or even allowed for by the language as documented. But it is not, so it goes beyond blunt into an I-don’t-care-I-want-a-pony land.

I want back an what I declared the variable to actually be. When I declare something as an unsigned integer, I do not want to see the range come back with negative infinity. .^name and .Range need TO BE ACCURATE. No participation trophies allow.

That is not a reasonable expectation.

It’s not an expectation followed for core:

my Numeric $x;
$x = 3.5;
say $x.^name; # Rat

So to expect it to be followed for user programs is a wish, and an unreasonable one.

Native types by definition do not have methods (unless you’re on a much fancier architecture than the rest of us are!). So once you’ve violated this by calling .^name or .Range, you’ve autoboxed it, and all bets are off. Native types are intended for working with native types when you must, not simply to score additional performance, and certainly not as full-fledged replacements for core object types.

If you don’t force OO behavior onto your native-typed containers, they will act as you should expect. For instance:

$ perl6
To exit type 'exit' or '^D'
> sub unsigned-lt(uint32 $x, Numeric $y) { say "less than $y" if $x < $y }
&unsigned-lt
> sub signed-lt(int32 $x, Numeric $y) { say "less than $y" if $x < $y }
&signed-lt
> unsigned-lt(3, 6)
less than 6
> unsigned-lt(-3, 6) # ← NOTE HERE
()
> signed-lt(-3, 6) # ← VERSUS HERE
less than 6
> signed-lt(3, 6)
less than 6
> signed-lt(-13, 6)
less than 6
> signed-lt(13, 6)
()

Your definition uses the P6int trait and is cargo-culted, I believe, from a line in the docs which is immediately followed by this text:

This trait, however, is not intended to be used in your programs since it is not part of the Raku specification.

So demanding any expectations in using a definition that you’ve been specifically warned away from is entirely unreasonable.

ToddAndMargo commented 4 years ago

Hi Trey, I do not mean to be "demanding". I get a bit frustrated at times. I just want an accurate answer back. Thank you for the wonderful exposition. I usually adore boxing, but there are a few times where it gets annoying.

my native D32 is repr('P6int') is Int is nativesize(32) is unsigned { } (D32)

my D32 $d = 0xFF44; say D32.^name; say D32.Range; D32 -Inf^..^Inf

Kinda, sorts missed the "is unsigned " part in the inaccurate answer. I presume "D32.Range" came back with the range of an Int as it got unboxed. Be nice if there was some kind of warning that that had happened. ^name did not unbox it. -T

ToddAndMargo commented 4 years ago

I do believe my frustration here is that I am after the range and type of the variable. And I have no idea or warning that such a question will change the type of the variable. This akin to Quantum Physics' Observer Effect where observing the experiment, changes the experiment. I want to "observe" what the variable or type is, but the "observation" alters the variable. And there is no warning that that happened.

treyharris commented 4 years ago

I do believe my frustration here is that I am after the range and type of the variable. And I have no idea or warning that such a question will change the type of the variable. This akin to Quantum Physics' Observer Effect where observing the experiment, changes the experiment. I want to "observe" what the variable or type is, but the "observation" alters the variable. And there is no warning that that happened.

But what are you asking for? .^name is a method; asking for a method to work on a value without autoboxing it into an object is meaningless.

Are you asking for something like typeof in C? typeof is not a function, but a compiler operator, operating on the variable, not the value. Native values have no metadata, including type; the most you can do is heuristics to say “this binary data blob looks most likely to be an X”, but such heuristics would be subject to false positives and negatives.

You may want to ask, “is this binary data blob a valid X?”, but you can already do that using a test on a natively-typed anonymous variable.

The constraint is less like the Observer Principle and more like the Uncertainty Principle—you can’t know truth about it without either accepting some degree of uncertainty, or accepting that you’re going to change it in order to force it to be something you can observe directly.

Raku could, as part of the native interface, provide a low-level operation to tell you the constraints on a variable—there’s already one for Signature parameters, .constraints, if that’s what you’re requesting—but it would only tell you what you could already see from inspecting your own code.

What do you need to know about a native value, and can show example code for needing, beyond curiosity or distrust of the language?

ToddAndMargo commented 4 years ago

On 2020-01-28 15:28, Trey Harris wrote:

there’s already one for Signature parameters, |.constraints|,

my $u = 0xF8; $u.constraints No such method 'constraints' for invocant of type 'Int'. Did you mean 'contains'? in block at line 1

I just want an accurate answers back.

I will work around the quantum observation problems (unboxing)

If you want to see what my code is doing, I can post it up on vpaste

treyharris commented 4 years ago

On Tue, Jan 28, 2020 at 18:53 ToddAndMargo notifications@github.com wrote:

On 2020-01-28 15:28, Trey Harris wrote:

there’s already one for Signature parameters, |.constraints|,

my $u = 0xF8; $u.constraints No such method 'constraints' for invocant of type 'Int'. Did you mean 'contains'? in block at line 1

You’re literally quoting the place where I told you .constraints wouldn’t work except on Signature parameters. What on earth leads you to believe that “my $u = 0xF8;” is a Signature parameter?

I just want an accurate answers back.

And I just want you to at least read the part you quote back to me; otherwise typing things for you to read is pointless.

ToddAndMargo commented 4 years ago

On 2020-01-28 15:56, Trey Harris wrote:

On Tue, Jan 28, 2020 at 18:53 ToddAndMargo notifications@github.com wrote:

On 2020-01-28 15:28, Trey Harris wrote:

there’s already one for Signature parameters, |.constraints|,

my $u = 0xF8; $u.constraints No such method 'constraints' for invocant of type 'Int'. Did you mean 'contains'? in block at line 1

You’re literally quoting the place where I told you .constraints wouldn’t work except on Signature parameters. What on earth leads you to believe that “my $u = 0xF8;” is a Signature parameter?

I just want an accurate answers back.

And I just want you to at least read the part you quote back to me; otherwise typing things for you to read is pointless.

Sorry. missed that

lizmat commented 4 months ago

Closing as native uints are now first classs citizens. Please re-open if you disagree.