Re: valid values?

2019-05-12 Thread yary
"is copy" is what I wanted to allow modifying MAIN's passed-in values. "is
rw" correctly rejects constants.

sub MAIN(Int $value is copy where ($value .= Int) ∈ (1,2,4,8,16)) {say
"\$value.perl = ",$value.perl }
# says $value.perl = 4

-y


On Sun, May 12, 2019 at 5:02 PM yary  wrote:

> On #perl6  Int(IntStr) will not coerce because IntStr is
> already an Int; coercions will only fire if the type doesn't match, like
> with Array and Hash for example
>
> IntStr is a subclass of Int thus no coercion needed to set $value. A
> catch-22 if each right side element is Int as opposed to IntStr, because
> Main gets an IntStr $value and the set-matching operation ∈ needs an exact
> class match. There is a work-around:
>
> # Be sure we are comparing with Int
> sub MAIN(Int $value where Int($value) ∈ (1,2,4,8,16)) {say "\$value.perl =
> ",$value.perl }
> # says *$value.perl = IntStr.new(4, "4")*
>
> As an alternate workaround, I tried converting $value to Int while
> comparing. That means $value needs to be writable, but the above plus
> "$value is rw", fails:
>
> sub MAIN(Int $value is rw where Int($value) ∈ (1,2,4,8,16)) {say
> "\$value.perl = ",$value.perl }
> # 6.c says *Cannot find method 'Int' on object of type NQPMu*
> *# *6.d says Usage:␤   ␤
>
> Without "$value is rw" working, the following also break.
>
> sub MAIN(Int $value is rw where ($value += 0) ∈ (1,2,4,8,16)) {say
> "\$value.perl = ",$value.perl }
> sub MAIN(Int $value is rw where ($value = Int($value)) ∈ (1,2,4,8,16))
> {say "\$value.perl = ",$value.perl }
>
> -y
>
>
> On Sun, May 12, 2019 at 3:55 PM yary  wrote:
>
>> Side note, using the angle brackets creates IntStr objects, which in some
>> cases is harmless, sometimes necessary.
>>
>> > say <1 2 4 8 16 >.perl
>>
>> (IntStr.new(1, "1"), IntStr.new(2, "2"), IntStr.new(4, "4"),
>> IntStr.new(8, "8"), IntStr.new(16, "16"))
>>
>> > say (1,2,4,8,16).perl
>>
>> (1, 2, 4, 8, 16)
>>
>> That's thanks to allomorphs from quote-word -
>> https://docs.perl6.org/language/glossary#index-entry-Allomorph* "**Keep
>> in mind that certain constructs, such as sets, bags, and mixes care about
>> object identity, and so will not accept an allomorph as equivalent of its
>> components alone."*
>>
>> I usually save angle brackets for strings but in this case, MAIN is
>> getting IntStr, so we have to also have IntStr for the Set operator
>> element-of:
>>
>> sub MAIN(Int $value where $value ∈ <1 2 4 8 16>) { say "\$value.perl =
>> ",$value.perl }
>> perl6 main.p6 4
>> *says $value.perl = IntStr.new(4, "4")*
>>
>> sub MAIN(Int $value where $value ∈ (1,2,4,8,16)) {say "\$value.perl =
>> ",$value.perl }
>> perl6 main.p6 4
>> *says Type check failed in binding to parameter ''; expected Any
>> but got Mu (Mu)*
>> *  in block  at main.p6 line 1*
>>
>> Which brings up another question- how to coerce $value to Int? These
>> don't work, even though IntStr has an Int() method.
>>
>> sub MAIN(Int(IntStr) $value where $value ∈ (1,2,4,8,16)) {say
>> "\$value.perl = ",$value.perl }
>> sub MAIN(Int() $value where $value ∈ (1,2,4,8,16)) {say "\$value.perl =
>> ",$value.perl }
>>
>>
>> -y
>>
>>
>> On Thu, Apr 18, 2019 at 5:31 PM mimosinnet  wrote:
>>
>>> El Sunday, 03 de March del 2019 a les 02:09, ToddAndMargo via
>>> perl6-users va escriure:
>>>
>>> >I want to pass an integer to a sub.  The only
>>> >valid values of the integer are 1, 2, 4, 8, and 16.
>>> >
>>> >Other than using "if" to test their values, is
>>> >there a way to state that an integer can only
>>> >have certain predefined values?
>>>
>>> I like this syntax:
>>>
>>> sub MAIN(Int $value where $value ∈ <1 2 4 8 16 >) {
>>> 
>>> }
>>>
>>> It is readable and I really like to use the '∈' symbol :D.
>>>
>>> Cheers!
>>>
>>> --
>>> (≧∇≦) Mimosinnet (Linux User: #463211)
>>>
>>


Re: valid values?

2019-05-12 Thread yary
On #perl6  Int(IntStr) will not coerce because IntStr is already
an Int; coercions will only fire if the type doesn't match, like with Array
and Hash for example

IntStr is a subclass of Int thus no coercion needed to set $value. A
catch-22 if each right side element is Int as opposed to IntStr, because
Main gets an IntStr $value and the set-matching operation ∈ needs an exact
class match. There is a work-around:

# Be sure we are comparing with Int
sub MAIN(Int $value where Int($value) ∈ (1,2,4,8,16)) {say "\$value.perl =
",$value.perl }
# says *$value.perl = IntStr.new(4, "4")*

As an alternate workaround, I tried converting $value to Int while
comparing. That means $value needs to be writable, but the above plus
"$value is rw", fails:

sub MAIN(Int $value is rw where Int($value) ∈ (1,2,4,8,16)) {say
"\$value.perl = ",$value.perl }
# 6.c says *Cannot find method 'Int' on object of type NQPMu*
*# *6.d says Usage:␤   ␤

Without "$value is rw" working, the following also break.

sub MAIN(Int $value is rw where ($value += 0) ∈ (1,2,4,8,16)) {say
"\$value.perl = ",$value.perl }
sub MAIN(Int $value is rw where ($value = Int($value)) ∈ (1,2,4,8,16)) {say
"\$value.perl = ",$value.perl }

-y


On Sun, May 12, 2019 at 3:55 PM yary  wrote:

> Side note, using the angle brackets creates IntStr objects, which in some
> cases is harmless, sometimes necessary.
>
> > say <1 2 4 8 16 >.perl
>
> (IntStr.new(1, "1"), IntStr.new(2, "2"), IntStr.new(4, "4"), IntStr.new(8,
> "8"), IntStr.new(16, "16"))
>
> > say (1,2,4,8,16).perl
>
> (1, 2, 4, 8, 16)
>
> That's thanks to allomorphs from quote-word -
> https://docs.perl6.org/language/glossary#index-entry-Allomorph* "**Keep
> in mind that certain constructs, such as sets, bags, and mixes care about
> object identity, and so will not accept an allomorph as equivalent of its
> components alone."*
>
> I usually save angle brackets for strings but in this case, MAIN is
> getting IntStr, so we have to also have IntStr for the Set operator
> element-of:
>
> sub MAIN(Int $value where $value ∈ <1 2 4 8 16>) { say "\$value.perl =
> ",$value.perl }
> perl6 main.p6 4
> *says $value.perl = IntStr.new(4, "4")*
>
> sub MAIN(Int $value where $value ∈ (1,2,4,8,16)) {say "\$value.perl =
> ",$value.perl }
> perl6 main.p6 4
> *says Type check failed in binding to parameter ''; expected Any but
> got Mu (Mu)*
> *  in block  at main.p6 line 1*
>
> Which brings up another question- how to coerce $value to Int? These don't
> work, even though IntStr has an Int() method.
>
> sub MAIN(Int(IntStr) $value where $value ∈ (1,2,4,8,16)) {say
> "\$value.perl = ",$value.perl }
> sub MAIN(Int() $value where $value ∈ (1,2,4,8,16)) {say "\$value.perl =
> ",$value.perl }
>
>
> -y
>
>
> On Thu, Apr 18, 2019 at 5:31 PM mimosinnet  wrote:
>
>> El Sunday, 03 de March del 2019 a les 02:09, ToddAndMargo via perl6-users
>> va escriure:
>>
>> >I want to pass an integer to a sub.  The only
>> >valid values of the integer are 1, 2, 4, 8, and 16.
>> >
>> >Other than using "if" to test their values, is
>> >there a way to state that an integer can only
>> >have certain predefined values?
>>
>> I like this syntax:
>>
>> sub MAIN(Int $value where $value ∈ <1 2 4 8 16 >) {
>> 
>> }
>>
>> It is readable and I really like to use the '∈' symbol :D.
>>
>> Cheers!
>>
>> --
>> (≧∇≦) Mimosinnet (Linux User: #463211)
>>
>


Re: valid values?

2019-05-12 Thread yary
Side note, using the angle brackets creates IntStr objects, which in some
cases is harmless, sometimes necessary.

> say <1 2 4 8 16 >.perl

(IntStr.new(1, "1"), IntStr.new(2, "2"), IntStr.new(4, "4"), IntStr.new(8,
"8"), IntStr.new(16, "16"))

> say (1,2,4,8,16).perl

(1, 2, 4, 8, 16)

That's thanks to allomorphs from quote-word -
https://docs.perl6.org/language/glossary#index-entry-Allomorph* "**Keep in
mind that certain constructs, such as sets, bags, and mixes care about
object identity, and so will not accept an allomorph as equivalent of its
components alone."*

I usually save angle brackets for strings but in this case, MAIN is getting
IntStr, so we have to also have IntStr for the Set operator element-of:

sub MAIN(Int $value where $value ∈ <1 2 4 8 16>) { say "\$value.perl =
",$value.perl }
perl6 main.p6 4
*says $value.perl = IntStr.new(4, "4")*

sub MAIN(Int $value where $value ∈ (1,2,4,8,16)) {say "\$value.perl =
",$value.perl }
perl6 main.p6 4
*says Type check failed in binding to parameter ''; expected Any but
got Mu (Mu)*
*  in block  at main.p6 line 1*

Which brings up another question- how to coerce $value to Int? These don't
work, even though IntStr has an Int() method.

sub MAIN(Int(IntStr) $value where $value ∈ (1,2,4,8,16)) {say "\$value.perl
= ",$value.perl }
sub MAIN(Int() $value where $value ∈ (1,2,4,8,16)) {say "\$value.perl =
",$value.perl }


-y


On Thu, Apr 18, 2019 at 5:31 PM mimosinnet  wrote:

> El Sunday, 03 de March del 2019 a les 02:09, ToddAndMargo via perl6-users
> va escriure:
>
> >I want to pass an integer to a sub.  The only
> >valid values of the integer are 1, 2, 4, 8, and 16.
> >
> >Other than using "if" to test their values, is
> >there a way to state that an integer can only
> >have certain predefined values?
>
> I like this syntax:
>
> sub MAIN(Int $value where $value ∈ <1 2 4 8 16 >) {
> 
> }
>
> It is readable and I really like to use the '∈' symbol :D.
>
> Cheers!
>
> --
> (≧∇≦) Mimosinnet (Linux User: #463211)
>


Re: valid values?

2019-04-18 Thread mimosinnet

El Sunday, 03 de March del 2019 a les 02:09, ToddAndMargo via perl6-users va 
escriure:


I want to pass an integer to a sub.  The only
valid values of the integer are 1, 2, 4, 8, and 16.

Other than using "if" to test their values, is
there a way to state that an integer can only
have certain predefined values?


I like this syntax: 


sub MAIN(Int $value where $value ∈ <1 2 4 8 16 >) {

}

It is readable and I really like to use the '∈' symbol :D.

Cheers! 


--
(≧∇≦) Mimosinnet (Linux User: #463211)


Re: valid values?

2019-03-04 Thread Tom Browder
On Mon, Mar 4, 2019 at 8:22 AM Brad Gilbert  wrote:
...
> Somewhere on the Internet I layed out the rules that I think that
> should normally be followed, but I am not sure where.
...

It would be nice to find it and add to the docs.

-Tom


Re: valid values?

2019-03-04 Thread Brad Gilbert
An Array isn't a type of Str.

@ ~~ Str; # False
Array ~~ Str; # False

You can have an array that has a type constraint.

(my Str @) ~~ Array[Str]; # True
(my @ of Str) ~~ Array[Str]; # True

Or you could check that all of the values of the Array are of some type.

(my @ = ) ~~ *.all ~~ Str
(my @ = ) ~~ (.all ~~ Str)

This is one of the few times that it is acceptable to have a ~~ in a
smart-match.

sub test1(:@array? where .all ~~ Str) { say 'ok' }

test1; # ok
test1 array => ; # ok

test1 array => (1,2,3);
# Constraint type check failed in binding to parameter '@array'; …

Somewhere on the Internet I layed out the rules that I think that
should normally be followed, but I am not sure where.

On Mon, Mar 4, 2019 at 5:32 AM Fernando Santagata
 wrote:
>
> Hi Brad,
>
> How far should I follow the rule that I should not use a smartmatch in a 
> where clause?
>
> I'm thinking of this:
>
> > sub test1(:@array? where Str) { say 'ok' }
> 
> > test1()
> Constraint type check failed in binding to parameter '@array'; expected 
> anonymous constraint to be met but got Array ($[])
>   in sub test1 at  line 1
>   in block  at  line 1
>
> > sub test2(:@array? where .all ~~ Str) { say 'ok' }
> 
> > test2()
> ok
>
> The where clause in test1() doesn't work, but is the clause in test2() 
> dangerous (action at a distance)? Should I rephrase it differently?
>
> On Mon, Mar 4, 2019 at 5:29 AM Brad Gilbert  wrote:
>>
>> The `where` clause is already a smart-match, adding `~~` to it is not
>> only redundant, it can cause confusing action at a distance.
>> (By that I mean the right side of `where` is exactly the same as the
>> right side of `~~`)
>>
>> You wouldn't write this:
>>
>> * ~~ (* ~~ 1|2|4|8|16)
>>
>> So don't write this either:
>>
>> … where * ~~ 1|2|4|8|16
>>
>> ---
>>
>> It should be
>>
>> sub mysub(Int $value where 1|2|4|8|16)
>>{
>>   say "Got $value"
>> }
>>
>> On Sun, Mar 3, 2019 at 4:16 AM Fernando Santagata
>>  wrote:
>> >
>> > Hi Todd,
>> > is this what you're looking for?
>> >
>> > sub mysub(Int $value where * ~~ 1|2|4|8|16)
>> > {
>> >   say "Got $value"
>> > }
>> >
>> > mysub 2; # Got 2
>> > mysub 3; # Constraint type check failed in binding to parameter '$value'; 
>> > expected anonymous constraint to be met but got Int (3)
>> >
>> > On Sun, Mar 3, 2019 at 11:09 AM ToddAndMargo via perl6-users 
>> >  wrote:
>> >>
>> >> Hi All,
>> >>
>> >> I want to pass an integer to a sub.  The only
>> >> valid values of the integer are 1, 2, 4, 8, and 16.
>> >>
>> >> Other than using "if" to test their values, is
>> >> there a way to state that an integer can only
>> >> have certain predefined values?
>> >>
>> >> Many thanks,
>> >> -T
>> >>
>> >> --
>> >> ~~~
>> >> Having been erased,
>> >> The document you're seeking
>> >> Must now be retyped.
>> >> ~~~
>> >
>> >
>> >
>> > --
>> > Fernando Santagata
>
>
>
> --
> Fernando Santagata


Re: valid values?

2019-03-04 Thread ToddAndMargo via perl6-users

On 3/3/19 8:29 PM, Brad Gilbert wrote:

It should be

 sub mysub(Int $value where 1|2|4|8|16)
{
   say "Got $value"
 }



:-)


Re: valid values?

2019-03-03 Thread Brad Gilbert
The `where` clause is already a smart-match, adding `~~` to it is not
only redundant, it can cause confusing action at a distance.
(By that I mean the right side of `where` is exactly the same as the
right side of `~~`)

You wouldn't write this:

* ~~ (* ~~ 1|2|4|8|16)

So don't write this either:

… where * ~~ 1|2|4|8|16

---

It should be

sub mysub(Int $value where 1|2|4|8|16)
   {
  say "Got $value"
}

On Sun, Mar 3, 2019 at 4:16 AM Fernando Santagata
 wrote:
>
> Hi Todd,
> is this what you're looking for?
>
> sub mysub(Int $value where * ~~ 1|2|4|8|16)
> {
>   say "Got $value"
> }
>
> mysub 2; # Got 2
> mysub 3; # Constraint type check failed in binding to parameter '$value'; 
> expected anonymous constraint to be met but got Int (3)
>
> On Sun, Mar 3, 2019 at 11:09 AM ToddAndMargo via perl6-users 
>  wrote:
>>
>> Hi All,
>>
>> I want to pass an integer to a sub.  The only
>> valid values of the integer are 1, 2, 4, 8, and 16.
>>
>> Other than using "if" to test their values, is
>> there a way to state that an integer can only
>> have certain predefined values?
>>
>> Many thanks,
>> -T
>>
>> --
>> ~~~
>> Having been erased,
>> The document you're seeking
>> Must now be retyped.
>> ~~~
>
>
>
> --
> Fernando Santagata


Re: valid values?

2019-03-03 Thread Fernando Santagata
On Sun, Mar 3, 2019 at 11:41 AM ToddAndMargo via perl6-users <
perl6-users@perl.org> wrote:

> That way I can catch bad values at compile time and not have
> to wait and see what it gets fed.
>

The snippet I showed you doesn't intercepts wrong values at compile time,
but rather at run time.

-- 
Fernando Santagata


Re: valid values?

2019-03-03 Thread Fernando Santagata
Hi Todd,
is this what you're looking for?

sub mysub(Int $value where * ~~ 1|2|4|8|16)
{
  say "Got $value"
}

mysub 2; # Got 2
mysub 3; # Constraint type check failed in binding to parameter '$value';
expected anonymous constraint to be met but got Int (3)

On Sun, Mar 3, 2019 at 11:09 AM ToddAndMargo via perl6-users <
perl6-users@perl.org> wrote:

> Hi All,
>
> I want to pass an integer to a sub.  The only
> valid values of the integer are 1, 2, 4, 8, and 16.
>
> Other than using "if" to test their values, is
> there a way to state that an integer can only
> have certain predefined values?
>
> Many thanks,
> -T
>
> --
> ~~~
> Having been erased,
> The document you're seeking
> Must now be retyped.
> ~~~
>


-- 
Fernando Santagata