Wiggins has asked for the wisdom of the Perl Monks concerning the following question:

Once again, is seek enlightenment. I have the code (below) that works (with 1 mod), but I can't explain why. I have an interest in random numbers. So I tried the iterator code from Higher Order Perl to create an independent RNG as an iterators.

The code contains page references to HOP as to where the individual parts came from that I pulled together. For 5 hours, I couldn't get a successful run. The commented line labeled "!!! Important ..." was missing.

It was way back in the iterator chapter, and simply called "a bit of sugar". There is no explanation of that sort of magic it is causing the Perl interpreter to do. It seems to be a duplicate definition for the function 'Iterator' .

Can someone explain what this 'sugar' does and how?

use strict; # Definition from HOP page 122 sub NEXTVAL { $_[0]->() } # HOP top of page 123, called "a bit of sugar" ??? #sub Iterator (&) { return $_[0] } #!!Important to make this work unc +omment!!! #HOP page 156 sub make_rand { my $seed = shift || (time & 0x7ffff); print "Seed=$seed\n"; return Iterator { #print " << $seed\n"; $seed = (13 * $seed + 31011) & 0x7ffffff; #print " >> $seed\n"; return $seed; }; } # My test code my $rng = make_rand(); # a reference to an "Iterator" code different # from the one defined originally ?? my @bucket; my $i; my $t; #printf " ==%d\n",(2**31); # HOP pages 156,7 for $i (1..10000){ my $rndx = NEXTVAL ($rng); #print " $rndx "; $rndx %= 100; #print " $rndx\n"; $bucket[$rndx] ++; } # test code $t=0; for $i (0..99) { print "$bucket[$i]- "; $t+=$bucket[$i]; } printf "\nAvg= %6.2f\n", $t/100; __END__
Aside: While very "advanced", I would probably *not* use this technique due to the corresponding very high "obscure" and "unmaintainable" score.

It is always better to have seen your target for yourself, rather than depend upon someone else's description.

Replies are listed 'Best First'.
Re: "a bit of sugar "(HOP)
by ig (Vicar) on Mar 13, 2009 at 19:00 UTC
      Thank you! +++++ Your progression of equivalent examples showed/taught me what was going on in that creation of an iterator.
      • example #1 was perfectly clear; that, I was familiar with.
      • #2 was still not a stretch.
      • #3 is where the "Ah Ha" moment came and the I realized that this was a 'labeling' technique.
      • #4 was just another layer of obsfication.

      By the time I was reading the responses, I had gotten to the imap amd igrep examples in HOP, and it all came together.

      This does make me wonder how many books one would have to read to find, and understand, all of these little special cases that exist within the language?

      Thanks again..

      It is always better to have seen your target for yourself, rather than depend upon someone else's description.

        This does make me wonder how many books one would have to read to find, and understand, all of these little special cases that exist within the language?

        For my part, I won't live long enough to learn them all. Following Perl Monks and trying to understand and answer questions has taught me more than I learned in many years of using perl.

Re: "a bit of sugar "(HOP)
by JavaFan (Canon) on Mar 13, 2009 at 16:54 UTC
    I only see one definition of Iterator in your code - and it's outcommented. Essentially, "Iterator" is a noop, but because Perl allows you to leave off the 'sub' keyword if the first argument of a subroutine has prototype '&' (as here), the code is allowed to write:
    return Iterator {BLOCK}
    instead of
    return sub {BLOCK}
      Iterator appears twice. The first where you found it. The second is 6 lines below, in a "return Iterator { ..... } line that is the actual code reference of the iterator. This is the confusing part...

      It is always better to have seen your target for yourself, rather than depend upon someone else's description.

        The syntactic sugar is in the fact that the & prototype allows you to write return Iterator {...} instead of return Iterator sub {...}
        The string Iterator indeed appears twice. But an appearance isn't a definition. There's only one definition of Iterator in the code - and that's outcommented.
Re: "a bit of sugar "(HOP)
by CountZero (Bishop) on Mar 14, 2009 at 09:03 UTC
    Your program will run equally well if you replace
    return Iterator {
    by
    return sub {
    but then you are missing a clue that you have written an iterator-like sub.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James