Mailing List Archive

This is not an RFC to bring modern OO into the Perl core
Hi all,
Recently Nick wrote that before we send an RFC, we should send what I think of as "an RFC for an RFC":
> 1: Here is a problem> 2: Here is the syntax that I'm proposing
> 3: Here are the benefits of this
> 4: Here are potential problems
The following is deliberately brief as I know many of you are familiar, at least roughly, with the Corinna project, but it's hard to summarize something this large. Further, we've been stripping everything out of the MVP that we think we reasonably can, but still, this is not as brief as what Nick asked for. (Nick, I still might have that photo of you with a tea cozy on your head at OSCON, so be kind).

1. The problem
We need modern OO in the Perl core. Myself, Paul Evans, and many other people have contributed to the following, but I take full responsibility for any idiocy.

Inside the echo chamber: "It's so easy to do X in Perl that there's no need to add X to core."

Outside the echo chamber: "Perl's missing many features that modern languages need."

This is hurting us and we're losing developers and jobs as a result.

2. The syntax
This limited example shows a simplistic LRU cache (not showing roles):
use feature 'class';

class Cache::LRU v0.1.0 {
use Hash::Ordered;

has $cache :handles(qw/exists delete/) = Hash::Ordered->new;
has $max_size :new :reader = 20;
has $created :reader = time;

method set ( $key, $value ) {
if ( $self->exists($key) ) {
$self->delete($key);
}
elsif ( $cache->keys > $max_size ) {
$cache->shift;
}
$cache->set( $key, $value ); # new values in front
}

method get($key) {
if ( $self->exists($key) ) {
my $value = $cache->get($key);
$self->set( $key, $value ); # put it at the front
return $value;
}
return;
}
}
3. The benefits:

- Compile-time failure of misspelled slots/attributes
- Proper encapsulation
- Solves Perl's version of "The Lisp Curse" http://www.winestockwebdesign.com/Essays/Lisp_Curse.html
- Many others!
-

This has been over two years of work, though initial work wasn't public until October of 2019. Since then, many, many people have contributed to make the design better and Paul Evans release Object::Pad, a test bed for many of the ideas (one that's powerful enough that it's already being used in production).
4. The potential problems:

For older Perl's, if you have a single instance or class variable in your class, you get a compile-time failure if you're using strict. Otherwise, you get weird runtime failures due to indirect object syntax. We're compatible with older Perl's in that the code won't run, but there are a few unusual cases which can be constructed (for example, reusing existing package names) which would prove confusing, but we are hoping this will be minimal and the risks worth the reward. For reasonable Perl code bases (stop laughing), we feel we're good to go.

I've been doing most of the design and Paul Evans has been doing most of the implementation. Many members of the Perl community (https://github.com/Ovid/Cor/wiki/Contributors) have been improving the design by pointing out weaknesses I've missed.

5. Not asked for, but ...
We don't plan to send the RFC for a while. Instead, this is a sounding board for your receptiveness to it. We're still working on the RFC because, while Paul's already finished much of the implementation, we don't feel rushing this is a good idea. Hence, over a year and a half between first announcement and this email (and over two years since development started).

Best,Ovid
-- IT consulting, training, specializing in Perl, databases, and agile developmenthttp://www.allaroundtheworld.fr/. 
Buy my book! - http://bit.ly/beginning_perl
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
On Sat, 19 Jun 2021 at 20:45, Ovid via perl5-porters <perl5-porters@perl.org>
wrote:

> We need modern OO in the Perl core.
>

One very small comment on this, because the "modern OO" phrase is used
frequently and I think it's harmful:

I'd claim that "modern" is not a useful term to be using in any
documentation here - it's not descriptive, and the way it's used is more
subjective than anything.

The proposal isn't really "modern" at all - it starts by adding class and
attribute keywords, something other languages such as C++ or Java have had
for decades, so it's like claiming ET is a "modern film". What's "modern"
today will be outdated next week. It also acts as an implicit criticism for
any existing approach or code, so it's not a very inclusive term either!

Could we instead put the focus on what advantages this might have over the
existing options? For example, these might include:

- typo safety
- clear, concise syntax
- extensible grammar?
>
>
"Modern" because it's popular isn't a useful target - if it were, we'd be
encouraging the discussions about dropping sigils and ; statement
separators! - so instead let's have clear goals for this RFC that can be
used to measure suggestions against.
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
(Top posting because I need to use a real email client one day)

Tom wrote:


I'd claim that "modern" is not a useful term to be using in any documentation here - it's not descriptive, and the way it's used is more subjective than anything.


I've very annoyed by that comment because, damn it, it's spot on. I'll update the RFC when I have figured out a more appropriate phrasing. Or maybe Paul will. Dunno.

/me shakes his little fist at Tom for being in the long line of people proving Ovid wrong.
Best,dviO ????
-- IT consulting, training, specializing in Perl, databases, and agile developmenthttp://www.allaroundtheworld.fr/. 
Buy my book! - http://bit.ly/beginning_perl

On Saturday, 19 June 2021, 15:28:03 CEST, Tom Molesworth via perl5-porters <perl5-porters@perl.org> wrote:


On Sat, 19 Jun 2021 at 20:45, Ovid via perl5-porters <perl5-porters@perl.org> wrote:

We need modern OO in the Perl core.


One very small comment on this, because the "modern OO" phrase is used frequently and I think it's harmful:

I'd claim that "modern" is not a useful term to be using in any documentation here - it's not descriptive, and the way it's used is more subjective than anything.

