6

Following this post on perlgeek, it gives an example of currying:

my &add_two := * + 2;
say add_two(5); # 7

Makes sense. But if I swap the + infix operator for the min infix operator:

my &min_two := * min 2;
say min_two(5); # Type check failed in binding; expected 'Callable' but got 'Int'

Even trying to call + via the infix syntax fails:

>> my &curry := &infix:<+>(2, *);
Method 'Int' not found for invocant of class 'Whatever'

Do I need to qualify the Whatever as a numeric value, and if so how? Or am I missing the point entirely?

[Edited with responses from newer rakudo; Version string for above: perl6 version 2014.08 built on MoarVM version 2014.08]

Elizabeth Mattijsen
  • 25,654
  • 3
  • 75
  • 105
Phil H
  • 19,928
  • 7
  • 68
  • 105

1 Answers1

3

Your Rakudo version is somewhat ancient. If you want to use a more recent cygwin version, you'll probably have to compile it yourself. If you're fine with the Windows version, you can get a binary from rakudo.org.

That said, the current version also does not transform * min 2 into a lambda, but from a cursory test, seems to treat the * like Inf. My Perl6-fu is too weak to know if this is per spec, or a bug.

As a workaround, use

my &min_two := { $_ min 2 };

Note that * only auto-curries (or rather 'auto-primes' in Perl6-speak - see S02) with operators, not function calls, ie your 3rd example should be written as

my &curry := &infix:<+>.assuming(2);

This is because the meaning of the Whatever-* depends on context: it is supposed to DWIM.

In case of function calls, it gets passed as an argument to let the callee decide what it wants to do with it. Even operators are free to handle Whatever explicitly (eg 1..*) - but if they don't, a Whatever operand transforms the operation into a 'primed' closure.

Christoph
  • 164,997
  • 36
  • 182
  • 240
  • re whatever star and min: ["looks kinda buggy to me"](http://irclog.perlgeek.de/perl6/2014-09-04#i_9298954). Re auto priming: `m: sub foo ($a,$b) { say $a + $b }; my &bar = &foo.assuming(1); bar 3` works fine -- ie it works for arbitrary functions not just operators. (In fact operators are just functions with funny "long" names. eg the `+` infix operator is also known as `&infix:<+>`.) – raiph Sep 05 '14 at 04:35
  • @raiph: but `*` only auto-primes operator expressions: `&infix:<+>(2, *)` passes a `Whatever` as argument instead; explicitly using `assuming()` is not *auto* anything – Christoph Sep 05 '14 at 06:01
  • Adding `{}` works for the operator, but the call via `infix:` parses but fails when called with a numeric argument with `Method 'Int' not found for invocant of class 'Whatever'. I don't really see why operators and functions would be treated differently for currying. – Phil H Sep 05 '14 at 09:23
  • 1
    @PhilH: `perl6 -e 'my &curry := &infix:<+>.assuming(2); say curry(42);'` works fine here; function calls are treated differently because `*` is not the lambda-creation/auto-priming operator (or term, rather), but `Whatever`, which can have different meanings in different contexts; see [S02](http://perlcabal.org/syn/S02.html#The_Whatever_Object), which I already linked to in my answer – Christoph Sep 05 '14 at 09:35
  • @Christoph My apologies. I thought "auto priming" was P6ish for partial function application. But that's just "priming". As you say, the auto bit involves the Whatever star and operators. – raiph Sep 05 '14 at 19:58
  • 4
    auto primed min not working has been filed as a bug: [RT #122708](http://rt.perl.org/rt3/Ticket/Display.html?id=122708) – raiph Sep 05 '14 at 23:08
  • 2
    **Dec-2015**: [RT #122708](http://rt.perl.org/rt3/Ticket/Display.html?id=122708) has been resolved. Both OP examples now work as expected: `perl6 -e'my &add_two := * + 2; say add_two(5); # 7'` `perl6 -e 'my &min_two := * min 2; say min_two(5); #2'` – dwarring Dec 23 '15 at 17:54