A (not so) simple matter of privacy

You may have seen Ovid's recent post on his discussions with the Perl Steering Committee about moving forward with implementing an initial subset of the Corinna proposal in the Perl core.

One of the issues that came up during those discussions was the best way to provide private methods in Corinna. The current Corinna proposal is that this would be done (like almost everything else in Corinna) via an attribute:

method do_internal :private () {...}

Thereafter, the do_internal() method can only be called from within the current class, and is never overridden by derived-class methods when it is called within its original class.

In other words, the :private method effectively prepends the following code to the start of the method:

croak "Can't call method 'do_internal'"
    if caller ne __CLASS__;

...and, in addition, causes the compiler to treat any call to that particular method from within the current class as a fully qualified method call. That is, within any class C with a private do_internal() method, any call to $self->do_internal() is treated as a call to $self->C::do_internal().

All of which means that there is no way to call a private method from anywhere except within the same class. Which, of course, is the whole point of having private methods in the first place.

But the need to automagically convert any call to a private method into a fully qualified method call is (to put it mildly) a complication for the compiler. So the members of the Perl Steering Committee Cor design team suggested that rather than having private methods, Perl should have lexical methods instead. Specifically, they suggested that instead of:

method do_internal :private () {...}

method do_external () {
    $self->do_internal();   # Call private method
    ...
}

...Perl would provide anonymous methods, which you could place in lexical variables and then call using the existing call-via-reference method call syntax:

my $do_internal = method () {...};

method do_external () {
    $self->$do_internal();   # Call lexical method
    ...
}

That neatly avoids of the challenge of rewriting private methods to check their caller, or the much greater challenge of rewriting private method calls to be fully qualified. Instead, it cleverly enforces the “can be called only from the current class” requirement by making it impossible to refer to the method at all, except in the lexical scope of the $do_internal variable.

You could even consider the slightly uglier $self->$do_internal() call syntax as a win: because it means that private method calls are explicitly marked as such.

The only downsides are:

  • The call-via-reference syntax is more obscure and perhaps a little more challenging for less-experienced Perl developers. That might discourage them from using this approach, even for methods that really should be private, thereby penalizing a good OO practice.

  • Using anonymous methods to implement private methods is structural rather that declarative. That is: we can’t just say what we want to have happen, we have to say how to actually implement it. In practical terms, this means that private method definitions are no longer explicitly marked as being private, and hence are far less searchable.

And that second issue is the real problem here. Because they’re structural, not declarative, lexical methods specified like this are also much easier to “enbug”. For example, if the developer mistakenly wrote something like this:

method other () {
    ...
    $do_internal++;
    ...
}

Then any call to the $do_external() method will be fine so long as the other() method is never called. But after other() has been called, the next call to $do_external() will throw a weird exception:

   Can't locate object method "140362266577153" via class "C"

Of course, we can get around that potential bug by making $do_internal immutable:

use Const::Fast;
const my $do_internal => method () {...};

but that’s now an extra module load, and even more infrastructure to get right.

(BTW, wouldn’t it be cool if the existing :const subroutine attribute could also be applied to scalar variables, in which case we’d just need:

my $do_internal :const = method () {...};

Maybe one day!)

Yet another issue with using anonymous methods as private methods is that they make it easy to subvert the intended encapsulation:

our $do_internal = method () {...};

That’s no longer a private method, because you can now call it from literally anywhere in your code:

$obj->$C::do_internal();

And, even if it were still a my variable, there’s nothing to prevent a class from explicitly exporting it:

method circumvent_privacy () { return $do_internal }

As an OO purist, I find that possibility worrying. And as someone who has reviewed a vast amount of real-world Perl OO code over the past few decades, I think that kind of expedient kludge is...inevitable.

So what do we do?

The good folks of the Perl Steering Committee Cor team suggested an approach that does address some of these issues. They proposed that the syntax for private methods be:

method $do_internal () {...}

method do_external () {
    $self->$do_internal();   # Call private method
    ...
}

