Moritz Lenz wrote:
pugs-comm...@feather.perl6.nl wrote:
+You can leave out the block when matching against a literal value of some
+kind:
+
+ multi sub fib ($n where 0|1) { return $n }
+ multi sub fib (Int $n) { return fib($n-1) + fib($n-2) }
+
+In fact, you can leave out the 'where' declaration altogether:
+
+ multi sub fib (0) { return 0 }
+ multi sub fib (1) { return 1 }
+ multi sub fib (Int $n) { return fib($n-1) + fib($n-2) }
As much as I like this new syntax, it's not as useful as it looks.
multi sub fib (0) desugars to (Any $ where 0), which is just a type
constraint in terms of multi dispatch. Which (Int $n) is also, so you
actually get an "ambiguous dispatch" error in your example.
Actually, you'd not get an ambiguous dispatch. Int is narrower than Any,
so the Any cases with the constraints are never considered. So in:
+ multi sub fib ($n where 0|1) { return $n }
+ multi sub fib (Int $n) { return fib($n-1) + fib($n-2) }
You'd always dispatch to the second of those, because Int is narrower than Any.
And:
+ multi sub fib (0) { return 0 }
+ multi sub fib (1) { return 1 }
+ multi sub fib (Int $n) { return fib($n-1) + fib($n-2) }
Here you'd always call the last one too, for the same reason. (And thus both
would recourse infinitely. Fail.)
Of course, leaving Int off of both examples should make it work.
Any thoughts on how that could be improved in a dwimmy way?
Well, in this case of simple literal integers we can probably statically
know their type and be able to generate "Int $ where 0" instead. But I'm
not sure how well that will scale up...
Jonathan