The proposal isn't really "modern" at all - it starts by adding class and attribute keywords, something other languages such as C++ or Java have had for decades, so it's like claiming ET is a "modern film". What's "modern" today will be outdated next week. It also acts as an implicit criticism for any existing approach or code, so it's not a very inclusive term either!

Could we instead put the focus on what advantages this might have over the existing options? For example, these might include:

- typo safety
- clear, concise syntax
- extensible grammar?


"Modern" because it's popular isn't a useful target - if it were, we'd be encouraging the discussions about dropping sigils and ; statement separators! - so instead let's have clear goals for this RFC that can be used to measure suggestions against.
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
On 2021-06-19 7:31 a.m., Ovid via perl5-porters wrote:
> Tom wrote:
>
> /I'd claim that "modern" is not a useful term to be using in any
> documentation here - it's not descriptive, and the way it's used is more
> subjective than anything.
> /
>
> I've very annoyed by that comment because, damn it, it's spot on. I'll update
> the RFC when I have figured out a more appropriate phrasing. Or maybe Paul will.
> Dunno.

I completely agree with this, but it hadn't occurred to me before.

Using "modern" to describe something is so over-used its lost all meaning. It
feels like every module on CPAN providing an object system calls itself
"modern". So by NOT doing so, Corinna would actually stand out more.

I propose the term "effective" rather than "modern", barring that something
better comes along. Also "concise" is good. You can use more than one.

Frequently when I'm trying to figure out a name for something, including in my
own language/format development, I explore thesaurus-dot-com which has been
immensely helpful.

-- Darren Duncan
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
??????? Original Message ???????

On Saturday, June 19th, 2021 at 3:44 PM, Darren Duncan <darren@darrenduncan.net> wrote:

> On 2021-06-19 7:31 a.m., Ovid via perl5-porters wrote:
>
> > Tom wrote:
> >
> > /I'd claim that "modern" is not a useful term to be using in any
> > documentation here - it's not descriptive, and the way it's used is more
> > subjective than anything.
> > /
> >
> >
> > I've very annoyed by that comment because, damn it, it's spot on. I'll update
> >
> > the RFC when I have figured out a more appropriate phrasing. Or maybe Paul will.
> >
> > Dunno.
>
> I completely agree with this, but it hadn't occurred to me before.
>
> Using "modern" to describe something is so over-used its lost all meaning. It
>
> feels like every module on CPAN providing an object system calls itself
>
> "modern". So by NOT doing so, Corinna would actually stand out more.
>
> I propose the term "effective" rather than "modern", barring that something
>
> better comes along. Also "concise" is good. You can use more than one.
>
> Frequently when I'm trying to figure out a name for something, including in my
>
> own language/format development, I explore thesaurus-dot-com which has been
>
> immensely helpful.

I don't think "post-modern" is helpful either. I much prefer the term "counter culutural".

That said, I'd like that as that we dig a little deeper into the fundamental support core needs to provide things like Corinna (formally known as Cor, let's not forget that). Rather than peeling the OOP "onion" back layer by layer, build it out from what exists now. Starting with what's needed to augment "bless", prototypes, and override.pm.

I also don't find any weight to arguments like,

* we're losing developers
* no one is hiring

It's about the application, <something that rhymes with cupid>.

And if this is not an RFC, what the hell is it? Create some iterative RFCs by deconstructing what you think you need to get to this "not-RFC".

Cheers,
Brett

>
> -- Darren Duncan
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
This is probably going to annoy some of you. If you want something
that is concise, relevant, and technical ... don't read this email.
It's any one of the three, but never all three together.

On Sat, Jun 19, 2021 at 9:41 PM mah.kitteh via perl5-porters
<perl5-porters@perl.org> wrote:
>
> On Saturday, June 19th, 2021 at 3:44 PM, Darren Duncan <darren@darrenduncan.net> wrote:
> >
> > Using "modern" to describe something is so over-used its lost all meaning.
>
> I don't think "post-modern" is helpful either. I much prefer the term "counter culutural".
>

Wikipedia says "A counterculture is a culture whose values and norms
of behavior differ substantially from those of mainstream society,
sometimes diametrically opposed to mainstream cultural mores."[1] so
obviously Corrinna cannot possibly be counter-cultural. Her norms of
behaivor do not differ substantially from those of either mainstream
Perl *nor* mainstream Object Oriented Programming. This was in fact
the original complaint about the term "modern".

Second, Corinna is patently not postmodern either. As has been
discussed before[2], postmodernity has three basic parts in its
definition, Corinna only matches one of them— “of, relating to, or
being an era after a modern one”. It is not a return to traditional
mediums and forms, it is also not an ironically self referential
commentary on the status quo. Neither is it entirely a radical
reappraisal of modern assumptions about culture, identity, history, or
language, in so far as I don't think anything about it is at this
point radical for anyone who's worked with an object oriented language
developed after the year 2006.

Corinna is a post-postmodern object system—though possibly not the
first one, Raku probably has a claim to that title. Corinna oscillates
between modernist positions regarding Object Oriented Design, and the
postmodern deconstructionist principles that were embraced
dramatically by Moose. Corinna is a metamodern[3] object system. "How
on earth is this relevant?" I imagine you asked *long* before you got
to this part of the email. It speaks to why the approach Brett is
advocating simply _won't_ work (beyond the fact that people have been
trying it for several years now).

> Rather than peeling the OOP "onion" back layer by layer, build it out from what exists now. Starting with what's needed to augment "bless", prototypes, and [overload.pm].

Without trying to sound offensive, this list kinda suggests you've not
really done any extensive thought about what an object system is and
should be. Most people don't and shouldn't ever need to. A list of
things that in my opinion would need enhancement:

* Classes: Perl just gives you packages with a special @ISA variable
for inheritance. Packages are just a bag of subroutines, they have no
idea of state.
* Attributes: `bless` associates a package with a data structure to
provide "attributes", except it doesn't actually provide attributes,
it just provides a place to store data and leaves you to figure out
what attributes are and what that means. This also means that all
instance data is public by default. While we pretend that it doesn't
because Larry told us not to play with shotguns, it hasn't stopped a
lot of people putting shotgun like things onto CPAN (or into Perl Best
Practices).
* Metamodel: The way you interrogate and manipulate a package is ....
not obvious. Package::Stash exists on CPAN simply to provide an API
for this manipulation because it's fraught with edge cases and weird
syntax.
* Methods: Perl's concept of a method is a subroutine called in a
funky way. Combined with the public nature of the data, this means you
can call any method on any object ... and the only thing that can
prevent this is the method itself. I've never seen anyone write enough
validation code at the beginning of their methods to deal with what is
actually possible to throw at a method.
* Class composition: _Design Patterns: Elements of Reusable
Object-Oriented Software_, published literally 4 days after Perl 5.000
says to prefer composition to inheritance. Perl's only solution to
reusable behavior is inheritance. Worse, Perl supports multiple
inheritance using a default algorithm that can cause weird non-obvious
bugs.
* Object Construction Protocol: Ensuring that all of the attributes
are initialized properly in the correct data structure during
construction is left entirely as a lemma for the programmer.
* Object Destruction Protocol: See above, but because Perl has
universal destruction where we can't even guarantee the order in which
things are destroyed.

The fact that Perl's built in object system just gives you a bag of
primitives and leaves you to build a robust object system for every
application you write is kinda the reason things like Moose exist.
Moose's choices to solve many of these problems is the reason Corinna
exists. Let's take Classes, attributes, and methods for example
(because this is the most obvious change in Corinna). Classes are
supposed to be a template for creating objects with initial
definitions of state and implementations of behavior. Perl's native
system only provides the second half of that.

````
package Player;
use 5.34.0;
use warnings;
use experimental 'signatures';

sub new($class, $data) {
# a "character" property is required so we have to check here
die "Must provide a character object" unless $data->{character};

# every player must have a name, but we can provide a default
$data->{name} //= do { state $n = 1; 'Player' . $n++ };

bless $data, $class;
}

# and we have to write our own accessor if we don't want people to
just use $self->{name}
sub name($self) { $self->{$name} }