That is: when you want to declare a private method, you put a $ at the start of its name. This form of the method keyword would then create a (presumably immutable!) lexical $do_internal variable, initialized with a reference to an anonymous method. You could then use the reference in that variable to call the private method.

While it doesn’t solve the problem of evil developers explicitly exporting that variable, it does make the syntax declarative again, and it could solve the issue of accidentally changing the variable (assuming the variable were indeed to be created as immutable).

The only problem is that now we have the method keyword not just declaring methods,
but also declaring variables.

Which, from the perspective of a language designer, is...less than ideal.
And, from the perspective of someone who actually still teaches Perl,
is much less than ideal.

So, how do we solve that?

Well, Raku solves it by marking private methods not with a $, but with a !
and then calling them with the ! as well (rather than Raku’s usual . method call operator):

# In Raku...
method !do_internal () {...}  # Private method

method do_external () {
    self!do_internal();       # Private method call
    ...
}

That’s a neat solution, but it probably wouldn’t work for Perl.

Nevertheless, the ideal of prefix-marking private methods and private method calls in some way might work. For example, we could consider formalizing the “private methods start with an underscore” convention inside the new class blocks:

method _do_internal () {...}

method do_external () {
    $self->_do_internal();
    ...
}

In other words, we could specify that any method definition that starts with an underscore doesn’t get added to the method symbol table. Instead, it implicitly creates an immutable and invisible lexical scalar within the class. Then, within any class block, any call to a method whose name starts with an underscore actually calls the method through the associated invisible lexical scalar instead.

Or, to put it more simply: it’s precisely the Steering Committee Cor team’s proposal, but: s/\$/_/g
And with the added advantage that the lexical is not otherwise accessible within its scope,
and therefore not accidentally modifiable, or maliciously exportable.

That’s by far the safest alternative I can think of, but I concede that it might still be too magical.

In which case we’d instead need to address just the immediate problem: that we’re contemplating using the method declarator to declare something that isn’t actually a method. Specifically, we’re using method to declare variables.

And the easiest solution to that problem is simply to define another declarator:

private $do_internal () {...}   # Declare private method

method do_external () {
    $self->$do_internal();      # Call private method
    ...
}

Now method once again only declares named methods, and we can easily explain that private declares a lexically scoped variable whose immutable value is a reference to the anonymous method.

We get very clear declarative labelling of private methods and equally clear labelling of calls to those private methods.

We don’t solve the “naughty folk can export that variable to circumvent privacy” problem, but I suppose we could always just spin that as a feature, rather than a bug. /s

For the moment, however, unless the Steering Committee Cor team is happy with either the “underscore enforces private” approach or the addition of a private keyword, I expect what we’ll actually have to do is to remove private methods entirely from the first stage of the implementation, and simply keep on pondering how to get them exactly right.

In the meantime, don’t let anyone ever tell you that language (re-)design is easy. :-)

Vale, David

David H. Adler passed away yesterday.

David was a gentleman and a scholar: a gentle, warm, erudite, funny, clever, and deeply kind man. And one who has made a vast contribution to our Perl and Raku communities over more than quarter of a century.

My most sincere condolences to David's family...and to the countless other colleagues, acquaintances, and admirers around the world who will be mourning him today.

Like so many others, I was proud to call David my friend.
I will miss him profoundly.

A dream resyntaxed

