Wednesday, January 6, 2010

'Til You've Learned Your Lesson

One of my favorite writers is a guy who is currently in the midst of writing a specification for a programming language.  He recently made some changes to the first synopsis of Perl 6, and I am replicating some of it here, because I think it's a useful exhortation.  I hope he doesn't mind:
This was added to the synopsis with the log comment: "take another lap around Mt Sinai..." Since it's possible the intended message did not get across, even with this addition, I'd like to remind everyone that the next line in that song is, "'til you've learned your lesson."

Labels: , ,


Thursday, December 24, 2009

Promises of Parallel in Perl6


Been reading through the Perl6 specs again.  I like the way the synopses make "promises of parallelizability" on three families: junctions, hyperops, and feeds.  I also like the way these three promises differ from one another.  This post is a little thought experiment, in which I will act as the interpreter for all three.


Junctions
Of the three, junctions are the most difficult for me to grok.  Junctions are a family of four: all()any()none(), and one().  One obvious place where this family of four comes in handy:
say "foo" if all(1,2,3) # says foo 
The semantics, in this case, are obvious.  In Boolean context, all evaluates to True if all of the arguments are true, any if any are true, none if (and only if) none are true, and one if exactly one is true.  In this case, it's meant as a nice shorthand for:
say "foo" if (1 && 2 && 3) # says foo
 Except under the covers, it's much different (or at least I suspect it is, inside the brain of Larry Wall).  Since junctions carry a promise of autothreading, the former is a way of handing off to three threads in any order, and the latter (probably) executes in a promised order, (probably) with short-circuiting.  Concentrating on the former, it's not that interesting the way it's written, so let's imagine it a bit differently:
say "foo" if any(bar(1), bar(2), bar(3));
Basically, what I imagine this to be saying is, "go execute bar() in wherever it is convenient, in boolean context, and return the result here.  I will continue whenever either: a) one of you comes back true, or b) all of you come back false."  In fact, you can imagine doing something like this:
do_stuff() if any(breadthfirst($tree), depthfirst($tree));
This could be shorthand for: "do a breadth first and a depth first at the same time, and whenever one of you returns True, the other one can just stop."  It's a very nice kind of syntax in a world where we have a few processors to play around with.

Hyperops
Hyperoperators differ slightly from junctions- they still promise autothreading, but they cannot short-circuit in the same way a junction can.  Hyperops, instead, execute a block-alternatively-statement (this, in Perl6 is called a "blast" I think) on every single member of a list.  It looks like this:
[1,2,3]>>.say # prints 1\n2\n3\n
 Once again, it's a pretty simple example that executes .say on every member of the list.  This, under the covers, might be done in any order, even somewhere else.  As such, any side effects might also occur out-of-order.  I've heard that the order of results is generally preserved, but I'm not at all clear how much that matters in most cases.

Anyhow, back to the previous example, if I did something like [1,2,3]>>.bar(), it would promise to execute bar() three times with three topics (1,2, and 3), side effects would be preserved with all three.  One can imagine how this would be useful for building cellular automata, where one has a grid to keep in synch, and one might do something like @grid>>.next() to yield a subsequent state.

Feeds
Feeds are autothreading just like the previous two, but instead of promising that all will be executed, or short-circuiting, the control of the timing of the autothreading is left to the context (caller?).  A feed looks something like this:
my $a,$b,$c <== 0..Inf
 That <== thing is the feed.  Basically, what this does is says "ask my pointy side how many it wants, grab that many from my blunt end when my pointy end needs them, execute them in any order, anywhere, but give them back to the pointy end in the order they were asked for."  It's not short-circuiting like a junction, it's doesn't guarantee execution on the whole list like a hyperop, but it does provide some pretty nuanced control when combined with either itself or its friends.


I'm still thinking about it, but this increasingly seems to be a nice approach to parallelization, which has good dwimmery (e.g. if you're doing hypers and junctions, even if you weren't trying to autothread, it probably does what you meant), nice fine-grained control (execute all, execute some number, execute with short-circuiting), and still mixes nicely with other parts of the language.

I'm not sure if there are other parallel constructions either already in the spec or on their way in, but I don't find any immediate holes in the semantics here.  Some additional control over how and where the processes are spread around might be achieved with some introspection on the current context, which may require some additional syntax, but that may also be left as an exercise for the reader.

Labels: , ,


Monday, December 21, 2009

Merry Christmas

In celebration of the Federal Government having a snow day today, I tweeted this:
say <. X>[my@i=0 xx 9,1,0 xx 9];map {say <. X>[@i=map {%([^8]>>.fmt("%03b") Z 0,1,1,1,1,0,0,0){@i[($_-1)%19,$_,($_+1)%19].join}},^19]},^9;
It's my geekery for the day.  It is written in Perl 6, and it prints out a Christmas tree, which is also a cellular automaton (Wolfram rule #30).  Thanks to the phenomenal people at Parrot and Rakudo, it looks like this when it is run:


.........X.........
........XXX........
.......XX..X.......
......XX.XXXX......
.....XX..X...X.....
....XX.XXXX.XXX....
...XX..X....X..X...
..XX.XXXX..XXXXXX..
.XX..X...XXX.....X.
XX.XXXX.XX..X...XXX

