Chapter 1: The Convenience Seeker
Coming from Python, the Raku object model is recognizable, but brings a tad more structure:
What works for me, as a convenience seeker, is:
- the attributes $.x, $.y are automatically provided with setter and getter methods
- the constructor new() is automatically provided
- the output method e.g. ‘say $p.Str’ is automatically provided
- I can simply assign to an attribute with ‘=’
These are the things you want if you are writing in a more procedural or functional style and using class as a means to define a record type.
Chapter 2: The Control Freak
Here’s the rub…
When we describe OO, terms like “encapsulation” and “data hiding” often come up. The key idea here is that the state model inside the object – that is, the way it chooses to represent the data it needs in order to implement its behaviours (the methods) – is free to evolve, for example to handle new requirements. The more complex the object, the more liberating this becomes.
However, getters and setters are methods that have an implicit connection with the state. While we might claim we’re achieving data hiding because we’re calling a method, not accessing state directly, my experience is that we quickly end up at a place where outside code is making sequences of setter calls to achieve an operation – which is a form of the feature envy anti-pattern. And if we’re doing that, it’s pretty certain we’ll end up with logic outside of the object that does a mix of getter and setter operations to achieve an operation. Really, these operations should have been exposed as methods with a names that describes what is being achieved. This becomes even more important if we’re in a concurrent setting; a well-designed object is often fairly easy to protect at the method boundary.
Let’s fix that:
Now, I had to do a bit more lifting, but here’s what I got:
- the private attributes $!x, $!y are formally encapsulated
- the BUILD submethod does constructor .new() – zero boilerplate needed
- it takes a method call [$p.y( 2 )] or the colon variant [$p.y: 3] to affect state
And, in contrast to Chapter 1:
- I cannot assign to has attributes using ‘=’
- since accessors are explicit I can easily code for constraints and side-effects
- it’s a pita to code accessors encouraging proper separation of behaviours
Chapter 3: Who Got the Colon in the End?
I also discovered Larry’s First Law of Language Redesign: Everyone wants the colon
Apocalypse 1: The Ugly, the Bad, and the Good https://www.perl.com/pub/2001/04/02/wall.html/
I conclude that Larry’s decision was to confer the colon on the method syntax, subtly tilting the balance towards the strict model: by preferring $p.y: 3 over $p.y = 2.