Hacker News new | ask | show | jobs
by b2gills 2753 days ago
The following doesn't do what you think it does

    * > 10 && * %% 2
That is two WhateverCode objects which each take one argument. Since both are definite it gives you the second one.

    my &a = * > 10;
    my &b = * %% 2;

    my &c = &a && &b;

    &c === &b; # True
If it wasn't split up by the `&&`, it would be a code object that took two arguments.

    # using multiplication (×) as a boolean and
    # (it always cooperates in the WhateverCode lambda syntax)
    my &c = (* > 10) × (* %% 2);

    say so c(10,2); # True

    say (1..20).grep(&c);
    # ((11 12) (13 14) (15 16) (17 18) (19 20))
Note that `grep` is written in terms of `map`

    (1..20).map({ ($^a,$^b) if  ($^a > 10) × ($^b %% 2) })
    # ((11 12) (13 14) (15 16) (17 18) (19 20))
If you need to refer to an argument more than once, you (generally) can't do it with the WhateverCode lambda syntax.

    ->   $n {  $n > 10 &&  $n %% 2 }
            { $^n > 10 && $^n %% 2 }
    sub ($n){  $n > 10 &&  $n %% 2 }
I say generally because array indexing will give you the number of elements for all the arguments you ask for.

    @a[ (* × ⅓) .. (* × ⅔) ]
    @a[ (@a.elems × ⅓) .. (@a.elems × ⅔) ]
1 comments

I noticed that error too but decided I didn't have the energy to provide a response worthy of the situation.

I'm so glad I didn't try. As always you've provided a helpful answer and I learned something new. I hadn't twigged that `[...]` context would treat each Whatever as the same value -- though in retrospect I can see of course it would given the Perlish principle of doing something very useful rather than doing something useless (generating an error).

I noticed what looked like a mistake in your post:

    my &c = (* > 10) × (* %% 2);

    say so c(10,2); # True
I thought "surely that returns False" and when I tried, it did.
Right it was late, and I was writing the code in different ways when writing here and writing in the REPL.