[Author’s note: If you’ve read Curtis Poe’s most recent blog post, what follows is going to seem eerily familiar. This post uses the same concepts, arguments, and code examples as his, and reaches exactly the same conclusions. That’s because both posts originate from a long and wide-ranging email discussion between Curtis and myself, as I’ve been privately consulting with him over the past few months on the design of Corinna.

When I read Curtis’s post I almost decided to bin this one, as he managed to cover everything necessary in his usual succinct, eloquent, and engaging style. But he has encouraged me to post my version of this discussion too, as it provides a little more detail on some of the issues we’re addressing, and on the design rationale for the changes we are jointly proposing.

Personally, I always relish the opportunity to read two versions of exactly the same story by two very different authors, or to watch two directors’ very different takes on the same screenplay. In fact, that’s what initially attracted me away from SmallTalk/C++/Eiffel and into Perl: I read Larry’s version of “Object Orientation”, and found it much more entertaining, and also more enlightening than the other earlier interpretations.

So here’s the “Conway cut” of our joint proposal. Of course, if you’re short on time, you should just go and read Curtis’s original version of this story. But if you’d like some extra insights into the syntactic design of Corinna (and of Perl itself!), and perhaps a slightly more detailed and stereoscopic view of the issues we’re addressing...read on!]

The Corinna project is fundamentally about providing a declarative mechanism for building OO code in Perl, as opposed to Perl’s current fundamentally emergent approach.

So let’s look at the way we declare things in Perl.

Overwhelmingly, declarations (of variables, subroutines, packages, and formats) are made using the following syntax:

    <keyword>  <identifier>  <modifiers>?  <setup>?

For example:

    <keyword>  <identifier>  <modifiers>?  <setup>?
      my         $lexvar       :shared
      our        $packvar      :Tracked     = 0
      state      $statevar     :Readonly    = 1
      sub        action        :lvalue      () {...}
      package    Namespace      v1.2.3      {...}
      format     Report                     = ... .

Note that in every case, except for the package keyword, any modifications or deviations from standard behaviour (i.e. anything in the <modifiers> column) are always specified by attributes. And, arguably, the package version syntax is a mis-design; it should have been :vers(v1.2.3) instead.

The only other significant deviation from this general syntactic pattern is the way in which modern lexical subroutines are specified:

    my sub foo () {...}

This syntax concatenates two keywords to denote the non-standard behaviour of a lexically scoped subroutine. However, I would argue that this too was a mis-design, or at least an anomaly. It would have been much more consistent with Perl’s underlying syntactic structure if the syntax had been:

    sub foo :lexical () {...}

Or, perhaps, if we had added a completely new declarator keyword to reflect the fundamental differences between package and lexical subs:

    lexsub foo () {...}

Except in the two cases noted above, the unifying principle of Perl’s declaration syntax is that the keyword specifies what the declarand is, and the optional modifiers (i.e. attributes) specify how this particular declarand differs from the standard behaviour for that kind of declarand.

Or in OO terms: the keyword specifies the standard type that the declarand IS-A new instance of, and the modifiers specify any unusual roles/traits or non-standard behaviours that this particular declarand also DOES.

Which brings us to the new object-oriented declaration syntax proposed in Corinna.

Here’s a somewhat contrived example that attempts to exercise all of the new OO features that Corinna provides:

    role Tracked {
        slot $msg :param;
        method report () { $self->show($msg++) }
        method show;
    }

    class Root {
        method is_root () { return 1; }
    }

    abstract class Counter {
        my $obj_count = 0;    # common slot for all objects in class
        method obj_count :common () { return $obj_count; }

        ADJUST   { $obj_count++ }
        DESTRUCT { $obj_count-- }
    }

    class MetaHandler isa Counter does Tracked {
        slot $handler  :handles(exists delete) = Handler->new;
        slot $size     :reader  :param         = 100;
        slot $created  :reader                 = time;

        ADJUST   { croak("Too small") if $size < 1; }
        DESTRUCT { $handler->shutdown; }

        method insert :private ($key, $value ) {
            if ( ! $self->exists($key) ) {
                $handler->set( $key, $value );
            }
        }

        method show ($msg) { say $msg; }

        method obj_count :overrides :common () {
            $self->next::method() - 42;
        }

        before method obj_count :common () { warn "Counting...";         }
        after  method obj_count :common () { warn "...done";             }
        around method obj_count :common () { return 1 + $class->$ORIG();  }
    }

