Jonathan Worthington wrote:
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...

O AKSHUALY...that's quite easy to do, since we just calls .WHAT on the value to get its proto-object and stick it in the sig. So perhaps best is just to re-define:

multi sub fib (LITERAL) { ... }

As meaning

multi sub fib (LITERAL.WHAT $ where LITERAL) { ... }

Jonathan

Reply via email to