Christmas announcement, two.

As we prepare to cut the first monthly release of the Rakudo Perl 6 compiler of 2016, we wanted to specifically thank all the individuals, companies, and organizations who donated money, services, equipment, or their employee’s time to the effort.  This includes efforts going back to 2000 over multiple Perl 6 related projects. As with our developer list on the Christmas release, our sincere apologies to anyone who was accidentally left off this list.

  • ActiveState
  • BBC
  • Blackstar
  • Booking.com
  • craigslist
  • Richard Dice of Toronto.pm
  • Dijkmat
  • Edument
  • ETH Zürich
  • Google Summer of Code
  • Ian Hague
  • Manning Publications
  • Morgan Stanley
  • Mozilla
  • NLNet
  • noris network AG
  • O’Reilly Media
  • Frédéric Schütz of the Swiss Institute of Bioinformatics
  • Stonehenge Consulting
  • The Perl Foundation
  • TPF’s Perl 6 Core Development Fund sponsors
  • VA Linux
  • WenZPerl
  • Fritz Zaucker of Oetiker+Partner AG

Again, thank you all for your support.

Christmas is here.

On behalf of the Rakudo development team, I’m proud to announce the Christmas release (December 2015) of Rakudo Perl 6 #94 “коледа”. Rakudo is an implementation of Perl 6 on the Moar Virtual Machine[^1].

This is the Christmas release of Rakudo Perl 6. This version of the compiler targets the v6.c “Christmas” specification of the Perl 6 language. The Perl 6 community has been working toward this release over the last 15 years. Together, we’ve built a language that:

  • Retains the core values of Perl: expressiveness, getting the job done, taking influences from natural language, and pushing the boundaries of language design
  • Has clean, modern syntax, rooted in familiar constructs but revisiting and revising the things that needed it
  • Is truly multi-paradigm, enabling elegant object-oriented, functional, procedural, and concurrent programming
  • Serves as a great glue language, allowing for easy calling of C/C++ (using NativeCall) and staying compatible with Perl 5 (via Inline::Perl5).
  • Provides composable constructs for working with asynchronous data and parallel computations
  • Dramatically reforms and sets a new standard in regex syntax, which scales up to full grammars – powerful enough to parse Perl 6 itself
  • Has outstanding Unicode support, with strings working at grapheme level
  • Values lexical scoping and encapsulation, enabling easy refactoring
  • Is extensible through meta-object programming, user-defined operators, and traits

The tag for this release is “коледа”[^2], a slavic word for an ancient winter festival that has been incorporated into Christmas. We hope you join us in our celebration of getting our Christmas release shipped!

While we are extremely happy to ship an official Perl 6 release, this is not the end of Rakudo’s development. We will continue to ship monthly releases, which will continue to improve performance and our users experience. We’ll also continue our work on the specification, with feedback from the community.

To be clear on that point, this Rakudo release is not considered the primary deliverable for this Christmas; it is the language specification, known as “roast” (Repository Of All Spec Tests), that is considered the primary deliverable. The specification tests that define this 6.c version[^3] of the language are now frozen, and we hope it will be quite some time before we feel obligated to define a 6.d (Diwali) version of the language.

This Rakudo release targets those tests (over 120 thousand of them), and passes them all on at least some architectures when the moon is in the right phase. But Rakudo itself is not frozen. There is still plenty of work ahead for us to improve speed, portability, and stability. Do not expect the level of perfection that you see in established products. This is essentially a .0 release of a compiler. We do not claim an absence of bugs or instabilities. We do not claim the documentation is complete. We do not claim portability to many architectures. We do not claim that all downstream software will work correctly. Think of it as a first kernel release, and now we get to build and port various distributions based around that kernel.

What we do claim is that you now have a stable language specification, and you can enjoy getting some stuff done with Perl 6 without us breaking it every month—as long as you stick to the features that are actually tested in the test suite, that is. Please note that any “feature” you discover that is not tested in the test suite is considered fair game for change without notice.

Have the appropriate amount of fun!

The tarball for this release is available from http://rakudo.org/downloads/rakudo/.

Please note: This announcement is not for the Rakudo Star distribution[^4] — it’s announcing a new release of the compiler and the specification. For the latest Rakudo Star release, see http://rakudo.org/downloads/star/. A Christmas-based version will be available soon.

In addition to being our Christmas release, this is yet another monthly compiler release; Some of the changes that are new in release are outlined below:

New in 2015.12:

  • Fixed size and multi-dimensional typed and native arrays
  • Greatly overhauled module loading and installation, including handling precompilation at module installation time in Rakudo
  • while/until loops can now return lists of values
  • We now catch many more kinds of “Useless use of X in sink context”
  • A number of convenient Unicode equivalents were introduced
  • Superscripts can now be used for integer powers
  • Non-digit unicode characters with a numeric value (½ and such) can now be used for that numeric value
  • There is a new “approximately equal” operator
  • Add support for USAGE argument help
  • Provide tau constant (also: τ)
  • Can now use channels with supply/react/whenever
  • Bool is now a proper enum
  • Supply/Supplier improvements
  • Use of EVAL now requires a declaration of ‘use MONKEY-SEE-NO-EVAL’
  • Make pack and unpack experimental
  • Dynamic variables are now visible inside start { … } blocks
  • Autoincrements on native ints are now faster than on Int
  • The ~~ operator can now chain with other comparisons in many circumstances Various numeric operations now return overflow/underflow failures instead of wrong value
  • The :ss, :ii, and :mm options to s/// now all work together

This is only a partial list of the changes in this release. For a more
detailed list, see “docs/ChangeLog”.

The development team thanks all of our contributors and sponsors for making Rakudo Perl possible, as well as those people who worked on the design docs, the Perl 6 test suite, MoarVM and the specification. Additionally, the Pugs, Parrot, and Niecza projects were all instrumental with their contributions to the specification and the community.

The following people contributed to the development of the Christmas release. We’ve gone back through the logs of all the various projects. Thanks to everyone who has worked to make this release happen over the past 15 years. We would also like to thank everyone who submitted bug reports or dropped in on the various forums to discuss things. Finally, we’d like to extend a special thanks to everyone who we accidentally left out of this list.