Note that most of these new constructs conform well to the standard syntactic structure for declarations:

    <keyword>  <identifier>   <modifiers>                <setup>?

     role       Tracked                                  {...}

     class      Root                                     {...}

     slot       $msg           :param
     slot       $handler       :handles(exists delete)   = Handler->new;
     slot       $size          :reader  :param           = 100;
     slot       $created       :reader                   = time;

     method     is_root                                  () {...}
     method     show
     method     report                                   () {...}
     method     obj_count      :common                   () {...}
     method     insert         :private                  ($key,$value) {...}
     method     show                                     ($msg) {...}
     method     obj_count      :overrides :common        () {...}

But a few of them diverge significantly from that standard syntactic structure:

    <modifier>  <keyword>  <identifier>  <setup>
     abstract    class      Counter       {...}

    <keyword>  <identifier>  <keyword-modifiers>        <setup>
     class      MetaHandler   isa Counter does Tracked   {...}

    <modifier>  <keyword>  <identifier>  <modifiers>  <setup>
     before      method     obj_count     :common      () {...}
     after       method     obj_count     :common      () {...}
     around      method     obj_count     :common      () {...}

So while Corinna usually specifies modifiers on a declarand in the standard Perl <modifier> syntactic position, sometimes a modifier is instead specified via a prefix keyword, or with both a prefix keyword and something in the usual <modifier> slot:

      before method obj_count :common () {...}

Of course, the class and role declarators do specify some modifiers (namely: the classes they inherit and the roles they compose) in the third syntactic position that is traditionally reserved for modifiers. But they don’t specify those modifiers in the standard form: as attributes. Instead, they are specified as internal keyword-modifier subsequences:

    class Name isa <modifier> does <modifier> {...}

There is one other significant deviation from standard Perl syntactic structure in the Corinna proposal: a particularly nasty case in which specific non-standard behaviour must be requested implicitly by context, rather than explicitly by a distinct keyword or attribute.

Namely, when specifying class data slots:

    my $obj_count = 0;    # common slot for all objects in the class

Of course, this declaration does still have a keyword, but that my keyword is silently behaving very differently from every other my keyword, simply because of the context in which it’s being used. Hence the need to comment it, as a reminder of those unusual extra behaviours.

So how is it different? (And notice that the very fact you have to ask about this tells you that it really shouldn’t be different at all!)

The example my keyword does still inject the symbol $obj_count into the current lexical scope but, because that lexical scope is the block of a class, that particular my has two fundamental context-sensitive differences from any other my declaration anywhere else in the program.

Specifically, because it is declared inside a class declaration, the initialization behaviour and the destruction behaviour of this lexical variable are completely different. Normally, a my variable is initialized at run-time, every time it is encountered in the code. And it is garbage-collected in the usual way whenever it goes out of scope with a zero reference-count. But inside a Corinna class, a my variable is initialized only once — at compile-time — and is garbage-collected only once — after all execution terminates.

That’s the correct and necessary behaviour for a variable which is acting as a class data slot, because we have to be able to use class data slots everywhere, including inside a BEGIN, CHECK, INIT, or END block. So class data has to be initialized at compile-time and persist until the end of execution.

But those special context-sensitive initialization and destruction semantics are nothing like the behaviour of a regular my variable in any other Perl code. So, even though they’re essential to the correct working of their surrounding class, those semantics are also likely to be misleading, confusing, bug-inducing, and brittle.

So, how do we fix these various problems?

The inconsistencies that are purely syntactic in nature:

    abstract  class   Counter                                {...}
              class   MetaHandler  isa Counter does Tracked  {...}
    before    method  obj_count    :common                   () {...}
    after     method  obj_count    :common                   () {...}
    around    method  obj_count    :common                   () {...}

...could easily be handled either by replacing all pre-keyword modifiers and all post-identifier keyword-modifier pairs with simple attributes:

    class   Counter      :abstract                     {...}
    class   MetaHandler  :isa(Counter) :does(Tracked)  {...}
    method  obj_count    :before :common               () {...}
    method  obj_count    :after  :common               () {...}
    method  obj_count    :around :common               () {...}

