in reply to Elegantly map fizz to buzz

Hi,

this is a Perl 6 solution using the reduction metaoperator, tested in the REPL interpreter:

> say [+] grep {$_ %% 5 or $_ %% 3}, 1..10; 33
or, as a subroutine, tested under the REPL:
> sub sum3_5 (Int $max) { return [+] grep {$_ %% 5 or $_ %% 3}, 1..$ma +x}; sub sum3_5 (Int $max) { #`(Sub|320422744) ... } > say sum3_5 10; 33
Another solution, using the reduce function:
> say reduce {$^a + $^b}, grep {$_ %% 5 or $_ %% 3}, 1..10; 33
Update: yet another one:
> say reduce * + *, grep {$_ %% 5 or $_ %% 3}, 1..10; 33

Replies are listed 'Best First'.
Re^2: Elegantly map fizz to buzz
by raiph (Deacon) on May 17, 2016 at 05:40 UTC
    With two simplifications:
    say [+] grep * %% (5|3), 1..10

    Simplification #1. The code $_ %% 5 or $_ %% 3 can use a Junction instead: $_ %% (5|3). Junctions are designed mostly with the performance boost from automatic parallelism in mind but they can also aid readability.

    Simplification #2. The compiler recognizes when a Whatever pronoun is used as an argument of an operator. For almost all operators it makes that operation its own block, replacing the Whatever with It ($_). So these are equivalent:

    say [+] grep * %% (3|5), 1..10; say [+] grep { $_ %% (3|5) }, 1..10;

      Thank you, raiph, these are good ideas.

      Using a junction is indeed a nice idea, and does improve readability, but I doubt there can be a performance boost in this specific case, because I can't see how the compiler or the VM could run this in parallel (or if it does, it would need to add a duplicate removal phase, it seems to me that this might be too much for a compiler optimization).

      As for the * whatever pronoun, I should confess that I have been trying to use it from time to time, but am still uneasy with its syntax. Essentially, I haven't really figured out how the compiler can tell the difference between * as the multiply sign and * as the whatever pronoun, so that I have been using it so far with a try and error method, rather than with a true understanding of where and how this should work.

        Rakudo does not yet attempt parallelization of any Junctions. Even if/when it one day does, overhead will sometimes dominate, especially when trying to parallelize really tiny computations. I'm curious what you meant by "duplicate removal phase" and would enjoy reading an elaboration of that.


        Here are the two rules which drive how the grammar distinguishes a Whatever * from a multiplication *:

        1. If a token appears where an operator is allowed and there's a corresponding operator definition then it's that operator.

          For example, an operator is allowed between values, and an infix:<+> definition is in scope in ordinary code (here's the built in Numeric role's contribution to that definition), so the token + in 2 + 3 is treated as invoking infix:<+>. The same thing applies for other infix operators including multiplication with Infix:<*>.

        2. If an asterisk is NOT treated as an operator and appears where a value is allowed then it's a Whatever.

          For example, 2 + 3 includes the two values 2 and 3 and there is no prefix:<*> so one could write * + * to express "Whatever plus Whatever".

        I have been using it so far with a try and error method, rather than with a true understanding of where and how this should work.

        That was my experience of much of the syntax; albeit a long time since.

        A language designed for computers to understand; and humans to be in awe of those few that can dedicate their lives to learning it.

        (It's not unique in that sense; there are plenty of others around that are equally guru only territory.)


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.