sub attack($self, $target) { print STDERR "$self->{name} attacks
$target->{name}"; ... }

1;
```
Moose provides a template for state but the way it provides it
encourages a proliferation of behavior;
```
package Player;
use 5.34;
use Moose;
use experimental 'signatures';

has name => ( is => 'ro', default => sub { state $n = 1; 'Player' . $n++ } );
has character => ( is => 'ro', required => 1 );

__PACKAGE__->meta->make_immutable;
```
This has templates for the state, but now our character object has a
public accessor. Moose can be told not to generate an accessor.
```
package Player;
use 5.34;
use Moose;
use experimental 'signatures';

has name => ( is => 'ro', default => sub { state $n = 1; 'Player' . $n++ } );
has character => ( is => 'bare', required => 1 );

sub attack($self, $target) { print STDERR $self->name() . " attacks "
. $target->name(); ... }
__PACKAGE__->meta->make_immutable;
```
But now the only way to access the character attribute is to look in
$self->{character} which poses a problem. Moose tries to hide the fact
that all objects are blessed hashes, they are, everyone knows they
are, but it's considered bad form to treat them as such because doing
that you throw away any advantages Moose can provide to attribute
access. We can fix that as well
```
package Player;
use 5.34;
use Moose;
use experimental 'signatures';

has name => ( is => 'ro', default => sub { state $n = 1; 'Player' . $n++ } );
has character => (
is => 'bare',
reader => '_character',
required => 1
);

sub attack($self, $target) { print STDERR $self->name() . " attacks
$target->{name}"; ... }

__PACKAGE__->meta->make_immutable;
```
Now you have a public method that uses the Perl convention of
underscore prefix means it's private so pretend you don't see it. Oh
and to make all of this operate at a reasonable speed you have to
include __PACKAGE__->meta->make_immutable; at the end of every package
so that Moose spends a lot of compile time generating and eval-ing
strings into packages so that at runtime you get almost the same speed
as an equivalent native method.

From a design perspective this means that there is a lot of state and
behavior you either simply pretend aren't public or actively work
around Moose to encapsulate. Corinna's approach to this is to have
lexically scoped member variables that aren't accessible outside the
class.
```
use strict;
use warnings;
use feature 'class'; # bring in Corinna

class Player {
has $name :new :reader = do { state $n = 1; 'Player' . $n++ };
has $character :new;

method attack($target) { say STDERR "$name attacks " .
$target->name(); ... }
}
```
This default is changed from public first, to private first. The only
subroutines in the class are the ones you explicitly ask for (:reader)
or define (method). Because Corinna is baked into core there is no
need to inject strings into packages at compile time to be parsed so
that everything runs at native speed. The augmentation kind of
requires the entire re-thinking of how classes are implemented in
Perl. Oh! And the pieces are hard to tease apart, because once you
start thinking about attributes as an essential part of a Class you
now have to have an Object Construction Protocol to make sure they're
initialized. An Object Construction Protocol is a part of a well
defined metamodel. If you want to encapsulate data into a lexical
scope you need methods that can access that lexical scope (and can't
access a different classes scope). So the augmentation starts hitting
several parts that Perl currently doesn't have ... just to get the
basic behavior.

You've slogged through all of this ... but yeah there's one more thing
I wanted to point out. You could reduce Corinna by getting rid of the
slot attributes like ':new' and ':reader'. All of the features we were
looking for with private attributes are still there, the code is just
more verbose.
```
use strict;
use warmings;
use feature 'simpler_class'; # a simpler Corinna

class Player {
has $_name = do { state $n = 1; 'Player' . $n++ };
has $_character;

method new($character, $name=undef) {
$_character = $character;
$_name = $name if defined $name;
return $self;
}
method name() { $_name }
method attack($target) { say STDERR "$name attacks " . $target->name(); ... }
}
```

So where were we? Oh right! Corinna is a metamodern object system
because it rejects the postmodern concept of deconstructing the
existing object system (by rebuilding it with a robust framework) and
instead returns to the modernist design of extending the core language
with the attributes we found most appealing after gazing at the system
with our postmodernist mindset, but without the baggage that the
postmodernist ironic self-reflexive implementation required us to
have.

Corinna is metamodern.

Thank you for coming to my Ted Talk.

[1]: https://en.wikipedia.org/wiki/Counterculture
[2]: https://chris.prather.org/why-moose-is-post-modern.html
[3]: https://en.wikipedia.org/wiki/Metamodernism#Vermeulen_and_van_den_Akker
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
+5 Insightful. Thank you, Chris. I was neither annoyed, nor offended. I also read it all (lest I get accused of not reading or thinking, which happens quite often).

FWIW, I have not done much thinking about what an object system looks, mnuch less in in perl. It's not necessarily that I personally don't see the need or use OOP beyond providing convenient dereference syntax, it's that nothing I have seen seems at all complementary to Perl or perl. Util::H2O is a good example of what it means to be complementary or to work within the framework established by Perl/perl. It also seems quite "counter-cultural" if you ask me. Is it good on large scale code? Idk, I am going to guess probably not without sufficient additional abstractions - so I am not advocating this as the solution, only a good and interesting option for some.

Ultimately, my point is this: whatever is done to support things like "class", "private", etc should be natural extensions and complements to the current Perl "OO" syntax (superficially at the very least). This is important to me for two reasons: 1) I want to be able to reach for it if I need it doing what I already know (package, bless, deref syntax); and 2) I want to feel confident that supporting such syntax is not bolting on a "parallel" system to the perl core runtime to support these things when the existing can be simultaneously improved and extended to support such things.

A corollory to #1 is that I want to be able to jump into maintenance of a code written using Corinna (or whatever is Perl's OOP-ng) and be immediately familiar with it knowing what I already know: a) about Perl/perl, and b) about OOP in general. I can't do that with Moo/Moose and in fact have gotten to the point where I simply refuse to do so because the code base it generates is so abjectly foreign to me that I can't even consider it Perl.

And this gets the my preference for a "bottom up" versus "top down" approach to this. Given what we have now, how do we extend things to get to where we (think) we wish to go? Rather than saying we want $THIS, how do we work back? Can we go from status quo to Corinna as it is specified now, incrementally and naturally? I pointed out Util::H2O at the start because it is the result of such thinking. (and for that matter, regarding another topic, so is Sub::Infix) - how far can we get with what we have _now_? What fundamental capabilities of core are require to easily support such things? How can we flush out new interesting things and also minimally extend core, etc?

Cheers,
Brett

??????? Original Message ???????

On Saturday, June 19th, 2021 at 11:51 PM, Chris Prather <chris@prather.org> wrote:

> This is probably going to annoy some of you. If you want something
>
> that is concise, relevant, and technical ... don't read this email.
>
> It's any one of the three, but never all three together.
>
> On Sat, Jun 19, 2021 at 9:41 PM mah.kitteh via perl5-porters
>
> perl5-porters@perl.org wrote:
>
> > On Saturday, June 19th, 2021 at 3:44 PM, Darren Duncan darren@darrenduncan.net wrote:
> >
> > > Using "modern" to describe something is so over-used its lost all meaning.
> >
> > I don't think "post-modern" is helpful either. I much prefer the term "counter culutural".
>
> Wikipedia says "A counterculture is a culture whose values and norms
>
> of behavior differ substantially from those of mainstream society,
>
> sometimes diametrically opposed to mainstream cultural mores."[1] so
>
> obviously Corrinna cannot possibly be counter-cultural. Her norms of
>
> behaivor do not differ substantially from those of either mainstream
>
> Perl nor mainstream Object Oriented Programming. This was in fact
>
> the original complaint about the term "modern".
>
> Second, Corinna is patently not postmodern either. As has been
>
> discussed before[2], postmodernity has three basic parts in its
>
> definition, Corinna only matches one of them— “of, relating to, or
>
> being an era after a modern one”. It is not a return to traditional
>
> mediums and forms, it is also not an ironically self referential
>
> commentary on the status quo. Neither is it entirely a radical
>
> reappraisal of modern assumptions about culture, identity, history, or
>
> language, in so far as I don't think anything about it is at this
>
> point radical for anyone who's worked with an object oriented language
>
> developed after the year 2006.
>
> Corinna is a post-postmodern object system—though possibly not the
>
> first one, Raku probably has a claim to that title. Corinna oscillates
>
> between modernist positions regarding Object Oriented Design, and the
>
> postmodern deconstructionist principles that were embraced
>
> dramatically by Moose. Corinna is a metamodern[3] object system. "How
>
> on earth is this relevant?" I imagine you asked long before you got
>
> to this part of the email. It speaks to why the approach Brett is
>
> advocating simply won't work (beyond the fact that people have been
>
> trying it for several years now).
>
> > Rather than peeling the OOP "onion" back layer by layer, build it out from what exists now. Starting with what's needed to augment "bless", prototypes, and [overload.pm].
>
> Without trying to sound offensive, this list kinda suggests you've not
>
> really done any extensive thought about what an object system is and
>
> should be. Most people don't and shouldn't ever need to. A list of
>
> things that in my opinion would need enhancement:
>
> - Classes: Perl just gives you packages with a special @ISA variable
>
> for inheritance. Packages are just a bag of subroutines, they have no
>
> idea of state.
> - Attributes: `bless` associates a package with a data structure to
>
> provide "attributes", except it doesn't actually provide attributes,
>
> it just provides a place to store data and leaves you to figure out
>
> what attributes are and what that means. This also means that all
>
> instance data is public by default. While we pretend that it doesn't
>
> because Larry told us not to play with shotguns, it hasn't stopped a
>
> lot of people putting shotgun like things onto CPAN (or into Perl Best
>
> Practices).
> - Metamodel: The way you interrogate and manipulate a package is ....
>
> not obvious. Package::Stash exists on CPAN simply to provide an API
>
> for this manipulation because it's fraught with edge cases and weird
>
> syntax.
> - Methods: Perl's concept of a method is a subroutine called in a
>
> funky way. Combined with the public nature of the data, this means you
>
> can call any method on any object ... and the only thing that can
>
> prevent this is the method itself. I've never seen anyone write enough
>
> validation code at the beginning of their methods to deal with what is
>
> actually possible to throw at a method.
> - Class composition: Design Patterns: Elements of Reusable
>
> Object-Oriented Software, published literally 4 days after Perl 5.000
>
> says to prefer composition to inheritance. Perl's only solution to
>
> reusable behavior is inheritance. Worse, Perl supports multiple
>
> inheritance using a default algorithm that can cause weird non-obvious
>
> bugs.
> - Object Construction Protocol: Ensuring that all of the attributes
>
> are initialized properly in the correct data structure during
>
> construction is left entirely as a lemma for the programmer.
> - Object Destruction Protocol: See above, but because Perl has
>
> universal destruction where we can't even guarantee the order in which
>
> things are destroyed.
>
> The fact that Perl's built in object system just gives you a bag of
>
> primitives and leaves you to build a robust object system for every
>
> application you write is kinda the reason things like Moose exist.
>
> Moose's choices to solve many of these problems is the reason Corinna
>
> exists. Let's take Classes, attributes, and methods for example
>
> (because this is the most obvious change in Corinna). Classes are
>
> supposed to be a template for creating objects with initial
>
> definitions of state and implementations of behavior. Perl's native
>
> system only provides the second half of that.
>
> package Player;
> use 5.34.0;
> use warnings;
> use experimental 'signatures';
>
> sub new($class, $data) {
> # a "character" property is required so we have to check here
> die "Must provide a character object" unless $data->{character};
>
>
> # every player must have a name, but we can provide a default
> $data->{name} //= do { state $n = 1; 'Player' . $n++ };
>
>
> bless $data, $class;
> }
>
> # and we have to write our own accessor if we don't want people to
> just use $self->{name}
>
> sub name($self) { $self->{$name} }
>
>
> sub attack($self, $target) { print STDERR "$self->{name} attacks
>
> $target->{name}"; ... }
>
>
> 1;
> ```
> Moose provides a template for state but the way it provides it
> encourages a proliferation of behavior;
> ```
> package Player;
> use 5.34;
> use Moose;
> use experimental 'signatures';
>
> has name => ( is => 'ro', default => sub { state $n = 1; 'Player' . $n++ } );
>
> has character => ( is => 'ro', required => 1 );
>
>
> __PACKAGE__->meta->make_immutable;
>
> ```
> This has templates for the state, but now our character object has a
> public accessor. Moose can be told not to generate an accessor.
> ```
> package Player;
> use 5.34;
> use Moose;
> use experimental 'signatures';
>
> has name => ( is => 'ro', default => sub { state $n = 1; 'Player' . $n++ } );
>
> has character => ( is => 'bare', required => 1 );
>
>
> sub attack($self, $target) { print STDERR $self->name() . " attacks "
>
> . $target->name(); ... }
>
> __PACKAGE__->meta->make_immutable;
>
> ```
> But now the only way to access the character attribute is to look in
> $self->{character} which poses a problem. Moose tries to hide the fact
>
> that all objects are blessed hashes, they are, everyone knows they
> are, but it's considered bad form to treat them as such because doing
> that you throw away any advantages Moose can provide to attribute
> access. We can fix that as well
> ```
> package Player;
> use 5.34;
> use Moose;
> use experimental 'signatures';
>
> has name => ( is => 'ro', default => sub { state $n = 1; 'Player' . $n++ } );
>
> has character => (
>
> is => 'bare',
>
> reader => '_character',
>
> required => 1
>
> );
>
> sub attack($self, $target) { print STDERR $self->name() . " attacks
>
> $target->{name}"; ... }
>
>
> __PACKAGE__->meta->make_immutable;
>
> ```
> Now you have a public method that uses the Perl convention of
> underscore prefix means it's private so pretend you don't see it. Oh
> and to make all of this operate at a reasonable speed you have to
> include __PACKAGE__->meta->make_immutable; at the end of every package
>
> so that Moose spends a lot of compile time generating and eval-ing
> strings into packages so that at runtime you get almost the same speed
> as an equivalent native method.
>
> From a design perspective this means that there is a lot of state and
> behavior you either simply pretend aren't public or actively work
> around Moose to encapsulate. Corinna's approach to this is to have
> lexically scoped member variables that aren't accessible outside the
> class.
> ```
> use strict;
> use warnings;
> use feature 'class'; # bring in Corinna
>
> class Player {
> has $name :new :reader = do { state $n = 1; 'Player' . $n++ };
> has $character :new;
>
> method attack($target) { say STDERR "$name attacks " .
> $target->name(); ... }
>
> }
> ```
> This default is changed from public first, to private first. The only
> subroutines in the class are the ones you explicitly ask for (:reader)
> or define (method). Because Corinna is baked into core there is no
> need to inject strings into packages at compile time to be parsed so
> that everything runs at native speed. The augmentation kind of
> requires the entire re-thinking of how classes are implemented in
> Perl. Oh! And the pieces are hard to tease apart, because once you
> start thinking about attributes as an essential part of a Class you
> now have to have an Object Construction Protocol to make sure they're
> initialized. An Object Construction Protocol is a part of a well
> defined metamodel. If you want to encapsulate data into a lexical
> scope you need methods that can access that lexical scope (and can't
> access a different classes scope). So the augmentation starts hitting
> several parts that Perl currently doesn't have ... just to get the
> basic behavior.
>
> You've slogged through all of this ... but yeah there's one more thing
> I wanted to point out. You could reduce Corinna by getting rid of the
> slot attributes like ':new' and ':reader'. All of the features we were
> looking for with private attributes are still there, the code is just
> more verbose.
> ```
> use strict;
> use warmings;
> use feature 'simpler_class'; # a simpler Corinna
>
> class Player {
> has $_name = do { state $n = 1; 'Player' . $n++ };
> has $_character;
>
> method new($character, $name=undef) {
> $_character = $character;
> $_name = $name if defined $name;
> return $self;
> }
> method name() { $_name }
> method attack($target) { say STDERR "$name attacks " . $target->name(); ... }
>
> }
> ```
>
> So where were we? Oh right! Corinna is a metamodern object system
> because it rejects the postmodern concept of deconstructing the
> existing object system (by rebuilding it with a robust framework) and
> instead returns to the modernist design of extending the core language
> with the attributes we found most appealing after gazing at the system
> with our postmodernist mindset, but without the baggage that the
> postmodernist ironic self-reflexive implementation required us to
> have.
>
> Corinna is metamodern.
>
> Thank you for coming to my Ted Talk.
>
> [1]: https://en.wikipedia.org/wiki/Counterculture
> [2]: https://chris.prather.org/why-moose-is-post-modern.html
> [3]: https://en.wikipedia.org/wiki/Metamodernism#Vermeulen_and_van_den_Akker
>
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
On Sun, Jun 20, 2021, at 10:56 AM, mah.kitteh via perl5-porters wrote:
> +5 Insightful. Thank you, Chris. I was neither annoyed, nor offended. I also read it all (lest I get accused of not reading or thinking, which happens quite often).
>
> FWIW, I have not done much thinking about what an object system looks, mnuch less in in perl.

"How to improve the state of OO affordances in Perl" is a topic that some people on this list have spent 10 or more years thinking about, including the changes required to the language and implementation. Suggesting, based on "not much thinking" that we consider digging deeper, is not done from a place of wisdom.

--
rjbs
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
On Sat, Jun 19, 2021, at 8:44 AM, Ovid via perl5-porters wrote:
> [ I have a cool idea. ]

Ovid,

I would definitely like for Perl to provide many improved OO features, and while I bet you and I could debate the fine points of many small details, let's do that later.

In general, I want to say that this is welcome. What I'm most keen to get a handle on is "where it all gets shoved in". That is: I can imagine that this is "perl5.git gets oo.c which handles all this" or "we need to add three new parser hooks and a new kind of SV" or "this will all run on top of the existing core, but I want it to ship with perl."

Can you (or Paul) give even a rough idea of where you think this will fall? It will help set my level of circumspection later. ;)

--
rjbs
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
??????? Original Message ???????
On Sunday, June 20th, 2021 at 8:59 PM, Ricardo Signes <perl.p5p@rjbs.manxome.org> wrote:

> On Sun, Jun 20, 2021, at 10:56 AM, mah.kitteh via perl5-porters wrote:
>
>> +5 Insightful. Thank you, Chris. I was neither annoyed, nor offended. I also read it all (lest I get accused of not reading or thinking, which happens quite often).
>>
>> FWIW, I have not done much thinking about what an object system looks, mnuch less in in perl.
>
> "How to improve the state of OO affordances in Perl" is a topic that some people on this list have spent 10 or more years thinking about, including the changes required to the language and implementation. Suggesting, based on "not much thinking" that we consider digging deeper, is not done from a place of wisdom.

I get what you're saying and I don't discount the depth of thought done; there is necessarily going to be a period of fire from a lot of people with highly refined mental models of perl/Perl. Probably most of them also have not thought much about this either (or at all) - other than hoping that when the day of OOP Perl comes, the result is recognizable and coherent with their existing mental model (and even more fun!).

Cheers,
Brett

> --
> rjbs
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
As long as 10 years? From Wikipedia:

Alan Kay is one of the fathers of the idea of object-oriented programming
<https://en.wikipedia.org/wiki/Object-oriented_programming> (OOP), which he
named. Some of the original object-oriented concepts, including the use of
the words 'object' and 'class', had been developed for Simula
<https://en.wikipedia.org/wiki/Simula> *67* at the Norwegian Computing
Center <https://en.wikipedia.org/wiki/Norwegian_Computing_Center>. Later he
said:

I'm sorry that I long ago coined the term "objects" for this topic because
it gets many people to focus on the *lesser* idea. The big idea is
"messaging"


On Mon, Jun 21, 2021 at 5:33 AM mah.kitteh via perl5-porters <
perl5-porters@perl.org> wrote:

> ??????? Original Message ???????
> On Sunday, June 20th, 2021 at 8:59 PM, Ricardo Signes <
> perl.p5p@rjbs.manxome.org> wrote:
>
> On Sun, Jun 20, 2021, at 10:56 AM, mah.kitteh via perl5-porters wrote:
>
> +5 Insightful. Thank you, Chris. I was neither annoyed, nor offended. I
> also read it all (lest I get accused of not reading or thinking, which
> happens quite often).
>
> FWIW, I have not done much thinking about what an object system looks,
> mnuch less in in perl.
>
>
> "How to improve the state of OO affordances in Perl" is a topic that some
> people on this list have spent 10 or more years thinking about, including
> the changes required to the language and implementation. Suggesting, based
> on "not much thinking" that we consider digging deeper, is not done from a
> place of wisdom.
>
>
> I get what you're saying and I don't discount the depth of thought done;
> there is necessarily going to be a period of fire from a lot of people with
> highly refined mental models of perl/Perl. Probably most of them also have
> not thought much about this either (or at all) - other than hoping that
> when the day of OOP Perl comes, the result is recognizable and coherent
> with their existing mental model (and even more fun!).
>
> Cheers,
> Brett
>
>
> --
> rjbs
>
>
>
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
On 2021-06-20 7:04 p.m., Ricardo Signes wrote:
> In general, I want to say that this is welcome.  What I'm most keen to get a
> handle on is "where it all gets shoved in".  That is:  I can imagine that this
> is "perl5.git gets oo.c which handles all this" or "we need to add three new
> parser hooks and a new kind of SV" or "this will all run on top of the existing
> core, but I want it to ship with perl."
>
> Can you (or Paul) give even a rough idea of where you think this will fall?  It
> will help set my level of circumspection later. ;)

