Categories
Posts in this category
- A shiny perl6.org site
- Creating an entry point for newcomers
- Sprixel, a 6 compiler powered by JavaScript
- Another perl6.org iteration
- Blackjack and Perl 6
- Why I commit Crud to the Perl 6 Test Suite
- Report from the Perl 6 Hackathon in Copenhagen
- Custom operators in Rakudo
- Defined Behaviour with Undefined Values
- Dissecting the "Starry obfu"
- Perl 6: Failing Softly with Unthrown Exceptions
- The first Perl 6 module on CPAN
- Google Summer of Code Mentor Recap
- Building a Huffman Tree With Rakudo
- Immutable Sigils and Context
- Is Perl 6 really Perl?
- Perl 6: Lost in Wonderland
- Lots of momentum in the Perl 6 community
- Musing and the future of feather and the Pugs repository
- Musings on Rakudo's spectest chart
- My first executable from Perl 6
- Trying to implement new operators - failed
- Let's build an object
- Perl 6 is optimized for fun
- How to get a parse tree for a Perl 6 Program
- Perl 6 in 2009
- Perl 6 ticket life cycle
- The Perl 6 Advent Calendar
- How to Plot a Segment of a Circle with SVG
- Publicity for Perl 6
- Rakudo architectural overview
- Rakudo Rocks
- Rakudo "star" announced
- Rakudo's rough edges
- Rats and other pets
- Releasing Rakudo made easy
- Set Phasers to Stun!
- Starry Perl 6 obfu
- Recent Perl 6 Developments August 2008
- Strings and Buffers
- Subroutines vs. Methods - Differences and Commonalities
- A SVG plotting adventure
- A Syntax Highlighter for Perl 6
- Test Suite Reorganization: How to move tests
- The Happiness of Design Convergence
- Perl 6 Tidings from September and October 2008
- Perl 6 Tidings for November 2008
- Perl 6 Tidings from December 2008
- Perl 6 Tidings from January 2009
- Perl 6 Tidings from February 2009
- Perl 6 Tidings from March 2009
- Perl 6 Tidings from April 2009
- Perl 6 Tidings from May 2009
- Perl 6 Tidings from May 2009 (second iteration)
- Perl 6 Tidings from June 2009
- Perl 6 Tidings from August 2009
- Perl 6 Tidings from October 2009
- Timeline for a syntax change in Perl 6
- Visualizing match trees
- We write a Perl 6 book for you
- When we reach 100% we did something wrong
- Where Rakudo Lives Now
- Why was the Perl 6 Advent Calendar such a Success?
- What you can write in Perl 6 today
- Why you don't need the Y combinator in Perl 6
Wed, 27 Aug 2008
Why you don't need the Y combinator in Perl 6
Permanent link
The other day on IRC we discussed the book "Higher Order Perl" and the Y combinator. Aristotle wrote an excellent article about the Y combinator in Perl.
In short it's a rather involved construction that allows you to write anonymous recursive subs that truely have no name.
If you read about it the first time, you might become scared by its complexity, and ask yourself "do I have to understand such things to become a good programmer?". The good answer is, with Perl 6 you don't, because there's an easy way to avoid the complexity:
my $factorial = sub (Int $x) { if ($x < 2) { return 1; } else { return $x * &?ROUTINE($x - 1); } }
You see that Perl 6 cheats: although you never gave the sub a name (except
$factorial, but you wouldn't even need that, for example when
passing it as a parameter to another function), you can still access it
through the &?ROUTINE variable.
It contains the innermost routine definition (sub, method, regex,
submethod or whatever) in the current lexical scope. The &
sigil stands for a Callable object, and the ? twigil
for a variable or constant that is known at compile time ("Compiler hint
variable").
So let's golf a bit. Just for the fun of it. First the if ...
else can be replaced by the ternary operator ?? !!, and we
don't need explicit return's:
my $factorial = sub (Int $x) { $x < 2 ?? 1 !! $x * &?ROUTINE($x - 1); }
For a golfed version you clearly don't need a type signature, and the
&?ROUTINE thing has too long a name. We can circumvent it by
using a block instead of a sub:
my $factorial = -> $x { $x < 2 ?? 1 !! $x * &?BLOCK($x - 1); }
Actually we don't even need that -> $x declaration (a
"pointy block" that other programming languages call
"Lambda"), we can use a self-declared positional argument:
my $factorial = { $^x < 2 ?? 1 !! $^x * &?BLOCK($^x - 1); }
Of course there's a much shorter version, but it's not recursive so it
doesn't really fit the current topic: my $factorial = { [*] 1 .. $^x
};, which uses the [ ] reduction meta operator.
Comments / Trackbacks:
Trackback URL:
/blog-en/perl-6/y-combinator-not-needed.trackback
Pedro Melo wrote
Wicked...
... and nice!
Can you expand on the "self-declared
Moritz wrote
Self-declared positional argument
Your explanation is mostly correct, but they are taken from the argument list not in the order in which they appear in the source code, but rather in lexicographic order, which allows you to write @list.sort({ $^b $^a}).
Moritz wrote
correction
{ $^b cmp $^a }, the blog software seems to each less-than and greater-than sign :(
Ævar Arnfjörð Bjarmason wrote
Not just the innermost scope
Something you neglected to mention is that while &?ROUTINE and &?BLOCK refer to the innermost scope outer scopes are accessible through the corresponding array versions of those variables, namely @?ROUTINE and @?BLOCK.
Write a comment
The comments on this blog post have been disabled; the comment form below will not work.