I was working my way through reading Iterators: Signs of Weakness in Object-Oriented Languages until I came to the samefringe function (which checks to see if two lists -- array references in the code here -- have the same "fringe" -- update: i.e. they have identical "leaves" or they have the same contents if both lists are "flattened"), when I reached a "Huh, what's going on?" moment...I still don't entirely get it, but rewriting it in perl helps some. The main weakness in this perl version is that cdr() is O(N) (update: because I'm using straight array references instead of real linked lists as Joost points out below), though still fairly fast here. A minor weakness is not having named parameters...but it was marginally educational anyway. I wrote the printfringe() function while debugging samefringe(). Enjoy! or not :-)

#!/usr/bin/perl use strict; use warnings; my $l1 = [ "a", [qw(b c)], "d" ]; my $l2 = [ qw(a b c d) ]; print_fringe($l1); print "same\n" if samefringe($l1, $l2); sub print_fringe { my $x = shift; print_fringec( sub { my $c = shift; genfringe($x, $c, \&eof); }, ); } sub print_fringec { my $xg = shift; $xg->( sub { my ($x, $eofx, $xg) = @_; ( $eofx ) || do { print "F: $x\n"; print_fringec($xg) }; } ); } #defun eof (c) (funcall c nil t nil)) ; empty generator, send e +of flag. sub eof { my $c = shift; $c->(undef, 1, undef); } #(defun samefringe (x y) ; "lazy" sa +mefringe. # (samefringec #'(lambda (c) (genfringe x c #'eof)) # #'(lambda (c) (genfringe y c #'eof)))) sub samefringe { my ($x, $y) = @_; samefringec( sub { my $c = shift; genfringe($x, $c, \&eof); }, sub { my $c = shift; genfringe($y, $c, \&eof); }, ); } #(defun samefringec (xg yg) ; check equality of leaves generated by g +enfringe. # (funcall xg ; We don't need Scheme 1st class conti +nuations. # #'(lambda (x eofx xg) ; receive 1st elt., eof flag, & generator +for rest. # (funcall yg # #'(lambda (y eofy yg) # (or (and eofx eofy) ; equal if both reach eof simult +aneously. # (and (eql x y) (samefringec xg yg)))))))) sub samefringec { my ($xg, $yg) = @_; $xg->( sub { my ($x, $eofx, $xg) = @_; $yg->( sub { my ($y, $eofy, $yg) = @_; ( $eofx && $eofy ) || ( $x eq $y and samefringec($xg, $yg) ) +; } ); } ); } #(defun genfringe (x consumer genrest) ; call consumer with leaves fo +und in x. # (if (atom x) (funcall consumer x nil genrest) ; send 1st elt. & ~ +eof flag. # (genfringel x consumer genrest))) sub genfringe { my ($x, $consumer, $genrest) = @_; ref($x) ? genfringel( $x, $consumer, $genrest ) : $consumer->( $x, undef, $genrest ); } #(defun genfringel (xl consumer genrest) # (if (null xl) (funcall genrest consumer) # (genfringe (car xl) consumer # #'(lambda (consumer) (genfringel (cdr xl) consumer genrest))))) sub genfringel { my ($xl, $consumer, $genrest) = @_; return $genrest->($consumer) if !$xl; genfringe( car($xl), $consumer, sub { my $consumer = shift; genfringel( cdr($xl), $consumer, $genrest ); } ); } sub car { $_[0][0] } sub cdr { lcdr(@{$_[0]}) } sub lcdr { shift; return @_ ? \@_ : undef }


In reply to No Iterators Allowed by runrig

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.