Skip to content

Instantly share code, notes, and snippets.

@smls
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smls/1484e13b89490e218ddc to your computer and use it in GitHub Desktop.
Save smls/1484e13b89490e218ddc to your computer and use it in GitHub Desktop.

The cheating "Amb" example for Perl 6 on Rosetta Code

In http://rosettacode.org/wiki/Amb#Using_lazy_lists, the problem statement part of the Perl 6 code seems to be hand-crafted so that after going through the hyper and gather/take on Rakudo, the correct word for each step ends up at the front of the list.

Printing out the problem statement lines like this:

multi dethunk(Callable $x) { try take $x() }
multi dethunk( Any $x) { take $x }
sub amb (*@c) { gather @c».&dethunk }
say amb(<the that a>, { die 'oops'}).perl;
say amb('frog',{'elephant'},'thing').perl;
say amb(<walked treaded grows>).perl;
say amb({ die 'poison dart' },
{'slowly'},
{'quickly'},
{ die 'fire' }).perl;
("that", "a", "the")
("thing", "frog", "elephant")
("grows", "walked", "treaded")
("slowly", "quickly")

...which has the correct solution "that thing grows slowly" already in the first column.

Unless I'm mistaken, this relies on the intrinsic re-ordering which the hyper operator currently applies on Rakudo (but won't in the future once it has learned to actually auto-thread).

And indeed when you change the order of some words in the problem statement (e.g. "the" and "that"), it no longer finds the correct solution, so the code actually depends on this "cheating" and doesn't just benefit from it as a performance optimization.

I'd vote for:

  • removing that solution from Rosettacode
  • presenting the regex-based one as the "main" Perl 6 solution for the Amb task instead
  • and below it, present the following non-cheating, non-confusing variation of the above as a "more idiomatic solution that solves the example use-case and also satisfies the non-determinism requirement, but does not actually use an Amb operator in the way the task intends":
sub infix:<joins> ($a,$b) is cached {
$a.substr(*-1,1) eq $b.substr(0,1) ?? "$a $b" !! Empty;
}
sub amb { @_.pick(*) }
say first *, (
amb(<the that a>) Xjoins
amb(<elephant thing>) Xjoins
amb(<walked treaded grows>) Xjoins
amb(<slowly quickly>)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment