Perl 6 Essentials
I started reading Perl 6 Essentials last night. I got it mainly because Dan Sugalski is one of the authors, and because I like the idea of the Parrot VM.
I've been kinda sorta following the Perl Apocalypses, but it's much more convenient to have a book lay everything out all at the same time. The writing style of the book is also significantly more compact than Larry Wall's rambling, tangential style.
Anyway, I have some initial impressions to share.
- The distinction between scalar and list contexts is probably one of the most scoffed at aspects of Perl, but I'm starting to think they may offer one of its strongest potentials. For example, as I mentioned in this post, it's not always clear what the meaning of some expressions should be -- it depends on the context in which they're used. Perl 6 is adding even more contexts, and using them for some new purposes (e.g. a new boolean context for evaluating whether a given value is true or false). However Perl 6's conception of contexts still doesn't quite go far enough to solve the kind of problem I mentioned in that post. I would be intrigued if Perl 6 made it possible for programmers to define new contexts, but since they're intertwined with the parsing process, I'm not sure that would be possible.
- Traits and properties rock! They're basically metadata attached to compile-time variables (traits) and run-time values (properties). I'm sure the perl community will come up with lots of uses for properties that nobody anticipated before hand. Metadata is simply a very useful concept, with tons of uses. The ability to say "return 'error message' but false" is merely one cool trick among many.
- Perl 6 will have multimethods! Happiness.
- The ~~ operator (a.k.a. "smart match") is a great way of handling switch statements. ~~ is basically a "do the right thing" equality test that can compare such disparate things as strings, regular expressions, lists, numbers, hashes, etc. It would be really great if the ~~ operator were implemented as a multimethod, so that a programmer could extend its behavior for custom types.
- I like the concept of junction types. For example, any(1,2) == any(2,3) is true, because 2 is in both junctions. Other junction types are "all", "one", and "none". I'm not familiar enough with junctions yet to know whether their Perl incarnation is elegant or unfortunate, but I think I'm leaning slightly towards unfortunate, since junctions are basically sets, and it really should be up to the code in question whether it wants to treat a given set as an any, an all, a none, or a one junction. That is, the type of the junction should be part of the operations on them, rather than part of the junction value itself. On the other hand, I realize that this would make it impossible to automatically use junctions as if they were simple scalars, which is a really nice trick. I suppose as long as one can easily convert between junction types, that'll be enough. I should also mention that junctions remind me vaguely of Icon, with its implicit failure and retry.
- I like sigils. I'm glad Perl 6 is keeping them. Most programmers hate the dollar signs that you have to put in front of every variable in Perl, but I think they're a very good way of distinguishing dynamic values from static values. By "static values", I'm referring to method names and class names, as well as keywords like "for", "while", "my", etc. In Perl, whenever you see a word without a sigil, you know it has one and only one meaning, which can be determined at compile-time. Whenever you see something with a sigil, you know that its meaning won't be determined until run-time. This is one of my pet peeves about Lisp and Scheme -- they make too many things look syntactically identical (e.g. built-in forms look like function calls, but they aren't).
- I like the new lightweight closure syntax: just put {} around some code, and you've created a closure. This is similar to smalltalk's blocks. I think when closures get this simple, you cross a qualitative boundary, not just a quantitative boundary. However I'm not so hot on using $_ as the implicit argument to closures. I'd prefer Smalltalk- or Ruby-style variable declarations (e.g. "
{|arg| ...}"). Perl 6 could easily introduce a redundant syntax here, so that both would be supported.
- The "temp" and "let" statements, along with UNDO blocks, make me wish that Perl had gone whole-hog and included full transaction support, as I described in this post.
- NEXT blocks are great for creating comma-separated lists (something I have to do quite frequently). Haskell's intersperse function is also great for this, but it obviously doesn't play very well with for loops.
- The use of "when" to match exception types is remarkably elegant. "when" is the same statement that's used for switch statements, so it makes use of the ~~ "smart match" operator. This means that exception handlers in perl can use several kinds of pattern matching to catch exceptions. They can match on the exception's class, as in Java and C++, but they can also match using regular expressions, predicate functions, etc. This blows Python's exception handling mechanism out of the water.
- I don't like the use of "?" and "+" in argument lists to indicate optional and named parameters. The syntactic overlap between using the same operators to force boolean and numeric contexts causes some very unpleasant cognitive dissonance. I suspect that this decision will be changed, if it hasn't changed already.
I've only gotten through page 63, so more impressions shall be forthcoming. I haven't even gotten to the Parrot parts.
Posted on November 5, 2003 06:58 PM
More languages articles
I'm glad you like it, even if you've not gotten to the bits I did yet. :) Couple'a things:
*) ~~ will be multimethod dispatchable.
*) Junctions make more sense if you think in terms of Quantum Mechanics than set theory. (Whether that's a good or bad thing is entirely separate :)
*) Full transaction support would be really nice, but in a language with side-effects (and arguably perl is all about the side-effects) it can't be done--there's too much behind-the-scenes stuff going on and too many un-rollbackable resources. If we promised transactions people would reasonably expect file activity to roll back, third-party extension libraries (like, say, GD or expat) to undo actions, and action-at-a-distance changes (like tie-triggered code) to revert. I don't know how do do that, unfortunately.
*) I don't think the ? and + changes in arglists have happened, and I'm not sure they will. People are reasonably good at context shifting. OTOH, Larry may still change it, and the grammar will be mutable so it'll definitely be there to experiment with.
Oh, and you'll have even more fun when you get to the parroty bits, except for the odd errors. (Make space in your schedule and mark that calendar!)
And now you get answers to almost all of your bullets.
Perl 6 will definitely make it possible for programmers to define new contexts. That probably comes from attaching a trait to a class that says "expecting this class means expecting this context". Since the grammar being mutable is a fundamental part of the language, adding parse rules for a context wouldn't be an uncommon thing to do.
You have no idea how nice junctions are until you've used them (Damian's Quantum::Superpositions implements the funtionality). Associating the type with the junction allows you to do things like:
if $x == 1 | 2 | 3 { ... }
Which reads like the wind. As Damian pointed out, any() is the equivalent of a formal mathematical set.
You've probably read this bit already, but $_ is just the most compact way to refer to variables in closures. You can make parameterized closures like this:
-> $x {...}
or, as before, like this:
sub ($x) {...}
$_ is just so you can make nice, concise closures like { split }.
As one of my epiphanies on perl6-language, I showed a way to implement a hypothetical function call in pure perl 6. It handled all objects with an UNDO method. Considering this and the fact that Parrot has event support, I suspect it won't be long after Perl 6's release that
use Transactions;
is on the CPAN.
I get the impression that "+" and "?" are staying.
One of the main decisions that impressed the hell out of me is the pervasiveness of $_ as the topic. It keeps you from having to name variables that don't need names, like each element of a list in a for loop. Names are hard to think of, and many times harder to read than just saying "it".