develooper Front page | perl.perl6.users | Postings from January 2020

Re: stolen uint's

Thread Previous | Thread Next
From:
ToddAndMargo via perl6-users
Date:
January 26, 2020 02:36
Subject:
Re: stolen uint's
Message ID:
c3881a8b-787e-2c19-5bf6-4a81cfd41d35@zoho.com
On 2020-01-25 18:21, Tobias Boege wrote:
> On Sat, 25 Jan 2020, ToddAndMargo via perl6-users wrote:
>> Hi All,
>>
>> Anyone have a workaround to my stolen uint's?
>>
>>> 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
>>
> 
> Raku allows you to use native datatypes and to constrain variables to
> refuse anything but some kind of native data. But an uint32 is just
> 32 bits, no class and no methods attached.
> 
> If nevertheless you call methods on native values, they will be boxed
> into objects that actually support methods to be called on themselves.
> Native integers, signed or not, are boxed into Int.
> 
> With that in mind, re-read the documentation section about native
> dispatch [1]. Your sub x has no candidate that statically accepts
> a native integer. Since you use a subset type, the typecheck is
> deferred until runtime, but StrOrDword.ACCEPTS has no native integer
> candidate either, and at that point you lost already, as
> 
>    x(my uint32 $ = 3)
> 
> would result in the 3 being auto-boxed to be able to check it against
> `Str | uint32` and because of the boxing, its type is now Int and the
> check fails. Consider:
> 
>    sub x(uint32 $item) { say "$item is a " ~ $item.^name }
> 
>    x(3);                # works, `only` subs auto-unbox the Int literal
>    x(my uint32 $ = 3);  # works, a native integer is provided
> 
> In both cases, "3 is a Int" will be printed, because the class name
> is obtained by calling a (meta-)method on $x, which triggers boxing
> to Int. There is no room for a class name in a 32 bits native integer.
> 
> Now, if you change the signature to something subsetty/dynamic like
> 
>    sub x($item where uint32)
> 
> both calls fail to dispatch, as explained above. On the other hand,
> this works because there is an explicit native integer candidate for
> the dynamic typecheck, so you don't get boxed:
> 
>    sub x($item where -> uint32 { True })
> 
> By the way, this has nothing to do with unsigned or signed integers,
> your signs are not stolen, your values are boxed. The uint32 type is
> simply not suitable to be typechecked against, as this quintessentially
> paradoxical line of code tells you:
> 
>    say (my uint32 $ = 3) ~~ uint32;  # False
> 
> Native data is second-class data in a language where everything
> is an object.
> 
> If you want a workaround, eschew the subset and provide two candidates
> for your sub x: one for Str and one for uint32. How do you expect to
> handle something that may either be a Raku string object or a native
> integer in a single candidate anyway? Or drop the native integer
> altogether and use Int until you really need the native thing.
> 
> Regards,
> Tobias
> 
> [1] https://docs.raku.org/language/numerics#Native_dispatch
> 

Most of the time "Boxing" is a sweet feature.  But are times
when it is a pain in the neck (not my exact word).

I am trying to make my sub declaration match:

https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regsetvalueexw

       C++
         LSTATUS RegSetValueExW(
         HKEY        hKey,
         LPCWSTR     lpValueName,
         DWORD       Reserved,
         DWORD       dwType,
         const BYTE  *lpData,
         DWORD       cbData
       );
       return a DWORD.  0 = success

Where cdData is either a little endian UTF16 C String or
a little endian 32 bit unsigned integer (DWORD)

And I am trying to catch when folks mix the two up.
based on lpValueName (REG_DWORD, etc.)

Question: how do I create a 32 bit variable that is hands off
to the boxing?

Many thanks,
-T

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About