The impression I get is that the appropriate and proper way to implement Corinna
is most like your "we need to add three new parser hooks and a new kind of SV"
option.

As Chris Prather said, the most fundamental thing Corinna brings to the table is
a new primitive, an opaque record type, like a SV that is not any of
hash/array/etc we have now but rather is a peer to those.

-- Darren Duncan
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
On Sun, 20 Jun 2021 22:04:27 -0400
"Ricardo Signes" <perl.p5p@rjbs.manxome.org> wrote:

> In general, I want to say that this is welcome. What I'm most keen
> to get a handle on is "where it all gets shoved in". That is: I can
> imagine that this is "perl5.git gets oo.c which handles all this" or
> "we need to add three new parser hooks and a new kind of SV" or "this
> will all run on top of the existing core, but I want it to ship with
> perl."
>
> Can you (or Paul) give even a rough idea of where you think this will
> fall? It will help set my level of circumspection later. ;)

I can imagine two stages of implementation.

In Stage 1 we do a fairly surface-level lift of the existing
Object::Pad implementation, using perl core's parser (so plenty of
edits to perly.y) and implementing most of the inner pieces in some new
file - oo.c seems as good a working title as any. Some still-open
questions at that point about things like where MOP objects will go.

In Stage 2 we can do a deeper dive into things like making a true
SVt_OBJECT (and maybe even SVt_CLASS) type to avoid some of the
limitations that Object::Pad has had to do to work around the fact it
is "only" an XS module and not true core, so it has limits to the new
things it can invent.

