Chip’s Core Hacker Presentation
At YAPC::NA, Chip Salzenberg held a last minute brief talk that really started making me think. Well, to be honest, the thought process started at the Parrot Workshop but really began in this talk.
I’ve always been fascinated with programming languages and compilers. These things had always struck me as not academically challenging and basically a solved engineering problem. I never really did much in the area except for an undergraduate course where I wrote compiler for TinyC, written in Perl, with a MIPS assembler code generator backend. It was a study in recursive decent parsers, so it lacked any real semantic capabilities, such as symbol tables, garbage collector, or ASTs.
So anyways, back to how this relates to Chip’s laid back talk. Basically, he encouraged people to become core Perl hackers. “Yes, things are bad, but they’re not that bad.” The talk only lasted 20 minutes, but my brain started spinning for the rest of the day. I tried having a few conversations, but I failed to sustain anything more than a few minutes. The talk wasn’t overly special. It wasn’t groundbreaking or funny; it was clearly an impromptu presentation with slides obviously created quickly; it lacked substantial content and it was not thought provoking. It was the perfect talk at the perfect time because my brain was in the perfect state of mind to think clearly and creatively.
So I have since turned my attention away from my thesis for the summer and towards compilers and programming languages. I have started filling my research notebook with all sorts of ideas in the chance that I spark a true flash of genius. My advisor is likely to be annoyed that I decided to change directions radically but he went overseas for the summer and has stopped responding to email.
Thank you Chip, you may very well have ignited my imagination and passion to create something truly worthwhile.
Sub Method
So today, I ended up starting a very long discussion with several members of the Perl6 community about how functions are declared. Basically, I made several mistakes in trying to call my class functions “sub” when I meant method. Perl6 happily lets me shoot myself in the foot and then complains when I try calling the sub against an object, which doesn’t exist. Here’s a few examples of things to illustrate the clunky OO model:
Snippet 1:
class A {
sub foo {
say "never gonna happen"
}
};
my A $a .= new;
$a.foo;
Snippet 2:
class A {
method foo {
say "nope"
};
method bar {
foo()
}
}
note: the code highlighter does not support perl6
So basically, that first snippet is an error. ’sub’ apparently means something other than what we want it to mean in this case. That snippet will fail with an error about no such method. The second snippet will fail because the ’self’ invocant is not assumed in the bar function. jnth says it’s because they don’t want methods like push being overwritten if I define a push method in my class.
The really sad thing is that I still don’t get it. I can’t make heads or tails of this object model. In some cases, Perl6 chooses to reuse syntax correctly, and in others it fails. There are about a billion ways to define a function. Each function can be a sub, method or submethod. It can have modifiers like multi and my and attributes like does and a huge multitude of parameters. The list of function modifiers just keeps going. How anyone is going to be able to use all of this is beyond me; I doubt I’ll ever be able to make sense of it.
Okay, so my raw opinion is this: they are doing it wrong. The “many paradigms” argument is wrong because the language should do one thing and do it well. It can’t serve all masters and still do a good job. If the object model is to be a real first-class citizen, then it must place the object model above all else.
That being said, I am of the opinion that C++ is the only language to get it right (see this, this, and this). Well almost, it still can’t do runtime template binding (think variant or Boost::Any) and I loathe the ‘friend‘ keyword (breeds bad code). Namespaces and classes are different concepts, so they are treated differently. When I place a function inside of a class definition, it becomes a member function. If I prepend ‘static‘, it becomes a class method (not a Class member like Java) and I can call it without a ‘this’ reference. If I want a function outside any class, just put it at the file scope and external storage. Calling a function defined within the scope (file or member) that has been included (imported) implies the ‘this’ invocant. All parameters are required unless given default values (Perl6 has 3 different syntaxes for this: required “!”, optional “?”, default value “=”). This is simple and direct. Templates were added for an additional level of flexibility, which worked out pretty well. In fact, C++0x will improve on this, assuming it’s ever released this year (otherwise it’ll be C++1x).
In bringing this up in the channel, I was really hoping to make people think about how Perl6 is doing it in hopes that someone who knows better than I would stop and think whether Perl6’s design is ideal. I was wrong and I think I may have agitated some of the developers. The beauty of open source is that I can do things my way if I see fit and likely will once the only usable implementation has support for macros.