Merry Christmas, Perl6!

Labels: , , ,


Saturday, December 5, 2009

Perl6 Advent

Thanks in part to the Perl 6 Advent Calendar, in part to Ed showing me how easy it was to pop a subversion repo into github, and in part to whim, I dusted off some old Perl6 and got it running under Rakudo.  The gang on #perl6 was smart and fun as always, and to top it all off, there's a butterfly now.  Anyone who wants to see the code, it's on Github.

Labels: , , ,


Tuesday, March 25, 2008

Perl 6 Is Not Just a Language

Perl 6 is a programming language I've discussed before.

Like anyone else who spent more than five minutes on the Perl 6 IRC channel, I got a commit bit to Pugs, but Pugs isn't really moving. Perl 6 has some traction on other fronts: Rakudo is moving along at a good clip, Parrot keeps getting cooler, and Perl 5 keeps getting more Perl 6 syntax built in. There are variants of Perl 6 syntax, too: KindaPerl, NotQuitePerl, etc.

Now, I'm not part of the Perl 6 design team, and I don't speak for anyone but myself. But Perl 6 is still a long ways off. I mean a real Perl 6 with mutable grammar and meaningful interoperability with other Perls and maybe other languages as well, along with all the pretty new syntax that could probably be "done" a lot sooner if it weren't so tied up in other aspects of the implementation.

By "a long ways off" I mean "more than five years."

I don't say this to denigrate the efforts that are bringing us pieces of Perl 6 right now. I say this in the interest of recognizing how big a change Perl 6 is likely to be. Especially if it keeps the interesting bits that Larry Wall seems pretty likely to keep. It's a whole culture. And it has to be rewritten from scratch. And we're just starting.

Perl 6 is not just a language.

It's a new programming culture that recognizes programmers for the language designers we are, and gives us the tools we need to do it well. A presumption that we will write code which looks at itself and adapts. A recognition that most the good ideas will be someone else's, and we should have easy ways to use them.

These kinds of changes won't come easy, especially since they'll break so many of our existing tools. Syntax highlighters and IDEs and testing frameworks will all need to be rethought, along with who knows what else. Best practices will need to be borrowed from communities that have dealt with some of the same problems, and new practices will need to be invented for dealing with new problems. We'll have to gradually move in that direction, discovering obstacles along the way, and hopefully not forgetting to enjoy ourselves.

Yeah, Perl 6 is still a ways off. But getting there is still fun. And once we've gotten there it will be worth it.

Since we'll be able to use Perl 6 to write Perl 7.

Labels: , , ,


Friday, February 29, 2008

Perl 6, Compiling, and Even More Smartness of Others

In the previous post, I talked about why I like Perl:
I also talked about other, better languages, mentioning Python and Ruby in particular. Python and Ruby fixed a lot of Perl's syntax problems, inherited from scripting languages. Unfortunately, I really like many of those problems, but that doesn't keep me from recognizing that they make programming in Perl harder to learn and easier to mess up. Especially for people who have no interest in scripting (e.g. the majority of people).

Perl 6 is a new language, which is much like Perl in some ways. Unless there is some secret Perl Cabal working on a project they're not talking about, Perl 6 is still a ways away. But there are a number of interesting documents that describe what Perl 6 will do when it comes, which bear thinking about, particularly in the context of Perl.

Of course, there is new syntax- new nouns and verbs and even punctuation that some people will love and some people will hate but most people will just use (or not use) without thinking about it a great deal. From what I've seen of it, I like the new grammar in Perl 6, and I especially like that it is a grammar (rather than an implementation of a grammar, like Perl). But syntax aside, there are two points worth noting about Perl 6 that mirror Perl's original contributions in many ways:
I predict we'll see more of both features in other languages, regardless of the success of Perl 6. That being said, Perl 6 already has a lot going for it.


On Boundaries

Perl blurred the traditional boundary between scripting and application development. Using Perl, application developers write code quickly that is platform independent and easily modified. These three variables (speed, portability, and agility) are not altogether unrelated, but that is a topic for another day. With the caveats spelled out in the previous post, Ruby and Python erase these boundaries even more completely.

Perl 6 is aiming for a different boundary. Traditionally, there is a huge gulf between a programming language and its compiler. This gulf is filled with Compiler Compilers like yacc and bison, which make grammars into parsers, which parse languages, which create an abstract syntax tree, which is ultimately compiled down to machine instructions (either virtual, or actual, physical machine instructions). It's a lot of steps.

Perl 6 is not the first language to aim for this boundary, by a long shot. But Perl 6 does take aim with style and flair. If the approach is successful, it may signal the end of learning a new syntax for writing parsers with compiler-compilers. Programmers themselves will be able to experiment with creating new programming paradigms by rewriting the rules as they go along.

Is this a good idea?

The heck if I know. I imagine it will not be used by a great horde of programmers, but then most programming language features aren't.

