The Pony Diaries

So I’ve just discovered Pony the Language and am fascinated so I thought I’d give it a try, creating a brand new version of my experimental reimagination of the Unix Toolbox, the Q// aka Q shell. I shall be following the Pony Tutorial and will try my best to also praise the language, for I am fascinated by what I’ve seen so far, but, needless to say, most of the stuff I’ll end up writing will be some caremad meandering in programming language theory.

Some Links First

Introduction & Getting Started

The Introduction of the tutorial says loads of things that sound lovely, my excitement just grew as I kept on reading it. So I really won’t pick any individual entries, I agree wholeheartedly with the attitude laid out there and invite you to read it. Seriously. Read it.

Pony was created by Sylvan Clebsch, and there’s a great introductory video interview on InfoQ that also answers the most important question: why is it called Pony? So much goodness in half an hour, so many exciting things to look forward to. Watch it.

Then on advice of the friendly folks in the IRC channel I took this Starter Project and tweaked it to my liking, thereby separating sources from tests, because I don’t believe in tight coupling of tests and production code. See my version here. I also adapted this Sublime Package, added make targets, so here’s my version.

Lesson Learnt #1: Creators of programming languages will get extra special bonus points from me when choosing names that can be used in web search.

Objects: Namespace Visibility vs Information Hiding

And there are classes Pony and members starting with _ are considered private and such “private fields can only be accessed by code in the same type” – which immediately became suspect so I tried it and can confirm that I’m sad again for a lost opportunity, as Pony considers privacy a matter of namespace visibility and not information hiding. The following program compiles and prints I'm OK... and thus disappoints yours truly.

class Bunny
  var _is_happy: Bool = true

  fun be_mean_to(other: Bunny) =>
    other._is_happy = false // How can this be happening?!?

  fun how_are_you(): String =>
    if _is_happy then "Doing great!" else "I'm OK..." end

actor Main
  new create(env: Env) =>
    let happy_bunny: Bunny = Bunny.create()
    let mean_bunny: Bunny = Bunny.create()
    mean_bunny.be_mean_to(happy_bunny) // WTF, no!!!
    env.out.print(happy_bunny.how_are_you())

If you ask me, little bunnies should be able to decide whom to tell how they feel and should be safe from other bunnies messing with their feelings directly. Having an effect on their feelings indirectly, e.g. by sharing a carrot, is all fine of course. (And yes, I know most languages go this way, but “it’s my website and I’ll rant if I want to” haha.)

Lesson Learnt #2: Hardly anyone shares my belief that private members ought to be hidden from all others, irrespective of their classes.

PS: After wondering why other needs to ref qualifier, I was told that it’s because classes are by default ref types.

Interfaces Are Counter-Intutive Traits of Pony

Then I learnt about Pony’s Nominal and Structural subtyping and got really glad for also having the latter. But I’ve also realised that now I’ll have to flip my personally ‘intuitive’ interpretation of the terms Interface and Traits. I’ve seen interfaces in several languages, such as in Java, for formal, strict, before-the-fact, declaratively enforced contracts (think API), which is the Nominal kind Pony calls trait. The term traits, on the other hand, I’ve met in C++, and understood as means of associating ancillary information with types, which is the structural, informal, after-the-fact, ad-hoc kind Pony calls interface. So in Pony, at least for me, these two words are reversed in meaning. Yay.

Lesson Learnt #3: Life is hard not having unanimous definitions or consistent uses of terms. And now it’s a tiny bit harder still, thanks to Pony’s definition of Interfaces and Traits.

So, again: Traits are nominal and Interfaces are structural subtypes. Traits are formal and Interfaces are informal. Traits are before-the-fact and Interfaces are after-the-fact. Mkay.

Don’t Get Me Wrong: Pony is Absolutely Amazing!

This time the shout goes out about the ‘closed world’ union types combined with | and the intersection types combined by & – that all make superbly sense and are so pure and elegant, sheer joy! Loving it!

(But still, have to ask, why are generics square- and not angle-bracketed?)

To Be Continued…