...or, alternatively, by providing additional keywords to replace the current prefix modifier-keyword sequences:

    abstraction  Counter             {...}
    before       obj_count  :common  () {...}
    after        obj_count  :common  () {...}
    around       obj_count  :common  () {...}

Creating new attributes is almost certainly the better choice here, however. One of Corinna’s fundamental design principles is to avoid adding new declarator keywords to Perl wherever possible. So far, we’ve only needed to add four: class, role, slot, and method.

We could add more keywords for abstract classes plus the three kinds of method wrappers, but that would double the proposed number of new keywords, and with a proportionately much smaller payback on the second four, as those specialized constructs are far less common than classes, roles, slots, and methods.

Method wrappers can also be a “code smell” in OO code, indicating something is amiss is the original design of a class hierarchy. So it seems odd to devote three entire keywords to them.

Of course, the concept of being able to extend an existing chunk of behaviour without having to copy-and-paste the original code is, in itself, perfectly valid. But that concept is also not unique to methods. We might, for example want to be able to wrap regular subroutines as well. But if we make before mean before method, we’d then have to come up with yet another keyword (ante? ere?, afore?) if we ever want to support before sub. And that way lies madness.

To leave open the future possibility of general-purpose wrappers, it’s clearly better to specify method wrappers with attributes (:before, :after, :around), so that those same attributes might later be applied to subroutines as well, if we ever decide that Perl should also have that capacity.

As for the implicit, context-sensitive behaviour of my inside a class or role, it could also be made explicit and context-free via either of those same two syntactic changes. That is: either by an explicit attribute on an existing keyword:

    slot $obj_count :common = 0;

...or else with a more precise, distinct, and explicit keyword:

    common $obj_count = 0;

Here too, an attribute is probably the right choice. A class data slot still intrinsically IS-A data slot, just one that DOES something slightly different in terms of its initialization and destruction. So the slot keyword is the right one for it, with a :common attribute to denote the differing behaviour.

Moreover, we already specify class methods using the :common attribute. So it would be more consistent (i.e. more teachable and more likely to just DWIM) if we also specify class slots with that same attribute.

But whether or not we add a common keyword, or simply allow a :common attribute on the slot keyword, the use of my as a declarator for class data slots really has to go. Having declarators whose behaviour silently changes in fundamental ways depending on their context is always a Very Bad Idea.

Note, too, that by adopting the slot $name :common approach for specifying class slots, we also remove the very real annoyance of always having to hand-code any accessors for such slots:

    my $obj_count = 0;
    method obj_count :common () { return $obj_count; }

...because now we can just write:

    slot $obj_count :common :reader = 0;

The only remaining problem is the actual name of the :common attribute. While I do agree that “common” is the least-worst linguistic alternative to have been suggested so far, it’s still significantly less-than-awesome.

So what is the fundamental difference between an instance slot and a class slot, or between an instance method and a class method?

Well, it’s right there in the definition:

    Class slots and methods are mutually shared
    and jointly accessible by all objects, classwide.

So, instead of:

    slot   $obj_count  :common  = 0;
    method  obj_count  :common  () {...}
    before  obj_count  :common  () {...}

...why not:

    slot   $obj_count  :joint  = 0;
    method  obj_count  :joint  () {...}
    before  obj_count  :joint  () {...}

...or:

    slot   $obj_count  :mutual  = 0;
    method  obj_count  :mutual  () {...}
    before  obj_count  :mutual  () {...}

...or even:

    slot   $obj_count  :classwide  = 0;
    method  obj_count  :classwide  () {...}
    before  obj_count  :classwide  () {...}

Myself, I rather like :joint. It’s concise, distinct, and (best of all) I’m sure there are a couple of really good “role-ing a joint” and “high-class joint” puns to be had in there somewhere!

Ahem.