There are a number of other features that take aim at this boundary, but setting their phasers on stun rather than kill. The design of Perl 6 has a great deal of introspection built in- giving programmers the ability to not only inspect the contents of a container, but also to inspect the container itself, and even make changes to the container.

Once again, I don't really know if this is a good idea. Python and Ruby have already got it in the form of duckpunching or monkeypatching or whatever they're calling it these days. We're going to call it Perl 6, and rather than hating it, we're going to love it. Since, after all, there is more than one way to do it.


On Leveraging the Smartness of Others

Perl programmers believe that other Perl programmers are real smart. It's why CPAN works so well. But there are problems with this belief. Sometimes other programmers get smarter faster than I do, which means they change how their code works in a new version. CPAN made it a little hard to grab a specific instance of someone else's smartness. There might also be more than one smart person working on a particular problem, who both call their code by the same name (since they're both real smart). CPAN made it a little hard to pick one or to not care or to do whatever else I want to do in that instance.

On top of all this, there are times when I may even think someone else is smart, who isn't even a Perl (or Perl 6) programmer. I know it sounds far-fetched, but it does happen sometimes.

Once again, Perl 6 is not the first language to aim for this ability. Perl gave us interfaces to the C programming language, and others eventually, but they are real hard to use unless someone else had already done it (which is often the case). Perhaps I should say real hard to write.

Perl 6 provides enough optional type declaration that writing interfaces to other languages becomes much easier. And in the case that Perl is running on a (possibly virtual) machine that supports other languages (approximately 100% of the time in the current implementation efforts), it will (hopefully) be a no-brainer, such that using the smartness of others will be the same kind of reflex it was with Perl.

And as for CPAN- Perl 6 comes packaged with a nice abstraction layer that allows a great deal of information to be specified about a given class or grammar or package. Authors, versions, and namespaces are built in.

So, I imagine in the future world of Perl 6, I'm going to care even less about who wrote the code I'm running (especially if that person is not-me), but to be able to trust more reliably that the code won't be changing out from under me. I may even care less about what language it's written in, which brings us full-circle to the earlier point.

The code I'm running very well may look like it's written in Ruby or Python, but simply be using a grammar from one of those languages on top of Perl 6. Wouldn't that be strange? Talk about blurring boundaries.


Conclusion

It's hard to conclude anything from this exploration. But it is worth noting that after thinking about it for a while, I do think taking down the language/compiler barrier is a great long-term goal, and I do think (re-)using the smartness of other people is nice. And I admit that it's possible Perl programmers eventually lost their way on the latter some time in the past twenty years. It happens to the best of us. Twenty more years, and we'll be ready for version seven, which will, according to Larry, be the perfect language.

Labels: , , , , , ,


Perl, Scripting, and the Smartness of Others

Perl is the name of a programming language I like.

Meaning, I like the name, and I like the language. Perl opened an ecological niche for programming languages that may have since been filled with other, better languages, but Perl was first. The other languages even have fun names. Python and Ruby come to mind in particular.

The niche is hard to describe- people call them "scripting" languages, but that term only has meaning when they're used for writing scripts (programs that control other programs, basically). Which is not, for the most part, what people do with these languages any more.

The thing that distinguishes the best of these languages is the relationship between development time and execution time. The languages allow people to write code quickly, which may or may not run quickly. They are best used in scenarios where the difference between one second and two seconds probably doesn't matter. For the most part.

Real scripting languages are still used mostly for scripting (e.g. sed, awk, bash). But Perl expanded this niche beyond scripting, and that's one of the things I like it for. People have used Perl for development of all kinds of applications over the past couple decades. Yes, perl is ancient.

When I was thinking about this post, I re-read Steve Yegge's essay about ancient Perl. It's full of his usual blah-blah-blah, but one point in particular amused me:
You see, someday I will start my own company, and I'll decide my own hiring bar. I'll of course be my own company's chief technical officer (wouldn't you?), so I'll decide how I expect people to engineer their software. And there will be no Perl. So there's no need for me to get worked up about its use at Amazon. Whew. I feel so much better.
I did start my own company. And we did use Perl. Steve Yegge probably makes as much money in a month at Google as I did by selling that company, but it still gives me a very different perspective. We used Perl because it blurred the boundary I talked about earlier, and because of CPAN. The Comprehensive Perl Archive Network. What a beautiful thing. For all they've done, none of those other, better languages have replicated CPAN.

CPAN is institutional knowledge of a bunch of badass Perl hackers dumped into a central place and mirrored around the world for anyone to use. It is as schizophrenic and disorganized as you might expect from this kind of a resource. But it's also the answer to a big load of common problems that Perl hackers have had. And man, do Perl hackers have problems.

For all of the better-ness of other languages (and I really do like the syntax of those languages better in some ways), they still lack a CPAN. Some of them probably consider this a feature more than it is a bug, which may be the biggest bug of all.

Python and Ruby and their many friends fixed lots of problems with Perl syntax, and maybe even with Perl culture. But while they were busy throwing away the bad syntax Perl inherited from the real scripting languages, they left but the one feature that made Perl more than a novelty, which was not what we could do with it, but what others had already done.

Labels: , , ,


This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]