We'd only have to get as far as Stage 1 in order to be useful to Perl
programmers as a core feature. (Well personally I'd argue that Stage 0,
of Object::Pad existing, is also useful to Perl programmers ;). Stage 2
is mostly about improving efficiency, better integration into core, and
making possible things that could not be done currently in the CPAN
module.

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
On 2021-06-21 7:10 a.m., Paul "LeoNerd" Evans wrote:
> I can imagine two stages of implementation.
>
> In Stage 1 we do a fairly surface-level lift of the existing
> Object::Pad implementation, using perl core's parser (so plenty of
> edits to perly.y) and implementing most of the inner pieces in some new
> file - oo.c seems as good a working title as any. Some still-open
> questions at that point about things like where MOP objects will go.
>
> In Stage 2 we can do a deeper dive into things like making a true
> SVt_OBJECT (and maybe even SVt_CLASS) type to avoid some of the
> limitations that Object::Pad has had to do to work around the fact it
> is "only" an XS module and not true core, so it has limits to the new
> things it can invent.
>
> We'd only have to get as far as Stage 1 in order to be useful to Perl
> programmers as a core feature. (Well personally I'd argue that Stage 0,
> of Object::Pad existing, is also useful to Perl programmers ;). Stage 2
> is mostly about improving efficiency, better integration into core, and
> making possible things that could not be done currently in the CPAN
> module.