Anyway, putting all those ideas together, the earlier full example would become:

    role Tracked {
        slot $msg :param;

        method report () { $self->show($msg++) }

        method show;
    }

    class Root {
        method is_root () { return 1; }
    }

    class Counter :abstract {
        slot $obj_count :common :reader = 0;

        ADJUST   { $obj_count++ }
        DESTRUCT { $obj_count-- }
    }

    class MetaHandler :isa(Counter) :does(Tracked) {
        slot $handler  :handles(exists delete) = Handler->new;
        slot $size     :reader  :param         = 100;
        slot $created  :reader                 = time;

        ADJUST   { croak("Too small") if $size < 1; }
        DESTRUCT { $handler->shutdown; }

        method insert :private ($key, $value ) {
            if ( ! $self->exists($key) ) {
                $handler->set( $key, $value );
            }
        }

        method show ($msg) { say $msg; }

        method obj_count :common :overrides () {
            $self->next::method() - 42;
        }

        method obj_count :common :before () { warn "Counting...";         }
        method obj_count :common :after  () { warn "...done";             }
        method obj_count :common :around () { return 1 + $class->$ORIG();  }
    }

They’re not huge changes to the current proposal, but I think they make the new OO syntax cleaner, clearer, more consistent, and — most importantly — more Perlish.

A dream realized

Have you heard that they are finally putting together a proposal to add a clean modern OO system into the core of Perl?

If you haven’t, I strongly encourage you to look over the RFC for Corinna, or at least watch Ovid’s excellent presentation on the project.

It’s reassuring that the list of contributors to the proposed design includes some of the most highly respected names in the Perl community, many of whom have previously taken one (or more!) tilts at this particular object-oriented windmill.

Indeed, over the past two decades I too have repeatedly attempted to design and prototype richer and more robust OO systems for Perl, starting way back in the previous millennium with a brief stint as the maintainer of Class::Struct, and continuing on though the release of modules such as Class::Std, Class::Delegation, and most recently: Dios.

The Dios module represented almost everything I thought a comprehensive Perl OO system should contain. Not surprisingly, that actually meant it simply stole almost everything that Raku’s comprehensive OO system contains (mostly because I had spent quite a lot of time over the past two decades helping design that OO mechanism as well).

The only three problems with Dios are:

  • It’s not built-in to Perl itself, so its performance is suboptional;
  • It’s not built-in to Perl itself, so it requires a huge amount of extremely complex multi-layer code to make it feel as if is;
  • It’s not built-in to Perl itself, so it's merely one possible choice amongst the vast and incoherent array of entirely reasonable alternatives already on CPAN.

That’s why, when people ask me whether I support the Corinna proposal, my response is: OH, HELL YES! I’ve literally been waiting two decades to see Perl gain a proper, built-in, declarative, encapsulated, and performant OO system. And this, I firmly believe, is it.

At this point I could launch into one of my usual extended exegeses on why this particular design is so exceptionally good, but I think two quick and specific examples are actually sufficient to explain my excitement about this proposal.

The first example is purely syntactic. If you were kind enough to watch the Three Little Words video in which I introduced Dios, you’ll have seen how that module vastly improves the syntax for declaring a Perl class. Instead of something like:

  package Account {
      use experimental 'signatures';
      use Carp 'croak';

      state $next_ID = 'AAA0001';

      sub new($class, %arg) {
          croak('Cannot specify ID as an constructor argument')
              if exists $arg{ID};
          bless {
              name    => $arg{name}    // croak('Missing name arg'),
              balance => $arg{balance} // 0,
              ID      => $next_ID++,
          }, $class;
      }

      sub name ($self) {
          return $self->{name};
      }

      sub set_name ($self, $newname) {
          $self->{name} = $newname;
      }

      sub balance ($self) {
          return $self->{balance};
      }

      sub ID ($self) {
          return $self->{ID};
      }

      sub deposit ($self, $amount) {
          $self->{balance} += $amount;
      }

      sub report ($self, $fh = *STDOUT) {
          $fh->say( $self->ID . ': ' . $self->balance );
      }
  }