Gisle Aas, abcxyzp, Chuck Adams, Colin Paul Adams, Rod Adams, C.J. Adams‑Collier, David H. Adler, Chirag Agrawal, Amir E. Aharoni, Bilal Akhtar, Julian Albo, Alekssasho, alexghacker, Paco Alguacil, Brandon S Allbery, Geir Amdal, Markus Amsler, Paul C. Anagnostopoulos, Nikolay Ananiev, anatolyv, andras, Saleem Ansari, Joji Antony, Tomoki Aonuma, Syed Uzair Aqeel, arathorn, Arcterus, Kodi Arfer, Daniel Arbelo Arrocha, ash, Ted Ashton, Arnaud Assad, atroxaper, Ori Avtalion אורי אבטליון, Auzon, Greg Bacon, Ivan Baidakou, Alex Balhatchet, Szabó, Balázs, Amir Livine Bar‑On עמיר ליבנה בר‑און, Luca Barbato, Mattia Barbon, Ann Barcomb, Christian Bartolomäus, Alex “Skud” Bayley, bcmb, Jody Belka, Shachaf Ben‑Kiki, Andrei Benea, benedikth, Zev Benjamin, benmorrow, Kevan Benson, Martin Berends, Anton Berezin, Arthur Bergman, Anders Nor Berle, bestian, Peter Bevan, Mark Biggar, Carlin Bingham, Ævar Arnfjörð Bjarmason, J. David Blackstone, Ronald Blaschke, Ingo Blechschmidt, bloonix, blwood, Kristof Bogaerts, Dan Bolser, Конрад Боровски, Christopher Bottoms, Gonéri Le Bouder, Jos Boumans, Brad Bowman, Matt Boyle, bpetering, H.Merijn Brand, Terrence Brannon, Gwern Branwen, Stig Brautaset, Herbert “lichtkind” Breunung, bri, brian_d_foy, Fernando Brito, Geoffrey Broadwell, Leon Brocard, Benjamin Brodfuehrer, Samuel Bronson, Dan Brook, Nathan C. Brown, Roger Browne, Philippe Bruhat (BooK), David Brunton, Corwin Brust, Klaus Brüssel, Lucas Buchala, buchetc, Christoph Buchetmann, Norbert Buchmuller, Buddha Buck, Alexandre Buisse, Tim Bunce, Bryan Burgers, Sean M. Burke, Matthew Byng‑Maddick, András Bártházi, Jürgen Bömmels, Caelum, Aldo Calpini, Edward Cant, David Cantrell, Carlin, Michael Cartmell, Hezekiah Carty, Nuno ‘smash’ Carvalho, Marcelo Serra Castilhos, Piers Cawley, cdavaz, cdpruden, Gianni Ceccarelli, cfourier, Marc Chantreux, Mitchell N Charity, Oliver Charles, Vasily Chekalkin, Yuan‑Chen Cheng 鄭原真, Daniel Chetlin, Hsin‑Chan Chien 簡信昌, N. Hao Ching, Joshua Choi, Elizabeth Cholet, David Christensen, chuck, cjeris, Nicholas Clark, Steve Clark, Jeff Clites, cmarcelo, cmeyer, Paul Cochrane, Daniel Colascione, Jason Cole, Will “Coke” Coleda, Sylvain Colinet, cono, Tim Conrow, Géraud Continsouzas, Damian Conway, Neil Conway, Stuart Cook, David Corbin, Deven T. Corzine, cosmicnet, Timothy Covell, Beau E. Cox, Simon Cozens, Philip Crow, cspenser, Franck Cuny, Tyler Curtis, David Czech, Daenyth, Dagur, Ritz Daniel, darkwolf, Chris Davaz, David Warring, Justin DeVuyst, Daniel Dehennin, Akim Demaille, Detonite, Lars “daxim” Dieckow 迪拉斯, Matt Diephouse, Bob Diertens, Wendy “woolfy” van Dijk, Jeffrey Dik, John M. Dlugosz, dimid, diotalevi, Hans van Dok, Chris Dolan, Mark Dominus, Bryan Donlan, Andy Dougherty, Dave Doyle, drKreso, dr_df0, dudley, Jonathan Scott Duff, dug, Lee Duhem, Darren Duncan, Andrew Egeler, Havard Eidnes, Nelson Elhage, Fitz Elliott, Alex Elsayed, Jay Emerson, Aankhola Encorporated, ennio, Enveigler, Jon Ericson, Shae Matijs Erisson, Eryq, Mike Eve, Pat Eyler, Aaron Faanes, Kevin Falcone, David Farrell, Angel Faus, Jason Felds, Paul Fenwick, Jose Rodrigo Fernandez, Nelson Ferraz, Adriano Ferreira, João Fernando Ferreira, Chris Fields, Caio Marcelo de Oliveira Filho, Steve Fink, Shlomi “rindolf” Fish שלומי פיש, Mark Leighton Fisher, Scott Fitzenrider, Dudley Flanders, Richard Foley, Vincent Foley, Julian Fondren, Ruben Fonseca, David Formosa, Karl Forner, Solomon Foster, Chaddaï Fouché, Lloyd Fournier, Michael Fowler, Matt Fowles, franck, Austin Frank, Carl Franks, Kent Fredric, Chaim Frenkel, Piotr Fusik, gabriele, John Gabriele, Christoph Gärtner, Martin von Gagern, Felix Gallo, Salvador Ortiz Garcia, Rafaël Garcia‑Suarez, Joshua Gatcomb, Jerry Gay, gcomnz, Jonathan Gentle, iVAN Georgiev, Brian Gernhardt, Bram Geron, Alessandro Ghedini, Imran Ghory, Peter Gibbs, Tanton Gibbs, Brad Gilbert (b2gills), Karl Glazebrook, Nick Glencross, Mark Glines, Flávio S. Glock, Jason Gloudon, Simon Glover, gnuvince, Garrett Goebel, Jeffrey Goff, Mikhael Goikhman, Benjamin Goldberg, Arcady Goldmints‑Orlov, Dimitry Golubovsky, Gerard Goossen, Goplat, Alex Gough, Léo Grange, Chad “Exodist” Granum, Kenneth A Graves, Bruce Gray, Nathan Gray, Mark Grimes, Lucien Grondin, Rolf Grossmann, David Grove, Marcel Grünauer, Daniel Grunblatt, Uri Guttman, gwern, Swaroop C H, Richard Hainsworth, Roger Hale, John “ab5tract” Haltiwanger, Nigel Hamilton, Eric Hanchrow, Sterling Hanenkamp, Ask Bjørn Hansen, Christian “chansen” Hansen, Eirik Berg Hanssen, Samuel Harrington, Trey Harris, John Harrison, Carsten Hartenfels, Richard Hartmann, Kyle Hasselbacher, Austin Hastings, Carl Hayter, Florian Helmberger, Gordon Henriksen, Felix Herrmann, Peter Heslin, Fred Heutte, Jarkko Hietaniemi, Michael H. Hind, Joshua Hoblitt, Zack Hobson, Eric Hodges, Rob Hoelz, Masahiro Honma, Lyle Hopkins, JD Horelick, Jeff Horwitz, Chris Hostetter, Laurens Van Houtven, Jeremy Howard, Yiyi Hu 鹄驿懿, Benedikt Huber, Brad Hughes, Sterling Hughes, Tom Hughes, Tristan Hume, Donald Hunter, Douglas Hunter, Juan Francisco Cantero Hurtado, Kay‑Uwe ‘kiwi’ Hüll, Ran Eliam, Alin Iacob, Ibotty, ibrown, ihrd, Roland Illing, Jan Ingvoldstad, Joshua Isom, isop, Ivan_A_Frey, ivanoff, Akash Manohar J, jafelds, Robert G. Jakabosky, jamesrom, S. A. Janet, jani, Heiko Jansen, Stuart Jansen, Jarrod, Jedai, Chris Jepeway, Chris Jeris, Dagur Valberg Johannsson, Erik Johansen, Paul Johnson, johnspurr, Isaac Jones, Norman Nunley, Jr, Yoshikuni Jujo, Brian S. Julin, Josh Juran, Michal Jurosz, David KOENIG, Prakash Kailasa, Shoichi Kaji, Daniel Kang, Isis Kang, Chia‑Liang Kao 高嘉良, Dmitry Karasik, Luben Karavelov, Amir Karger, Offer Kaye, Bruce Keeler, James E Keenan, Cole Keirsey, Adam Kennedy, Matt Kennedy, Shane Kerr, khairul, Mikhail Khorkov, Krzysztof Kielak, Andres Kievsky, Daehyub Kim, Rob Kinyon, Oleg Kiselyov, OOLLEY kj, Martin Kjeldsen, Thomas “domm” Klausner, Zohar “lumi” Kelrich זהר קלריך/卡卓哈, Damian Miles Knopp, Dan Kogai 小飼弾, Yuval “nothingmuch” Kogman יובל קוג’מן, Tomasz Konojacki, Vadim Konovalov, Nick Kostirya, Matt Kraai, Thomas Kratz, Adrian Kreher, John van Krieken, Matthias Krull, Bradley M. Kuhn, Bob Kuo, Colin Kuskie, Kamil Kułaga, Sage LaTorra, Brent Laabs, laben, Johannes Laire, Markus Laire, Fayland Lam 林道, Mike Lambert, lanny, Leo Lapworth, last.of.the.careless.men, Bart Lateur, Jia‑Hong Lee, Lola Lee, Jonathan Leffler, Tobias Leich, lembark, Mark Lentczner, Moritz A Lenz, Jean‑Louis Leroy, Andy Lester, Jonathan “Duke” Leto, Vladimir Lettiev, Mike Li 李曉光, Stefan Lidman, Yung‑Chung Lin 林永忠, Glenn Linderman, Vladimir Lipsky, Zach Lipton, Stevan Little, Kang‑Min Liu 劉康民, Skip Livingston, David M. Lloyd, Daniel Lo, Peter Lobsinger, Andres Löh, Nick Logan, Eric Lubow, Nolan Lum, Peter Lunicks, LylePerl, Ian Lynagh, lysdexsik, Kiran Kumar M., Jerry MacClure, Noel Maddy, Christopher J. Madsen, Abhijit A. Mahabal, Max Maischein, Peter Makholm, Ujwal Reddy Malipeddi, malon, Christopher Malon, Dagfinn Ilmari Mannsåker, Michael Maraist, Roie Marianer רועי מריאנר, markmont, Simon Marlow, martin, Paolo Martini, Ilya Martynov, Jaume Martí, James Mastros, Michael J. Mathews, Vyacheslav Matjukhin, Tokuhiro Matsuno, mattc, Mike Mattie, Elizabeth “lizmat” Mattijsen, Вячеслав Матюхин, Markus Mayr, Josh McAdams, Martin McCarthy, Mark McConnell, Steven McDougall, John McNamara, Scott McWhirter, mdinger, Olivier “dolmen” Mengué, Kevin Metcalf, Patrick R. Michaud, mimir, mjreed, Tom Moertel, Michael Mol, Paolo Molaro, Shawn M Moore, Brandon Michael Moore, Alexander Moquin, Ion Alexandru Morega, Dino Morelli, Kolia Morev, Zach Morgan, mr_ank, Alex Munroe, muraiki, Paweł Murias, mvuets, Steve Mynott, mzedeler, Carl Mäsak, naesten, Tim Nelson, Ailin Nemui, Ingy döt Net 應吉大聶, David Nicol, Faye Niemeyer, Nigelsandever, Karl Rune Nilsen, Salve J. Nilsen, Per Christian Nodtvedt, Ben Noordhuis, Paweł Nowak, Norman Nunley, Tony O’Dell, יהושע “שי” אוחיון, Clayton O’Neill, Stefan O’Rear, Sean O’Rourke, Matt Oates, Tony Olekshy, Martin Olsen, Dmitriy Olshevskiy, Dave Olszewski, Nelo Onyiah, William Orr, Jon Orwant, Andrei Osipov, Christoph Otto, Pawel Pabian, Walter Pallestrong, Luke Palmer, Bartłomiej Palmowski, Pancake, Paolo, Marton Papp, Andrew Parker, Roman M. Parparov, Anthony Parsons, Mike Pastore, Nova Patch, Timo Paulssen, Tony Payne, Stéphane “cognominal” Payrard, Slava Pechenin, Gael Pegliasco, Stéphane Peiry, Felipe Pena, Nayden Pendov, Wenzel P. P. Peppmeyer, François Perrad, Markus Peter, Ben Petering, Steve Peters, Tim Peterson, Ronny Pfannschmidt, Clinton A. Pierce, Jerrad Pierce, Thilo Planz, plunix, pmakholm, Curtis ‘Ovid’ Poe, Gerd Pokorra, Peter Polacik, Flavio Poletti, Kevin Polulak, John Porter, Ryan W. Porter, Stephen P. Potter, Philip Potter, Adam Preble, premshree, Klāvs Priedītis, Adam Prime, Richard Proctor, Christopher Pruden, Kevin Puetz, Gregor N. Purdy, purl, Hongwen Qiu, Jerome Quelin, quester, Gerhard R., Peter Rabbitson, Florian Ragwitz, raiph, Matt Rajca, Marcus Ramberg, Claudio Ramirez, Prog Rammer, Allison Randal, David Ranvig, Lars Balker Rasmussen, Curtis Rawls, raydiak, Robin Redeker, Ted Reed, Jens Rehsack, Charles Reiss, Gabriele Renzi, Kenneth C. Rich, Jason Richmond, Ryan Richter, Sebastian Riedel, Dennis Rieks, Jens Rieks, Lanny Ripple, John Rizzo, rkhill, Andrew Robbins, Amos Robinson, Jonathan Rockway, Stefano Rodighiero, Andrew Rodland, Lindolfo Rodrigues, Bob Rogers, Dave Rolsky, David Romano, ron, Eric J. Roode, Garret Rooney, Garrett Rooney, David Ross, Andreas Rottmann, Brent Royal‑Gordon, Shmarya Rubenstein, Sam Ruby, Simon Ruderich, Daniel Ruoso, Jake Russo, ruz, Joseph Ryan, Gilbert Röhrbein, Sam S, s1n, sahadev, Patrick Abi Salloum, salty_horse, Chip Salzenberg, Shrivatsan Sampathkumar, Igor Rafael Sanchez‑Puls, Hugo van der Sanden, Thomas Sandlaß, Yun SangHo, sanug, Siddhant Saraf, Sasho, Andrew Savige, John Saylor, Matt Schallert, Bernhard Schmalhofer, Arthur Axel Schmidt, Ronald Schmidt, Michael Schroeder, Steven Schubiger, Steve “thundergnat” Schulze, Andreas Schwab, Randal L. Schwartz, Pepe Schwarz, Frederik Schwarzer, Calvin Schwenzfeier, Michael G. Schwern, Steffen Schwigon, Tom Scola, Ariel Scolnicov, Michael Scott, Peter Scott, Rick Scott, Stefan Seifert, Austin Seipp, Mark Senn, Filip Sergot, Seth Gold (Sgeo), William Shallum, Kris Shannon, shenyute, Aaron Sherman, Mark Shoulson, Ryan Siemens, Ricardo Signes, Hinrik Örn Sigurðsson, Jonathan Sillito, Miroslav Silovic, Steve Simmons, Alberto Manuel Brandao Simoes, John Siracusa, Arne Skjærholt, Barrie Slaymaker, Radek Slupik, Mike Small, Benjamin Smith, Melvin Smith, Tim Smith, Adrian White aka snarkyboojum, Richard Soderberg, SolidState, Vishal Soni, Syloke Soong, Shawn Sorichetti, Tadeusz Sośnierz, sue spence, Cory Spencer, Robert Spier, Michael Stapelberg, Edwin Steiner, stephenpollei, Michael Stevens, Don Stewart, Radu Stoica, Klaas‑Jan Stol, Alek Storm, David Storrs, Mark Stosberg, Jonathan Stowe, Cosimo Streppone, Jonathan Strickland, Pascal Stumpf, Su‑Shee, Sue, Laye Suen, Dan Sugalski, Mark Summerfield, Simon Sun, Cheng‑Lung Sung 宋政隆, Sunnavy, Samuel Sutch, svatsan, svn, Andrew Sweger, sygi, Sebastian Sylvan, Gábor Szabó, Bálint Szilakszi, Marek Šuppa, TOGoS, Arvindh Rajesh Tamilmani, Audrey Tang 唐鳳, Bestian Tang 唐宗浩, Adrian Taylor, Jesse Taylor, Philip Taylor, Kevin Tew, the_dormant, Marcus Thiesen, Adam Thomason, Richard Tibbetts, Carey Tilden, Marcel Timmerman, Leon Timmermans, tkob, John Tobey, Frank Tobin, Bennett Todd, Graham Todd, Leopold Tötsch, Daniel Toma, Nathan Torkington, Timothy Totten, John J. Trammell, Matt S. Trout, Nat Tuck, Adam Turoff, Ben Tyler, ujwal, Bernd Ulmann, Reini Urban, parrot user, uzair, VZ, Ilmari Vacklin, vamped, Wim Vanderbauwhede, vendethiel, David Vergin, Ted Vessenes, Sam Vilain, Cédric Vincent, Jesse Vincent, Jos Visser, John van Vlaanderen, vmax, Jeremy Voorhis, Martin Vorländer, Johan Vromans, Maxim Vuets, Juerd Waalboer, Mariano Wahlmann, Kevin Walker, Gloria Wall, Larry Wall, Lewis Wall, Michal J Wallace, John Paul Wallington, walter, Matthew Walton, Ting Wang, Xinyuan Wang, Andy Wardley, Bryan C. Warnock, wayland, Stephen Weeks, Zhen‑Bang Wei, Nick Wellnhofer, Shu‑Chun Weng, Danny Werner, Brian Wheeler, David E. Wheeler, Dave Whipp, Adrian White, Andrew Whitworth, Bart Wiegmans, Nathan Wiger, Brock Wilcox, Edwin Wiles, Bob Wilkinson, Chris ‘BinGOs’ Williams, Greg Williams, Josh Wilmes, Matthew Wilson, Ashley Winters, Brian Wisti, Dave Woldrich, Helmut Wollmersdorfer, Kevin J. Woolley, Jonathan Worthington, Kuang‑Che Wu 吳光哲, xenu, Liang‑Qi Xie 謝良奇, Xtreak, Gaal Yahas גל יחס, Thomas Yandell, Alvis Yardley, Thomas Yeh 葉志宏, Natan Yellin, yiyihu, Matt Youell, Tony Young, Shen, Yu‑Teh, Ilya Zakharevich, Ruslan Zakirov, Ahmad M. Zawawi, Michael A. D. Zedeler, zengargoyle, zeriod, Agent Zhang 章亦春, Jimmy Zhuo, Ziggy6, Rob Zinkov, Zoffix Znet