So to confirm, these 2 stages are such that all user-visible changes happen in
stage 1 and stage 2 is just performance improvements? Or would there be
differences between stage 1 and stage 2 that are visible to the user?

I would expect that if they're visibly different to users then these 2 stages
would be part of a single development series, for example in 2 different 5.35.x,
and that we wouldn't have say stage 1 only in 5.36.0 and stage 2 in 5.38.0, so
regular users only ever see the outcome of stage 2.

-- Darren Duncan
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
??????? Original Message ???????

On Monday, June 21st, 2021 at 5:26 PM, Darren Duncan <darren@darrenduncan.net> wrote:

> On 2021-06-21 7:10 a.m., Paul "LeoNerd" Evans wrote:
>
> > I can imagine two stages of implementation.
> >
> > In Stage 1 we do a fairly surface-level lift of the existing
> >
> > Object::Pad implementation, using perl core's parser (so plenty of
> >
> > edits to perly.y) and implementing most of the inner pieces in some new
> >
> > file - oo.c seems as good a working title as any. Some still-open
> >
> > questions at that point about things like where MOP objects will go.
> >
> > In Stage 2 we can do a deeper dive into things like making a true
> >
> > SVt_OBJECT (and maybe even SVt_CLASS) type to avoid some of the
> >
> > limitations that Object::Pad has had to do to work around the fact it
> >
> > is "only" an XS module and not true core, so it has limits to the new
> >
> > things it can invent.
> >
> > We'd only have to get as far as Stage 1 in order to be useful to Perl
> >
> > programmers as a core feature. (Well personally I'd argue that Stage 0,
> >
> > of Object::Pad existing, is also useful to Perl programmers ;). Stage 2
> >
> > is mostly about improving efficiency, better integration into core, and
> >
> > making possible things that could not be done currently in the CPAN
> >
> > module.
>
> So to confirm, these 2 stages are such that all user-visible changes happen in
>
> stage 1 and stage 2 is just performance improvements? Or would there be
>
> differences between stage 1 and stage 2 that are visible to the user?
>
> I would expect that if they're visibly different to users then these 2 stages
>
> would be part of a single development series, for example in 2 different 5.35.x,
>
> and that we wouldn't have say stage 1 only in 5.36.0 and stage 2 in 5.38.0, so
>
> regular users only ever see the outcome of stage 2.
>
> -- Darren Duncan