...Dios allows you to achieve exactly the same functionality with just:

  use Dios;

  class Account {
      state $next_ID = 'AAA0001';

      has $.name     is rw  is required;
      has $.balance  = 0;
      has $.ID       = $next_ID++;

      method deposit ($amount) {
          $balance += $amount;
      }

      method report ($fh = *STDOUT) {
          $fh->say( "$ID: $balance" );
      }
  }

Not only is that three times less code, it’s three times simpler code, which means it’s also likely to be code that’s three times less buggy.

But what really excites me about Corinna is that, under that proposal, the same code would look like this:

  use experimental 'class';

  class Account {

      state $next_ID = 'AAA0001';

      slot $name     :param :reader :writer;
      slot $balance  :param :reader  = 0;
      slot $ID              :reader  = $next_ID++;

      method deposit ($amount) {
          $balance += $amount;
      }

      method report ($fh = *STDOUT) {
          $fh->say( "$ID: $balance" );
      }
  }

In other words: just as concise, just as readable, just as declarative. But without the huge behind-the-scenes overheads that Dios currently imposes.

The second example that illustrates why I’m so enthusiastic about the Corinna proposal is simply a subset of the first example. If we zoom in on that deposit() method:

  # under Corinna
  method deposit ($amount) {
      $balance += $amount;
  }

...we can see an important improvement over the current standard Perl version:

  # under standard Perl
  sub deposit ($self, $amount) {
      $self->{balance} += $amount;
  }

...and an even greater improvement over what would be required under Moose or Moo or Object::InsideOut or most other existing OO frameworks:

  # under most OO frameworks
  sub deposit ($self, $amount) {
      $self->balance( $self->balance + $amount );
  }

Under Corinna, the slots of an object are accessed via simple scalar variables (e.g. $balance) , not via a (slower) hash look-up (e.g. $self->{balance} or via (much slower) accessor methods (e.g. $self->balance).

This means that each individual slot access is going to be faster under Corinna, and so almost every method call will likewise be less expensive. For instance, each call to deposit() is likely to be at least three times quicker than under any of the many OO frameworks, because we’re dispensing with the two additional embedded method calls to $self->balance().

More subtly, if we happened to misspell our slot variable:

  # under standard Perl
  sub deposit ($self, $amount) {
      $self->{balence} += $amount;
      # Silent bug (autovivifies useless 'balence' key)
  }

  # under most OO frameworks
  sub deposit ($self, $amount) {
      $self->balance( $self->balence + $amount );
      # Runtime exception ("No such method 'balence'...")
  }

  # under Corinna
  method deposit ($amount) {
      $balence += $amount;
      # Compile-time exception: ("No such variable: $balence...")
  }

I don't know about you, but I'd much rather discover this problem the first time I compile the code, rather than at the first time it happens to actually be executed or, even worse, after a long and fruitless day of trying to debug the mysterious absence of recent deposit amounts.

There are so many other reasons to be enthusiastic about this proposed addition to standard Perl, not the least of which is that it will become standard and universally available, which may finally cut through the endless debate over whether your next project should use Moose or Moos or Moo or Mu or Spiffy or Object::InsideOut or Class::InsideOut or Class::Simple or Class::Easy or Class::Tiny or Class::Std or Dios or...

So, yes, I’m very excited about the RFC for Corinna, and I strongly encourage you to take a look for yourself at the powerful new OO features that will soon be proposed for Perl.

Coders In Cars Getting Chatty

The last time I spoke at Craft Conference, I also took part in what is probably the most fun and unusual interview of my career: Ivette Ördög’s Morning Commute.

Bear in mind, however, that this discussion took place back in 2018, so you’ll need to mentally s/Perl 6/Raku/ in a couple of places.

Even if you’re not interested in my random thoughts on the importance of linguistic diversity, Ivette’s other interviews are well worth watching.