If you would like to contribute or find out more information, visit
http://perl6.org, http://rakudo.org/how-to-help, ask on the
perl6-compiler@perl.org mailing list, or ask on IRC #perl6 on freenode.

The next release of Rakudo (#95), is tentatively scheduled for 16 January 2016. A list of the other planned release dates is available in the “docs/release_guide.pod” file.

The development team appreciates feedback! If you’re using Rakudo, do get back to us. Questions, comments, suggestions for improvements, cool discoveries, incredible hacks, or any other feedback — get in touch with us through (the above-mentioned) mailing list or IRC channel. Enjoy!

[^1]: See http://moarvm.org/

[^2]: See https://en.wikipedia.org/wiki/Koliada

[^3]: See https://github.com/perl6/roast/tree/6.c

[^4]: What’s the difference between the Rakudo compiler and the Rakudo Star distribution?

The Rakudo compiler is a compiler for the Perl 6 language. Not much more.

The Rakudo Star distribution is the Rakudo compiler plus a selection of useful Perl 6 modules, a module installer, the most recent incarnation of the “Using Perl 6” book, and other software that can be used with the Rakudo compiler to enhance its utility. Rakudo Star is meant for early adopters who wish to explore what’s possible with Rakudo Perl 6 and provide feedback on what works, what doesn’t, and what else they would like to see included in the distribution.

Day 24 – An Unexpectedly Long-expected Party

Camelia-small

Hello. Ting, ting, ting. Attention! … ATTENTION!

Thank you.

Hi, I’m Camelia, if you don’t know me. (Or even if you do.) They told me I had to give a speech at Perl 6’s official Coming Out Party. So here I am. Someone else is doing the roast. I’m just the toast. They told me it had to be a serious speech. Ha, like I’d know how to give a serious speech. Seriously?

Well. Seriously, I’d like to thank you all for coming out today.

Oops, I guess that was a pun. Sorry. Well, no, not really…

But thanks for showing up. This is a big day for Perl 6. She is officially of age now. Well, kinda sorta. She has her driver’s license, anyway. Watch out, world!

[inaudible comment from a table in back]

Oh, should I not have mentioned that? I wasn’t really talking about those fender benders she had while… Well, anyway, let’s move on. I’m sure she’ll be a really good driver. From now on.

Anyway, I have a great deal of empathy for Perl 6, because I am a butterfly. I too had to spend Far Too Long as a chrysalis before I had my own coming out. A literal coming out in my case. Hah, a literal coming out FROM my case, I should say!

Er, oops. I did it again, didn’t I.

Anyway, please be patient with Perl 6. Today we declare her to be a relatively competent being, but she is still just a teenager, y’know. When we’re very young, we’re just the age we are, but when we get to be teenagers, and go through all these hormonal changes, well, we start to oscillate. And the swings just get wider for a while. So when you’re 15, the swing is like plus-or-minus 10 years. One day you’ll act like you’re 25, and the next day like you’re 5 again.

So Perl 6 still has some maturing to do, fershure. That doesn’t mean we don’t love her any less on the days she’s throwing tantrums and driving us crazy. It just means, well, I guess it just means she’s family, and you love family through thick and thin. Because you trust family to turn thin back into thick someday.

And we’re all her extended family, gathered here today. They say it takes a village to raise a child. But never has there been such a child, or such a village! When you get a chance to look at your program tomorrow after your hangover wears off, just look at the list of benefactors in back. There are over 800 names of people who actively contributed to the development of Perl 6, one way or another. And undoubtedly there are a few names missing from the list.

You are a great bunch of people. All of you. Not just the closest members of the family. The family realized long ago that some of the most valuable guidance a growing computer language can get comes from outside the immediate family. It comes from friends and acquaintances who can have more perspective than someone who is always close. That’s why it takes a village.

Maturity is a fractal entity, and operates on many different scales. You all have been a proxy for the wide, wide world that Perl 6 is going out into. And it’s a rough world out there. Perl 6 is ready for some of it, thanks to you.

Of course, she’s still just 15. She does some things really well now. Her communication skills are pretty good, and she is very polite when she can’t understand you. She can carry on several conversations at once. She’s getting pretty good at math, and shows skill in manipulating objects of various sorts. She loves foreign languages, and all those funny characters.

But she’s still a deliberate child, and sometimes seems to be thinking too hard when learning something. That’s okay. She’ll get faster and more efficient over the next several years, as her brain rewires itself into full adulthood. She’ll learn new things, about the world and about herself. But I don’t think her personality will change much, that’s pretty obvious by now.

And that’s because her personality really comes from all of you. You’ve all loved her into existence, and now she’s ready to pass that love on to others who haven’t met her yet.

We all get really excited when a rocket takes off. TimToady tells me about getting up in the wee hours of the morning to watch Mercury, Gemini, and Apollo rockets take off. I’m too young to remember those, but we have our own thrilling developments to track. Me, I was very happy to see a SpaceX rocket stick its landing this week. After several fender benders…

[another inaudible comment]

I’m ignoring you. Be careful. We’ve gotten really, really good at ignoring certain kinds of people. Don’t be one of them.

Really, I feel sorry for the people who are only happy when they have something to be unhappy about.

Anyway, launching Perl 6 into the world is a lot like a rocket launch. A lot of excitement during the countdown, that hold-your-breath moment when you wonder if it’s really going to go up or explode. That’s where we are now. The main engines are lit, the clamps are letting go. It’s all very dramatic, mostly because nothing much seems to be happening right now.

But that’s not what a rocket is about. Drama is not what a rocket wants to do. A rocket wants to go up, faster and faster and faster. It’s not about position. It’s not really even about velocity. It’s about acceleration.

[raises glass]

So, I give you Perl 6. She is free to fly. May she have joy in her existence. May she have joy in discovering the world. May she accelerate as long as she will! Cheers!

Day 23 – macros and secret agents

Let’s talk about 007.

$ perl6 bin/007 -e='say("OH HAI")'
OH HAI

007 is a small language, implemented in Perl 6. Its reason for existing is macros, a topic that has become quite dear to me.

I want to talk a little bit about macros, and what's happened with them in 2015. But first let's just get out of the way any doubts about 007 being a real language. Here, have a Christmas tree.

for [1, 2, 3, 4, 5, 2, 2] -> n {
    my indent = " " x (5 - n);
    my tree = "#" x (2 * n - 1);
    say(indent ~ tree);
}

Which gives this output:

    #
   ###
  #####
 #######
#########
   ###
   ###

If you want to describe 007 real quick, you could say it has a syntax very much like Perl 6, but it borrows things from Python (and JavaScript). For example, there are no sigils. (Awww!) There's no $_, so if you're interested in the elements you're iterating over, you need to declare a loop variable like we did. There's no flattening, no list context, and no conflation between a single item and a list-of-one. (Yay!)

007 does have objects:

my agent = {
    name: "James Bond",
    number: 007
};

say(agent.name);             # James Bond
say(agent.has("number"));    # 1

And, as it happens, all the types of statements, expressions, and other program elements are also expressible in the object system.

my code = quasi {
    say("secret agent!")
};

say(code.statementlist.statements[0]
        .expr.argumentlist.arguments[0]
        .value);             # secret agent!

The quasi there "freezes" the program code into objects, incidentally the exact representation that the 007 compiler deals with. We can then dig into that structure, passing down through a block, a statement, a (function invocation) expression, and finally a string value.

Being able to take this object-oriented view of the program structure is very powerful. It opens up for all kinds of nice manipulations. Perhaps the most cogent thing I've written about such manipulations is a gist about three types of macros. But the way ahead is still a bit uncertain, and 007 is there exactly to scout out that way.

I recently blogged about 007 over at strangelyconsistent, telling a little bit about what's happened with the language in the past year. Here, today, I want to tell about some things that are more directly relevant to Perl 6 macros.

But first...

What are all those Q types, then?

Giving a list of the Q types is still dangerous business, since the list itself is still in mild flux. But with that in mind, let's see what we have.

There's a Q type for each type of statement. Q::Statement::If is a representative example. There's also while loops, for loops, declarations of my variables, constants, subs, macros, etc. Return statements.

A common type of statement is Q::Statement::Expr, which covers anything from a function call to doing some arithmetic. A Q::Statement::Expr is simply a statement which contains a single expression.

So what qualifies as an expression? All the operators: prefix, infix, postfix. Various literal forms: ints, strings. Bigger types of terms like arrays and objects. Identifiers — that is, something like a variable, whether it's being declared or being used. Quasi terms, like we saw above.

Some constructs have some "extra" moving parts that are neither statements nor expressions. For example, blocks have a parameter list with parameters — the parameter list is a Q type, and a parameter is a Q type. Function calls have argument lists. Subs and macros have trait lists. Quasis have "unquotes", a kind of parametric hole in the quasi where a dynamic Qtree can be inserted.

And that's it. For a detailed current list, see Q.pm.

First insight: the magic is in the identifiers

Way back when we started to think about macros in Perl 6, we came to realize that Qtrees are never quite free of their context. You always keep doing variable lookups, calling functions, etc. Because this happens in two vastly different environments (the macro's environment, and the macro user's environment), quite a bit of effort goes to keeping these lookups straight and not producing surprising or unsafe code. This concern is usually referred to as "hygiene", but all we really need to know is that the macro environment is supposed to be able to contain any variable bindings and still not mess up the macro user's environment... and vice versa.

macro moo() {
    my x = "inside macro";
    
    return quasi { say(x) };
}

my x = "outside macro";
moo();    # inside macro

The prevailing solution to this (and the one that I started to code into Rakudo as part of my macros grant) was to achieve hygiene by the clever use of scopes. See this github issue comment for a compelling example of how code blocks would be injected in such a way that the variable lookup would just happen to find the right declaration, even if that means jumping all over the program.

With the recent work of 007, it's evident that the "clever use of scopes" solution won't work all the way. I'm glad I discovered this now, in a toy language implementation, and not after investing lots more time writing up a real solution of this in Rakudo.

The fundamental problem is this: injecting blocks is all good and well in either a statement or an expression. Both of these situations can be made to work. But we also saw in the previous section that there are "extra" Q types which fall outside of the statement/expression hegemony. We don't always think about those, but they are just as important. And they sometimes contain identifiers, which would be unhygienic if there wasn't a solution to cover them. Example: a trait like is looser(infix:<+>). The hygiene consists of infix:<+> being guaranteed to mean what it means in the defining macro environment, not what it means in the using mainline environment.

The new solution is deceptively simple, and will hopefully take us all the way: equip identifiers with a knowledge of what block they were defined in. If we exclude all macro magic, all identifiers will always start their lookup from "here", the position in the code that the runtime is in. (Note that this is already strong enough to account for things like closures, because "here" is exactly the context in which the closure was defined.)

The magic thing about macros is that you will inject a lot of code, and all the identifiers in that code will remember where they were born: in a quasi in a macro somewhere. That's the context in which they will do the lookup, not the "here" of the mainline code. Et voilà, hygiene.

We still allow identifiers to be synthetically created (using object construction syntax) without such a context. This makes them "detached", and the idea is that this will provide a little bit of a safety vent for when people explicitly want to opt out of hygiene. The Common Lisp and Scheme people seem to agree that there are plenty of such cases.

Second insight: there are two ways to create a program

So we know that Qtrees are formed by the parser going over a program, analyzing it, and spitting out Q objects that hang together in neat ways. We know that this process is always "safe", because we trust the parser and the parser is nice.

But in 007 where Q objects are in some sense regular objects, and they can be plugged together in all kinds of way by the user, anything could happen. The user is not necessarily nice — as programmers we take this as a self-evident truth. Someone could try to cram a return statement into a trait! Or drop a parameter list into a constant declaration. Many other horrors could be imagined.

So there have to be rules. Kind of like a HTML DOM tree is not allowed to look any which way it wants. We haven't set down those rules in stone yet in 007, but I suspect we will, and I suspect it will be informative.

(The challenging thing is when we try to combine this idea of restriction with the idea of extending the language. Someone wants to introduce optional parameters. Ok, let's say there's a process for doing that. Now the first obstacle is the rule that says that a parameter consists of just an identifier and nothing else. Once you've negotiated with that rule and convinced it to loosen up, you still have various downstream tools such as linters and code formatters you need to talk to. The problem is not unsolvable as such, just... the right kind of "interesting".)

But it doesn't end with just which nesting relationships — there's a certain sense in which a completely synthetically constructed Qtree isn't yet part of the program as such. For example, it contains variable declarations, but those variable haven't been declared yet. It contains macro calls, but those macros haven't been applied yet. And so on. All of those little things need to happen as the synthetic Qtree is introduced into the bigger program. We currently call this process checking, but the name may change.

Parsing and checking are like two sides of the same coin. Parsing is, in the end, just a way to convince the compiler that a piece of program text is actually a 007 program. Checking is just a way to convince the compiler that a Qtree is actually a 007 program (fragment). We've grown increasingly confident in the idea of checking, partly because we're using it quite heavily in our test suite.

But why stop there? Having two code paths is no fun, and in a sense parsing is just a special case of checking! Or, more exactly, parsing is a very optimized form of checking, where we make use of the textual medium having certain strengths. Why are identifiers limited to the character set of alphanumerics and underscores (and, in Perl 6, hyphens and apostrophes)? Mostly because that's a way for the parser to recognize an identifier. There's nothing at all that prevents us from creating a synthetic Q::Identifier with the name , and there's nothing at all that prevents the checker from processing that correctly and generating a correct program.

It seems to me that the work forwards is to explore the exact relationship between text and Qtrees, between parsing and checking, and to set up sensible rules within which people can write useful macros.

This is exciting work, and will eventually culminate in very nice macros in Perl 6. Expect to hear more about 007 in 2016. See you on the other side!

Perl 6.christmas – have an appropriate amount of fun!

A decade ago Audrey Tang started the Pugs project to implement Perl 6 in Haskell and declared that Perl 6 was optimized for fun: -Ofun.

Game designers know what -Ofun looks like – it’s when players find themselves engrossed in their game, time flies and they experience flow. The art of great game design is balancing the player’s increasing ability with the challenge of the game. Sometimes it’s a bumpy ride!

flow

Flow can happen when programming too: when you’re free from distraction, and the challenge you’re facing is not too easy, not too hard and you’re making positive progress.

Audrey’s invitation to new Perl 6 contributors to have ‘the appropriate amount of fun’ encouraged them to step forward and pick their place on this challenge/ability curve.

The challenge of designing and implementing Perl 6 has presented some scary technical dragons! Fortunately some of the most able programmers stepped forward to hack them down to size.

Over the past decade, it has been a joy to regularly read the #perl6 IRC logs and watch this process unfold. Despite the naysayers, #perl6 has remained a positive, productive place – the propensity for -Ofun is part of the DNA of Perl 6.

camelia-flowing

Camelia, the Perl 6 butterfly logo, helps sum this up. Camelia includes a reference to a ‘camel’ in her name, however, unlike a camel she doesn’t smell or spit. Flow requires a positive mindset. Camelia is a licence to have -Ofun – not the frivolous, Christmas cracker type, but the deeply productive, enjoyable and enduring type.

The Christmas release is a turning point in the whirlpool of Perl 6 development. The -Ofun will now freely flow outwards to new programmers.

Perl 6, with its emphasis on whipupitude and expressivity, makes it ideally suited to finding flow while programming.

If you haven’t unwrapped Perl 6 yet, this Christmas is the perfect time. You can download Perl 6 here and remember to have an appropriate amount of fun!

Day 17 – A loop that bears repeating

I don’t believe anyone has ever Advent blogged about this topic. But it’s getting hard to tell, what with almost six years of old posts. 😁

This story starts in Perl 5, where we implement a countdown with a simple while loop:

$ perl -wE'my $c = 5; while ($c--) { say $c }'
4
3
2
1
0

And of course, if we want to exit early from the loop, we use the trusty last:

$ perl -wE'my $c = 5; while ($c--) { say $c; last if $c == 2 }'
4
3
2

So far, so good. But notice that $c is decremented before each run of the loop body. Under some circumstances it makes more sense to do it afterwards. In Perl 5, we’d use do ... while:

$ perl -wle'my $c = 5; do { print $c; } while $c--'
5
4
3
2
1
0

Great. Now we just need to combine this with the early exit:

$ perl -wle'my $c = 5; do { print $c; last if $c == 2 } while $c--'
5
4
3
2
Can't "last" outside a loop block at -e line 1.

Eh? Oops.

Experienced Perl people will know what’s going on here. The documentation, in this case perldoc perlsyn, explains it clearly:

The “while” and “until” modifiers have the usual “”while” loop” semantics (conditional evaluated first), except when applied to a “do”-BLOCK […], in which case the block executes once before the conditional is evaluated.

…and then…

Note also that the loop control statements described later will NOT work in this construct, because modifiers don’t take loop labels. Sorry.

In other words, the do ... while construct is a little bit of a cheat in Perl 5, made to work as we expect, but really just a do block with reindeer horns glued on top of its head. The cheat is exposed when we try to next and last from the do block.

perldoc perlsyn goes on to explain how you can mitigate this with more blocks and loop labels, but in a way, the damage is already done. We’ve lost a little bit of that natural belief in goodness, and Santa, and predictable language semantics.

It goes without saying that this is a situation up with which Perl 6 will not put. Let’s see what Perl 6 provides us with.

Instead of painstakingly lining up differences, let’s just first replay our Perl 5 session with the corresponding Perl 6:

$ perl6 -e'my $c = 5; while $c-- { say $c }'
4
3
2
1
0
$ perl6 -e'my $c = 5; while $c-- { say $c; last if $c == 2 }'
4
3
2
$ perl6 -e'my $c = 5; repeat { say $c } while $c--'
5
4
3
2
1
0
$ perl6 -e'my $c = 5; repeat { say $c; last if $c == 2 } while $c--'
5
4
3
2

We’ve gotten rid of a few parentheses, as is usually the case when changing to Perl 6. But the biggest difference is that do has now been replaced by another keyword repeat.

In Perl 5, when we saw the do keyword and a block, we didn’t know if there would come a while or until statement modifier after the block. In Perl 6, when we see the repeat, that’s a promise that this is a repeat ... while or repeat ... until loop. So it’s a real loop in Perl 6, not a fake.

Oh, and the last statement works! As it does in real loops.


The story might have ended there, but Perl 6 has a little bit more of a gift to give with this type of loop.

Let’s say we’re waiting for an input that has to have exactly five letters.

sub valid($s) {
    $s ~~ /^ <:Letter> ** 5 $/;
}

This is the type of thing that we’d tend to express with a repeat-style loop, because we have to read the input first, and then find out if we’re done or not:

my $input;
repeat {
    $input = prompt "Input five letters: ";
} until valid($input);

The $input variable has to be declared separately outside of the loop block, because we’re testing it in the until condition outside of the loop block.

Even though we now know to expect a while or until after the block, having that information there makes the end-weight of the loop a bit problematic: we’re delaying some of the most pertinent information until last.

(A similar problem happens in Perl 5 regexes, where a lot of modifiers can show up after the final /, changing the meaning of the whole regex body. And of course, even in spoken and written language, you might have a sentence which goes on and on and just won’t stop, even though it should have long ago, and finally when you think you’ve got the hang of it, it surprises you unduly by ending with altogether the wrong hamster.)

For this reason, Perl 6 allows the following variant of the above repeat loop:

my $input;
repeat until valid($input) {
    $input = prompt "Input five letters: ";
}

That looks nicer!

I hasten to underline that even after moving the condition to the top of the loop like this, the code still has the previous behavior — that is, the condition valid($input) is still evaluated after each iteration of the loop body. (That is, after all, the difference between a repeat until loop and just an until loop.) In other words, we get to place the condition where it’s more prominent and harder to miss, but we retain the expected eval-condition-afterwards semantics.

As a final nice bonus, we can now inline the declaration of $input into the loop condition itself.

repeat until valid(my $input) {
    $input = prompt "Input five letters: ";
}

This clearly shows the difference between order of elaboration (in which variables are declared before they are used) and order of execution (in which statements and expressions evaluate in the order they damn well please).

That’s repeat, folks. Solves a slew of problems, and lets us write nice, idiomatic code.

Day 13 – A new trait for old methods

use v6;

El_Che expressed the desire on IRC to have Perl 6 watch his fingers when typing named arguments. It is indeed quite easy to send a wrong name the right way. Luckily we can help him.

First we need some exception to throw. Perl 6 kindly creates a constructor for us that deals with filling all attributes with values, so we can provide details when we throw the exception.

class X::Parameter::ExtraNamed is Exception {
    has $.extra-parameters;
    has $.classname;
    has $.method-name;
    method message () {
        "The method $.method-name of $.classname is offended by the named parameter(s): $.extra-parameters";
    }
}

We want to modify a method (.new in this case) so we need a trait. A trait is a modification of the Perl 6 grammar and a subroutine. It’s name comes from the required named argument. The thing it operates on is stored in the first positional. In our case that’s a method.

multi sub trait_mod:<is>(Method $m, :$strict!){

We want to check named arguments against the list of arguments that are defined in the methods signature. We have to store them somewhere.

    my @named-params;

When we provide some error message we may want to name the class the method is member of.

    my $invocant-type;
    my $method-name = $m.name;

The signature of a method can provide us with a list of parameters.

    for $m.signature.params -> $p {

But first the classname.

        $invocant-type = $p.type if $p.invocant;

We are only interested in named arguments.

        next unless $p.named;

Each named argument starts with a sigil ($ in this case). That would get in our way, so we strip it from the method name and store the rest for safekeeping.

        @named-params.push: $p.name.substr(1);
    }

After we got all the information we need, we come to the business end of our trait. We wrap the method in a new method. We only want to peek into it’s argument list so we take a capture. Conveniently a capture provided us with a method to get a list of all named arguments it contains.

    $m.wrap: method (|args) {

We first check with the subset operator (<=) if there are any named arguments we don’t like and if so, we use the set difference operator (-) to name only those. The exception we defined earlier takes care of the rest.

        X::Parameter::ExtraNamed.new(
            method-name => $method-name,
            classname => $invocant-type.perl, 
            extra-parameters => args.hash.keys (-) @named-params
        ).throw unless args.hash.keys (<=) @named-params;

If all named arguments are fine, we can call the wrapped method and forward all arguments kept in the capture.

        callwith(self, |args);
    }
}

Let’s test it.

class Foo {
    has $.valid;

Perl 6 will deal with the positional part, our trait is strict will learn about :$valid.

    method new (Int $p1, :$valid) is strict { self.bless(valid => $valid) }
    method say () { say 'Foo' }
}

New instance is new and got 2 extra named arguments the method doesn’t know of.

Foo.new(42, valid => True, :invalid, :also-invalid).say;

OUTPUT:

<<The method new of Foo is offended by the named parameter(s): invalid also-invalid>>

Traits are a nice way to generalise behaviour of methods and subroutines. Combined with exceptionally good introspection Perl 6 can be mended and bended to fit into any Christmas package. Merry 1.0 and a happy new Perl 6 to you all!

Day 12 – I just felt a disturbance in the switch

So I said “I’m going to advent post about the spec change to given/when earlier this year, OK?”

And more than one person said “What spec change?”

And I said, “Exactly.”


We speak quite proudly about “whirlpool development” in Perl 6-land. Many forces push on a particular feature and force it to converge to an ideal point: specification, implementation, bugs, corner cases, actual real-world usage…

Perl 6 is not alone in this. By my count, the people behind the HTML specification have now realized at least twice that if you try to lead by specifying, you will find to your dismay that users do something different than you expected them to, and that in the resulting competition between reality and specification, reality wins out by virtue of being real.

I guess my point is: if you have a specification and a user community, often the right thing is to specify stuff that eventually ends up in implementations that the user community benefits from. But information can also come flowing back from actual real-world usage, and in some of those cases, it’s good to go adapting the spec.


Alright. What has happened to given/when since (say) some clown described them in an advent post six years ago?

To answer that question, first let me say that everything in that post is still true, and still works. (And not because I went back and changed it. I promise!)

There are two small changes, and they are both of the kind that enable new behavior, not restrict existing behavior.

First small change: we already knew (see the old post) that the switching behavior of when works not just in a given block, but in any “topicalizer” block such as a for loop or subroutine that takes $_ as a parameter.

given $answer {
    when "Atlantis" { say "that is CORRECT" }
    default { say "BZZZZZZZZZT!" }
}
for 1..100 {
    when * %% 15 { say "Fizzbuzz" }
    when * %% 3 { say "Fizz" }
    when * %% 5 { say "Buzz" }
    default { say $_ }
}
sub expand($_) {
    when "R" { say "Red Mars" }
    when "G" { say "Green Mars" }
    when "B" { say "Blue Mars" }
    default { die "Unknown contraction '$_'" }
}

But even subroutines that don’t take $_ as a parameter get their own lexical $_ to modify. So the rule is actually less about special topicalizer blocks and more about “is there something nice in $_ right now that I might want to switch on?”. We can even set $_ ourselves if we want.

sub seek-the-answer() {
    $_ = (^100).pick;
    when 42 { say "The answer!" }
    default { say "A number" }
}

In other words, we already knew that when (and default) were pretty separate from given. But this shows that the rift is bigger than previously thought. The switch statement logic is all in the when statements. In this light, given is just a handy topicalizer block for when we temporarily want to set $_ to something.

Second small change: you can nest when statements!

I didn’t see that one coming. I’m pretty sure I’ve never used it in the wild. But apparently people have! And yes, I can see it being very useful sometimes.

when * > 2 {
    when 4 { say 'four!' }
    default { say 'huge' }
}
default {
    say 'little'
}

You might remember that a when block has an implicit succeed statement at the end which makes the surrounding topicalizer block exit. (Meaning you don’t have to remember to break out of the switch manually, because it’s done for you by default.) If you want to override the succeed statement and continue past the when block, then you write an explicit proceed at the end of the when block. Fall-through, as it were, is opt-in.

given $verse-number {
    when * >= 12 { say "Twelve drummers drumming"; proceed }
    when * >= 11 { say "Eleven pipers piping"; proceed }
    # ...
    when * >= 5 { say "FIIIIIIVE GOLDEN RINGS!"; proceed }
    when * >= 4 { say "Four calling birds"; proceed }
    when * >= 3 { say "Three French hens"; proceed }
    when * >= 2 {
        say "Two turtle doves";
        say "and a partridge in a pear tree";
    }
    say "a partridge in a pear tree";
}

All that is still true, save for the word “topicalizer”, since we now realize that when blocks show up basically anywhere. The new rule is this: when makes the surrounding block exit. If you’re in a nested-when-type situation, “the surrounding block” is taken to be the innermost block that isn’t a when block. (So, usually a given block or similar.)


It’s nice to see spec changes happening due to how things are being used in practice. This particular spec change came about because jnthn tried to implement a patch in Rakudo to detect topicalizer blocks more strictly, and he came across userland cases such as the above two, and decided (correctly) to align the spec with those cases instead of the other way around.

The given/when spec has been very stable, and so it’s rare to see a change happen in that part of the synopses. I find the change to be an improvement, and even something of a simplification. I’m glad Perl 6 is the type of language that adapts the spec to the users instead of vice versa.

Just felt like sharing this. Enjoy your Advent.

Day 11 – The Source will be with you, always

Reportings from a Learnathon

This past weekend I had the pleasure of hosting a Perl 6 learnathon with a friend who contacted me specifically to have a night of absorbing this new version of Perl. I thought it might be interesting to share some of what we learned during the process. I will begin with by explaining the single line of code which ended up and then show you some examples of where our evening took us.

Pick Whatever, rotor by five

As we opened our laptops, I was excited to show the newest example I had pushed to my Terminal::Print project. It’s taken quite some time to achieve, but asynchronous printing is now working with this module. It’s not fast, yet, but my long saught multi-threaded “Matrix-ish” example is working. Each column is being printed from an individual thread. This approach of spinning off a bunch of new threads and then throwing them away is not efficient, but as a proof of concept I find it very exciting.

pick-rotor

This line contains a few things that inspired questions. The first is the precise meaning of pick(*), which here means that we want to produce a randomized version of @columns. You can think of the Whatever here as a meaning “as many as possible”. It triggers a different multi method code path which knows to use the invoking objects’s own array size as the length of the list to pick.

The second part to explain was rotor. This is another one of those Perl 6 English-isms that at first felt quite strange but quickly became a favorite as I began visualizing a huge turbine rotor-ing all of my lists into whatever shape I desire whenever I use it. In this case, I want to assemble a list of 5-element arrays from a random version of @columns. By default, rotor will only give you back fully formed 5-element arrays, but by passing the :partial we trigger the multi-method form that will include a non 5-element array if the length of @columns is not divisible by 5 (‘Divisibility’ is easily queried Perl 6, by the way. We phrase it as $n %% 5.)

Put another way: rotor is a list-of-lists generator, taking one list and chopping it up into chunks according to your specifications. My friend mentioned that this resembles a question that he asks in interviews, inviting an investigation into the underlying implementation.

I’ve always considered Rakudo’s Perl 6-implemented-in-Perl 6 approach as a secret weapon that often goes overlooked in assessment of Perl 6’s viability. Even with the current reliance on NQP, there is a great deal of Perl 6 which is implemented in the language itself. To this end, I could immediately open src/core/Any.pm in an editor and continue explaining the language by reading the implementation of the language. Not just explaining the implementation, which can be accomplished by the right combination of language/implementation language and polyglot coverage. I mean explaining the language by looking at how it is used to implement itself, by following different threads from questions that arise as a result of looking at that code.

A word of caution

Now, I don’t mean to imply that one’s initial exposure to core can’t be a shocking experience. You are looking at Perl 6 code that is written according to constraints that don’t exist in perl6 which arise from not being fully bootstrapped and performance concerns. These are expressed in core by NQP and relative placement in the compilation process, on the one hand, and in prototyping and hoop jumping, on the other.

In other words: you are not expected to write code like this and core code does not represent an accurate representation of what Perl 6 code looks like in practice. It is 100% really Perl 6 code, though,  and if you look at NQP stuff as funky library calls, everything you are seeing is possible in your own code. You just don’t normally need to.

Down the rabbit hole

From src/core/Any.pm, here is the code for rotor:

any-rotor.png

And the code for pick:

pick-any

These are not the actual implementations, mind you. Those live in List.pm. But already these signatures inspire some questions

What is this |c thing in the signature?

This represents a Capture, which is an object representing the arguments passed into the method call. In this case it is being used such that no unpacking/containerization occurs. Rather we simply accept what we have been given and pass them as a single parameter to self.list.rotor without looking at them.

In the proto signature for pick we see that there is no name for the Capture, but rather a bare ‘|‘ which tells the method dispatcher that there can be zero or more arguments. Put another way: there are no mandatory arguments that apply to all the pick candidates.

What is this proto thing?

The answer is that it is a clarification that you can apply to your multi methods that constrains them to a specific “shape”.  It is commonly used in conjunction with a Capture, and in fact we see this in our pick example.

As the docs put it, a proto is ‘a way to formally declare commonalities between multi candidates’. The prototype for pick specifies that there are no mandatory arguments, but there might be. This is basically the default behavior for multi method dispatch, but here it allows us to specify the is nodal trait, which provides further information to the dispatcher relating to the list-y. Also due to bootstrapping issues, all multi methods built into Rakudo need an explicit proto.In practice we do not need either of these for our code. But they are there when you need them. One example of a trait that you might use regularly is the pure trait: when a given input has a guaranteed output, you can specify that it is pure and the dispatcher can return results for cached arguments without repeated calculations.

Midnight Golf

As promised, here are a few code examples from the learnathon.

stateful.pngstateful-results.png

This is using anonymous state variables, which are available to subroutines and methods but not to other Callables like blocks.  My friend shared my marvel at the power and flexibility of the Perl 6 parser to be able to handle statements like $--*5, when every character besides the 5 in that statement has a different meaning according to context. Meanwhile Perl 6 gives you defaults for your subroutine parameters by using the assignment operator.

Note that each bare $ in a subroutine creates/addresses a new, individual state variable. Some people will hate this, as they hate much that I appreciate about the language. These anonymous state variables are for situations where a name doesn’t matter, such as golfing on the command line. They can be confusing to get a full grasp of, though.

Here is another example we generated while exploring (and failing many times) to grasp the nuances of these dynamics.

more-state.pngmore-state-results.png

Gone is the anonymous state variable. This is by necessity, because you can only refer to an anonymous state variable once in a subroutine. We’ve switched $a to be optional. The parens around the state declaration are necessary because trying to declare a variable in terms of itself is undefined behavior and Perl 6 knows that.

The same thing, expressed in slight variations but with the same meaning:

more-more-state.png

The bottom example shows that the assignment to zero in our initial more-state is actually unnecessary. The middle shows creating a variable and binding it to a state var, which is a rougher way to get the same behavior as openly declaring a state variable. The top example shows what might be considered the ‘politely verbose’ option.

Concluding thoughts

I was hoping to share more from the evening with you, but it’s been a lot of words already and we’ve only scratched the surface of the first example we examined! Instead, I recommend that you spend some time with src/core in an editor,  the perl6 repl in a terminal, and #perl6 in an IRC client (or web browser) and just explore.

This language is deep. Opening src/core is like diving into the deep end of the ocean from the top of a Star Destroyer. The reward for your exploration of the language, however, is an increasing mastery of a programming language that is designed according to a human-centric philosophy and which approaches a level of expressivity that, some would argue, is unparalleled in the world of computing.

 

Day 10 – Perl 6 Pod

Whenever you write code, you also write documentation, right? Wait, don’t answer that! Let me just pretend that you said “yes”.

As with Perl 5, Perl 6 has a built-in documentation format called Pod. In Perl 5, POD was short for “Plain Ol’ Documentation”, but in Perl 6 we just call it Pod and there’s no acronym. One of the great things about Pod in Perl 6 is that the compiler parses Pod for you. The resulting structure is essentially a tree (really, an Array of trees).

Let’s take a look at a few examples …

use v6;

=begin pod

=head1 NAME

example1.p6 - It's a script to show you how Pod works in Perl 6!

=end pod

sub MAIN {
    say $=pod.WHAT;
    say $=pod[0].WHAT;
}

When I run this script I get:

$ perl6 ./bin/example1.p6 
(Array)
(Named)

The $=pod variable is a reference to the parsed Pod from the current file.

From the code above we can see that the $=pod variable contains an Array. Each element of that array is a Pod node of some sort, and those nodes in turn will usually contain more Pod nodes, and so on. Essentially, Pod is parsed into a tree that you can recursively descend and examine.

The $=pod variable is an array is because you can have several distinct chunks of Pod in a single file …

use v6;

=begin pod

=head1 NAME

example2.p6 - It's a script to show you how Pod works in Perl 6!

=end pod

sub MAIN {
    say $=pod.elems;
    say $=pod[0].WHAT;
    say $=pod[1].WHAT;
}

=begin pod

=head1 DESCRIPTION

This is where I'd put some more stuff about the script if it did anything.

=end pod

When we run this script we get:

$ perl6 ./bin/example2.p6 
2
(Named)
(Named)

So there are now two elements in $=pod, one for each chunk of Pod delimited by our =begin pod/=end pod pairs.

Pod Syntax in Perl 6

Up until this point I’ve shown you some Pod without actually explaining what it is. Let’s take a look at some valid Pod constructs in Perl 6 so you can get a better sense of how it looks, both when you write it and when you’re writing code to process it.

Perl 6 Pod is purely semantic. In other words, you describe what something is, rather than how to present it. It’s left up to code that turns Pod into something else (HTML, Markdown, man pages) to decide how to present any given construct.

Perl 6 Pod has quite a bit more to it than we can cover here, so see Synopsis 26 for all the details. We’ll cover some of the highlights and then look more closely at how to process Pod programmatically.

Blocks

Pod supports several different ways to declare a block. You can use =begin and =end markers …

=begin head1
Heading Goes Here
=end head1

Or you can use a =for marker …

=for head1
Heading Goes Here

These block styles allow you to include configuration information:

=begin head3 :include-in-toc
This will show up in TOC
=end head3

=for head4 :!include-in-toc
Not in the TOC

With a =for block, only the lines immediately following the =for is part of that block. Once there is an empty line, anything that follows is separate.

You can use an “abbreviated” block …

=head1 Heading Goes Here

… but abbreviated blocks don’t allow for configuration information. Like =for blocks, abbreviated blocks end at the first empty line.

There are many types of blocks, including table, code, I/O blocks (input and output), lists, and more.

Paragraphs

Text that isn’t explicitly part of a block is considered to be a paragraph block …

use v6;

=begin pod

=begin head1

NAME

=end head1

This is a paragraph block.

=end pod

sub MAIN {
    say $=pod[0].contents[1].WHAT;
}

The output will be (Para), because the second element of contents is a plain paragraph.

Lists

Lists are much simpler in Perl 6 than they were in Perl 5 …

=begin pod

=item1 The first item
=item1 The second item
=item2 This is a sub-item of the second item
=item1 The third item

Of course, you can also use the =for and =begin/=end form with list items too.

Formatting Codes

There are a variety of formatting codes available …

See L<http://design.perl6.org/S26.html> for details.

Some times you need to mark some text as C<code>,
B<being the basis of the sentence>,
or I<important>.

And More

There are a lot of new things with Perl 6 Pod, and if you want to learn more I encourage you to read Synopsis 26 for all of the gory details.

Processing Pod with Perl 6

As I said before, the Perl 6 compiler parses Pod in your program and makes it available to you via various variables. We already saw the use of $=pod, which contains all of the Pod in the current file. That pod is an array of Pod::Block objects. In future versions of Rakudo, you will also be able to get at specific types of Pod blocks by name with variables such as $=head1 or $=TITLE, but this is not yet implemented.

Let’s write a simple program to show us an outline of the Pod in a given file. For example, given some Pod like this …

=head1 NAME

...

=head1 DESCRIPTION

...

=head1 METHODS

...

=METHOD $obj.foo

...

=METHOD $obj.bar

...

 

… we want to print this output …

NAME
DESCRIPTION
METHODS
  $obj.foo (METHOD)
  $obj.bar (METHOD)

Here’s the code to do just that …

use v6;

sub MAIN {
    for $=pod.kv -> $i, $block {
        say "Block $i";
        recurse-blocks($block);
        print "\n";
    }
}

sub recurse-blocks (Pod::Block $block) {
    given $block {
        when Pod::Block::Named {
            if $block.name eq 'pod' {
                for $block.contents.values -> $b {
                    recurse-blocks($b);
                }
            }
            else {
                my $output = $block.contents[0].contents[0]
                    ~ " ({$block.name})";
                depth-say( 2, $output );
            }
        }
                
        when Pod::Heading {
            depth-say( $block.level,
                       $block.contents[0].contents[0] );
        }
    }
}

sub depth-say (Int $depth, Str $thing) {
    print '  ' x $depth;
    say $thing;
}

 

This code takes some shortcuts wherever it uses $block.contents[0].contents[0] by making the very big assumption that a block contains one element which is a single Pod::Block::Para. It then assumes that the Para block contains one element which is plain text.

In practice, blocks may contain arbitrarily nested blocks because of things like formatting codes, but this gives you an idea of how you might walk through the Pod tree.

Of course, because Perl 6 is still Perl, there’s a module for that! I’ve sketched out a preliminary module called Pod::TreeWalker that will do the tree walking for you, generating events as it finds different nodes. You provide a listener object that is called for each event.

GitHub Repo

All of the code shown in these examples is on GitHub. I’ve also written an additional script that uses Pod::TreeWalker to implement the outlining I demonstrate above.