1. In which a challenge is thrown, but there is a spanner in the works!

Haskell suddenly became “important” in the Perl community when Audrey Tang started to blog about Pugs, the prototype version of the Perl 6 interpreter/compiler. So, when I started looking at Haskell, I did so with another Perl-monger, larsen, one of the key guys in perl.it. We worked through some of the exercises in YAHT together when we shared a flat. Since I moved out we never really got around to doing that, and I've been working through the exercises in SOE on my own. I realised that the poor chap was missing out on all the fun! So I thought I could let him “catch up”, but as that would involve having to give up my precious copy of “Haskell School of Expression” up, even for a few days, I panicked slightly.

My alternative was almost a stroke of genius. For a couple of months I've had “Practical Common Lisp”, which larsen lent me, on my bookshelf. I even read some of it! But I've not gone through in any rigorous way. My challenge to him was to do what I'm doing with SOE and to blog the exercises.

The “concept” is that at the end of it, I will be able to teach him Haskell, and he can teach me Lisp. If you need to know both to be a truly great programmer, perhaps we can both at least be half of one of those!

The flaw, as it happens, would seem to be that PCL doesn't have seem to have exercises... (though we seem to remember them existing somewhere, this was only on a brief scan).

2. In which osfameron squees at slime, and criticises the Perl debugger and REPL

He has already downloaded SLIME, and mentioned how cool the video with Marco Beringer was. I hadn't seen it so he passed me the link. It is rather nifty, and certainly you can see how features of Lisp like its regularity make it a joy to parse and manipulate in an IDE. Other things, like the incremental compilation are interesting, and the depth of debugging information is astounding.

Compared to this, perl -debug comes off rather badly. Actually, compared to a drunken, syphilitic stoat, the Perl debugger might come off badly, but the SLIME package is really rather well put together. The Perl REPL has several disadvantages, such as not understanding lexical scopes and not printing out the results of each call. The cry of “it's hard to use” is probably just an excuse, after all, if a tool's worth using, you put time into learning it. The suspicion though is that the Perl debugger isn't really worth learning. Certain things add to this conviction: for example, I had a vivid memory that Larry Wall had declared that he was more of a “print statements kind of guy”. (But, not I can't find it via Google, perhaps I dreamt it). In any case, there is the fact that generally, Perl programmers, if they even know about the debugger, tend to use it only for the REPL (and then moan about it).

At some point, Acme did some work on improving the debugger internals, documentation and test-suite while creating Devel::ebug, which looked very cute. In theory at least: I could never get it to install, and I believe it's now unmaintained and targetting an outdated version of Catalyst. (Some time passes... some facts are checked...: eeek! No, there have been 2 releases over the last couple of months, yay Acme! And my colleague Mattia Barbon submitted patches, yay Mattia! I guess I'll have to check it out again at some point).

Anyway, Lisp absolutely has an impressive toolchain. But the aesthetic appeal (and, yes, I know that this is influenced by a lack of familiarity) is still lacking - all those #\UPPER-CASE-SYMBOLS, especially on the stack traces. Meh. Yes, I know this is stupid, but it is odd that a language whose algorithms and concepts are so beautiful should look so fugly.

(Of course, I find (well written) perl code pleasant to read, so I may not be qualified to pronounce on the aesthetics of programming. OTOH, this Larry Wall quote I do remember (and Google confirms that I didn't dream it) “Lisp has all the visual appeal of oatmeal with fingernail clippings mixed in”.)

3. In which osfameron ponders the virtues of Perl as a functional programming language, and sings the praises of join

Since the publication of Dominus's seminal Higher Order Perl, it's hard to deny that Perl enables some Functional Programming techniques (though you can certainly argue that some of the techniques are uglier, harder, or less efficient). The three functions in common use are map, grep, and join.

When Marco creates the convert-to-morse function, he started by writing a stream to a string, (nice technique! see also IO::Stringy etc. in Perl) prints a morse character for every character, followed by a space. He then points out that there's a spurious space after the last character.

He then starts musing about how to get rid of this and ends up dealing with the head of the string first, and then doing the rest of the string, this time prepending the space. While he starts doing this, every Perl-programmer's muscle in me is screaming, “use join you fool!”

Anyway, he may be doing it this way for pedagogical purposes, but his solution surprised me nonetheless. And while I was thinking about it, I noticed that I hadn't come across join in Haskell either yet, so I decided to write it.

First of all, I thought it would be:

  > join j = foldr (\left right -> left ++ j ++ right) [] 

which compiles like so

  *Main> :t join
join :: [a] -> [[a]] -> [a]

But there is a problem

  *Main> join "," ["hello","world"]
"hello,world,"

A final comma! Of course as the list is really (“hello” : “world” : []) the fold will join “world”,”“. Pesky blighter.

I ended up with the slightly less beautiful:

  > join j (v:[]) = v
> join j (v:vs) = v ++ j ++ join j vs

with the same signature. (We could also do join [100] [[1,2], [3,4,5] for example).

What is the standard Haskellish way of writing join?

(Update: dons on #haskell suggested that the obvious name for this in haskell is "intercalate".  Actually intercalate (so named, because "join" is already taken - for joining monads) would work.  intercalate would be defined as the concatenation of "intersperse".  Steven Ashley suggested this solution too.  (Update: and dcoutts in irc backlog, thanks all!)

    concat $ intersperse "," ["hello", "world"]

on a related note, while I'm hating crappy REPLs, why does ghci make it so bloody hard to do "import Data.List" (in order to get intersperse)?  Interestingly, Perl (5) doesn't have intersperse, as "join" only operates on strings, and it would be nice if it did have the generalised version too.)



4. In which a better REPL for Perl is sighted, and osfameron bemoans the lyf so short

This morning, via a cpanranting on Rocco Caputo's Lexical::Persistance, I came across Matt Trout's new-ish Vox blog. As well as an interesting polemic about Ruby, there's a series about developing a REPL (called Devel::REPL, not yet on CPAN but it's on his bast repo, linked from the blog), which uses that module to allow variables like my $foo to persist from one line in the REPL to another. Just like they should!

mst also talks a lot about Moose, the new Perl object framework which is massive news in a subset of the modern Perl community. It's quoted as bringing to Perl the things that you would otherwise have to flee to Ruby for. Things like declarative class generation and function argument unrolling (in an extension iirc). And (as this post is already too long), “much much more”.

All of which reminds me that, as well as spending time learning Haskell, I should really keep up to date with learning Perl. Which I will obviously do in my proverbial Copious Free Time!