There is a reason people use the term "MVP" (minimal viable product). It's because in most cases that's all that gets delivered for an appreciable amount of time. Any RFC should encapsulate just a single pass without relying on a second to deliver something complete. Let's get some minimal, achievable "wins" under the belt. This will do wonders for moral. Anything else will demoralize further, there is no "in between". I think that the RFC as "use feature 'class'" accomplishes this. The trick is to define what is minimal, yet complete. So I have some skin in the game, I volunteer to help write Perl based tests given some well defined specification; that's where I can be most of service at this time. If someone can let me know where to start, I am happy to start working on that now (perhaps with Object::Pad?).

Cheers,
Brett
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
On Tue, 22 Jun 2021 01:02:04 +0000
"mah.kitteh via perl5-porters" <perl5-porters@perl.org> wrote:

> So I have some skin in the game, I volunteer to help write Perl based
> tests given some well defined specification; that's where I can be
> most of service at this time. If someone can let me know where to
> start, I am happy to start working on that now (perhaps with
> Object::Pad?).

I'd imagine most of these would just directly apply for core:

https://metacpan.org/release/PEVANS/Object-Pad-0.41/source/t

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: This is not an RFC to bring modern OO into the Perl core [ In reply to ]
[.This mail was drafted last night, and is already technically out of date]

On Sat, Jun 19, 2021 at 12:44:51PM +0000, Ovid via perl5-porters wrote:
> Hi all,
> Recently Nick wrote that before we send an RFC, we should send what I think of as "an RFC for an RFC":
> > 1: Here is a problem> 2: Here is the syntax that I'm proposing
> > 3: Here are the benefits of this
> > 4: Here are potential problems

It was an "elevator pitch", and I think your "take 2" version nailed it.

> The following is deliberately brief as I know many of you are familiar, at least roughly, with the Corinna project, but it's hard to summarize something this large. Further, we've been stripping everything out of the MVP that we think we reasonably can, but still, this is not as brief as what Nick asked for. (Nick, I still might have that photo of you with a tea cozy on your head at OSCON, so be kind).

I know that Elaine has photos of me in a sombre swigging tequila from a
bottle, but clearly that's the tequila's fault, not mine. But I totally
don't remember a tea cozy - what the heck was I drinking - *just* tea? I
must have been really jet lagged. That's my excuse and I'm sticking to it.

(Dammit, and why are we talking about blackmailing the PSC, instead of
bribing it? I'm sure I could do with *more* tea - a friend came to visit and
gave me gin. Came to visit again and gave me tea. I finished the tea first.
(The gin was nice too, but it seems that I drink more tea than gin.))

> 5. Not asked for, but ...
> We don't plan to send the RFC for a while. Instead, this is a sounding board for your receptiveness to it. We're still working on the RFC because, while Paul's already finished much of the implementation, we don't feel rushing this is a good idea. Hence, over a year and a half between first announcement and this email (and over two years since development started).

Phew!

In that, I knew that you'd been working hard on Corinna in the background,
but I wasn't aware that you were ready to send RFCs. This is a nice problem
to have.

Corinna might be ready for the RFC process, but I'm not confident that the
RFC process is ready for Corinna. At least not, this week. (Next week, I'm
no longer on the PSC. It becomes SEP, in theory. In practice, I suspect that
they'll delegate me the hat for a while yet. But that's their call, not
mine.)


On Sun, Jun 20, 2021 at 10:04:27PM -0400, Ricardo Signes wrote:

> I would definitely like for Perl to provide many improved OO features, and while I bet you and I could debate the fine points of many small details, let's do that later.

Agree.

> In general, I want to say that this is welcome. What I'm most keen to get a handle on is "where it all gets shoved in". That is: I can imagine that this is "perl5.git gets oo.c which handles all this" or "we need to add three new parser hooks and a new kind of SV" or "this will all run on top of the existing core, but I want it to ship with perl."
>
> Can you (or Paul) give even a rough idea of where you think this will fall? It will help set my level of circumspection later. ;)

This is also what I'm wondering, and I note that Paul has already started
filling in details.

Nicholas Clark