New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maybe warn when thunking *.foo ~~ $bar constructs?
#2086
Comments
|
hmm, |
|
On Wed, Jul 18, 2018 at 8:16 AM, 陈梓立 ***@***.***> wrote:
hmm, * could either be a Whatever or a WhateverCode, is this the problem?
In the case of *.&method, it is always a WhateverCode.
The issue is rather that *.&method ~~ Thing is not going to DWIM for the
user that is expecting the whole expression to be a WhateverCode.
Instead it is creating a where clause which is always false (smartmatching
a WhateverCode against an Int isn't going to return True).
*.so ~~ WhateverCode
True
subset Foo of Int where *.so ~~ 2
(Foo)
my Foo $f = 2
Type check failed in assignment to $f; expected Foo but got Int (2)
in block <unit> at <unknown file> line 1
subset Foo2 of Int where { $_ ~~ 2 }
(Foo2)
my Foo2 $f = 2
2
So, if I understand it correctly, one way to interpret this issue is that
creating subsets that don't have an actual Callable should be a
compile-time error?
Does someone have an example of where a subset without a Callable is useful?
… —
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#2086 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAAKtmn0duTaVKAmpJ-KDu7boERf1xqiks5uHtKjgaJpZM4VTIiq>
.
|
Nope. The issue is a WhateverCode inside a thunk should be a compile-time warning.
The
|
|
I think if this gets covered by a best practices book, it should tell you to use a literal or a statement rather than a Callable. It should also say to steer clear of writing a WhateverCode there. subset Foo where 2 | 3; # literal (best - declarative)
subset Foo where $_ ~~ 2 | 3; # statement (next best - same but less declarative)
subset Foo where {$_ ~~ 2 | 3} # block (ok - but best for long code)
subset Foo where * ~~ 2 | 3; # WhateverCode (- easy to get wrong)
# These don't work because the first part is a WhateverCode,
# but the `~~` doesn't co-mingle with existing WhateverCodes.
# So they test if a WhateverCode smartmatches against 2|3.
# (Always False as WhateverCode doesn't do .Numeric)
subset Foo where *.Int ~~ 2 | 3;
subset Foo where +* ~~ 2 | 3;Another reason against WhateverCode is that the following doesn't do what you might expect. subset Bar where * > 5 && * < 10;What it does is produce two WhateverCodes One reason I say that a literal is better is because the code written is always used as the right side of # These are all functionally equivalent
subset Foo where 2 | 3;
subset Foo where {2 | 3};
subset Foo where $_ ~~ 2 | 3;
subset Foo where $_ ~~ {2 | 3};
subset Foo where {$_ ~~ 2 | 3 };
subset Foo where $_ ~~ $_ ~~ 2 | 3;
subset Foo where $_ ~~ {$_ ~~ 2 | 3};
subset Foo where {$_ ~~ $_ ~~ 2 | 3 };
subset Foo where {$_ ~~ {$_ ~~ 2 | 3}};
subset Foo where $_ ~~ $_ ~~ $_ ~~ 2 | 3;
subset Foo where {$_ ~~ {$_ ~~ {$_ ~~ 2 | 3}}};This is also part of the reason T.L.D.R.:I think that any time that someone writes a WhateverCode in a subset and it doesn't get put into place as the matcher it should warn and indicate that it's best to use a literal, statement, or a block. (It may be useful to state that |
We should warn about |
|
The reason I took a step away from disallowing WhateverCode entirely is someone might want to use About the only thing that I can come up with is using a specific comparison operator subset Foo where * eqv …
subset Foo where $_ eqv …I can not come up with a better example that wouldn't use I can see someone saying that a method call on subset Bar where $_.method() == 42;
subset Bar where *.method() == 42;
subset Bar where .method() == 42;I now think that it should always at least warn on a WhateverCode in a And if you write a WhateverCode that doesn't get put into place as the matcher, that it should be a compiler error. As I don't think it's possible to do without getting it wrong. In a future version, we may consider making a WhateverCode |
But I don't know how we got from a suggestion of making the "double-dipped" WhateverCode warning in thunks consistent with Blocks, to outright banning an extremely common feature that's part of the 6.c specification, and making the language inconsistent in that |
|
That's because class Foo { method foo { "x" } }
subset Z where ?.foo;
say Foo ~~ Z; # True |
|
On Wed, Jul 18, 2018 at 12:45 PM, Zoffix Znet ***@***.***> wrote:
this issue is that creating subsets that don't have an actual Callable
should be a compile-time error?
Nope. The issue is a WhateverCode inside a thunk should be a compile-time
warning.
Ah, I see this now. It is a *very* common issue when people are learning
about WhateverCode and I would love it if the compiler could catch it.
And of course, a warning is the obviously more polite manuever for a core
thingy.
Nice catch, Zoffix.
Does someone have an example of where a subset without a Callable is
useful?
The where clause supports thunking, so there's an infinite number of
examples really
- where 42|5
- where Int|Num
- where 'meows'
- 'where .is-prime`
- ...
Excellent point. (also: D'oh!)
I'm not sure whether it is habit, history, or superstition but I've always
leaned on passing Callable objects (generally proper blocks because
multi-stage guards are fun but otherwise usually WhateverCode).
Thanks for mentioning these specific thunking examples. You have inspired
to take a look at how thunk dispatching is handled in core. It's always
been a bit of a fuzzy concept to me.
|
|
Another user bitten by this issue and a bit of discussion here: http://colabti.org/irclogger/irclogger_log/perl6?date=2018-09-26#l39 |
|
Is there any reason why I mean, it's not like that smartmatching with a literal |
|
@2colours - I think that this ^^^ is best |
Had the user wondering why
subset Tuesday of Date where *.day-of-week ~~ 2;doesn't work as expected.The reason is
~~is not an op that gets closed over, so thatwhereclause is actually a thunk that has a smartmatch inside of it, with the whatevercode being just an arg. This doesn't give an warnings or error and just givesFalseeven when given correct date object.Perhaps this case should warn, same as we warn in, for example
{ *.so }about "double closure"?The text was updated successfully, but these errors were encountered: