-
Notifications
You must be signed in to change notification settings - Fork 35
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
alias references incorrectly bomb out on empty array refs #69
Comments
Actually, what you should do is Does that make it make better sense? |
Arrays with zero elements are perfectly valid things in Perl. And aliases of zero-element arrays happen all the time: see @_ in subroutines. So why should an alias of a zero-element arrayref fail type checking? |
On 3/10/13 11:18 PM, Buddy Burden wrote:
It is counter-intuitive, and fortunately we control how it works! Can we automatically change |
The problem really has nothing to do with your array being empty. The problem is that the type checking is applied to the parameter passed in, which is not a
Sure, we could ... I guess the question is, do we want to? :-D Saying that it's "counter-intuitive" really just means that it's counter-intuitive to @Randian. It wasn't counter-intuitive to me, for instance, although I certainly have an unfair advantage by knowing a lot of the internal implementation. I'm not sure whether it's counter-intuitive to other users or not, but I'm betting that if we fix that issue for some users, we'll create counter-intuition for others. My general rule-of-thumb is that I try to imagine how to document it. If it seems like it's going to be difficult to explain how it works, I'm wary of trying to make it work like that. In this case, if I pass in |
FWIW its counter intuitive to me, too. Because of the aliasing, from OTOH does a type check of "Str @array" even make sense? Its not a |
Running some code, "Str @array" does make sure that the first element is a Str, but the rest can be anything. In other words, the sigil is not part of the type of the variable for type checking purposes. Indeed, all the @ sigil seems to signify is "one or more", rather than "exactly one". here's an interesting test case.
[bin]$ perl zzz |
Nope, it doesn't. That's because you can't really pass an array to a function. Since arrays (and hashes) are always flattened, there's no concept of an array (or a hash) in the parameter list. You can typecheck the individual parameters, but there's no way to typecheck an arbitrary group of them.
Hunh. So we are trying to typecheck the local variable and not the parameter passed in. I'd consider that a bug, actually--you can't typecheck an array or hash (see above). Maybe we just have to state a rule that you can't typecheck slurpy parameters .... ? (See, that would be easy to document. ;-> ) I think we can do it however we like, mostly. We are sort of stuck with how Moose (or Mouse or Moo or whatever) does types, and there is no non-scalar typechecking. But we could make it so that the type of a slurpy parameter was enforced across the elements of the container. But it would be a bit of work, and, as I say, difficult to describe. (OTOH, smart matching is horrific to describe, but that's still useful. So there are exceptions to my rule-of-thumb, I suppose.) |
Type checking of an "@name" parameter only happens against the first element. The rest are ignored. HashRef[Type] and ArrayRef[Type] both already check every element against Type. For example,
$a passes an ArrayRef[Str] check, but $b doesn't. Which gets me back to: shouldn't
mean exactly the same thing (ignoring aliasing)? |
Seems like there's two different problems here. First is what to do about type checking arrays and hashes. It seems to Second is what to do about type checking aliased arrays and hashes. Both would seem to involve some sort of adapting the type declaration to |
Schwern concluded:
I strongly agree. This approach would be (as) consistent (as possible) Again, I strongly agree. This too would be consistent (or at least FWIW, the Perl 6 principle here is that the type specifier on a For M::S, you could document the proposed semantics like so:
Giving us:
ArrayRefs of Bar"
of ArrayRefs of Bar" Likewise:
Damian |
I wouldn't put it that way. I would say instead that when you say Contrariwise, when you say
I think so, yes. Which is why I said I'd consider that a bug. But that's very different from what you were originally suggesting (and what @schwern and @thoughtstream suggest afterwards), which is that you should write instead
I think so, yes. Assuming that it's at the end, which it would have to be, since it's a slurpy parameter. I don't think it's particularly easy, but it should be possible, yes.
Oh, I definitely wouldn't suggest that. I was suggesting that you can't type check slurpy parameters at all. In fact, realistically, I'm having difficulty imaginging a non-contrived case where you'd actually want to.
Welll ... I'm a bit hesitant conflating the two too much. Now, if we had a
I'm also a bit leery of trying to conflate with Perl 6 too much here, because this is one of those specific instances where Perl 5 and Perl 6 really are different. That is, when you pass So, point being, if we're going to try to parallel P6, I think we should parallel what we're closest to, which in this case would be flattened slurpy params. |
I'm now thinking less is more. A comparable %hash syntax for aliasing hashrefs would be neat, though. |
Oh, does |
On 3/12/13 4:29 PM, Buddy Burden wrote:
@barefootcoder I'm not sure if you're advocating this or not. Either While I agree that right now Perl is interpreting To put it another way, what should Yet another way, if the user wants to treat the first element of a list In short, the next parameter on the list is While I agree this should be tempered with a healthy respect for how far |
On the second invocation of method y, I get the error:
Use of uninitialized value $name in concatenation (.) or string at /usr/local/lib/perl5/site_perl/5.16.2/Method/Signatures.pm line 1272
In call to A::y(), the '' parameter ("args") is not of type Str
Basically, "Str @Args" doesn't care if it's passed a zero element array, while "Str @Args" bombs out when passed an arrayref with zero elements. That doesn't seem right, arrayrefs should work just like arrays in this case.
You can, of course, do "ArrayRef[Str] $args" instead of "Str @Args" and have no problems receiving an empty array ref, but you'd lose the sugar you get by using the reference alias syntax.
The text was updated successfully, but these errors were encountered: