masak's Journal masak's use Perl Journal en-us use Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners. 2012-01-25T01:45:20+00:00 pudge Technology hourly 1 1970-01-01T00:00+00:00 masak's Journal The Pugs repository is dead; long live Mu! <p>This weekend marks the end of a quite astonishing era. The Pugs repo, that hosted all the <a href="">amazing Perl 6 activity</a>, is no more. At its height, this repository had 242 committers! I just checked.</p><p>The Pugs repository has functioned as a common writing area for Perl 6-related things. First <a href="">Pugs</a>; then a lot of external <a href="">modules and scripts</a> written in Perl 6; what would eventually morph into <a href="">the Perl 6 test suite</a>; even the <a href="">Perl 6 specification</a> and the <a href="">standard grammar</a>. Commit bits (write access credentials) were handed out liberally, and newcomers were encouraged to help improve things they found amiss. The degree to which this system worked without a hitch has been quite astonishing. There have been no edit wars, no vandalism, no banning. Just the continuing flow of commits. Trust the anarchy.</p><p>So why are we killing off the Pugs repository? Well, technologies come and go; not so much because they worsen by each year, but because our expectations rise in a sort of software inflation. The SVN repository became too high-maintenance, and a transition to git was the natural next step. The Pugs repository has been split up into the git repositories linked to in the previous paragraph. Those bits that don't belong in any of the standard bins remain in the <a href="">Mu repository</a>. (Its name is a reference to the most-general object type in Perl 6, what in other languages is commonly known as 'Object'.)</p><p>I for one salute our new git-based overlords! May the commits keep flowing even under this new system. Also, moritz++ for carrying out the move.</p> masak 2010-09-06T06:30:29+00:00 perl6 Yapsi 2010.09 Released! <p>It is with a peevish exultation of spirit that I announce on behalf of the Yapsi development team the September 2010 release of Yapsi -- soon to be a major motion picture -- a Perl 6 compiler written in Perl 6.</p><p>You can download it <a href="">here</a> (or, if you happen to be on an <a href="">avian-carrier-based</a> network, you can "pidgeon" it <a href="">here</a>).</p><p>Yapsi is implemented in Perl 6. It thus requires a Perl 6 implementation to build and run. This release of Yapsi has been confirmed to work on both Rakudo Star 2010.08 and Rakudo Star 2010.07.</p><p>Yapsi is an "official and complete" implementation of Perl 6. Yapsi's official status has been publicly confirmed by Patrick Michaud, the Rakudo pumking. The claim about Yapsi being complete... well, it might just be what PR people sometimes refer to as "a slight exaggeration". On the bright side, it's becoming less so with each new release.</p><p>This month's release brings you <code>unless</code> and <code>until</code>, as well as <code>our</code>-scoped variables:</p><p> <code> $ yapsi -e 'my $a = 0; unless $a { say 42 }'<br> 42 </code> </p><p> <code> $ yapsi -e 'my $a = 0; until $a { say ++$a }' 1 </code> </p><p> <code> $ yapsi -e 'our $a = 42; { my $a = 5; { say our $a } }' 42 </code> </p><p>For a complete list of changes, see <a href="">doc/ChangeLog</a>.</p><p>Quite a lot of features are within reach of people who are interested in hacking on Yapsi. See the <a href="">doc/LOLHALP</a> file for a list of 'em. In fact, that's how isBEKaml++ implemented 'unless' this month. (After which he exclaimed "that was easy!" and tackled 'until'.) If you're wondering whether you're qualified to help with the Yapsi project, that probably means you are.</p><p>Yapsi consists of a compiler and a runtime. The compiler generates instruction code which the runtime then interprets. In Yapsi, that instruction code (unfortunately) is called SIC[!]. Until further notice, SIC as a format changes with each monthly release for various, mostly good reasons. However, if you write a downstream tool that makes assumptions about the SIC format, someone might change it just out of spite. SIC is explicitly not compatible with later, earlier, or present versions of itself.</p><p>An overarching goal for making a Perl 6 compiler-and-runtime is to use it as a server for various other projects, which will hook in at different steps:</p><ul> <li> A time-traveling debugger (tardis), which hooks into the runtime.</li><li> A coverage tool (lid), which will also hook into the runtime.</li><li> A syntax checker (sigmund), which will use output from the parser.</li></ul><p>Another overarching goal is to optimize for fun while learning about parsers, compilers, and runtimes.</p><p>Have the appropriate amount of fun!</p> masak 2010-09-01T22:31:48+00:00 perl6 Idiomatic Perl 6 <p>So, I wrote a program to generate <a href="">Pascal's triangle</a>. The first ten rows of the triangle, at least. It only used simple features of Perl 6, such as scalars, nested arrays, and <code>for</code> loops.</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;my @current;<br> &nbsp;&nbsp;&nbsp;&nbsp;push @current, @last[0];<br> &nbsp;&nbsp;&nbsp;&nbsp;for 0<nobr> <wbr></nobr>.. @last - 2 {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push @current, @last[$_] + @last[$_ + 1];<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;push @current, @last[ * - 1 ];<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, [@current];<br> }<br> <br> say @pascal.perl; </code> </p><p>In fact, save for simple mechanically substitutable differences, it could have been a Perl 5 script. In fact, with a bit of manual array allocation, it could have been a C script. That's OK; there's a tolerance in the Perl community of writing code that looks like it was thunk in some other language.</p><p>But I've heard that Perl 6 is great at doing things with operators. For example, the <code>Z</code> operator, which interleaves two lists, seems to be able to help me write my <code>push</code> statements more succinctly:</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;my @current;<br> &nbsp;&nbsp;&nbsp;&nbsp;<b>for (0, @last) Z (@last, 0) -&gt; $left, $right {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push @current, $left + $right;<br> &nbsp;&nbsp;&nbsp;&nbsp;}</b> <br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, [@current];<br> }<br> <br> say @pascal.perl; </code> </p><p>The parentheses before and after the <code>infix:&lt;Z&gt;</code> aren't necessary, because the <code>Z</code> operator has looser precedence than comma. They're just shown here to make your eyes accustomed to reading this construct.</p><p>In fact, now that only the addition is performed in the inner loop, I might as well use the <code>Z+</code> operator, which does this for me.</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;my @current <b>= 0, @last Z+ @last, 0;</b> <br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, [@current];<br> }<br> <br> say @pascal.perl; </code> </p><p>Now as the remaining loop shrinks to a size I can take in all at once, I see a bit more clearly what I'm doing: I'm building each new list from the previous one. I could feed the previous list into a named function to get the current one:</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <b> <br> sub next-list(@p) {<br> &nbsp;&nbsp;&nbsp;&nbsp;[0, @p Z+ @p, 0]<br> }<br> </b> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;my @current = <b>next-list(@last)</b>;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, @current;<br> }<br> <br> say @pascal.perl; </code> </p><p>Or I could just feed it into a in-place anonymous sub.</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, <b>(sub (@p) { [0, @p Z+ @p, 0] }).(@last)</b>;<br> }<br> <br> say @pascal.perl; </code> </p><p>But why even a sub? Perl 6 has a lighter construct, namely a "pointy block" (also known as a "closure" or a "lambda"). It doesn't participate in the call stack, and it's slightly easier to write.</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, (<b>-&gt; @p</b> { [0, @p Z+ @p, 0] }).(@last);<br> }<br> <br> say @pascal.perl; </code> </p><p>Let's look at what the code does. Seed with one element. Calculate the next element based on the previous one. Stop at some point.</p><p>But that's exactly what the series operator does. The one that's written with three dots. We have a starting value, a way to get from one value to the next (our code block above), and a stopping value.</p><p>Well actually, we don't have the stopping value. But that's OK, since the series operator is <em>lazy</em>. So if we only request the first 10 values, it won't loop forever giving us the rest of the list.</p><p> <code> <b>my @pascal<nobr> <wbr></nobr>:= do [1], -&gt; @p { [0, @p Z+ @p, 0] }<nobr> <wbr></nobr>... *;</b> <br> <br> say <b>@pascal[^10]</b>.perl; </code> </p><p>(The extra <code>do</code> required because of a <a href="">shortcoming in Rakudo</a>.)</p><p>Now. Something very much like this code was posted first <a href="'s_triangle#Perl_6">on Rosetta code</a> and then <a href="">on Moritz' blog</a>. (TimToady used a sub, but said later that he'd have preferred binding.)</p><p>A couple of Perl 5 people's reactions were &#8212; somewhat uncharacteristically &#8212; of a negative flavour, similar to how people <a href="">seem to react</a> to the periodic table of operators:</p><p> <code> <a href="">@shadowcat_mst</a>: an excellent example of why I consider camelia perl to be a language research project more than a production language </code> </p><p> <code> <a href="">@pedromelo</a>: I'm seriously considering this post as an example of what I don't want Perl6 to become... </code> </p><p>I think these reactions are mainly feature shock. Higher-order operators, pointy blocks, and the series operator... they're all good, well-established features, which find daily use in Perl 6 programs. Maybe using them all together like that flung some people off the deep end. Never mind that the resulting script is all <a href="">essential complexity</a>, with virtually no boilerplate from the original script left.</p><p>This is the first time that's happened. I think it's important to listen to what Perl 5 people think and to try to respond to that. But I also think that this time, it's a case of them seeing some highly idiomatic Perl 6, and freaking out a bit.</p><p>And I think that that, in some odd sense, is a good thing. Well, not freaking people out, per se. But the fact that we did shows that there's something forming which might be tentatively called "idiomatic Perl 6": people on the inside can read it quite easily, but those on the outside, even Perl 5 folks looking in, instinctively go "eeeeew!".</p><p>That's OK. You're not meant to start with the idiomatic stuff. <em>Language acquisition takes place step by step</em>, and that goes for learning Perl 6 as well. On the way there, just don't confuse distaste with lack of familiarity.</p> masak 2010-08-27T00:22:03+00:00 perl6 Where in the world is the package lexpad? <p> <i>(This post isn't very punny. For those of you who need puns to survive, try to figure out why jnthn++ named the IRC logs "the hottest footwear" recently. The answer, as with all good puns, is highly unsatisfying.)</i> </p><p>My quest for a Perl 6 implementation takes me ever deeper into the esoterics of lexpads, runtimes, and a far-more-than-everything-you-needed-to-know mindset. Today some random firings in my brain turned into the following conversation on #perl6.</p><p>During the conversation, I proposed two theories, both of which turned out to be wrong. (pmichaud++ shone the necessary light both times.) Being wrong felt less important than getting my mental model fixed.</p><p>I first thought of presenting the results of the below conversation as a simple tutorial ("How <code>our</code> declarations work. The complete guide."), but now I think that the conversation, minimally edited, manages to be such a tutorial on its own.</p><p>Besides, blogging things in their raw and undigested form is a sign of the times. Enjoy!</p><p> <code> &lt;masak&gt; I have a question. is there a need for a special "package lexpad" containing 'our'-declared variables, or can the package lexpad simply be equated to the topmost lexpad in the package?<br> <br> &lt;masak&gt; my suspicion is the latter, but I might be missing something.<br> <br> &lt;pmichaud&gt; the package lexpad can't be the same as the top most lexical<br> <br> &lt;pmichaud&gt; <b>module XYZ { my sub abc() {<nobr> <wbr></nobr>... } }; # abc should not appear in the package</b> <br> <br> &lt;masak&gt; oh!<br> <br> &lt;masak&gt; right.<br> <br> &lt;masak&gt; so, separate one, then.<br> <br> &lt;jnthn&gt; Additionally, lexpads are meant to be static by the time we hit runtime, and you're allowed to shove stuff into the package dynamically. Not quite sure how those two hold together.<br> <br> &lt;pmichaud&gt; well, <b>module XYZ {<nobr> <wbr></nobr>... }</b> creates a lexical XYZ entry that holds the package entries<br> <br> &lt;jnthn&gt; Aha!<br> <br> &lt;pmichaud&gt; and it's just a hash, really.<br> <br> &lt;masak&gt; does inserting the package lexpad below the outside lexpad (and above the topmost lexpad) make sense? that way, Yapsi wouldn't need any special opcodes for doing 'our'-variable lookups.<br> <br> &lt;pmichaud&gt; the package lexpad is an entry in the outside lexpad, yes.<br> <br> &lt;pmichaud&gt; I'm not sure it encapsulates the nested lexpad, though.<br> <br> &lt;masak&gt; hm.<br> <br> &lt;masak&gt; if it doesn't, I don't really see how it's visible from inside the package.<br> <br> &lt;masak&gt; I've more or less convinced myself that sandwiching it between outer and topmost is what I want to do for Yapsi.<br> <br> &lt;pmichaud&gt; <b>our &amp;xyz</b> can make an entry in both the package and in the lexical.<br> <br> &lt;pmichaud&gt; this is what rakudo does now.<br> <br> &lt;pmichaud&gt; we have to do similar things for methods already, too.<br> <br> &lt;masak&gt; sure. it makes entries in both.<br> <br> &lt;pmichaud&gt; by having entries in both, that's how it's visible inside the package<br> <br> &lt;masak&gt; hm, indeed.<br> <br> &lt;masak&gt; no need to have the package lexpad visible from inside.<br> <br> &lt;pmichaud&gt; anyway, sandwiching might work too. haven't quite gotten to that point in Rakudo thinking yet. And it can get a bit tricky with multis.<br> <br> &lt;masak&gt; no need to sandwich it in, either. it can sit in limbo outside the tree of scopes.<br> <br> &lt;pmichaud&gt; oh, I know why it perhaps shouldn't (or should) be visible:<br> <br> &lt;pmichaud&gt; <b>my $x = 'lexical'; module XYZ { say $x; { our $x = 'package'; } }</b> <br> <br> &lt;masak&gt;<nobr> <wbr></nobr>...yes?<br> <br> &lt;pmichaud&gt; I'm pretty sure "say $x" needs to grab the 'lexical' $x, not the one that might be "sandwiched" in a package.<br> <br> &lt;masak&gt; of course.<br> <br> &lt;masak&gt; that falls out from ordinary scope nesting and shadowing.<br> <br> &lt;masak&gt; innermost block binds its lexical to the container in the package lexpad.<br> <br> &lt;masak&gt; so, that speaks out against sandwiching.<br> <br> &lt;masak&gt; pmichaud++ </code> </p><p>So there you go. There's a separate package scope, and it isn't sandwiched.</p><p> <i>(Answer: The missing link is the "IR clogs" meme from #parrot. I can hear you groaning... I did warn you.)</i> </p> masak 2010-08-22T21:39:58+00:00 perl6 Weeks 8..12 of GSoC work on Buf -- not packing it in yet <p> <em>I was reproached by my colleague because of the lack of "no cake"-style jokes in this last grant update. So what can I do to amend the situation? Firstly, let me concede that the below blog post is almost tear-inducingly boring. Secondly, let me remind you that when accosted by boring material such as that in this post, the most important thing to have is a positive outlook on life. Thank you.</em> </p><p>The past couple of days have been really eventful. The coming couple of days probably will be, too. It seems fitting to punctuate all this eventfulness with a status-updating blog post, something that I apparently haven't gotten around to in a few weeks.</p><p>So, what's been happening?</p><ul> <li>In the <a href="">last update</a>, I was at a point where I needed to encode to different encodings, not just UTF-8. Tonight I had <a href="">an enlightening discussion</a> with the Parrot people, which gave all the pieces of the puzzle. Now it's just a Simple Matter of Programming. More precisely, I need to apply it to <a href="">this spot</a> in the code base.</li><li>By that discussion, I was once again made aware that Parrot differs between <em>encodings</em> and <em>charsets</em>. For example, <code>utf8</code> is an encoding, but <code>iso-8859-1</code> is a charset. It's confusing me slightly, but that's OK. I can make the code work so that both are treated as "encodings" on the Perl 6 level.</li><li>I got unexpected assistance from oha++, who took me aside in private discussions to discuss new wild ideas for <code>Buf</code>. It all culminated in a <a href="">p6l thread</a>. Oha is writing code that uses Buf for network traffic, and has been preparing a patch for making <code>IO::Socket::INET</code> return <code>Buf</code>s instead of <code>Str</code>s. In trying out this patch, oha++ found that some tests <a href="">will never work</a> when <code>Buf</code>s are used. Those tests will probably need to be rewritten.</li><li>During the past week or so, I've been implementing <code>pack</code> and <code>unpack</code> in a branch. I'm making steady progress, and trying to take in documentation such as Perl 5's <a href=""> <code>perldoc -f pack</code> </a> and <a href=""> <code>perlpacktut</code> </a> and <a href="">Erlang's</a> <a href=""> <code>ei</code> </a> and <a href="">Tcl's <code>binary</code> </a>. It's a lot to take in, and I won't aim for full functionality &#8212; look, <a href="">Perl 5 has 14699 tests</a> for pack! &#8212; but rather a reasonable subset of the directives from Perl 5.</li></ul><p>There's a lot to be said about the interplay between Perl 6's high level of abstraction and the almost reckless to-the-metal feeling of <code>&amp;pack</code>/<code>&amp;unpack</code>. Add to this that the "metal" in this case is Parrot, which in some regards is there to abstract away the real metal. I think the details of this interplay might well be the subject of a separate blog post. When I'm not busy finishing up the code itself. &#21704;&#21704;</p><p>The hard pencils-down deadline for GSoC is on Monday. I'm pretty sure I will have tied up the remaining loose ends by then, but I also foresee a couple of fairly focused hours programming before that. Time to dig back in; see you on the other side.</p> masak 2010-08-13T22:35:51+00:00 perl6 There's just no way to keep up with all you people <p>Let's look at a week two years ago in the perl6 RT queue. Who submitted bugs?</p><p> <code> Moritz<br> Moritz<br> Moritz<br> Moritz<br> Yaakov<br> Yaakov<br> <strong>Carl</strong> <br> Moritz<br> Moritz<br> Ron<br> Charlie<br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> </code> </p><p>Seems I just managed to tie with Moritz++ there. Almost one ticket a day sounds about right from what I remember of my submit pace from that time. In total, there were 16 tickets in that week.</p><p>Ok, that was two years ago. What about one year ago? By this time, Rakudo had already picked up a bit of a reputation.</p><p> <code> Patrick<br> Patrick<br> <strong>Carl</strong> <br> Alex<br> Alex<br> Timothy<br> Moritz<br> Gilbert<br> <strong>Carl</strong> <br> Timothy<br> Timothy<br> Eduardo<br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> dakkar<br> dakkar<br> Hanno<br> Solomon<br> Ben<br> Solomon<br> Ben<br> dakkar<br> Aaron<br> Solomon<br> </code> </p><p>Dang, only five tickets that week. &#21704;&#21704;</p><p>Still, a pretty typical week. 25 tickets all in all. We see a bit more variation in the names now. That's the new people.</p><p>Finally, let's look at last week:</p><p> <code> Ekkehard<br> Timothy<br> Tom<br> cognominal<br> Cosimo<br> Sven<br> Chris<br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> Moritz<br> Simon<br> Mulander<br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> Pawe&#322;<br> Tadeusz<br> Aaron<br> cognominal<br> cognominal<br> <strong>Carl</strong> <br> Pawe&#322;<br> Lithos<br> Lithos<br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> Tyler<br> Alex<br> Lithos<br> Moritz<br> Lithos<br> Brian<br> Moritz<br> Moritz<br> Pawe&#322;<br> Steve<br> Francesco<br> Lithos<br> Jarrod<br> Lithos<br> Francesco<br> <strong>Carl</strong> <br> Moritz<br> </code> </p><p>These figures help express what I feel. I'm still submitting a fair amount of tickets &#8212; all of nine last week &#8212; and still they make up an ever-smaller proportion of the growing deluge of perl6 tickets on RT.</p><p>Or, put differently, all you other people finally caught up with me. I can no longer compete with the rest of you. &#21704;&#21704;</p><p>It makes me proud and excited to disappear under the waves of other people's contributions. There's been both a slow buildup over the past two years, and a sudden spike thanks to Rakudo Star. Together, they help drown out my insistent, repeating splashes on RT.</p><p>Rakudobugs are love. There's a whole lotta love out there right now. &#9829; This uptake is what we've been waiting for.</p> masak 2010-08-10T20:22:42+00:00 perl6 Perl 6 and Perl 5 are different languages <p>Today at the YAPC::EU keynote, the inimitable Larry Wall, accompanied by his guardian angel and his guardian devil, made a poll asking which ones in the audience believed Perl 5 and Perl 6 are the same language, and which ones believed they are two different languages.</p><p>I was in the front row, so I didn't see the sea of hands and which way the poll tipped. But on my row, both Patrick Michaud and Jonathan Worthington voted "different". I was slightly surprised to find myself voting "different" as well. I'm the one who only last year wrote <a href="">this entry</a> which seems to insist on a "same" vote, if only by criticizing those who take the opposite view.</p><p>I think that what's happened in the past year is that there's a bit more room in the "Perl" space. We're now talking of <a href="">two different languages in the Perl family</a>, and the Perl community being <a href="">shaped like a tuning-fork</a> with its Perl-5 people, Perl-6 people, and Perl-omnivore people. It simply feels safer now to state "different", in a way it didn't last year.</p><p>One thing about the tuning fork that I really like is that it's basically two universes in one. We could've had</p><dl> <dd>(a) Perl 6 taking off early and essentially killing Perl 5, precluding its renaissance as Modern Perl, or</dd><dd>(b) Perl 6 floundering so badly and for so long that Perl 5 took over with such force that no-one bothered to develop Perl 6 anymore, and a "Forever Five" condition in the community was announced.</dd></dl><p>Instead we find ourselves in a junctional universe where both languages are thriving and evolving. And they're different, not least because Perl 5 is older, more mature, and more used in business-oriented environments. But Perl 6 is getting there too, and the two languages will start playing together on increasingly equal footing, just like half-a-generation-apart siblings would.</p><p>I like that.</p> masak 2010-08-04T23:10:09+00:00 perl6 Yapsi 2010.08 Released! <p>It is with vertiginous modesty that I want to announce, on behalf of the Yapsi development team, the August 2010 release of Yapsi, a Perl 6 compiler written in Perl 6. (Am I using, too many, commas?)</p><p>You can get it <a href="">here</a> &#8212; as a bonus, if you download within 24 hours, the bits in your download will be hand-painted and signed by nine indefatigable mice from northern Belarus.</p><p>Yapsi is implemented in Perl 6. It thus requires a Perl 6 implementation to build and run. Both Rakudo Star and the latest monthly release ("Atlanta") seem to be fit to the task.</p><p>Yapsi is an "official and complete" implementation of Perl 6. It's official because we stole the "Official Perl 6" rubber stamp and applied it liberally. Unfortunately, we also used all the special ink -- please don't tell any of the other implementors that. It's complete because we implemented all the parts of the synopses that weren't eaten by the team's pet dugong.</p><p>This month's release consists of a total refactor of both the runtime and the compiler. The file is about 100 lines shorter, with the same functionality. Lexical variables are now handled more correctly. For a complete list of changes, see <a href="">doc/ChangeLog</a>.</p><p>Quite a lot of features are within reach of people who are interested in hacking on Yapsi. See the <a href="">doc/LOLHALP</a> file for a list of 'em.</p><p>Yapsi consists of a compiler and a runtime. The compiler generates a so-called instruction code, which is a code of instructions, for the runtime to run. This is fairly common, and nothing to be agitated about. The instruction code is called SIC, which is probably slightly less common. SIC is extended, re-thought and eaten by the team's pet dugong on a regular basis, so don't expect SIC from one release to be runnable on another.</p><p>An overarching goal for making a Perl 6 compiler-and-runtime is to use it as a server for various other projects, which will hook in at different steps:</p><ul> <li> A time-traveling debugger (tardis), which hooks into the runtime.</li><li> A coverage tool (lid), which will also hook into the runtime.</li><li> A syntax checker (sigmund), which will use output from the parser.</li></ul><p>Another overarching goal is to optimize for fun while learning about parsers, compilers, and runtimes.</p><p>Gotta go feed S16 to the team's pet dugong. We wish you the appropriate amount of fun!</p> masak 2010-08-01T23:50:48+00:00 perl6 6 built-ins in Perl 6 that you never knew you needed <p><nobr> <wbr></nobr><b>.pick</b> </p><p> <code> say&nbsp;@deck.pick();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;pick&nbsp;a&nbsp;card,&nbsp;any&nbsp;card...<br> <br> say&nbsp;@deck.pick(5);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;poker&nbsp;hand<br> <br> my&nbsp;@shuffled&nbsp;=&nbsp;@deck.pick(*);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;here,&nbsp;'*'&nbsp;means&nbsp;'keep&nbsp;going'<br> <br> my&nbsp;@urn&nbsp;=&nbsp;&lt;black&nbsp;white&nbsp;white&gt;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;beads,&nbsp;1/3&nbsp;black,&nbsp;2/3&nbsp;white<br><nobr> <wbr></nobr>.say&nbsp;for&nbsp;@urn.pick(50,&nbsp;:replace);&nbsp;&nbsp;&nbsp;#&nbsp;put&nbsp;back&nbsp;after&nbsp;each&nbsp;pick<br> <br> for&nbsp;@urn.pick(*,&nbsp;:replace)&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;.say;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;infinite&nbsp;bead&nbsp;picker<br> }<br> <br> say&nbsp;[+]&nbsp;(1..6).pick(4,&nbsp;:replace);&nbsp;&nbsp;&nbsp;#&nbsp;4d6<br> <br> class&nbsp;Enemy&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;method&nbsp;attack-with-arrows&nbsp;&nbsp;&nbsp;{&nbsp;say&nbsp;"peow&nbsp;peow&nbsp;peow"&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;method&nbsp;attack-with-swords&nbsp;&nbsp;&nbsp;{&nbsp;say&nbsp;"swish&nbsp;cling&nbsp;clang"&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;method&nbsp;attack-with-fireball&nbsp;{&nbsp;say&nbsp;"sssSSS&nbsp;fwoooof"&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;method&nbsp;attack-with-camelia&nbsp;&nbsp;{&nbsp;say&nbsp;"flap&nbsp;flap&nbsp;RAWWR!"&nbsp;}<br> }<br> <br> my&nbsp;$selector&nbsp;=&nbsp;{&nbsp;.name&nbsp;~~&nbsp;/^&nbsp;'attack-with-'&nbsp;/&nbsp;};<br> given&nbsp;;-&gt;&nbsp;$e&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$attack-strategy<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;$e.^methods().grep($selector).pick();<br> </code> </p><p> <code> &nbsp;&nbsp;&nbsp;&nbsp;$e.$attack-strategy();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;call&nbsp;a&nbsp;random&nbsp;method<br> }<br> </code> </p><p><nobr> <wbr></nobr><b>.classify</b> </p><p> <code> my&nbsp;@names&nbsp;=&nbsp;&lt;Patrick&nbsp;Jonathan&nbsp;Larry&nbsp;Moritz&nbsp;Audrey&gt;;<br> say&nbsp;.key,&nbsp;"\t",&nbsp;~.values<br> &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;@names.classify(&nbsp;*.chars&nbsp;);<br> <br> #&nbsp;Output:<br> #&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Larry<br> #&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Moritz&nbsp;Audrey<br> #&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Patrick<br> #&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Jonathan<br> <br><nobr> <wbr></nobr>.say&nbsp;for&nbsp;slurp("README")\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;whole&nbsp;file&nbsp;into&nbsp;string<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.words()\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;split&nbsp;into&nbsp;list&nbsp;of&nbsp;words<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.classify(&nbsp;*.Str&nbsp;)\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;group&nbsp;words&nbsp;w/&nbsp;multiplicity<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.map({;&nbsp;.key&nbsp;=&gt;&nbsp;.value.elems&nbsp;})\<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;turn&nbsp;lists&nbsp;into&nbsp;lengths<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.sort(&nbsp;{&nbsp;-.value&nbsp;}&nbsp;)\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;sort&nbsp;descending<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.[&nbsp;^10&nbsp;];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;10&nbsp;most&nbsp;common&nbsp;words<br> <br> class&nbsp;Student&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;has&nbsp;Str&nbsp;$.name;<br> &nbsp;&nbsp;&nbsp;&nbsp;has&nbsp;Int&nbsp;$.grade&nbsp;is&nbsp;rw;<br> }<br> <br> my&nbsp;Student&nbsp;@students&nbsp;=&nbsp;get-students();<br> for&nbsp;@students.classify(&nbsp;*.grade&nbsp;).sort&nbsp;-&gt;&nbsp;$group&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;"These&nbsp;students&nbsp;got&nbsp;grade&nbsp;$group.key():";<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;.name&nbsp;for&nbsp;$group.value.list;<br> }<br> </code> </p><p><nobr> <wbr></nobr><b>.sort</b> </p><p> <code> #&nbsp;1&nbsp;if&nbsp;$a&nbsp;is&nbsp;higher,&nbsp;-1&nbsp;if&nbsp;$b&nbsp;is&nbsp;higher,&nbsp;0&nbsp;if&nbsp;equal<br> $a&nbsp;&lt;=&gt;&nbsp;$b;<br> <br> #&nbsp;sort&nbsp;students&nbsp;according&nbsp;to&nbsp;grade<br> @students.sort:&nbsp;-&gt;&nbsp;$a,&nbsp;$b&nbsp;{&nbsp;$a.grade&nbsp;&lt;=&gt;&nbsp;$b.grade&nbsp;};<br> <br> #&nbsp;same&nbsp;thing<br> @students.sort:&nbsp;{&nbsp;$^a.grade&nbsp;&lt;=&gt;&nbsp;$^b.grade&nbsp;};<br> <br> #&nbsp;same&nbsp;thing<br> @students.sort:&nbsp;{&nbsp;.grade&nbsp;};<br> <br> #&nbsp;same&nbsp;thing<br> @students.sort:&nbsp;*.grade;<br> <br> #&nbsp;leg&nbsp;gives&nbsp;-1,&nbsp;0&nbsp;or&nbsp;1&nbsp;according&nbsp;to&nbsp;lexicographic&nbsp;ordering<br> #&nbsp;'leg'&nbsp;is&nbsp;for&nbsp;Str,&nbsp;'cmp'&nbsp;is&nbsp;now&nbsp;for&nbsp;type-agnostic&nbsp;sort<br> $a&nbsp;leg&nbsp;$b;<br> <br> #&nbsp;sort&nbsp;students&nbsp;by&nbsp;name&nbsp;(Unicode&nbsp;order)<br> @students.sort:&nbsp;{&nbsp;$^;leg&nbsp;$^;};<br> <br> #&nbsp;same&nbsp;thing<br> @students.sort:&nbsp;*.name;<br> <br> #&nbsp;don't&nbsp;worry,&nbsp;things&nbsp;are&nbsp;properly&nbsp;cached;&nbsp;no&nbsp;re-evaluations<br> @items.sort:&nbsp;*.expensive-calculation();<br> <br> #&nbsp;...which&nbsp;means&nbsp;this&nbsp;works&nbsp;(and&nbsp;is&nbsp;a&nbsp;fair&nbsp;shuffle)<br> @deck.sort:&nbsp;{&nbsp;rand&nbsp;}<br> <br> #&nbsp;...but&nbsp;this&nbsp;is&nbsp;cuter&nbsp;:)<br> @deck.pick(*);</code></p><p> <b> Operator&nbsp;overloading</b> </p><p> <code> sub&nbsp;infix:&lt;&#177;&gt;($number,&nbsp;$fuzz)&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;$number&nbsp;-&nbsp;$fuzz&nbsp;+&nbsp;rand&nbsp;*&nbsp;2&nbsp;*&nbsp;$fuzz;<br> }<br> <br> say&nbsp;15&nbsp;&#177;&nbsp;5;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;somewhere&nbsp;between&nbsp;10&nbsp;and&nbsp;20<br> <br> sub&nbsp;postfix:&lt;!&gt;($n)&nbsp;{&nbsp;[*]&nbsp;1..$n&nbsp;}<br> say&nbsp;5!;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;120<br> <br> class&nbsp;Physical::Unit&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;has&nbsp;Int&nbsp;$.kg&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;these&nbsp;attrs&nbsp;denote&nbsp;powers&nbsp;of&nbsp;units<br> &nbsp;&nbsp;&nbsp;&nbsp;has&nbsp;Int&nbsp;$.m&nbsp;&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;eg&nbsp;$.kg&nbsp;==&nbsp;2&nbsp;means&nbsp;that&nbsp;this&nbsp;object<br> &nbsp;&nbsp;&nbsp;&nbsp;has&nbsp;Int&nbsp;$.s&nbsp;&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;has&nbsp;a&nbsp;kg**2&nbsp;unit<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;has&nbsp;Numeric&nbsp;$.payload;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;method&nbsp;multiply(Physical::Unit&nbsp;$other)&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:kg(&nbsp;$.kg&nbsp;+&nbsp;$;),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:m(&nbsp;$.m&nbsp;+&nbsp;$other.m&nbsp;),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:s(&nbsp;$.s&nbsp;+&nbsp;$other.s&nbsp;),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:payload(&nbsp;$.payload&nbsp;*&nbsp;$other.payload&nbsp;)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;method&nbsp;invert()&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:kg(&nbsp;-$.kg&nbsp;),&nbsp;:m(&nbsp;-$.m&nbsp;),&nbsp;:s(&nbsp;-$.s&nbsp;),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:payload(&nbsp;1&nbsp;/&nbsp;$.payload&nbsp;)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;method&nbsp;Str&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$.payload<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~&nbsp;($.kg&nbsp;??&nbsp;($.kg&nbsp;==&nbsp;1&nbsp;??&nbsp;"&nbsp;kg"&nbsp;!!&nbsp;"kg**$.kg")&nbsp;!!&nbsp;"")<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~&nbsp;($.m&nbsp;&nbsp;??&nbsp;($.m&nbsp;&nbsp;==&nbsp;1&nbsp;??&nbsp;"&nbsp;m"&nbsp;&nbsp;!!&nbsp;"m**$.m")&nbsp;&nbsp;&nbsp;!!&nbsp;"")<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~&nbsp;($.s&nbsp;&nbsp;??&nbsp;($.s&nbsp;&nbsp;==&nbsp;1&nbsp;??&nbsp;"&nbsp;s"&nbsp;&nbsp;!!&nbsp;"s**$.s")&nbsp;&nbsp;&nbsp;!!&nbsp;"")<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> <br> sub&nbsp;postfix:&lt;kg&gt;(Numeric&nbsp;$payload)&nbsp;{&nbsp;;:kg(1),&nbsp;:$payload&nbsp;)&nbsp;} <br><nobr> <wbr></nobr> sub&nbsp;postfix:&lt;m&gt;(Numeric&nbsp;$payload)&nbsp;{&nbsp;;:m(1),&nbsp;:$payload&nbsp;)&nbsp;}<br> sub&nbsp;postfix:&lt;s&gt;(Numeric&nbsp;$payload)&nbsp;{&nbsp;;:s(1),&nbsp;:$payload&nbsp;)&nbsp;}<br> <br> #&nbsp;Note&nbsp;how&nbsp;we&nbsp;now&nbsp;use&nbsp;'multi&nbsp;sub',&nbsp;so&nbsp;as&nbsp;not&nbsp;to&nbsp;shadow&nbsp;the&nbsp;original&nbsp;infix:&lt;*&gt;<br> multi&nbsp;sub&nbsp;infix:&lt;*&gt;(Physical::Unit&nbsp;$a,&nbsp;$b)&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;$a.clone(&nbsp;:payload($a.payload&nbsp;*&nbsp;$b)&nbsp;);<br> }<br> <br> multi&nbsp;sub&nbsp;infix:&lt;*&gt;($a,&nbsp;Physical::Unit&nbsp;$b)&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;$b.clone(&nbsp;:payload($a&nbsp;*&nbsp;$b.payload)&nbsp;);<br> }<br> <br> multi&nbsp;sub&nbsp;infix:&lt;*&gt;(Physical::Unit&nbsp;$a,&nbsp;Physical::Unit&nbsp;$b)&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;$a.multiply($b);<br> }<br> <br> multi&nbsp;sub&nbsp;infix:&lt;/&gt;(Physical::Unit&nbsp;$a,&nbsp;$b)&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;$a.clone(&nbsp;:payload($a.payload&nbsp;/&nbsp;$b)&nbsp;);<br> }<br> <br> multi&nbsp;sub&nbsp;infix:&lt;/&gt;($a,&nbsp;Physical::Unit&nbsp;$b)&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;$b.invert.clone(&nbsp;:payload($a&nbsp;/&nbsp;$b.payload)&nbsp;);<br> }<br> <br> multi&nbsp;sub&nbsp;infix:&lt;/&gt;(Physical::Unit&nbsp;$a,&nbsp;Physical::Unit&nbsp;$b)&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;$a.multiply($b.invert);<br> }<br> <br> say&nbsp;5m&nbsp;/&nbsp;2s;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;2.5&nbsp;m&nbsp;s**-1<br> say&nbsp;100kg&nbsp;*&nbsp;2m&nbsp;/&nbsp;5s;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;40&nbsp;kg&nbsp;m&nbsp;s**-1<br> </code> </p><p> <b>infix:&lt;Z&gt;</b> </p><p> <code> #&nbsp;Z&nbsp;(the&nbsp;'zip&nbsp;operator')&nbsp;means&nbsp;"mix&nbsp;these&nbsp;lists&nbsp;together"<br> my&nbsp;@tastes&nbsp;=&nbsp;&lt;spicy&nbsp;sweet&nbsp;bland&gt;;<br> my&nbsp;@foods&nbsp;=&nbsp;&lt;soup&nbsp;potatoes&nbsp;tofu&gt;;<br> @tastes&nbsp;Z&nbsp;@foods;&nbsp;#&nbsp;&lt;spicy&nbsp;soup&nbsp;sweet&nbsp;potatoes&nbsp;bland&nbsp;tofu&gt;<br> <br> #&nbsp;&#187;&nbsp;means&nbsp;"call&nbsp;the&nbsp;method&nbsp;for&nbsp;each&nbsp;element"<br><nobr> <wbr></nobr>.say&nbsp;for&nbsp;@students&#187;.grade;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;all&nbsp;the&nbsp;grades<br> <br> for&nbsp;@students&#187;.name&nbsp;Z&nbsp;@students&#187;.grade&nbsp;-&gt;&nbsp;$name,&nbsp;$grade&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;"$name&nbsp;got&nbsp;a&nbsp;$grade&nbsp;this&nbsp;year";<br> }<br> <br> #&nbsp;Note&nbsp;that&nbsp;the&nbsp;latter&nbsp;list&nbsp;is&nbsp;infinite&nbsp;--&nbsp;it&nbsp;works&nbsp;anyway<br> for&nbsp;@students&#187;.name&nbsp;Z&nbsp;(1..6).pick(*,&nbsp;:replace)&nbsp;-&gt;&nbsp;$name,&nbsp;$roll&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;"$name&nbsp;rolls&nbsp;a&nbsp;$roll";<br> }<br> <br> #&nbsp;you&nbsp;can&nbsp;also&nbsp;Z&nbsp;together&nbsp;two&nbsp;lists&nbsp;with&nbsp;an&nbsp;infix&nbsp;op<br> my&nbsp;@total-scores&nbsp;=&nbsp;@first-scores&nbsp;Z+&nbsp;@second-scores;<br> <br> #&nbsp;strings&nbsp;as&nbsp;keys,&nbsp;the&nbsp;appropriate&nbsp;number&nbsp;of&nbsp;1s&nbsp;as&nbsp;values<br> my&nbsp;%hash&nbsp;=&nbsp;@names&nbsp;Z=&gt;&nbsp;1&nbsp;xx&nbsp;*;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;xx&nbsp;is&nbsp;list&nbsp;repeat<br> <br> #&nbsp;line&nbsp;people&nbsp;up&nbsp;with&nbsp;increasing&nbsp;numbers<br> my&nbsp;%people2numbers&nbsp;=&nbsp;@people&nbsp;Z=&gt;&nbsp;1..*;<br> <br> #&nbsp;don't&nbsp;have&nbsp;a&nbsp;good&nbsp;op?&nbsp;roll&nbsp;your&nbsp;own!<br> sub&nbsp;infix:&lt;likes&gt;($liker,&nbsp;$likee)&nbsp;{&nbsp;"$liker&nbsp;is&nbsp;fond&nbsp;of&nbsp;$likee"&nbsp;}<br> #&nbsp;note&nbsp;how&nbsp;the&nbsp;op&nbsp;infix:&lt;Zlikes&gt;&nbsp;is&nbsp;automatically&nbsp;available<br> my&nbsp;@relations&nbsp;=&nbsp;@likers&nbsp;Zlikes&nbsp;@likees;<br> </code> </p><p> <b>infix:&lt;...&gt;</b> </p><p> <code> 1&nbsp;...&nbsp;$n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;integers&nbsp;1&nbsp;to&nbsp;$n<br> $n&nbsp;...&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;and&nbsp;backwards<br> <br> 1,&nbsp;3&nbsp;...&nbsp;$n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;odd&nbsp;numbers&nbsp;to&nbsp;$n<br> 1,&nbsp;3,&nbsp;...&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;odd&nbsp;numbers<br> 1,&nbsp;2,&nbsp;4&nbsp;...&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;powers&nbsp;of&nbsp;two<br> map&nbsp;{&nbsp;$_&nbsp;*&nbsp;$_&nbsp;},&nbsp;(1&nbsp;...&nbsp;*)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;squares<br> <br> 1,&nbsp;1,&nbsp;-&gt;&nbsp;$a,&nbsp;$b&nbsp;{&nbsp;$a&nbsp;+&nbsp;$b&nbsp;}&nbsp;...&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;fibonacci<br> 1,&nbsp;1,&nbsp;{&nbsp;$^a&nbsp;+&nbsp;$^b&nbsp;}&nbsp;...&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;ditto<br> 1,&nbsp;1,&nbsp;*+*&nbsp;...&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;ditto<br> <br> 'Camelia',&nbsp;*.chop&nbsp;...&nbsp;'';&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;all&nbsp;prefixes&nbsp;of&nbsp;'Camelia'<br> <br> #&nbsp;See&nbsp;<br> #&nbsp;for&nbsp;the&nbsp;principle&nbsp;behind&nbsp;this<br> sub&nbsp;next-balanced-paren-string($s)&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;$s&nbsp;~~&nbsp;/^&nbsp;(&nbsp;'('+&nbsp;)&nbsp;(&nbsp;')'+&nbsp;)&nbsp;'('&nbsp;/;<br> &nbsp;&nbsp;&nbsp;&nbsp;[~]&nbsp;$s.substr(0,&nbsp;$/.from),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"()"&nbsp;x&nbsp;($1.chars&nbsp;-&nbsp;1),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"("&nbsp;x&nbsp;($0.chars&nbsp;-&nbsp;$1.chars&nbsp;+&nbsp;2),<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;")",<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$s.substr($/.to);<br> }<br> <br> my&nbsp;$N&nbsp;=&nbsp;3;<br> <br> my&nbsp;$start&nbsp;=&nbsp;"()"&nbsp;x&nbsp;$N;<br> my&nbsp;&amp;step&nbsp;=&nbsp;&amp;next-balanced-paren-string;<br> my&nbsp;$end&nbsp;=&nbsp;"("&nbsp;x&nbsp;$N&nbsp;~&nbsp;")"&nbsp;x&nbsp;$N;<br> <br> for&nbsp;$start,&nbsp;&amp;step&nbsp;...&nbsp;$end&nbsp;-&gt;&nbsp;$string&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$string;<br> }<br> <br> #&nbsp;Output:<br> #&nbsp;()()()<br> #&nbsp;(())()<br> #&nbsp;()(())<br> #&nbsp;(()())<br> #&nbsp;((()))<br> </code> </p><p>Rakudo Star releases in a week, July 29th.</p> masak 2010-07-23T01:24:48+00:00 perl6 Happy 10th anniversary, Perl 6 <p>On this date exactly 10 years ago, Jon Orwant threw coffee mugs against a wall during a meeting. Wikipedia chronicles the announcement of Perl 6 as being on July 19 ten years ago... but the throwing of mugs on the 18th can be said to spark the birth of Perl 6.</p><p>Why did he throw mugs? <a href="">Larry Wall's own explanation</a> covers it in sufficient detail:</p><p><div class="quote"><p>We spent the first hour gabbing about all sorts of political and organizational issues of a fairly boring and mundane nature. Partway through, Jon Orwant comes in, and stands there for a few minutes listening, and then he very calmly walks over to the coffee service table in the corner, and there were about 20 of us in the room, and he picks up a coffee mug and throws it against the other wall and he keeps throwing coffee mugs against the other wall, and he says "we are fucked unless we can come up with something that will excite the community, because everyone's getting bored and going off and doing other things".</p></div><p><div class="quote"><p>And he was right. His motivation was, perhaps, to make bigger Perl conferences, or he likes Perl doing well, or something like that. But in actual fact he was right, so that sort of galvanized the meeting. He said "I don't care what you do, but you gotta do something big." And then he went away.</p></div><p><div class="quote"><p>Don't misunderstand me. This was the most perfectly planned tantrum you have ever seen. If any of you know Jon, he likes control. This was a perfectly controlled tantrum. It was amazing to see. I was thinking, "should I get up and throw mugs too?"</p></div><p>When I thought up this blog post, I knew about the incident but wasn't sure when it had happened. I made some Internet research on my own, and couldn't really find a source mentioning the day of the mug throwing.</p><p>I did find <a href="">this email</a>, which outlines the participants and the number of mugs thrown.</p><p>In the end, I asked Larry Wall on IRC about the date. The ensuing pun-ridden discussion is quite typical of #perl6.</p><p> <code>&lt;TimToady&gt;&nbsp;masak:&nbsp;btw,&nbsp;the&nbsp;mugs&nbsp;were&nbsp;the&nbsp;day&nbsp;before<br> &lt;jnthn&gt;&nbsp;mugs?&nbsp;I&nbsp;thought&nbsp;it&nbsp;was&nbsp;just&nbsp;one&nbsp;mug!<br> &lt;masak&gt;&nbsp;jnthn:&nbsp;five.<br> &lt;masak&gt;&nbsp;jnthn:&nbsp;only&nbsp;one&nbsp;broke,&nbsp;though.<br> &lt;masak&gt;&nbsp;TimToady:&nbsp;thanks.&nbsp;still&nbsp;time&nbsp;to&nbsp;prepare&nbsp;for&nbsp;an&nbsp;anniversary&nbsp;blog&nbsp;post,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;then.<br> &lt;jnthn&gt;&nbsp;masak:&nbsp;Smashing.<br> &lt;TimToady&gt;&nbsp;I&nbsp;wish&nbsp;I'd&nbsp;collected&nbsp;the&nbsp;broken&nbsp;mug<br> &lt;masak&gt;&nbsp;"Perl&nbsp;6:&nbsp;breaking&nbsp;mugs&nbsp;and&nbsp;backwards&nbsp;compat&nbsp;since&nbsp;2000"<br> *&nbsp;pmichaud&nbsp;fires&nbsp;up&nbsp;photoshop,&nbsp;looks&nbsp;to&nbsp;cafepress<br> &lt;masak&gt;&nbsp;pmichaud:&nbsp;"Perl&nbsp;6:&nbsp;the&nbsp;greatest&nbsp;language&nbsp;ever&nbsp;to&nbsp;emerge&nbsp;out&nbsp;of&nbsp;the<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shards&nbsp;of&nbsp;a&nbsp;mug."<br> &lt;pmichaud&gt;&nbsp;"Break&nbsp;mug&nbsp;in&nbsp;case&nbsp;of&nbsp;language&nbsp;stagnation."<br> &lt;jnthn&gt;&nbsp;"Perl&nbsp;6.&nbsp;It's&nbsp;Perl&nbsp;5&nbsp;with&nbsp;a&nbsp;cupple&nbsp;of&nbsp;improvements."<br> &lt;pmichaud&gt;&nbsp;"Perl&nbsp;6&nbsp;mugs&nbsp;--&nbsp;another&nbsp;lucky&nbsp;break!"<br> &lt;masak&gt;&nbsp;"if&nbsp;$mug&nbsp;===&nbsp;all&nbsp;@shards&nbsp;{&nbsp;say&nbsp;'We&nbsp;need&nbsp;a&nbsp;break&nbsp;from&nbsp;all&nbsp;the&nbsp;mug&nbsp;puns!' }<br> &lt;jnthn&gt;&nbsp;Oh,&nbsp;you&nbsp;can&nbsp;handle&nbsp;it.&nbsp;:P<br> *&nbsp;masak shatters&nbsp;from&nbsp;laughter<br> &lt;TimToady&gt;&nbsp;"Why's&nbsp;Jon&nbsp;throwing&nbsp;donuts?"&nbsp;&nbsp;--topologist<br> &lt;masak&gt;&nbsp;:P<br> &lt;TimToady&gt;&nbsp;"This&nbsp;is&nbsp;a&nbsp;broken&nbsp;mug.&nbsp;&nbsp;&lt;mug&gt;&nbsp;This&nbsp;is&nbsp;your&nbsp;brane&nbsp;on&nbsp;broken&nbsp;mugs.<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;camelia&gt;&nbsp;Any&nbsp;questions?"<br> &lt;masak&gt;&nbsp;"Perl&nbsp;6:&nbsp;seeking&nbsp;the&nbsp;holy&nbsp;grail&nbsp;after&nbsp;accidentally&nbsp;smashing&nbsp;it&nbsp;ten<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;years&nbsp;ago."<br> &lt;jnthn&gt;&nbsp;"How&nbsp;is&nbsp;mug&nbsp;re-formed?"<br> &lt;masak&gt;&nbsp;They&nbsp;need&nbsp;to&nbsp;do&nbsp;way&nbsp;instain&nbsp;Jon&nbsp;Orwant.<br> &lt;jnthn&gt;&nbsp;Who&nbsp;harms&nbsp;5&nbsp;mugs&nbsp;that&nbsp;cannot&nbsp;frigth&nbsp;back!<br> &lt;masak&gt;&nbsp;My&nbsp;pary&nbsp;are&nbsp;with&nbsp;the&nbsp;cleaner.<br> &lt;masak&gt;&nbsp;"Perl&nbsp;6:&nbsp;poculum&nbsp;iacta&nbsp;est."</code> </p><p>By now, Perl 6 has a 10-year history. I thought I'd spend the rest of the blog post recounting it from (mostly) my perspective. With this I hope I will manage to convey not only the actual sequence of events, but also some of my enthusiasm about the project, and why I think Jon Orwant's broken mug kicked off one of the coolest projects in modern programming language history.</p><p> <b>The early years</b> </p><p>Perhaps you've heard about <strong>the RFC process</strong>. This was right at the beginning of Perl 6's life, when even Larry Wall wasn't sure which direction to take Perl 6, and a system was created wherein people could send in their proposals for language features. Something on the order of 20 or 30 RFCs were excpected before the closing date.</p><p>361 RFCs were sent in.</p><p>Not only were they many more than expected; they were all over the map, mutually inconsistent, and overall each of them advocated one feature without much concern for the rest of the language. Had we somehow decided to go right ahead and just make a language of all those RFCs, we probably would have ended up with something very much like this famous <a href="">parody of Perl 6</a>.</p><p>There was also little concern for <em>how</em> the proposed features would be added. Mark-Jason Dominus wrote in his <a href="">Critique of the Perl 6 RFC Process</a> how a large part of the RFCs neglected to consider the implementation of the proposed features:</p><p><div class="quote"><p>It leads to a who-will-bell-the-cat syndrome, in which people propose all sorts of impossible features and then have extensive discussions about the minutiae of these things that will never be implemented in any form. [...] It distracts attention from concrete implementation discussion about the real possible tradeoffs. [...] Finally, on a personal note, I found this flippancy annoying. There are a lot of people around who do have some understanding of the Perl internals.</p></div><p>Jarkko Hietaniemi countered with a <a href="">more optimistic view</a> of the process:</p><p><div class="quote"><p>[...] now we have an idea of the kind of things (both language-wise and application/data-wise) people want to do in Perl and with Perl, or don't like about Perl. [...] Based on that feedback Larry can design Perl 6 to be more flexible, to accommodate as many as possible of those requests in some way. [...] Without the RFC process we wouldn't have had that feedback.</p></div><p>In the end, Larry Wall took on the work of triaging the RFCs and distilling them into a coherent whole. He did this in the form of <strong>Apocalypses</strong>, which collected the RFCs in different categories and commented on them one by one. The RFCs were either accepted with different amounts of caveats, or rejected. The Apocalypse numbers were based on different chapters in the Camel book; for example, chapter 3 of that book describes operators, so Apocalypse 3 talks about operators in Perl 6.</p><p>Here are all the Apocalypses that were published:</p><ul> <li>Apocalypse 1, May 2001</li><li>Apocalypse 2, May 2001</li><li>Apocalypse 3, Oct 2001</li><li>Apocalypse 4, Jan 2002</li><li>Apocalypse 5, Jun 2002</li><li>Apocalypse 6, Mar 2003</li><li>Apocalypse 12, Apr 2004</li></ul><p>In other words, the whole period 2001-2004 can be seen as the period when Perl 6 was still being distilled from the various wishes people had about it.</p><p>Along with the Apocalypses were published same-numbered <strong>Exegeses</strong>, by Damian Conway who also had a central role in designing Perl 6. Where the Apocalypses were geared towards explaining language decisions for and against features, the Exegeses set out to showcase the new combinations of features, and to explain to Perl 5 programmers the improvements introduced in Perl 6.</p><p>Reading the Exegeses today, what's especially noticeable is the sense of Perl 6 as a variant of Perl 5. Sure there are lots of little tweaks and changes, but as Damian notes after writing a rather elaborate script in E02, "In fact, that's only 40 characters (out of 1779) from being pure Perl 5. And almost all of those differences are @'s instead of $'s at the start of array element look-ups. 98% backwards compatibility even without an automatic p52p6 translator...pretty slick!".</p><p>Not much remains of that idea today; if you'd step into the channel and ask "is Perl 6 like Perl 5?", we'd tell you that while the general goals and ideas can still be discerned, the syntax is so different that it's probably better to start learning it than try to code Perl 6 like one would code Perl 5.</p><p>In 2004, the Apocalypses were summarized down into <strong>Synopses</strong>, which contained the decisions from the Apocalypses without all the explanatory monologue. The Synopses would form a specification for Perl 6 the language, and were directed towards language implementors. They're fairly dense, but still a good read for anyone seriously interested in the language. The synopses are still normative and kept up-to-date. At the time of writing, I count 33 synoptic documents at <a href=""></a>. Synopses 2 through 6 tend to be fairly stable, although changes still occur. The remainder of the synopses are still drafts for the most part, awaiting more feedback from implementations and language use.</p><p>During all this, efforts to start implementing Perl 6 were planned, started and abandoned. Already before the mug throwing and the RFCs, Chip Salzenberg started developing a project code-named <strong>Topaz</strong> in C++, which was slated to grow into Perl 6. The Topaz project, a rewrite of Perl 5 internals, was eventually abandoned. <a href="">I asked Larry</a> why, and he replied that "reimplementing insanity is insane". (Meaning "don't try to extend the Perl 5 internals into Perl 6".)</p><p>There was also a one-week exploration project called <strong>Sapphire</strong>; another rewrite of Perl 5 internals in September 2000, shortly after the announcement of Perl 6, Sapphire was mostly intended to be a sort of tracer bullet to learn things about an eventual real implementation.</p><p>Finally, <strong>Parrot</strong> was a fledgling virtual machine created with the express purpose to be good at running dynamic languages; especially Perl 6, the dynamickest language of the bunch. <strong>Ponie</strong> was an attempt to drag the Perl 5 internals, kicking and screaming, into the Parrot Virtual Machine and have them run there. The Ponie project, as can be read <a href="">here</a> suffered from a too-low bus number as well as Parrot's relative immaturity; Ponie was ultimately "put out to pasture" in 2006. An early implementation of Perl 6 on Parrot was also developed at this time, but by 2004 it had also <a href="">proved to be unworkable</a>.</p><p>As someone on the outside looking in, I knew of Parrot, but not of the other projects. I didn't know about the Perl 6 project that already existed on Parrot, only about the Apocalypses and the Exegeses, all of which I had read with interest. What happened now? Would this programming language ever become a reality? No-one seemed to know. And nothing exciting seemed to happen.</p><p>In early 2005, a certain A. Tang made an entrance, posting a short <a href="">announcement</a> on the perl6-all list of a "side-effect-free subset of Perl6". (Notice the parallels between the tone of this email and Linus Torvald's famous "nothing serious like GNU" announcement.) Before I knew it, the side-effect-free subset of Perl 6 had mutated into something called <strong>Pugs</strong>, a full-fledged implementation.</p><p> <b>Pugs: The golden age</b> </p><p>I remember stumbling into the #perl6 channel on freenode, still fairly dazed by the fact that someone was taking the Synopses and implementing them. Add to this that Audrey Tang turned out to be a frighteningly productive hacker with a magnetic personality which drew other people into the project like nothing I or many others had ever seen. Being on the #perl6 channel was like standing close to the eye of a hurricane; things just magically happened, either because Audrey had just landed another set of commits, or because someone had started a cool side project and was hacking on that, all the while bringing interesting ideas and thoughts into the channel.</p><p>And we were all running (an early version of) Perl 6! Operators, subs, classes, operator overloading... one by one, the cool features we had anticipated started working. We introduced bots to be able to run Perl 6 code right in the channel. Audrey threw out commit rights to the Pugs repository to anyone who made as much as a peep about possible improvements. And it worked! Hundreds of people were given commit-bits, and rather than seeing a massive amount of vandalism like you would on a wiki, we saw a great number of these people contributing constructively to the project. The slogan at that time was to "trust the anarchy", a seriously scary notion. A happy Audrey stood in the middle of it all, guiding the various efforts along, blogging almost daily, contributing insane amounts of code herself, and injecting steam into an ever-more concrete Perl 6 community.</p><p>Pugs is written in Haskell, and many of the cultural traits at the beginning came from the Haskell culture. Pugs hackers went by the moniker "lambda-camels". There was an unusually high amount of references to comp.sci. papers, and books about Haskell, and esoteric books about programming in general. A representative list can still be found in Pugs' <a href="">READTHEM</a> file. The humor was intelligent and often riffed off of some computer topic or other.</p><p> <code>&lt;audreyt&gt;&nbsp;Alias_:&nbsp;my&nbsp;eyeglasses&nbsp;has&nbsp;style="border:&nbsp;none"<br> &lt;Alias_&gt;&nbsp;doesn't&nbsp;matter<br> &lt;Alias_&gt;&nbsp;optical&nbsp;edge&nbsp;cases&nbsp;at&nbsp;the&nbsp;boundaries&nbsp;create&nbsp;border:&nbsp;solid&nbsp;1px&nbsp;#99999<br> &lt;audreyt&gt;&nbsp;true<br> &lt;audreyt&gt;&nbsp;though&nbsp;it's&nbsp;more&nbsp;like&nbsp;ridged&nbsp;in&nbsp;my&nbsp;case<br> *&nbsp;audreyt&nbsp;sighs&nbsp;at&nbsp;the&nbsp;general&nbsp;geekiness</code> </p><p> <code>&lt;audreyt&gt;&nbsp;apparently&nbsp;malaire++&nbsp;is&nbsp;to&nbsp;blame<br> &lt;audreyt&gt;&nbsp;I&nbsp;mean,&nbsp;to&nbsp;praise<br> &lt;audreyt&gt;&nbsp;or&nbsp;to&nbsp;annotate</code> </p><p>The predominant interjection was "woot!". The predominant user of the interjection "woot!" was Audrey. Karma points were the new currency, and bots roamed the channel keeping track of the karma points, or handing them out while emitting real-time commit messages.</p><p>Let me be clear about one thing: at that point on the #perl6 channel, I was a groupie. I didn't contribute significantly to Pugs, or to the discussion around the Synopses or the language itself. I did try my best to contribute to the jokes.</p><p>In March 2005, I had made enough silly noise to get a commit bit:</p><p> <code>&lt;autrijus&gt;&nbsp;welcome&nbsp;aboard!<br> &lt;masak&gt;&nbsp;thx.&nbsp;i&nbsp;could&nbsp;hardly&nbsp;sleep&nbsp;last&nbsp;night&nbsp;because&nbsp;of&nbsp;pugs&nbsp;:)<br> &lt;autrijus&gt;&nbsp;all&nbsp;excited?<br> &lt;masak&gt;&nbsp;overly&nbsp;so<br> &lt;autrijus&gt;&nbsp;I&nbsp;know&nbsp;that&nbsp;feeling&nbsp;:)))</code> </p><p>Audrey kept up a high development tempo, often leading to jokes about her productivity:</p><p> <code>&lt;autrijus&gt;&nbsp;I'll&nbsp;brb&nbsp;--&nbsp;shower&nbsp;&amp;<br> &lt;geoffb&gt;&nbsp;So&nbsp;the&nbsp;rumors&nbsp;of&nbsp;autrijus&nbsp;ircing&nbsp;in&nbsp;the&nbsp;shower&nbsp;appear&nbsp;to&nbsp;be<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false&nbsp;.&nbsp;.&nbsp;.&nbsp;.<br> &lt;geoffb&gt;&nbsp;or&nbsp;maybe&nbsp;he&nbsp;just&nbsp;lurks,&nbsp;with&nbsp;the&nbsp;laptop&nbsp;right&nbsp;outside&nbsp;the&nbsp;curtain.<br> &lt;autrijus&gt;&nbsp;yup.<br> &lt;autrijus&gt;&nbsp;that's&nbsp;usually&nbsp;the&nbsp;case.<br> &lt;autrijus&gt;&nbsp;to&nbsp;avoid&nbsp;damaging&nbsp;the&nbsp;keyboard&nbsp;I&nbsp;usually&nbsp;type&nbsp;with&nbsp;a&nbsp;toothbrush<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;so.<br> &lt;geoffb&gt;&nbsp;LOL</code> </p><p> <code>&lt;Juerd&gt;&nbsp;Every&nbsp;*book*&nbsp;about&nbsp;Perl&nbsp;6&nbsp;is&nbsp;outdated.<br> &lt;Juerd&gt;&nbsp;They&nbsp;are&nbsp;outdated&nbsp;two&nbsp;hours&nbsp;after&nbsp;they&nbsp;are&nbsp;pressed.<br> &lt;Juerd&gt;&nbsp;By&nbsp;the&nbsp;time&nbsp;they&nbsp;are&nbsp;in&nbsp;stores,&nbsp;they&nbsp;are&nbsp;a&nbsp;month&nbsp;behind<br> &lt;Juerd&gt;&nbsp;And&nbsp;by&nbsp;the&nbsp;time&nbsp;you&nbsp;buy&nbsp;and&nbsp;read&nbsp;them,&nbsp;an&nbsp;entire&nbsp;perl&nbsp;6<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interpreter&nbsp;was&nbsp;written&nbsp;by&nbsp;autrijus&nbsp;:)<br> &lt;mauke&gt;&nbsp;while&nbsp;he&nbsp;was&nbsp;sleeping!<br> &lt;castaway&gt;&nbsp;autrijus&nbsp;sleeps?<br> &lt;nothingmuch&gt;&nbsp;castaway:&nbsp;sometimes&nbsp;he&nbsp;claims&nbsp;that<br> *&nbsp;castaway&nbsp;doesnt&nbsp;believe&nbsp;it<br> &lt;mauke&gt;&nbsp;maybe&nbsp;his&nbsp;computer&nbsp;has&nbsp;a&nbsp;neural&nbsp;interface&nbsp;and&nbsp;he&nbsp;codes&nbsp;in&nbsp;his&nbsp;dreams<br> &lt;castaway&gt;&nbsp;this&nbsp;would&nbsp;not&nbsp;surprise&nbsp;me&nbsp;:)<br> &lt;Juerd&gt;&nbsp;castaway:&nbsp;Well,&nbsp;he&nbsp;sometimes&nbsp;says&nbsp;he's&nbsp;off&nbsp;to&nbsp;bed,&nbsp;and&nbsp;then&nbsp;after&nbsp;a<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;few&nbsp;hours&nbsp;you&nbsp;see&nbsp;a&nbsp;huge&nbsp;commit&nbsp;in&nbsp;the&nbsp;logs.&nbsp;So&nbsp;I&nbsp;don't<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;believe&nbsp;it&nbsp;:)<br> &lt;castaway&gt;&nbsp;hehe<br> &lt;castaway&gt;&nbsp;from&nbsp;what&nbsp;I&nbsp;figure,&nbsp;he&nbsp;sleeps&nbsp;only&nbsp;in&nbsp;max.&nbsp;30&nbsp;min&nbsp;chunks,<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;something<br> &lt;Juerd&gt;&nbsp;I&nbsp;think&nbsp;he&nbsp;hyperthreads</code> </p><p>Audrey was once found saying "People think I'm this awesomely great coder, but it's really Haskell and Parsec [a parser combinator library for Haskell] that do all the magic". I didn't see people stop commenting on Audrey's prolificacy because of that, however.</p><p>Somewhere in 2006, Larry Wall joined the channel. He never really left.</p><p> <code>&lt;avar&gt;&nbsp;?eval&nbsp;&lt;good&nbsp;fast&nbsp;cheap&gt;.pick(2)<br> &lt;evalbot_r16148&gt;&nbsp;("good",&nbsp;"cheap")<br> &lt;TimToady&gt;&nbsp;that's&nbsp;us&nbsp;all&nbsp;right...</code> </p><p>We did lose Audrey, however. After her <a href="">gender change</a>, she continued work at an unabated pace; but then she was hit by a serious hepatitis infection, and disappeared in 2007 in the middle of a tough refactor of Pugs, never to return. Pugs ground to a halt. The channel became a lot quieter after she was gone.</p><p>Pugs was (and is) still around, but it had stopped evolving, and it wasn't a full Perl 6 implementation yet. The community still existed, but the central person to hold it together was manifestly missing. Not knowing what the future would hold, I longed for more Pugs.</p><p>(The reason for Audrey's disappearance didn't surface until two years later, when she made a tentative <a href="">blog post</a> about it.)</p><p> <b>Rakudo: The silver age</b> </p><p>Pugs sort of let the genie out of the bottle. Once Audrey had created a "rogue" project that just took off and increasingly embodied the Perl 6 idea, several other people started making <strong>"little" implementations</strong>, too. Between 2005 and now, about a dozen "little" implementations sprang into existence, several of which are still active today. Their respective goals range from exploring to actually implementing the whole language. I call them "little" mainly because they have few developers and a small user base.</p><p>While Pugs arrived with a bang and went dark just as quickly, work continued on implementing Perl 6 on top of Parrot. Progress came much more slowly here, because Parrot was an immature platform and needed a toolchain and compiler ecosystem in order to build Perl 6. Starting in 2005, Patrick Michaud began writing a grammar engine (PGE) and compiler toolkit (PCT) for Parrot. These eventually led to a fledgling Perl 6 implementation in 2007, which in early 2008 was given the name "<strong>Rakudo</strong> Perl 6". To be honest, I didn't pay much attention to it before it got the Rakudo name.</p><p>Patrick had a vision that a Perl 6 implementation needs to have <a href="">a decent Perl 6 grammar engine</a> at its foundation, followed by a good compiler-building toolchain. Once those bits were in place, Patrick turned to the actual Perl 6 compiler and runtime. An intrepid guy named Jonathan Worthington had in an unguarded moment promised Patrick to implement junctions (only to realize that junctions required multi-dispatch, which required the type system, which required much of the OO system to work...).</p><p>Together, Patrick and Jonathan put in feature after feature during the first half of 2008.</p><p>Things were happening again. It didn't look playfully effortless like with Audrey and Pugs; the features I picked up and tried out invariably broke. But things were happening again. Between Pugs, a relatively featureful project which no longer responded to pings, and Rakudo, a slow-moving but active project which could one day be made to do the things Pugs did, I gradually turned my attention to Rakudo.</p><p>The summer of 2008 is a bit of a blur. We (viklund and I) wrote a wiki engine in the not-yet-housebroken Rakudo. It was just a wacky idea we had. If we succeeded in any sense of the word, we said, we'd go to YAPC::EU and present it all in a lightning talk.</p><p>Well, we eventually made it, and we went to YAPC::EU, and we thrilled at the audience reaction upon hearing the news of someone writing a web app in Perl 6. But, um... the corners we cut on the way there. The workarounds for missing features we invented. The bugs we discovered. And it wasn't like we could just pop in on #perl6 and haul out some failing piece of code from our <em>secret project</em>. No; the code had to be scrubbed clean of all wiki-ness first. It was during this time I learned the value of golfing bug reports.</p><p>I submitted many bug reports that summer. All of them scrubbed. It became a bit of a thing, like when little kid starts collecting bottle caps. And it wasn't like Rakudo had a shortage of bugs. For a while, it felt like Rakudo was mostly <em>built</em> out of bugs. This is not meant to be a slight towards Patrick and Jonathan; they were, and are, doing an excellent job. But every project needs to be tested out in the field, and no-one had done that until viklund and I came along. I made field-testing and bug reporting into a sport, going round in a never-ending cycle of doing something new with Rakudo, seeing it break, and submitting a bug ticket about it.</p><p>It felt pretty good to be not so much of a groupie any more, and more of a contributor. Since then I've written a lot of Perl 6 code, and even gotten a Rakudo commit-bit... but I suspect I will remain "the guy who submits all the bugs" for a long time hence.</p><p>The current cultural references seem to lean heavily on lolcat references, exotic smilies, and other contemporary internet memes. Makes for a light-hearted atmosphere, and the contrast between lolcats and compiler guts is often quite refreshing.</p><p> <code>&lt;pmichaud&gt;&nbsp;good&nbsp;morning,&nbsp;#perl6<br> &lt;jnthn&gt;&nbsp;morning,&nbsp;pmichaud<br> &lt;PerlJam&gt;&nbsp;greetings&nbsp;pm<br> &lt;colomon&gt;&nbsp;o/<br> &lt;mathw&gt;&nbsp;o/&nbsp;pmichaud<br> &lt;moritz_&gt;&nbsp;/o/<br> &lt;mathw&gt;&nbsp;\o\<br> &lt;jnthn&gt;&nbsp;\o/&nbsp;|\o/|&nbsp;o&lt;&nbsp;/o\<br> &lt;jnthn&gt;&nbsp;;-)<br> &lt;mathw&gt;&nbsp;aaaaargh<br> *&nbsp;mathw hides<br> &lt;okeCay&gt;&nbsp;o/\o&nbsp;!</code> </p><p>As Rakudo keeps maturing, the Synopses change with it. This is scary to some. How can one start learning a language that keeps changing? Why won't the specification keep still? I can only speak for myself on this issue: I wouldn't want the specification to be "locked down" or "frozen", not as long as the changes going into it are ever-smaller adjustments, most of them responses to insights gained from implementations like Rakudo. On the one hand, the Perl 6 specification changes more than for any other language I know; on the other hand, it's becoming more stable by the day. We call it a kind of "whirlpool development", where later steps in the process are allowed to affect earlier ones, but things are successively centering on one single point.</p><p>IRC can be quite a brusque and unforgiving place, but the #perl6 channel has a reputation as one of the kindest places on the Net. A huge amount of time is spent answering newcomers' questions, helping sort out people's syntax errors, clarifying language terms and design decisions to outsiders and to ourselves, reviewing code, reviewing each other's blog posts, and generally making people feel welcome and cared for on the channel. #perl6 almost never sleeps entirely nowadays, since it has active participants from all over the globe. While we do feel that we have a really cool language to showcase to the world, we're also quite proud over the quality of the Perl 6 culture.</p><p>The story with Rakudo since 2008 is that it's slowly established itself as the front-runner among implementations, even surpassing Pugs in most areas. Rakudo now has most of the operators and control structures in place, excellent regexes and grammars (thanks, Patrick!), excellent OO and multi dispatch (thanks, Jonathan!), and many other very solid features. There are many other smaller implementations which help drive the spec and scout the solution domain in various ways; but Rakudo is the one with the most person-tuits put into it by far nowadays. The list of contributors in the monthly release announcement usually lands at a couple dozen people. Perl 6 is again arriving a little more every day. Life is good. I'm still submitting about one rakudobug a day, but the things submitted are increasingly more high-level and less and less about glaring omissions.</p><p>The action in the past year has been a pretty huge refactor, first of the grammar subsystem, but then of various other subparts that needed ripping out and rewriting. Inwardly, this has been known as a number of smaller projects all being part of a big Rakudo refactor. Outwardly, it has been known as the imminent release of Rakudo Star.</p><p> <b>Rakudo Star: Perl 6 takes off</b> </p><p>Ok, so this part of history hasn't happened yet. But it's about to. On July 29, the Rakudo team is releasing <strong>Rakudo Star</strong>, the first distribution of Rakudo Perl, a Perl 6 implementation. (Info links <a href="">here</a>, <a href="">here</a>, and <a href="">here</a>.)</p><p>I find it quite fitting that 10 years and a couple of days after the Jon Orwant mug that started it all, the Perl 6 people come forth and say "Here. We made this, and it's at a first stage of ready. We've been tinkering with it for quite some time, fixed a lot of bugs and polished the pearl to a relative shine. We'd like you to try it out and make something cool with it."</p><p>I, and many people with me, have been excited about this porcelain descendant for many years now. It's time to let a bigger circle of people in, and let them get excited as well.</p> masak 2010-07-18T19:34:37+00:00 perl6 Phasers are a blast: FIRST and LAST <p>I started thinking about the <code>FIRST</code> and <code>LAST</code> phasers the other day, thanks to moritz++. My attention was on how to implement them in Yapsi, and my conclusions were mostly SIC, but they can be converted to Perl 6 for public view.</p><p>For those who haven't kept up with the latest Perl 6 terminology, "phasers" are what we call those all-caps blocks which fire at different <em>phases</em> during program execution. Perl 5's <code>perldoc perlmod</code> simply calls them "specially named code blocks", but in Perl 6 it's been decided to call them "phasers".</p><p>So much for phasers. What do the <code>FIRST</code> and <code>LAST</code> phasers do? They don't exist in Perl 5. S04 describes them thus:</p><p> <code> FIRST&nbsp;{...}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;loop&nbsp;initialization&nbsp;time,&nbsp;before&nbsp;any&nbsp;ENTER<br> &nbsp;LAST&nbsp;{...}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;loop&nbsp;termination&nbsp;time,&nbsp;after&nbsp;any&nbsp;LEAVE<br> </code> </p><p>(There's a <code>NEXT</code> phasers too, which I'm not going to tackle today. The <code>ENTER</code> and <code>LEAVE</code> phasers are what they sound like; they trigger at block entrance and exit, respectively.)</p><p>Here's some code using these.</p><p> <code> my&nbsp;@a&nbsp;=&nbsp;1,&nbsp;2,&nbsp;3;<br> for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;FIRST&nbsp;{&nbsp;say&nbsp;"OH&nbsp;HAI"&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$item;<br> &nbsp;&nbsp;&nbsp;&nbsp;LAST&nbsp;{&nbsp;say&nbsp;"LOL&nbsp;DONE"&nbsp;}<br> }<br> </code> </p><p>The code, when run, should print the following:</p><p> <code> OH&nbsp;HAI<br> 1<br> 2<br> 3<br> LOL&nbsp;DONE<br> </code> </p><p>(At the time of writing, no Perl 6 implementation implements the <code>FIRST</code> and <code>LAST</code> phasers yet.)</p><p>The goal of this post is <em>transforming</em> the phasers into code using more primitive constructs, but which still produces the above results. Oh, and it should work not only in this case, but in general.</p><p>Here's a first attempt. (Phaser-ful code to the left, rewritten code to the right.) It doesn't work.</p><p> <code> my&nbsp;@a&nbsp;=&nbsp;1,&nbsp;2,&nbsp;3;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;@a&nbsp;=&nbsp;1,&nbsp;2,&nbsp;3;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;"OH&nbsp;HAI";<br> for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;FIRST&nbsp;{&nbsp;say&nbsp;"OH&nbsp;HAI"&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$item;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$item;<br> &nbsp;&nbsp;&nbsp;&nbsp;LAST&nbsp;{&nbsp;say&nbsp;"LOL&nbsp;DONE"&nbsp;}<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;"LOL&nbsp;DONE";<br> </code> </p><p>More exactly, it does produce the desired output, but it doesn't work in general; it fails when <code>@a</code> is empty:</p><p> <code> my&nbsp;@a;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;@a;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;"OH&nbsp;HAI";<br> for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;FIRST&nbsp;{&nbsp;say&nbsp;"OH&nbsp;HAI"&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$item;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$item;<br> &nbsp;&nbsp;&nbsp;&nbsp;LAST&nbsp;{&nbsp;say&nbsp;"LOL&nbsp;DONE"&nbsp;}<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;"LOL&nbsp;DONE";<br> </code> </p><p>This code would still produce <code>"OH HAI\nLOL DONE\n"</code>, which is wrong, because there is no first and last iteration for the empty <code>@a</code> array.</p><p>Ok, we say. No worries; a bit more ad hoc, but we can detect for emptiness. No problem.</p><p> <code> my&nbsp;@a;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;@a;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$HAS_ELEMS&nbsp;=&nbsp;?@a;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;$HAS_ELEMS&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;"OH&nbsp;HAI";<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;FIRST&nbsp;{&nbsp;say&nbsp;"OH&nbsp;HAI"&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$item;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$item;<br> &nbsp;&nbsp;&nbsp;&nbsp;LAST&nbsp;{&nbsp;say&nbsp;"LOL&nbsp;DONE"&nbsp;}<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;$HAS_ELEMS&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;"LOL&nbsp;DONE";<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> </code> </p><p>That works for an empty list, but it fails to work when the <code>FIRST</code> block accesses variables that only exist within the <code>for</code> loop:</p><p> <code> my&nbsp;@a&nbsp;=&nbsp;1,&nbsp;2,&nbsp;3;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;@a&nbsp;=&nbsp;1,&nbsp;2,&nbsp;3;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$HAS_ELEMS&nbsp;=&nbsp;?@a;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;$HAS_ELEMS&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$x&nbsp;#&nbsp;BZZT&nbsp;PARSE&nbsp;ERROR<br> for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$x;<br> &nbsp;&nbsp;&nbsp;&nbsp;FIRST&nbsp;{&nbsp;$x&nbsp;=&nbsp;42&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$item,&nbsp;$x;<br> }<br> </code> </p><p>So. Back to the drawing-board. Two seemingly opposing forces constrain our problem: we need to put the rewritten <code>FIRST</code> block <em>outside</em> the <code>for</code> loop, because we only want it to execute once; but we also need to put it <em>inside</em> the <code>for</code> loop, so that it can have access to the same lexical environment. Is there a compromise somewhere in there?</p><p>Yes. We put the <code>FIRST</code> block inside the <code>for</code> loop, but then we keep track of whether we've already executed it once, with a special variable hidden in the surrounding scope:</p><p> <code> my&nbsp;@a&nbsp;=&nbsp;1,&nbsp;2,&nbsp;3;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;@a&nbsp;=&nbsp;1,&nbsp;2,&nbsp;3;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$FIRST_PHASER_HAS_RUN&nbsp;=&nbsp;False;<br> for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$x;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$x;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless&nbsp;$FIRST_PHASER_HAS_RUN&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;FIRST&nbsp;{&nbsp;$x&nbsp;=&nbsp;42&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$x&nbsp;=&nbsp;42;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$FIRST_PHASER_HAS_RUN&nbsp;=&nbsp;True;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$item,&nbsp;$x;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;say&nbsp;$item,&nbsp;$x;<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> </code> </p><p>Now it all works. This is the general way to make the <code>FIRST</code> behave according to spec. In the presence of several loops within the same block, one can re-use the same variable for all of the loops, just resetting it before each one. Explicitly setting to <code>False</code> even the first time is quite important, in case someone ever implements the <code>goto</code> statement.</p><p>With the <code>LAST</code> phaser, we encounter exactly the same dilemma as with the <code>FIRST</code> loop. The <code>LAST</code> phaser has to be both inside and outside the block; inside because it has to have access to the loop block's variables, and outside because... well, because in general one doesn't know which iteration was the last one until it has already run.</p><p>At one point I had the idea to put the <code>LAST</code> block at the end of the loop block, checking the loop condition just before the placement of the <code>LAST</code> block, possibly saving it somewhere so it doesn't have to be re-evaluated. But the sad truth there's no realistic way to evaluate the loop condition from within the loop block; what if the expression contains a variable which is shadowed by another variable inside the loop block? There's just no way to make that fly.</p><p>The whole situation with the <code>LAST</code> block really looks hopeless... until one remembers about closures:</p><p> <code> my&nbsp;@a&nbsp;=&nbsp;1,&nbsp;2,&nbsp;3;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;@a&nbsp;=&nbsp;1,&nbsp;2,&nbsp;3;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$LAST_PHASER;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$LOOP_HAS_RUN&nbsp;=&nbsp;False;<br> for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;@a&nbsp;-&gt;&nbsp;$item&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$x&nbsp;=&nbsp;"LOL&nbsp;DONE";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$x&nbsp;=&nbsp;"LOL&nbsp;DONE";<br> &nbsp;&nbsp;&nbsp;&nbsp;LAST&nbsp;{&nbsp;say&nbsp;$x&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$LAST_PHASER&nbsp;=&nbsp;{&nbsp;say&nbsp;$x&nbsp;};<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$LOOP_HAS_RUN&nbsp;=&nbsp;True;<br> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;$LOOP_HAS_RUN&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$LAST_PHASER();<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br> </code> </p><p>So in every iteration, we save away a closure <em>just in case</em> that particular iteration turns out to be the last one. Then we execute the last value assigned to the closure, provided the loop ever run. Sneaky, huh?</p><p>So that works in the general case. Of course, a clever optimizer which can detect with certainty that the loop will run at least once and that neither phaser uses loop-specific lexicals is perfectly entitled to rewrite the <code>FIRST</code> and <code>LAST</code> phasers to our first attempt. But the above rewritings work in the general case.</p><p>In explaining this to a colleague, a case of possible confusion involving the <code>FIRST</code> phaser was uncovered:</p><p> <code> for&nbsp;1,&nbsp;2,&nbsp;3&nbsp;{<br> &nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;$x&nbsp;=&nbsp;42;<br> &nbsp;&nbsp;&nbsp;&nbsp;FIRST&nbsp;{&nbsp;say&nbsp;$x&nbsp;}<br> }<br> </code> </p><p>One might perhaps expect this code to print <code>"42\n"</code>, but in fact it prints <code>"Any()"</code>. The reason is simple: whereas the lexical <code>$x</code> is reachable throughout the whole <code>for</code> loop, the <em>assignment</em> of <code>42</code> to it won't occur until <em>after</em> the <code>FIRST</code> block has executed. That's what <code>FIRST</code> blocks do, they execute first. Nevertheless, some people might expect assignments to be treated specially in some way, not counting as "real code" or whatever. But they are, and thus that's the result. In general, reading from freshly declared lexical variables in a <code>FIRST</code> block won't do you much good.</p><p>Lastly, there's this wording in S04:</p><p><div class="quote"><p> <code>FIRST</code>, <code>NEXT</code>, and <code>LAST</code> are meaningful only within the lexical scope of a loop, and may occur only at the top level of such a loop block.</p></div><p>I read that as saying that these kinds of blocks should be <em>illegal</em> if they are found in a block which isn't a loop block. STD.pm6 doesn't enforce this yet; it probably should.</p> masak 2010-07-15T16:13:40+00:00 perl6 Iterating your way to happiness with Perl 6 <p>I thought I'd have an easy time today, just regurgitating what <a href="">S04</a> says about "Loop statements". Perl 5 already got this part pretty right already. Actually, even C got it pretty right. So what new does Perl 6 have to offer? That's what this post is about.</p><p>So, nothing much has changed about the <code>while</code> and <code>until</code> loops that we know and love.</p><p> <code> while EXPR {<nobr> <wbr></nobr>... }<br> until EXPR {<nobr> <wbr></nobr>... }<br> </code> </p><p>Then there's the kind of loop when you want to test the condition *after* the block has run, rather than before. In Perl 5, that looks like this:</p><p> <code> do {<nobr> <wbr></nobr>... } while EXPR;<br> do {<nobr> <wbr></nobr>... } until EXPR;<br> </code> </p><p>This construct tends to cause fresh Perl programmers a lot of grief, since <code>do</code> isn't really a loop construct. There's some wording about this in <a href="">perldoc perlsyn</a>:</p><p><div class="quote"><p>Note also that the loop control statements described later will NOT work in this construct, because modifiers don&#8217;t take loop labels. Sorry.</p></div><p>Perl 6 solves this by</p><ul> <li>recognizing and disallowing <code>while</code> and <code>until</code> after <code>do</code> blocks, and</li><li>introducing the <code>repeat</code> block.</li></ul><p>So now you write it like this instead:</p><p> <code> repeat {<nobr> <wbr></nobr>... } while EXPR;<br> repeat {<nobr> <wbr></nobr>... } until EXPR;<br> </code> </p><p>And you get two bonus features from this: first, since the <code>while</code> or <code>until</code> is mandatory, you can put it on its own line. Generally, closing line-ending curlies act like they have implicit semicolons after them in Perl 6, but here the parser is smart enough to expect a <code>while</code> or <code>until</code>, so it doesn't put one in.</p><p>Second, you're allowed to put the condition up front if you want:</p><p> <code> repeat while EXPR {<nobr> <wbr></nobr>... }<br> repeat until EXPR {<nobr> <wbr></nobr>... }<br> </code> </p><p>Even though the condition is <em>before</em> the loop here, it'll still not be run until <em>after</em> each iteration, because it's a <code>repeat</code> loop, and they work like that.</p><p>Then there's the loop construct that loops forever, aptly named <code>loop</code>:</p><p> <code> loop {<nobr> <wbr></nobr>... } </code> </p><p>In C, we'd have that as <code>for (;;) {<nobr> <wbr></nobr>... }</code>. And, symmetrically, you can also write it like this in Perl 6:</p><p> <code> loop (;;) {<nobr> <wbr></nobr>... } </code> </p><p>Or, more generally, you can do any C-style for loop, if you just spell it <code>loop</code>:</p><p> <code> loop (EXPR; EXPR; EXPR) {<nobr> <wbr></nobr>... } </code> </p><p>And what was known alternately in Perl 5 as <code>for</code> and <code>foreach</code> becomes just <code>for</code> in Perl 6.</p><p>The syntax for <code>for</code> in Perl 6 is what you'd expect:</p><p> <code> for EXPR {<nobr> <wbr></nobr>... } </code> </p><p>But it packs a lot more power underneath. Or rather, the whole <em>language</em> is geared towards packing <code>for</code> with a lot more power. Some examples:</p><ul> <li>If you want to name the item you're currently looping over, just prefix the block with <code>-&gt; $a</code>. (If you don't, you'll find the item in <code>$_</code>, as usual.)</li><li>If you want to loop two items at a time, prefix the block with <code>-&gt; $a, $b</code>.</li><li>Neither of the above are special syntaxes belonging to the <code>for</code> construct as such; rather, the <code>-&gt;</code> arrows belong to the block, making it, in the prevailing terminology, a "pointy block". In fact, <em>all</em> of the loop constructs I've brought up (except the C-style loop) can be given pointy blocks; the expression will then be bound to the variable and usable from within the block. You can do it with <code>if</code> statements, too! It's quite useful.</li><li>If you want to loop over two lists simultaneously, you can use the <code>infix:&lt;Z&gt;</code> operator to interleave the lists. Loop one item at a time, and you'll get alternating elements from the two lists. Loop two at a time, and <code>$a</code> (or whatever) will always be from the first list, and <code>$b</code> from the second. Gone are the days when you had to do manual trickery with indexes and stuff because the <code>for</code> loop wasn't powerful enough.</li><li>You can even eliminate nested loops sometimes with the <code>infix:&lt;X&gt;</code> operator, which does a Cartesian product (known in SQL circles as a "cross join") of two lists. So if you planned to do <code>for @a { for @b {<nobr> <wbr></nobr>... } }</code> anyway, you might as well do <code>for @a X @b {<nobr> <wbr></nobr>... }</code> and save yourself one level of indentation.</li><li>All of the above is lazy, so with a sensible Perl 6 implementation, there's no huge memory waste from building up all these big lists; it's all generated on-the-fly. (This, incidentally, means that we also read files with <code>for</code> loops in Perl 6, rather than with a magical <code>while</code> construct as in Perl 5.)</li></ul><p>That's it for today. I forgot to mention the looping construct that only loops over <em>one</em> item... but you can look that one up yourself. Oh, and Perl 5.10 also has it.</p><p>Actually, I got to thinking about all this, since I figured out the other day how to do the <code>FIRST</code> and <code>LAST</code> phasers in Yapsi. But this blog post felt like a natural precursor to the one I wanted to write. Hopefully soon. &#21704;&#21704;</p> masak 2010-07-11T21:55:01+00:00 perl6 Weeks 6 and 7 of GSoC work on Buf -- roundtrip <p> <em>Warning: this blog post doesn't contain any puns at all. It's just a boring update about my progress. If you don't believe me, just go ahead and read it. I dare you.</em> </p><p>Been working on file I/O and <code>Buf</code>s lately. It's tough work, but I'm now at a point where things run. Some highlights:</p><ul> <li>I <a href="">asked on Parrot</a> how to write binary data. Got enough help to get me started coding an <code>IO.write</code> method.</li><li>I realized that I didn't like at all how the IO spec described <code></code> and <code>IO.write</code>. So I <a href="">rewrote</a> it.</li><li>Having got the <code>IO.write</code> method working, I wrote an <code></code> method along the same lines. <a href="">Here they are</a>.</li></ul><p>Now, these new methods obviously write and read bytes to and from files, but the tests indicate that things don't properly round-trip yet. Part of that is because <a href="">the tests</a> want the example string "f&#246;&#246;" to encode as iso-8859-1, but there's no logic that does that yet. My slightly sleepy brain tells me there's more to the story though, or the string wouldn't come back garbled as "f&#195;&#182;". (Interesting how that somehow <em>feels</em> like a small piece of <a href="">mojibake</a>, before the brain even takes in the individual characters.)</p><p>Another nice highlight was my question about <a href="">how <code>Buf</code>s should stringify</a>, which <a href="">TimToady just answered</a> on #perl6. That should be a smop to implement.</p> masak 2010-07-09T23:25:12+00:00 perl6 Dreaming in mixins <p>Working with pls (a next-gen project installer for the Perl 6 ecosystem), I had a few classes with code like this:</p><blockquote><div><p> <tt>class POC::Tester does App::Pls::Tester {<br>&nbsp; &nbsp; method test($project --&gt; Result) {<br>&nbsp; &nbsp; &nbsp; &nbsp; my $target-dir = "cache/$project&lt;name&gt;";<br>&nbsp; &nbsp; &nbsp; &nbsp; if "$target-dir/Makefile" !~~<nobr> <wbr></nobr>:e {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return failure;<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; unless run-logged( relative-to($target-dir, "make test"),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:step('test'),<nobr> <wbr></nobr>:$project ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return failure;<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br> <br>&nbsp; &nbsp; &nbsp; &nbsp; return success;<br>&nbsp; &nbsp; }<br>}</tt></p></div> </blockquote><p>(<code>success</code> and <code>failure</code> are <code>Result</code> enum values defined elsewhere. They felt like pleasant documentation, and when return type checking works, they'll even help catch errors!)</p><p>Now, I wanted to add super-simple progress diagnostics to this method. I wanted an <code>announce-start-of('test', $project);</code> at the start of the module, and either an <code>announce-end-of('test', success);</code> or an <code>announce-end-of('test', failure);</code>, depending on the success or failure of the method.</p><p>I have a low threshold for boilerplate. After realizing that I'd have to manually add those calls in the beginning of the method, and before each <code>return</code> &#8212; and not only in this method, but in several others &#8212; I thought "man, I shouldn't have to tolerate this. This is Perl 6, it should be able to do better!"</p><p>So I thought about what I really wanted to do. I wanted some sort of... method wrapper. Didn't really want a subclass, and a regular role wouldn't cut it (because class methods override same-named role methods).</p><p>Then it struck me: <em>mixins</em>. Did those already work in Rakudo? Oh well, try it and see. So I created this role:</p><blockquote><div><p> <tt>role POC::TestAnnouncer {<br>&nbsp; &nbsp; method test($project --&gt; Result) {<br>&nbsp; &nbsp; &nbsp; &nbsp; announce-start-of('test', $project&amp;lt;name&amp;gt;);<br>&nbsp; &nbsp; &nbsp; &nbsp; my $result = callsame;<br>&nbsp; &nbsp; &nbsp; &nbsp; announce-end-of('test', $result);<br>&nbsp; &nbsp; &nbsp; &nbsp; return $result;<br>&nbsp; &nbsp; }<br>}</tt></p></div> </blockquote><p>And then, later:</p><blockquote><div><p> <tt> does POC::TestAnnouncer</tt></p></div> </blockquote><p>And it worked! On the first attempt! jnthn++!</p><p>(If you're wondering what in the above method that does the wrapping &#8212; it's the <code>callsame</code> call in the middle. It delegates back to the overridden method. Note that with this tactic, I get to write my <code>announce-start-of</code> and <code>announce-end-of</code> calls <em>exactly once</em>. I don't have to go hunting for all the various places in the original code where a <code>return</code> is made.)</p><p>I guess this counts as using mixins to do Aspect-Oriented Programming. This way of working certainly makes the code less <a href="">scattered and tangled</a>.</p><p>So, in <a href="">this file</a>, I currently have a veritable curry of dependency injection, behavior-adding roles, lexical subs inside methods, AOP-esque mixins, and a <code>MAIN</code> sub. They mix together to create something really tasty. And it all runs, today, under Rakudo HEAD.</p><p>As jnthn said earlier today, it's pretty cool that a script of 400 LoC, together with a 230-LoC module, make up a whole working installer. With so little code, it almost doesn't feel like coding.</p> masak 2010-07-04T01:28:38+00:00 perl6 Speaking hypothetically in Perl 6 <p>So, arrays and hashes are considered central enough in Perl that they each have their own sigil, as well as a dedicated circumfix constructor:</p><p> <code> Type&nbsp;&nbsp;&nbsp;&nbsp;Sigil&nbsp;&nbsp;&nbsp;Circumfix<br> ====&nbsp;&nbsp;&nbsp;&nbsp;=====&nbsp;&nbsp;&nbsp;=========<br> Array&nbsp;&nbsp;&nbsp;@&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ ]<br> Hash&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ }<br> </code> </p><p>Apart from those, we consider scalars quite important, but they're really "containers of anything", including (references to) arrays and hashes. The <code>$</code> sigil simply means "untyped". Because of this, there's not really a circumfix constructor.</p><p> <code> Type&nbsp;&nbsp;&nbsp;&nbsp;Sigil&nbsp;&nbsp;&nbsp;Circumfix<br> ====&nbsp;&nbsp;&nbsp;&nbsp;=====&nbsp;&nbsp;&nbsp;=========<br> <strong>Scalar&nbsp;&nbsp;$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;N/A</strong> <br> Array&nbsp;&nbsp;&nbsp;@&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ ]<br> Hash&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ }<br> </code> </p><p>But there's one more sigil; one which has had to fight a bit more for its place in the food chain... but this is the one that really makes the hackers over at "Lambda the Ultimate" smile. Introducing the <code>&amp;</code> sigil:</p><p> <code> Type&nbsp;&nbsp;&nbsp;&nbsp;Sigil&nbsp;&nbsp;&nbsp;Circumfix<br> ====&nbsp;&nbsp;&nbsp;&nbsp;=====&nbsp;&nbsp;&nbsp;=========<br> Scalar&nbsp;&nbsp;$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;N/A<br> Array&nbsp;&nbsp;&nbsp;@&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ ]<br> Hash&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ }<br> <strong>Block&nbsp;&nbsp;&nbsp;&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ }</strong> <br> </code> </p><p>Ok, hold on a minute. <code>Block</code>? A block of what?</p><p>So here's the really neat thing. In many situations in perfectly normal, sane programming, we end up with wanting to execute some code, just <em>not right now</em>. Just as we'd reach for an array or a hash when we want to collect some structured data for later, we can reach for this block thingy when we want to collect some executable code for later.</p><p>If you haven't done this, I can see how it all sounds terribly esoteric, even pointless. You'd go "Just wait until later, and run the code at that point rather than passing around un-run code!", and if a <code>Block</code> was only what I've told you so far, I'd agree with you.</p><p>But it's more. A <code>Block</code> is automatically a <em>closure</em> &#8212; and this is where people who've grokked this normally use big words (like "it closes over its lexical environment!") and the eyes of people who are struggling to understand glaze over. So I'll go slow.</p><p>Take a look at the <code>Counter</code> class in <a href="">this blog post</a>. Hm, I'll reproduce it here for you:</p><p> <code> class LazyIterator {<br> &nbsp;&nbsp;&nbsp;&nbsp;has $!it;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;method get() {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$!it();<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> <br> class Counter is LazyIterator {<br> &nbsp;&nbsp;&nbsp;&nbsp;method new(Int $start) {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $count = $start;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.bless(*,<nobr> <wbr></nobr>:it({ $count++ }));<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> }<br> </code> </p><p>The <code>new</code> method contains code both to initialize and to increase <code>$count</code>, but only the initialization code (<code>my $count = $start;</code>) is run. The increasing code (<code>{ $count++ }</code>) is inside a <code>Block</code>, and thus protected from immediate execution. Instead, it's just stored away in the private attribute <code>$!it</code> (for "iterator").</p><p>When is <code>$counter</code> actually increased? Well, each time we call the <code>LazyIterator.get</code> method, it executes the <code>Block</code> stored in the <code>$!it</code>. This all seems perfectly obvious, until one starts to think about how magical it actually is. It increases... what, again? <code>$counter</code>? Which is... where, exactly? <em>In the lexical scope of the <code></code> method, which finished ages ago, and which by the way is in a subclass that wasn't even defined when we defined <code>LazyIterator.get</code>!!!</em> </p><p>For that to even have a chance at working, the <code>Block</code> in <code>$!it</code> must "save away" <code>$counter</code> from the lexical scope of the <code></code> method, enough for it to avoid being eaten by an evil garbage collector, etc. This is totally magical! It's as if you opened an empty bottle in orbit around Neptune to let some darkness in, and then whenever you opened the bottle again, <em>no matter where you were</em>, you'd get the same Neptune darkness from within the bottle.</p><p>Or like me coming to visit you, but instead of leaving my phone number, I activate one half of an entangled-pair portal in your living room and take the other half with me. Afterwards, I can just scribble whatever I want on my half, and you'd see it instantaneously appear in the other half in your living room. That's how insanely great closures are.</p><p>One of the very first blog posts I wrote here at was about <a href="">that magical ability of closures</a> to hold on to the environment in which they were created. Be sure to check out <a href="">the diagram</a> that goes with it, which explains how closures can be used to decouple parts of a large object-oriented system.</p><p>In fact, closures &#8212; or <a href="">lambda expressions</a>, same thing &#8212; are so general that they have been shown to be <em>universal</em>. That is, anything that a computer algorithm can do, lambda expressions can do, too. (In fact, Alonzo Church developed lambda calculus and used it to prove the <a href="">Halting Problem</a> undecidable in April 1936, only one month before Alan Turing showed the same with his <em>gedanken</em> state machine. In an addendum published that autumn, Turing shows that lambda calculus and his machine are equal in power.)</p><p>By the way, did you notice in the table at the start of the post that both hashes and blocks use the same circumfix constructor, <code>{ }</code>? How will you know when you've got a hash and when you've got a block of code?</p><p> <a href="">S04</a> explains and gives plenty of examples.</p><p> <code> $hash = { };<br> $hash = { %stuff };<br> $hash = { "a" =&gt; 1 };<br> $hash = { "a" =&gt; 1, $b, $c, %stuff, @nonsense };<br> <br> $code = { %_ };&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# use of %_<br> $code = { "a" =&gt; $_ };&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# use of $_<br> $code = { "a" =&gt; 1, $b, $c, %stuff, @_ };&nbsp;&nbsp;# use of @_<br> $code = { ; };<br> $code = { @stuff };<br> $code = { "a", 1 };<br> $code = { "a" =&gt; 1, $b, $c ==&gt; print };<br> </code> </p><p>Briefly, the code block will degenerate to a hash if it's empty or contains only a comma-separated list starting with either a pair or a <code>%</code>-sigil variable, and if it doesn't make use of any parameters. You can confirm that this covers all the cases above.</p><p>That might seem like a slightly arbitrary way of deciding, but it's actually the result of a fair bit of back-and-forth in the spec about when something is a closure and when it's a hash &#8212; and this spec iteration feels like a keeper. The previous ones led people into tricky situations where they supplied what they thought was a closure to a <code>map</code>, but it turned out to evaluate to a hash, and the multi dispatch to <code>map</code> failed. That doesn't seem to happen with the current spec, which is a good sign.</p><p>What are some common functions that accept blocks as arguments? I've already mentioned <code>map</code>, but even though the <a href=""> <code>map</code>/<code>grep</code>/<code>sort</code> triad</a> has that slightly built-in feel, so they're not really a good example.</p><p>Here's one that's a good example:</p><p> <code> $sentence = 'eye drops off shelf';<br> $newspaper-heading = $sentence.subst(/ \S+<nobr> <wbr></nobr>/, { $/.ucfirst },<nobr> <wbr></nobr>:global);<br> say $newspaper-heading; # Eye Drops Off Shelf<br> </code> </p><p>The vital part is the <code>{ $/.ucfirst }</code> block. Why do we need to put that part in a block? Because if we didn't, it'd get executed immediately, as in <em>before the<nobr> <wbr></nobr><code>.subst</code> call was even made</em>. The <code>{ }</code> block constructor creates a protective shell of delayed action (same principle as with orally administered pills, really), and the <code>substr</code> method can then invoke the block when the time is right &#8212; i.e. after a match has been found. Newcomers on <code>#perl6</code> often leave out the curlies, thinking that it'll magically work anyway.</p><p>If you're with me so far, you're ready for the next "look ma, no curlies!" stage.</p><p>We like closures so much (as language designers) that we want to build them into a lot of places. There are a number of places when we want to build them in so much that we even decide to lose the <code>{ }</code> circumfix! If that sounds crazy, just look at these perfectly harmless examples:</p><p> <code> if !@food || <strong>@food[0].lc eq 'marmite'</strong> {<br> &nbsp;&nbsp;&nbsp;&nbsp;say "You either have no food or just marmite!";<br> }<br> <br> class VeryImportantObject {<br> &nbsp;&nbsp;&nbsp;&nbsp;has $!creation-time = <strong>time()</strong>;<br> }<br> <br><nobr> <wbr></nobr><strong>.flip.say</strong> for lines();<br> </code> </p><p>In all of the above cases, it's as if <em>invisible <code>{ }</code> curlies</em> have been inserted around the emboldened parts for us, and then evaluated only if/when the time was right. Closures without curlies are sometimes referred to as "thunks".</p><p>(Why don't we special-case the second argument of <code>Str.subst</code> in the same way? Well, we certainly could, but it'd be kind of unfair to all other user-defined methods which don't automatically get the same special treatment. Somehow it's more OK to thunk language constructs like the <code>infix:&lt;||&gt;</code> operator, or <code>has</code>, or statement-modifying <code>for</code>, than it is to thunk the second argument in some method somewhere. But it's a perfect gotcha for static analysis to catch.)</p><p>But Perl 6 also gives you, the programmer, a way to omit the curlies if you just want to create a little one-off closure somewhere. It's provided through the ubiquitous "whatever" star, after which <a href="">Rakudo Star</a> was named.</p><p>The whatever star represents a curious bit of spec development, kind of a little idea that seemed to get a life of its own after a while and spread everywhere, like gremlins. It all started when the old "index from the end" syntax from Perl 5 was re-considered:</p><p> <code> @a[ -1]&nbsp;&nbsp;&nbsp;&nbsp;# getting the last element in Perl 5<br> @a[*-1]&nbsp;&nbsp;&nbsp;&nbsp;# getting the last element in Perl 6<br> </code> </p><p>Why was this change made? <a href="">S09</a> sums it up:</p><p><div class="quote"><p>The Perl&#160;6 semantics avoids indexing discontinuities (a source of subtle runtime errors), and provides ordinal access in both directions at both ends of the array.</p></div><p>When this feature was finally implemented in Rakudo, instead of treating the <code>* - 1</code> like a syntactic oddity that's only allowed to occur inside array indexings, they generalized the concept so that <code>* - 1</code> means <code>{ $_ - 1 }</code>. (Note the surrounding block curlies.) This was considered nifty and trickled back into the spec. So now you can use all of the following forms to mean the same thing:</p><p> <code> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ $_ - 1 } # means "something minus one"<br> -&gt; $_ { $_ - 1 }&nbsp;# explicit lambda mention of $_<br> -&gt; $a { $a - 1 }&nbsp;# change the name of the param<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ $^a - 1 } # "self-declaring" param<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* - 1&nbsp;&nbsp;&nbsp;# note the lack of curlies<br> </code> </p><p>I haven't mentioned the "self-declaring" type of parameter so far. They're very nice, especially in small blocks where an explicit signature would give the block too much of a front weight. The spectical name for those are "placeholder variables", because they make a space for themselves in the parameter list, I guess. The place they get is their rank in an ascending string sort, by the way. You can't have both an explicit signature and placeholder variables for the same block &#8212; it's an either-or thing.</p><p>(Also, the only form which isn't <em>exactly</em> identical in the list above, is the first one, which actually translates to <code>-&gt; $_? { $_ - 1 }</code>. That is, the <code>$_</code> is optional, and you can call the block with 0 arguments. I don't remember the rationale for this, nor whether I've ever benefitted from it.)</p><p>A recent spec change generalized the whatever star so that if two or more occur in the same expression, they get assigned successive parameter slots. <code>* + *</code> translates into <code>{ $^a + $^b }</code>, for example. So they're really starting to look a bit like "anonymous placeholder variables".</p><p>Now for the actual impetus for this post: in August 2000, almost ten years ago, Damian Conway made <a href="">an RFC which anticipated a lot of the features</a> outlined in this post. And it does this while suggesting syntax which is consistently less mnemonic and less maintainable than what we eventually ended up with. (Not the fault of Damian-from-ten-years-ago, of course. I'm pretty sure he's been instrumental in guiding us to many of the solutions we have today.)</p><p>Here's a quick summary of the key points of the RFC, and the modern Perl 6 responses:</p><ul> <li>The RFC suggests that one common use case for the "higher-order functions" (as it calls the closures) is in case statements with comparison ops in them, such as <code>case ^_ &lt; 10 { return 'milk' }</code>. Note that the whatever star nicely fills this niche: <code>when * &lt; 10 { return 'milk' }</code>.</li><li>Much of the rest of the RFC seems to be handled well today with either lambda signatures or placeholder variables (the <code>$^a</code> ones). <code>$check = ^cylinder_vol == ^radius**2 * ^height or die ^last_words;</code> could today be written <code>$check = -&gt; $cylinder_vol, $radius, $height, $last_words { $radius ** 2 * $height or die $last_words };</code>. I hesitate to put that example in placeholder-variable form, because they're too many and the alphabetical mess would be too hard to maintain, even once.</li><li>The model we ended up with doesn't do automatic currying, like in the RFC. We do, however, have the extremely nice method<nobr> <wbr></nobr><code>.assuming</code> on all <code>Code</code> objects (including <code>Block</code>), which gives you back a new <code>Code</code> object with one or more parameters pre-set.</li><li>Generally, the modern variants lean towards either explicit curlies or a whatever star to tell you that something mildly magical is going on. With the syntax proposed in the RFC, I suspect I'd be constantly less-than-certain about where implicit blocks ended.</li></ul><p>In <a href="">Apocalypse 6</a> the RFC was accepted with a "c" rating (that's for "major caveats"). I think that's accurate, because the spirit of the RFC definitely lives on, but the syntax of it all turned out much, much better. I guess that's the point of having the role of Language Designer centralized to one person.</p><p>Having exhausted the things I have to say about this topic, I'll stop here and see if I can get some closure myself. &#21704;&#21704;</p> masak 2010-07-02T19:25:17+00:00 perl6 Yapsi 2010.07 Released! <p>It is with an unwarranted sense of contentment that I want to announce, on behalf of the Yapsi development team, the July 2010 release of Yapsi, a Perl 6 compiler written in Perl 6.</p><p>You can get it <a href="">here</a> &#8212; try it, it's fresh!</p><p>Yapsi is implemented in Perl 6. It thus requires a Perl 6 implementation to build and run. We recommend the 'alpha' branch of Rakudo for this purpose. In practice, this means downloading Rakudo Minneapolis (#25) from January 2010.</p><p>Yapsi is an "official and complete" implementation of Perl 6. The fact that it's complete follows from a simple mis-applied proof technique: adding to something complete, one certainly doesn't make it less complete. We are making plenty of additions to Yapsi. Hence, Yapsi is complete; QED. It's official because there's no official definition of "official".</p><p>Here's how to get Yapsi up and running, once you have it:</p><ul> <li>Make sure you have a built Rakudo alpha in your $PATH as 'alpha'.</li><li>(Optionally) run 'make' for a load-time speedup.</li></ul><p>This month's release introduces 'if'/'else' statements and 'while' loops. Having Yapsi run all day on your computer just got a little easier. You're welcome.</p><p>Quite a lot of features are now within reach of people who are interested in hacking on Yapsi. See the <a href="">doc/LOLHALP</a> file for a list of 'em.</p><p>Yapsi consists of a compiler and a runtime. The program is compiled down into an instruction code that is "closer to the machine", for some imaginary value of "machine". Compiling down to an instruction code is not strictly necessary; if we wanted, we could compile down to tiny pecan pies. (But that would be NUTS! What we do instead is just plain SIC.) The instruction set changes quite a bit between releases; if you rely on SIC being stable between releases, you are completely bananas.</p><p>An overarching goal for making a Perl 6 compiler-and-runtime is to use it as a server for various other projects, which will hook in at different steps:</p><ul> <li>A time-traveling debugger (tardis), which hooks into the runtime.</li><li>A coverage tool (lid), which will also hook into the runtime.</li><li>A syntax checker (sigmund), which will use output from the parser.</li></ul><p>Another overarching goal is to optimize for fun while learning about parsers, compilers, and runtimes. We wish you the appropriate amount of fun!</p> masak 2010-07-01T21:48:43+00:00 perl6 Weeks 4 and 5 of GSoC work on Buf -- chrono-flies <p>Chrono-flies (<i>Drosophila chronogaster</i>, commonly known as "time-flies") are known for their fondness for arrows. Lately I've been distracted enough (by <code>$DAYJOB</code>, other Perl 6 projects, and other non-Perl 6 projects) to let two weeks pass by with only one commit in my local branch:</p><ul> <li> <code>Buf</code> is now <code>Positional</code>, and you can index it with <code>postcircumfix:&lt;[ ]&gt;</code>.</li></ul><p>I merged/pushed that one a few moments ago.</p><p>For good measure (pronounced "only one commit! how'd that happen?"), I did some pre-investigation this evening as to how one might read binary data from a file into a <code>Buf</code>. <a href="">cotto++ outlined how</a>. Haven't finished thinking about this, but it does seem perfectly doable, which is a notch better than I feared. &#21704;&#21704;</p><p>Also, worth noting here: remember how in Week 2, I <a href="">changed the <code>Buf</code> constructor spec</a> from slurpy array to non-slurpy array? Well, <a href="">pmichaud wondered why</a>, and it led to an interesting discussion. Will synch up with jnthn to see if it perhaps merits changing back for consistency with other list-y types.</p> masak 2010-06-28T21:27:03+00:00 perl6 Announce: Rakudo Perl 6 development release #30 ("Kiev") <p>On behalf of the Rakudo development team, I'm pleased to announce the June 2010 development release of Rakudo Perl #30 "Kiev". Rakudo is an implementation of Perl 6 on the Parrot Virtual Machine (see <a href=""></a>). The tarball for the June 2010 release is available from <a href="">Github</a>.</p><p>Rakudo Perl follows a monthly release cycle, with each release named after a Perl Mongers group. This release is named after the Perl Mongers from the beautiful Ukrainian capital, Kiev. They recently helped organize and participated in the Perl Mova + YAPC::Russia conference, the &#1093;&#1072;&#1082;&#1084;&#1080;&#1090; (hackathon) of which was a particular success for Rakudo. All those who joined the Rakudo hacking &#8212; from Kiev and further afield &#8212; contributed spec tests as well as patches to Rakudo, allowing various RT tickets to be closed, and making this month's release better. &#1044;&#1103;&#1082;&#1091;&#1102;!</p><p>Some of the specific changes and improvements occurring with this release include:</p><ul> <li>Rakudo now uses immutable iterators internally, and generally hides their existence from programmers. Many more things are now evaluated lazily.</li><li>Backtraces no longer report routines from Parrot internals. This used to be the case in the Rakudo alpha branch as well, but this time they are also very pleasant to look at.</li><li>Match objects now act like real hashes and arrays.</li><li>Regexes can now interpolate variables.</li><li>Hash and array slicing has been improved.</li><li>The REPL shell now prints results, even when not explicitly asked to print them, thus respecting the "P" part of "REPL".</li><li>Rakudo now passes 33,378 spectests. We estimate that there are about 39,900 tests in the test suite, so Rakudo passes about 83% of all tests.</li></ul><p>For a more detailed list of changes see <a href="">docs/ChangeLog</a>.</p><p>The development team thanks all of our contributors and sponsors for making Rakudo Perl possible, as well as those people who worked on parrot, the Perl 6 test suite and the specification.</p><p>The following people contributed to this release: Patrick R. Michaud, Moritz Lenz, Jonathan Worthington, Solomon Foster, Patrick Abi Salloum, Carl M&#228;sak, Martin Berends, Will "Coke" Coleda, Vyacheslav Matjukhin, snarkyboojum, sorear, smashz, Jimmy Zhuo, Jonathan "Duke" Leto, Maxim Yemelyanov, St&#233;phane Payrard, Gerd Pokorra, cognominal, Bruce Keeler, &#198;var Arnfj&#246;r&#240; Bjarmason, Shrivatsan, Hongwen Qiu, quester, Alexey Grebenschikov, Timothy Totten</p><p>If you would like to contribute, see <a href="">"How to help"</a>, ask on the <a href="">perl6-compiler</a> mailing list, or ask on IRC #perl6 on freenode.</p><p>The next release of Rakudo (#31) is scheduled for July 22, 2010. A list of the other planned release dates and code names for 2010 is available in the <a href="">docs/release_guide.pod</a> file. In general, Rakudo development releases are scheduled to occur two days after each Parrot monthly release. Parrot releases the third Tuesday of each month.</p><p>Have fun!</p> masak 2010-06-17T23:46:47+00:00 perl6 It isn't quite TDD, but I like it <p>In several tightly controlled projects over the past few years, I seem to either follow or approximate this sequence of steps:</p><ol> <li>Write a test suite <strong>skeleton</strong>.</li><li>Flesh it out into a <strong>test suite</strong>. (Make the tests run with a minimal implementation skeleton.)</li><li>Make the tests pass by fleshing out the <strong>implementation</strong>.</li></ol><p>I haven't seen such a way of working mentioned elsewhere, so I thought I'd make note of it here.</p><p>The idea with the first step is to separate most of the thinking from the automatic task of writing the tests. I find if I do this, I get better test coverage, because separation allows me to <strong>retain an eagle-eye view</strong> of the model, whereas if I were to switch back and forth between thinking about the whole and writing about the parts, I'd lose sight of the whole. To some degree. Also, having something to flesh out <strong>cancels out the impulse to cheat</strong> and skip writing tests.</p><p>Step two ignores the mandate of TDD to write only one failing test at a time. I still prefer to <strong>have the whole test suite done</strong> before starting the implementation, again because I get rid of some context-switching. Usually I treat the implementation process in much the same way as if I had written the tests on-demand. It occasionally happens that a test already passes as soon as I write the minimal scaffold needed to run the tests. As I currently understand TDD, this is also "frowned upon". I leave them in there, because they're still part of the specification, and might even catch regressions in the future.</p><p>I tried this out last weekend, and it was a really nice match with the problem domain &#8212; an I/O-free core of a package installer:</p><ol> <li>Write a test suite skeleton: <a href="">Just a bunch of prose comments</a>.</li><li>Flesh it out into a test suite: <a href="">one</a> <a href="">commit</a> <a href="">per</a> <a href="">skeleton</a> <a href="">test</a> <a href="">file</a>.</li><li>Make the tests pass: <a href="">one</a> <a href="">commit</a> <a href="">per</a> <a href="">subpart</a>.</li></ol><p>And presto, a complete (core) implementation with great test coverage.</p><p>Those who follow the links to actual commits will note that mistakes are corrected during the implementation phase. That's a symptom of the haltingproblem-esque feature of code in general; you don't know its true quality until you've run it in all possible ways.</p> masak 2010-06-17T13:04:32+00:00 perl6 Week 3 of GSoC work on Buf -- talk like a Parrot day <p>Remember that long-term solution for conversions between strings and arrays of bytes that I mentioned <a href="">last week</a> that the Parrot people were discussing?</p><p>No? Well, anyway, NotFound++ wrote one, and he suggested I try it for my Str&#8644;Buf conversions. It worked!</p><p>I thought I would get more than that done this week, but I didn't. Oh well. For next week, there are still a few low-hanging branches of fruit to persue.</p><ul> <li>I want to add <code>postfix:&lt;[ ]&gt;</code> indexing to the Buf class, so it feels a bit more Positional.</li><li>There's a lot of bounds-checking that needs to be made, both in the constructor and in decoding.</li><li>I have UTF-8 down pat; need to find a way to convince Parrot to do other encodings, such as ISO-8859-1.</li><li>There's one test that talks about <a href="">NFD</a>. Haven't even started looking at that yet.</li></ul><p>It's interesting to see where all the effort goes. I've spent most of my time so far on the <code>Str.encode</code> and <code>Buf.decode</code> methods, and almost everything else is trivial in comparison. Feels like some sort of 90%-10% rule at work.</p> masak 2010-06-13T22:59:57+00:00 perl6 This Week's Contribution to Perl 6 Week 6 <p> <b>This Week's Contribution to Perl 6 Week 6: help improve the sidebars in the book</b> </p><p> <i>(<b>Update 2010-06-10:</b> Two days, and already two submissions! I continue to be amazed by the willingness of people to contribute to these weekly challenges. Somehow, the noosphere generosity so prevalent in the open-source world feels much more magical when it's coming from lurkers. Thank you!)</i> </p><p>For this week's contribution to Perl 6, we ask you to wield some LaTeX skills in order to improve the appearance of the book some of us are writing.</p><p> <a href="">(Introduction to this series of challenges)</a> </p><p> <b>Background</b> </p><p>Have a look at page 23 in <a href="">the book</a>. There's a "sidebar" there, but it doesn't go on the side of the page, and it isn't especially aesthetically pleasing.</p><p>Help us make it better!</p><p> <b>Submission</b> </p><p>Please send your submission to the mailing list, and set me ( as CC, because the mailing list sometimes has a large delay.</p><p>If you have any questions, please ask the mailing list, me or (preferred) on our IRC channel, #perl6.</p><p>The best/most extensible/most complete/prettiest/whatever submission will make it into the next release of the book.</p> masak 2010-06-07T22:03:34+00:00 perl6 Week 2 of GSoC work on Buf -- the power of Swedish beer <p>Last week's summary was short out of choice; this week's is short out of necessity. I'm traveling a bit, and my access to the net isn't the best.</p><ul> <li>Changed the spec to contain only an array constructor for Buf, and removed the slury-array constructor.</li><li>The Parrot people are discussing a long-term solution for the conversion between strings and bytes. They are (rightly) worried about exposing the wrong bits, and want things to be right.</li><li>For the short term, jnthn++ hacked together a Parrot type called ByteView in my branch. I tried it, and it was almost enough for encoding a string. The whole thing is clearly doeable.</li></ul><p>Where does Swedish beer enter into it? Well, jnthn's example string was "&#246;l", the Swedish word for "beer". So the Buf implementation is definitely helped along by Swedish beer. &#21704;&#21704;</p> masak 2010-06-05T13:03:22+00:00 perl6 Yapsi 2010.06 Released! <p>It is with a mien of amusement that I want to announce, on behalf of the whole Yapsi development team, the June 2010 release of Yapsi, a Perl 6 compiler written in Perl 6.</p><p>You can get it <a href="">here</a>.</p><p>Yapsi is implemented in Perl 6. It thus requires a Perl 6 implementation to build and run. We recommend the 'alpha' branch of Rakudo for this purpose.</p><p>Yapsi releases are 'official and complete', shown here by a circular argument: clearly an official thing like Yapsi must be complete, and Synopsis 1 states that anything complete is official. QED. Yapsi passes 100% of its test suite.</p><p>Instructions for getting Yapsi up and running:</p><ol> <li> Make sure you have a built Rakudo alpha in your $PATH as 'alpha'.</li><li> Download Yapsi from <a href="">github</a>.</li><li><nobr> <wbr></nobr>...</li><li>Profit!</li></ol><p>The third (optional) step consists of running 'make' in the Yapsi directory. This will precompile Yapsi, making startup times much more bearable.</p><p>The big news since last month is that Yapsi now has a logotype. It's a picture of a M&#246;bius band, to symbolize self-loopiness, recursion and twisted ideas.</p><p>Yapsi consists of a compiler and a runtime. The program is compiled down into an instruction code called SIC, which doesn't stand for anything [sic]. All SIC listings start with a versioning line saying e.g. "This is SIC v2010.06". At this point during Yapsi development, we provide no guarantees about backwards compatibility whatsoever. Expect breakage between monthly releases.</p><p>An overarching goal for making a Perl 6 compiler-and-runtime is to use it as a server for various other projects, which will hook in at different steps:</p><ol> <li>A time-traveling debugger (tardis), which will hook into the runtime.</li><li>A coverage tool (lid), which will also hook into the runtime.</li><li>A syntax checker (sigmund), which will use output from the parser.</li></ol><p>Another overarching goal is to optimize for fun while learning about parsers, compilers, and runtimes. We wish you the appropriate amount of fun!</p> masak 2010-06-01T21:45:49+00:00 perl6 GGE now runs fine on Rakudo master <p>After <a href="">admitting that I had a problem</a>, I decided that perhaps it would be good to take one single application and just beat it into submission, making it run on Rakudo master.</p><p>I chose <a href="">GGE</a>. That was a mistake, but perhaps a positive one.</p><p>GGE is <em>big</em>, and has many tests, 750 of them. Running through them all takes almost 40 minutes. (The first "G" in GGE stands for "Glacial".) I keep thinking of GGE is "the biggest Perl 6 application out there", even though it's probably not that big, just fairly complex and well-tested. The mistake was attacking GGE first, and not something smaller.</p><p>The way the mistake might turn out to be a positive one is that I'll probably feel that converting other applications from alpha to master is relatively painless. &#21704;&#21704;</p><p>Here's a summary of things to think about, if you're planning to port your Perl 6 application from alpha to master:</p><p> <b>Improvements</b> </p><ul> <li>Rakudo master has better interpolation of things like <code>"@lol[]"</code>. I found a lot of cases where I "cheated" and used symbols which weren't magical in alpha, but which are now. Beware.</li><li> <code>is also</code> is now <code>augment</code>, and requires <code>use MONKEY_TYPING;</code>.</li><li>If you had put <code>sub</code>s in your class, chances are you'll need to <code>our</code> them now.</li><li>Rakudo master is stricter about not changing the <em>contents</em> of readonly containers, such as arrays and hashes. You'll get a slap on the fingers if you did this.</li><li> <code>undef</code> is gone. You probably meant <code>Nil</code> or <code>Any</code> or something.</li><li>If you were using <code>postcircumfix:&lt;( )&gt;</code>, remember that Rakudo master now requires the parameter list to consist of just a single Capture parameter. In practice, that means another layer of parentheses compared to alpha.</li><li> <code>break</code> in <code>when</code> blocks is now called <code>succeed</code> (and <code>continue</code> is called <code>proceed</code>)</li></ul><p> <b>Regressions</b> </p><ul> <li>Named enums work in master, but they're not really up to spec yet. If you used them as sets of constant, things might still work. If you used methods like<nobr> <wbr></nobr><code>.name</code> and<nobr> <wbr></nobr><code>.pick</code>, you'll need to <a href="">work around</a> for the time being. (And re-read the spec.)</li><li>The <code>&lt;-&gt;</code> syntax for pointy blocks <a href="">is no longer implemented</a>.</li><li>Backslash escapes <a href="">don't work</a> in character classes.</li><li> <code>Str.trans</code> doesn't work.</li><li> <a href=""> <code>handles</code> </a> doesn't work.</li><li>Using an optional hash parameter with <code>is copy</code> semantics? Well, <a href="">it won't work</a>. Sorry.</li><li> <code>Str.subst</code> works, but using <code>$_</code> in a closure in its second argument doesn't.</li><li>Sometimes you have to clone closures using <code>pir::clone</code>, or <a href="">they won't close properly</a> around their surrounding environments.</li><li> <code>"\e"</code> <a href="">doesn't work</a> at the moment. Use <code>"\c[27]"</code> or <code>"\x[1b]".</code></li><li>If you were general before and wrote <code>List</code> rather than <code>Array</code> because, well, it's shorter and more inclusive... that won't work now. <code>Array</code> no longer subclasses <code>List</code>.</li><li>There are some situations when you might wind up with <a href="">double [] in arrays.</a></li><li>There's something wrong with <a href="">list assignment and hashes</a>.</li></ul><p>It took two months of leisurely refactoring and debugging to bring GGE through the needle's eye. But I must confess that it was pretty sweet to subsequently rid it of all of alpha's workarounds. Clearly a net win.</p> masak 2010-05-31T15:44:10+00:00 perl6 Week 1 of GSoC work on Buf -- not a chocolate cake recipe <p>No-one likes to trawl through long grant progress reports that read like a recipe for chocolate cake, but without the chocolate cake. So I'll be mercifully brief.</p><ul> <li> <a href="">Implemented</a> <code>Str.encode</code> and <code>Buf.decode</code>.</li><li>Discovered two things in Parrot from doing Buf.decode. The first was <a href="">a bug</a> which bacek++ fixed quickly.</li><li>The second was that <a href="">Parrot can't decode lists of bytes</a>. That's why <a href="">test 8</a> fails. We've been <a href="">discussing</a> <a href="">how to</a> <a href="">proceed</a> from here.</li></ul><p>By the <a href="">plan</a> I'm supposed to work on constructors and indexing now, but I gravitated towards the Str.encode and Buf.decode stuff because that's where I left off last time I worked on this. There's still plenty of time next week to do the constructors and indexing.</p><p>Not used to writing a report this small. But I think I like it. &#21704;&#21704;</p><p>(What, this thing? Yes, it so happens it's a <a href="">chocolate cake</a>. No, you can't have any. Get your own.)</p> masak 2010-05-28T14:29:10+00:00 perl6 The trip to Moscow and the DevConf talk (iambic pentameter) <p> <i>My trip to Moscow was a pleasant one,<br> The city has <a href="">a certain feel</a> I like.<br> <a href="">The metro</a> is so big and full of win!<br> And so too was <a href="">the room</a> at my hotel.</i> </p><p> <i> <a href="">My talk</a> was well-received and fun to give,<br> on Yapsi, Tardis, Sigmund and Perl 6.<br> <a href="">sharifulin</a>++ for speedy help<br> with <a href="">setting up his laptop</a> for my talk.</i> </p><p> <i>The guys at <a href=""></a> made me feel<br> at home in Moscow, and enjoy my stay.<br> I only wish <a href="">my Russian</a> wasn't crap.<br> Incentive to learn more of it, I guess.</i> </p><p> <i>At <a href="">Airport Sheremetyevo</a> they said<br> "departure is tomorrow, not today".<br> 'Pro tip': when booking, check an extra time<br> that chosen dates are actually correct.</i> </p><p>I tried to write iambicly above... That Shakespeare guy was pretty good, it seems! I'm not, so my attempts don't even rhyme. But maybe some commenters' comments will...?</p> masak 2010-05-21T14:24:56+00:00 perl6 The tests Rakudo doesn't run <p>Just a short note.</p><p>After an <a href="">enlightening discussion with mberends</a> a couple of days ago, I became curious about how many spectests Rakudo <em>doesn't</em> run.</p><p>So I wrote a short script which takes a list of all spectest<nobr> <wbr></nobr><code>.t</code> files, a list of all the files mentioned in Rakudo's <code>t/</code> (including the commented-out ones), and did hash subtraction on them.</p><p>By the way, a common Perl 5 idiom in this situation is difficult to do in Rakudo, because some blocks are still erroneously parsed as hashes:</p><p> <code> $ perl6<br> &gt; my @array; my %hash = map { $_ =&gt; 1 }, @array;<br> No candidates found to invoke<br> &gt; say { $_ =&gt; 1 }.WHAT<br> Hash() </code> </p><p>Working around this, I arrived at the number 185. That's out of a total of 722. Here's the <a href="">whole list</a>.</p><p>Not too surprisingly, upon showing this list to #perl6, <a href="">I was quickly informed</a> (by the ever-knowledgeable moritz++) that there's already <a href="">a Rakudo tool script</a> which processes exactly this list of tests, and prints the much more useful subset of files with at least one test passing, thus being eligible for inclusion into <code>t/</code>.</p><p>I hope to be able to explore the spectest suite further, in my copious spare time. My long-term goal is to create alluring SVG graphs over the tests currently passing in Rakudo master, Rakudo alpha, and Pugs.</p> masak 2010-05-09T15:03:59+00:00 perl6 Perl 6: the Frankenstein's monster of operators <p>By this point, a stray comment on an <a href="">earlier blog post</a> of mine has snowballed into a real discussion, so let's hoist it up here for everyone to see. It's a friendly discussion full of smilies, between two people with different viewpoints. Get the popcorn; I'll provide the quotes.</p><p>The commentator, nilsonsfj, is a Perl 5 programmer who 'just didn't bother following up on Perl 6 anymore after the Unicode ops and the whole "periodic table of operators" thing.' I guess that description applies to quite a few Perl 5 programmers out there; Perl 6 just isn't relevant to them in its present state.</p><p>I <a href=";pid=71940">reply</a>:</p><p><div class="quote"><p>You should take a look at the <a href="">new table</a> from last year, if you haven't yet. It's gorgeous. Also &#8212; and I bet you know this &#8212; neither Perl 5 or Perl 6 is meant to be taken in all at once, and the periodic table sort of goes against that and says "Boo! Operators!" and scares everyone giddy with all the horrible richness. Perl isn't a first language, it's more of a last language. &#9786;</p></div><p><div class="quote"><p>Also, after you've recovered from the Unicode thing, you'll be pleased to know that all of the ops in that table are all quite ASCII-friendly. Wreaking havoc with Unicode operators is left as an exercise for module authors. &#9786;</p></div><p>nilsonsfj goes ahead and looks, and comes back <a href=";pid=71943">replying</a>:</p><p><div class="quote"><p>Well, I just looked at the new periodic table and if by "gorgeous" you meant "scary", I agree with you. &#9786;</p></div><p>(Boo! Operators!)</p><p>I <a href=";cid=71948">reply</a> with:</p><p><div class="quote"><p>In the interests of mutual understanding, I tried to look at the periodic table, and tried to instill a measure of fear in myself. The closest I got was "huh, that's quite a lot of them, isn't it?".</p></div><p><div class="quote"><p>I think one of the big dividing points between the Perl languages on the one hand and other programming languages on the other, is that Perl embraces complexity &#8212; often quite fearlessly. Language designers are known to talk about minimalism and orthogonality. Perl, in contrast, seems to take as a starting point that the world, including the programming world, is complex and messy and non-orthogonal and full of redundancy and can be seen in different ways by different people.</p></div><p><div class="quote"><p>Perl 5 has quite a lot of operators. I haven't counted them, and wouldn't really know where to start if I were to try. I'm sure Perl 6 has more, maybe even twice as many. (Again, by some half-defined measure.) I think I don't think "scary" when I look at the table because most of these operators are familiar to me now, and I see the rationale for them. (Yes, duh.) Also, many of them I don't normally consider operators, either because they're too infrastructural (like the comma or the different dotty method calls) or too abstract (like 'does' or most of the alphabetic list operators) to be real operators.</p></div><p><div class="quote"><p>With the rest of them, they're either new (which one would expect from a new language or even an upgrade), or they're instances of one Perl 5 operator that has exploded into a couple of Perl 6 operators because Perl 6 often takes a more strict view to keeping different things distinct and relies less on value context than does Perl 5. The shift/and/or/negate operators prefixed by plus or tilde or question mark are an example of this; I briefly give the rationale for why I like this change in <a href="">blog post</a> from a while back. I should add that I don't use those particular operators on a day-to-day basis, because of their quite specific and close-to-the-metal nature. (That's also a dimension not visible in the Table; some operators are uncommon in practice.)</p></div><p><div class="quote"><p>Much of the complexity is actually hidden and folded in by the presence of the metaoperators. Of course, the mere concept of a metaoperator and the sudden ability to create a fitting operator on the spot (along with the parser technology required to make that work) are, by rights, scary in an objective sense. But it's one of the things that grows on you. And I haven't seen people abuse it either; just because there are metaoperators available, people don't suddenly go crazy and produce unmaintainable code. Rather, it helps turn a for loop here and there into a one-liner.</p></div><p><div class="quote"><p>I came in at around 2004, and I've seen many of these operators mature and take shape. So I guess I'm biased by having seen the rationale for most changes, from Perl 5 through the Apocalypses and Synopses up until today. I agree with most of them. I still don't quite understand how we ended up with eight flip-flop operators, but I haven't really used them yet, so I'll reserve judgment on that point. Maybe they'll be handy in a perl6 -ne context or something.</p></div><p>Perl 6 is an 'operator-oriented' language. In fact, operators are described in the spec as being subroutines and methods with funny syntax. (I'm paraphrasing here.) In that sense, the whole discussion dissolves into a larger discussion on which subroutines and methods we want to keep in the Perl 6 core, and which one of those should manifest as operators.</p><p>Perl 5 and Perl 6 tend to favor a good operator in many cases where other languages would reach for a subroutine or method. That's fine. If you don't like it that way, we won't tell you to take your umbrella and go somewhere else, we'll tell you to show us how <em>you</em> would have it look, and your solution can even get its own life as a module or a spec change or a community best practice. It's happened many times before, and it'll happen many more times. As a result, we end up with a language covering one enormous sweet spot, looking like Frankenstein's monster and being quite proud of it. Because, as someone once said, <a href="">it's the magic that counts</a>.</p> masak 2010-05-02T14:09:16+00:00 perl6 Yapsi 2010.05 Released! <p>It is with undue sprightliness that I want to announce, on behalf of the Yapsi development team, the May 2010 release of Yapsi, a Perl 6 compiler written in Perl 6.</p><p>You can get it <a href="">here</a>.</p><p>Yapsi is implemented in Perl 6. It thus requires a Perl 6 implementation to build and run. We recommend the 'alpha' branch of Rakudo for this purpose.</p><p>Yapsi is an 'official and complete' Perl 6 release. It's official because we have little labels with the word 'official' on them that we glue to each download that takes off from github. (That much gluing takes a lot of work, but we think of it as a community service.) It's complete in the sense that all of the things it implements, it does. With gusto.</p><p>Instructions for getting Yapsi up and running:</p><ol> <li>Make sure you have a built Rakudo alpha in your $PATH as 'alpha'.</li><li>Download Yapsi from <a href="">here</a>.</li><li>...</li><li>Profit!</li></ol><p>The third (optional) step consists of running 'make' in the Yapsi directory. This will precompile Yapsi, making startup times much more bearable.</p><p>The big change since last month is that Yapsi now does immediate blocks.</p><p> <code> $ export PERL6LIB=`pwd`/lib<br> <br> $<nobr> <wbr></nobr>./yapsi -e 'my $a = 42; { my $a = 7; say $a }; say $a'<br> 7<br> 42 </code> </p><p>For other changes, see the doc/ChangeLog file.</p><p>This release, as opposed to the last one, contains hidden bugs. We encourage you to help us find them; if not for the fame and glory, than at least for the Schadenfreude.</p><p>Yapsi consists of a compiler and a runtime. The program is compiled down into an instruction code, which can be stored and executed weeks, years or even days [<em>sic</em>] later. If you want, you can execute the same piece of SIC several times over. All SIC listings start with a versioning line saying e.g. "This is SIC v2010.05". At this point during Yapsi development, we provide no guarantees about backwards compatibility whatsoever. Expect breakage between monthly releases.</p><p>An overarching goal for making a Perl 6 compiler-and-runtime is to use it as a server for various other projects, which will hook in at different steps:</p><ul> <li>A time-traveling debugger (tardis), which will hook into the runtime.</li><li>A coverage tool (lid), which will also hook into the runtime.</li><li>A syntax checker (sigmund), which will use output from the parser.</li></ul><p>Another overarching goal is to optimize for fun while learning about parsers, compilers, and runtimes. We wish you the appropriate amount of fun!</p> masak 2010-05-01T21:47:56+00:00 perl6 GSoC, contextuals, and intolerance (three posts in one) <p>This is three thirds of a post. The three parts will simply have to combine into one big <a href="">mechbot</a> in order to pass as a whole post.</p><p> <b>I'm a GSoC 2010 student</b> </p><p>I <a href="">sent in a proposal</a>, and it got accepted. Yay!</p><p> <b>Use contextuals for "process data", not attributes</b> </p><p>Sometimes you both want do subdivide methods into small manageable parts, all the while keeping some sort of data between them. Most people reach for the instance attributes to do this, since these shared between all the methods of one object.</p><p>But this can also be done with contextuals, as is now <a href="">done in Yapsi</a>. This keeps the lifetime of the variables as short as possible, and keeps the objects light-weight. And it still works with inheritance.</p><p>I like how Perl 6 allows me to mix OO and contextuals this way. And I really like that it works in Rakudo already.</p><p> <b>The mechanics of intolerance</b> </p><p>I've blogged before about how #perl6 is <a href="">a small, friendly community</a> which turns even flame wars into <a href="">interesting discussions</a> and which works on being <a href="">kind and open</a>. We've had a bit of troll activity since I wrote those posts, as well as a few borderline trolls.</p><p>The other day I treated someone with undue impatience. The whole episode ended well, and I've apologised. In short, what looked like nagging questioning may simply have been someone's slightly different means of communicating.</p><p>Mean and evil acts are often committed by people convinced that they're actually doing good. mst++ writes about the <a href="">reasons for being harsh</a>, and I thought this was one of those times when that was called for. It wasn't.</p><p>It taught me to look out for situations when I might be mistaking variations in personality and communication skills for truly annoying behaviour. In many ways, that's a refreshing reminder: a really open community requires that we recognize that everyone doesn't operate exactly the same as we do. That sounds terribly clich&#233;d, I know; but forgetting it is also far too easy.</p> masak 2010-04-29T15:01:41+00:00 perl6