Mailing List Archive

Not an OO RFC, take 2
Responding to earlier comments, here's an even more terse version:
We need an effective OO system in the Perl core. bless is not an effective OO system. With 80+ OO "variants" on the CPAN, and with even the best of them hobbled due to limitations in the Perl language itself, it's time to rectify that. Corinna is a large effort with input from many top-notch Perl devs on what an effective OO system would look like.
Would P5P be receptive to an RFC?

Best,Ovid
-- IT consulting, training, specializing in Perl, databases, and agile developmenthttp://www.allaroundtheworld.fr/. 
Buy my book! - http://bit.ly/beginning_perl
Re: Not an OO RFC, take 2 [ In reply to ]
On 2021-06-19 10:44 p.m., Ovid via perl5-porters wrote:
> Responding to earlier comments, here's an even more terse version:
>
> We need an effective OO system in the Perl core. bless is not an effective OO
> system. With 80+ OO "variants" on the CPAN, and with even the best of them
> hobbled due to limitations in the Perl language itself, it's time to rectify
> that. Corinna is a large effort with input from many top-notch Perl devs on what
> an effective OO system would look like.
>
> Would P5P be receptive to an RFC?
>
> Best,
> Ovid

Nice to see you like my "effective" terminology proposal. -- Darren Duncan
Re: Not an OO RFC, take 2 [ In reply to ]
??????? Original Message ???????
On Sunday, June 20th, 2021 at 12:44 AM, Ovid via perl5-porters <perl5-porters@perl.org> wrote:

> Responding to earlier comments, here's an even more terse version:
>
> We need an effective OO system in the Perl core. bless is not an effective OO system. With 80+ OO "variants" on the CPAN, and with even the best of them hobbled due to limitations in the Perl language itself, it's time to rectify that. Corinna is a large effort with input from many top-notch Perl devs on what an effective OO system would look like.
>
> Would P5P be receptive to an RFC?

I can't speak for p5p. But personally, I'd rather see a series of RFCs that introduce fundamental core capabilities that will come together to provide this "effective" OOP in Perl, rather than a kitchen sink take-it/leave-it approach. This is one reason things fail around here, the idea that prometheus is just going to show up and give us the answer. I've never seen that happen here, or anywhere.

I am suggesting this because I DO want to see Perl/perl improved out of this. The question is, what's the most efficient process for discovering the "best" or "least worse" way to extend "bless"?

And any RFC should probably begin with a break down of what "bless" _does_ and what it gives us, e.g.:

* associates a string package name to a trad reference
* gives runtime some hint as to where to find a method when a deref method call is made
* prepends the package name as a string to any deref method call
* enables some kind of inheritance via @ISA, UNIVERSAL::

Surely given the "little OOP system that could" we have now, there are some things that could be done seamlessly to really beef it up properly.

Perhaps in defining what it actually is, we can identify what is missing and therefore work deconstructively to what most seem to want. I do find it interesting that the limited nature of "bless" still gives enough of a feel of OOP that it still requires significant effort to argue that Perl needs a "real" one.

Cheers,
Brett

> Best,
> Ovid
> --
> IT consulting, training, specializing in Perl, databases, and agile development
> http://www.allaroundtheworld.fr/.
>
> Buy my book! - http://bit.ly/beginning_perl
Re: Not an OO RFC, take 2 [ In reply to ]
On Sunday, 20 June 2021, 17:17:54 CEST, oodler@cpan.org <mah.kitteh@protonmail.ch> wrote:

> I can't speak for p5p. But personally, I'd rather see a series of RFCs that introduce fundamental core capabilities that will come together to provide this "effective" OOP in Perl, rather than a kitchen sink take-it/leave-it approach.

As mentioned, I didn't sent an RFC. I tried to follow the suggested protocol and effectively sent a query letter. Thus, what you suggested—completely reasonably—misses the mark because I was trying to not send an entire RFC.  A change of this scope requires more than three or four terse paragraphs to do it justice. So what I really need is a "yes or no" regarding whether or not P5P would be interested in an RFC, not shooting down points which my query letter didn't propose. However, in reading what you've written, it's clear you're acting in good faith, so maybe I misunderstood the RFC process? I don't know.

That being said, as Chris pointed out, most people don't think about OOP to this level and, as you've stated, you're less familiar with it, so I realize why I've not done a great job of conveying what is needed. It's easy to preach to the choir. If you're in an entirely different religion, it's a touch harder ????

When you talk about "a series of RFCs", it sounds like what you're saying is a gradual refactoring (correct me if I'm wrong). In my opinion, this will fail on multiple fronts.
First, consider Perl signatures. They came in when? 5.20 I think? Seven years ago? Method/subroutine signatures have been best practice since before many of us were even born and we still can't get them out of experimental status? This is an embarrassment for Perl and it's one of many reasons why our company is getting contacted more and more by potential clients who are looking for "an exit strategy from Perl." How many other languages have to explain why something as fundamental as `my $foo = @_;` is broken? (that was rhetorical. Let's not get into language bashing here)

In the last four years, the number of companies contacting our company for an exit strategy from Perl has increased dramatically. I know of several large employers (that I cannot name) whose codebase is primarily Perl but are already in the process of eliminating it. This is part of the reason I wrote "rewriting the monolith." (https://dev.to/ovid/rewriting-the-monolith-part-2-2bgf) For many of our clients, it's gone from "Perl is dying" to "It's dead; we need to amputate." This was anticipated years ago, but it's happening now.

If you want to go gently into that good night, I will respect that you have a right to make that choice. Me? I will go down kicking and screaming because it didn't have to be this way. Maybe it still doesn't, but I don't know if we're too late.

A long, slow, "one feature at a time" dribble of experimental changes will be the nail in the coffin. Those changes will take *years* to get through. But I'll be retired before they do, so what do I care? (Hint: I care.)

Second, a series of refactorings implies that the current shambolic mess of Perl OO is topologically equivalent to Corinna. I do not believe that they are. In topology, you can't gradually transform a donut into a bowl, but I still know which one I'd rather eat soup out of. I concede I could be making the same "irreducible complexity" mistake that creationists make, but even if I am, I think the first point—years of slow, minor features being dribbled out to an audience who won't see the end goal—shows that it's not better to err on the side of caution.
Third, you refer to a "kitchen single take-it/leave-it approach." I apologize because that statement is my fault. I wasn't clear in my email. We have been working for many months to strip *everything* out of the MVP that we don't absolutely need. What is presented is, given the scope of what is needed, just about the smallest change we think we can make but that will still provide the needed value. We wanted to ensure that we didn't go overboard and back ourselves in a corner by offering features that we think are right, but aren't completely sure of. It's been a couple of years of acrimonious debate, but it's not been rushed.

Instead, we have something minimal enough, but powerful enough, that it's already being used in production by companies that appreciate OO and use it. https://www.reddit.com/r/perl/comments/nyuid5/were_starting_the_rfc_for_bringing_modern_oo_to/h1phg5z/)
Summary: I never wanted to say this, but I need to. Perl is dying. It's time to get off our butts and do something about this, but do it in a way that doesn't break backwards compatibility. We can be timid and let it die. Or we can be bold and have a chance. Given the companies that are seeking exit strategies for Perl, I don't believe that's a false dichotomy.

Best,Ovid
-- IT consulting, training, specializing in Perl, databases, and agile developmenthttp://www.allaroundtheworld.fr/. 
Buy my book! - http://bit.ly/beginning_perl
Re: Not an OO RFC, take 2 [ In reply to ]
Please see my comments below with the idea that I want there to be a successful RFC for OO in Perl. My thoughts are expressed below with the goal of saying something that might be helpful. I appreciate your efforts and agree Perl needs _something_ compelling in this area to offer the programming world and long time users, alike.

??????? Original Message ???????
On Sunday, June 20th, 2021 at 11:08 AM, Ovid <publiustemp-p5p3@yahoo.com> wrote:

> On Sunday, 20 June 2021, 17:17:54 CEST, oodler@cpan.org <mah.kitteh@protonmail.ch> wrote:
>
>> I can't speak for p5p. But personally, I'd rather see a series of RFCs that introduce fundamental core capabilities that will come together to provide this "effective" OOP in Perl, rather than a kitchen sink take-it/leave-it approach.
>
> As mentioned, I didn't sent an RFC. I tried to follow the suggested protocol and effectively sent a query letter. Thus, what you suggested—completely reasonably—misses the mark because I was trying to not send an entire RFC. A change of this scope requires more than three or four terse paragraphs to do it justice. So what I really need is a "yes or no" regarding whether or not P5P would be interested in an RFC, not shooting down points which my query letter didn't propose. However, in reading what you've written, it's clear you're acting in good faith, so maybe I misunderstood the RFC process? I don't know.
>
> That being said, as Chris pointed out, most people don't think about OOP to this level and, as you've stated, you're less familiar with it, so I realize why I've not done a great job of conveying what is needed. It's easy to preach to the choir. If you're in an entirely different religion, it's a touch harder ????
>
> When you talk about "a series of RFCs", it sounds like what you're saying is a gradual refactoring (correct me if I'm wrong). In my opinion, this will fail on multiple fronts.

No, I mean a comprehensive path forward with an end in mind; only starting from what we have now to something that brings us to the general benefits most turn to OOP for,

* extensibility
* inheritence, composability (i.e., intelligently managing/define @ISA)
* data encapsulation, protection

> First, consider Perl signatures. They came in when? 5.20 I think? Seven years ago? Method/subroutine signatures have been best practice since before many of us were even born and we still can't get them out of experimental status? This is an embarrassment for Perl and it's one of many reasons why our company is getting contacted more and more by potential clients who are looking for "an exit strategy from Perl." How many other languages have to explain why something as fundamental as `my $foo = @_;` is broken? (that was rhetorical. Let's not get into language bashing here)

I understand what you're saying here. I see this more as a procedural failure or lack of technical leadership than an issue with the merits of the feature. As of late, this seems to be changing and I am highly encouraged by this RFC process still in its infancy. Lack of leadership is more than just embarrasing, it's extremely dangerous.

> In the last four years, the number of companies contacting our company for an exit strategy from Perl has increased dramatically. I know of several large employers (that I cannot name) whose codebase is primarily Perl but are already in the process of eliminating it. This is part of the reason I wrote "rewriting the monolith." (https://dev.to/ovid/rewriting-the-monolith-part-2-2bgf) For many of our clients, it's gone from "Perl is dying" to "It's dead; we need to amputate." This was anticipated years ago, but it's happening now.

I suspect this is happening where I work as well, though since I identify as a Perl programmer, that just means I need to move on if it's clear that I'd be put in the position to learn something else. That's my decision but one I've already made, in principle. Maybe Perl needs it's own #rideordie hashtag. OOP is not going to save it nor is parity with other languages that are all starting to look the same. Hence my reference to the "counter cultural".

> If you want to go gently into that good night, I will respect that you have a right to make that choice. Me? I will go down kicking and screaming because it didn't have to be this way. Maybe it still doesn't, but I don't know if we're too late.

Does it look like I am being passive? Perl can't "die" (I mean in the literal sense) and it won't die. But's what's worse to me is a loss of its soul or identity. If Perl "lives" but becomes indistinguishable from something else, to me that's worst than it "dying". That said, I want this effort to succeed. There's definitely value in it. I just want perl to be recognizable after.

> A long, slow, "one feature at a time" dribble of experimental changes will be the nail in the coffin. Those changes will take *years* to get through. But I'll be retired before they do, so what do I care? (Hint: I care.)

It is clear you care. I suppose what I am suggesting is, can we start with addressing the insufficiency of "bless"? It is necessary in what it does, but not sufficient - so in the list of "OOP things we need" how far does "bless" take us? What is missing that "bless" _should_ do; what things in the "OOP things we want list" does bless not address and are not at all appropriate for it to handle? That's what I mean "incremental".

So what do we want:

* more intelligent composition (@ISA) [notable this also requires a 'signatures' component for dispatch/polymorphism]
* better "introspection"
* data encapsulation

What else?

As I said, my fear is not this "death" of Perl but the undeath. Moose/moo already created this weird schism with its DSL and runtime MOP framework. It also begat some weird ways to handle composition that seemed orthogonal to not only Perl, but Moose/moo itself. In practice it also made testing a nightmare.

The proof that it enabled a whole slew of cool things is a clear indicator to me that this kind of thing is wanted. How it did it and the way it fundamentally caused people to think differently far removed for traditional perl/Perl is what has always concerned me about it. What can be done to get the best of both worlds? My suggestions above are just some attempts to figure this out.

> Second, a series of refactorings implies that the current shambolic mess of Perl OO is topologically equivalent to Corinna. I do not believe that they are. In topology, you can't gradually transform a donut into a bowl, but I still know which one I'd rather eat soup out of. I concede I could be making the same "irreducible complexity" mistake that creationists make, but even if I am, I think the first point—years of slow, minor features being dribbled out to an audience who won't see the end goal—shows that it's not better to err on the side of caution.

What would it take for us to go from "bless" to Corinna?

Maybe a good MVP would be, for example, the introduction of the keyword "class" that is has a well defined behavior defined in terms of "bless", "package", and "parent". "class" would be constrained by the current vision of Corinna, as well. I am not so naive as to suggest "let's implement class then see where we're at". I am suggesting, "is there a way to implement 'class' that is a natural progression from package/bless/parent and a singular step forward?" Furthermore, does it allow us a path forward to the other "general" goals? Or something that would represent a huge improvement and opening up of options - all from a single "class" keyword.

For example, I should be able to replace the "bless" keyword with "class" with little or no changes; but with now a with a way to be even more perlish about the OOP module I am presenting.

> Third, you refer to a "kitchen single take-it/leave-it approach." I apologize because that statement is my fault. I wasn't clear in my email. We have been working for many months to strip *everything* out of the MVP that we don't absolutely need. What is presented is, given the scope of what is needed, just about the smallest change we think we can make but that will still provide the needed value. We wanted to ensure that we didn't go overboard and back ourselves in a corner by offering features that we think are right, but aren't completely sure of. It's been a couple of years of acrimonious debate, but it's not been rushed.
>
> Instead, we have something minimal enough, but powerful enough, that it's already being used in production by companies that appreciate OO and use it. https://www.reddit.com/r/perl/comments/nyuid5/were_starting_the_rfc_for_bringing_modern_oo_to/h1phg5z/)

I am not on reddit. I'll check this out.

> Summary: I never wanted to say this, but I need to. Perl is dying. It's time to get off our butts and do something about this, but do it in a way that doesn't break backwards compatibility. We can be timid and let it die. Or we can be bold and have a chance. Given the companies that are seeking exit strategies for Perl, I don't believe that's a false dichotomy.

I said above what I thought about this. I would suggest that things be named as clearly as possible. None of the OOP solutions in perl use clear names:

* bless
* Moose
* Util::H2O
* Zydaco
* Co/Corinna
* Object::Pad

I think focusing on proving a more sufficiently power "bless" using the keyword "class" would allow sever things; but most importantly focused discussion around defining what the "means" as a standalone capability. And once this is well defined (again, in terms of bless, etc); then I think you'll find a lot of support.

The other part I think I am trying to balance is this fickle line you're walking. Go too far in one direction, and you'll find yourself with a new language an community. I don't say this to be sarcastic, I say this because "perl" will show you the way if you keep your ear to the ground and hands on the grind stone. This has happened time and again; it's about time we recognize it and try to work _with_ this dynamic.

Cheers,
Brett

> Best,
> Ovid
> --
> IT consulting, training, specializing in Perl, databases, and agile development
> http://www.allaroundtheworld.fr/.
>
> Buy my book! - http://bit.ly/beginning_perl
Re: Not an OO RFC, take 2 [ In reply to ]
Please tell us what orthogonal features (like bless, __AUTOLOAD__) should
be added to the base language so that CPAN developers are no longer hobbled
and can, instead, continue the good work they have so nobly begun?


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

> Responding to earlier comments, here's an even more terse version:
>
> We need an effective OO system in the Perl core. bless is not an effective
> OO system. With 80+ OO "variants" on the CPAN, and with even the best of
> them hobbled due to limitations in the Perl language itself, it's time to
> rectify that. Corinna is a large effort with input from many top-notch Perl
> devs on what an effective OO system would look like.
>
> Would P5P be receptive to an RFC?
>
> Best,
> Ovid
> --
> IT consulting, training, specializing in Perl, databases, and agile
> development
> http://www.allaroundtheworld.fr/.
>
> Buy my book! - http://bit.ly/beginning_perl
>
Re: Not an OO RFC, take 2 [ In reply to ]
On Sunday, 20 June 2021, 19:30:08 CEST, mah.kitteh via perl5-porters <perl5-porters@perl.org> wrote:

mah.kitteh wrote:
> I am suggesting, "is there a way to implement 'class' that is a natural progression from package/bless/parent and a singular step forward?"

I'm skipping all the rest because this one question distills everything.
Do you know why high-risk Hail Mary passes are thrown in American football? Either you're near the end of the game and you have  nothing to lose, or it's in a game with an opponent so dominating that you know you can't win otherwise.
We can go ahead and be timid. Or we can take a chance at doing something good. Perl's dying. I've tried to avoid saying that for years, but I can't do that any longer. Too many companies are asking us "how do we get rid of Perl?"

We've been timid for a long, long time. Much of that is because we're afraid of saying it out loud. Much of that is because we don't have as many core developers involved. Much of that is because we don't want people attacking us for saying the emperor has no clothes. I'm done with that.

I have no interest in arguments from timidity. The emperor has no clothes.

A while ago, I was offered a job as a senior Python dev. It was paying less than half of what I typically charge. I was offended. I was tempted. I said "no." Please don't tell me I made a mistake.
Effective OOP isn't going to save Perl, any more than a single bullet in a gun will win a war. But it's a bullet we need.
Best,Ovid
-- IT consulting, training, specializing in Perl, databases, and agile developmenthttp://www.allaroundtheworld.fr/. 
Buy my book! - http://bit.ly/beginning_perl
Re: Not an OO RFC, take 2 [ In reply to ]
On 2021-06-20 8:17 a.m., mah.kitteh via perl5-porters wrote:
> I'd rather see a series of RFCs that
> introduce fundamental core capabilities that will come together to provide this
> "effective" OOP in Perl, rather than a kitchen sink take-it/leave-it approach.

That is ALREADY what is happening.

Corinna v1 is the first small chunk. It may have several parts but those parts
are a holistic collection.

Lots of things that could have been included are formally being left to later
for Corinna v2 etc, such as support for types.

You are suggesting that the already very minimal Corinna v1 proposal can be
split up into independent parts.

It is possible that it could be reduced a bit more but I feel at this point it
is already minimal and stripping it much more won't do anyone any good, that a
lot of the remaining aspects don't make sense except as a part of the whole.

-- Darren Duncan
Re: Not an OO RFC, take 2 [ In reply to ]
On Sun, 20 Jun 2021 15:17:51 +0000
"mah.kitteh via perl5-porters" <perl5-porters@perl.org> wrote:

> This is one reason things fail around here, the idea that prometheus
> is just going to show up and give us the answer. I've never seen that
> happen here, or anywhere.

FYI, this feature has already been ~90% implemented. It's my
Object::Pad CPAN module:

https://metacpan.org/pod/Object::Pad

That has about a 90% overlap with what we propose to put in core.

And sure, it's not in core yet, it's a CPAN module. But that doesn't
matter.

Remember when I added try/catch to core? That was a CPAN module
(Syntax::Keyword::Try) for a number of years, experimenting with
syntax, ideas, implementation, all sorts. When I finally decided to
move it into core it took me 3 days.

3 days.

That was all it took *because* that CPAN module already existed. All I
had to do was copy-paste a bunch of code, and reword a few bits and
pieces to make it fit better as a true core feature.

I feel that an object system is a little bigger than exceptional
control-flow, so I would suggest a couple of weeks to migrate that, but
that's all. If you told me, right now, "migrate the Object::Pad system
into core", I reckon I could have that done in two weeks.


So two requests. Firstly: Please lets not get hung up on "but it'll
take years to implement". Yes, a feature of this size does take years
to implement. But luckily I started it back in October 2019, so...
that's nearly two years ago now. I think it's mostly ready.

Secondly: You can already use it - right now - in production if you
like. I have already been using it for most of the new code I write,
along with converting a whole heap of my existing CPAN modules to using
it. Take a look at the reverse-depends list:

https://metacpan.org/module/Object::Pad/requires?size=500

Try it yourself. Experiment with it. See how it actually feels in
practice to use it. That sort of thing gives you so much more insight
than just arguing in the abstract about a spec on paper. That's why I
wrote it.

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: Not an OO RFC, take 2 [ In reply to ]
I'll try to be a bit less prosaic this time and leave the literary
criticism behind. Maybe.

Taking a cue from Nicholas, I've re-organized your email to make my reply
more coherent. You basically ask the same question several different ways
because (I assume) you think there's a communication error on your part ... I'm
pretty sure the communication error is coming from us (or me).

Also you describe yourself as a Perl programmer willing to change jobs
before learning
another language so I'm going to assume (possibly wrongly) you don't
have a lot of
experience with many object systems other than the plethora Perl has built on
it's primitives. If this is true, you're working at a disadvantage.
Perl's simplicity warps
the conversation around the primitives in OO.

On Sun, Jun 20, 2021 at 1:30 PM mah.kitteh via perl5-porters
<perl5-porters@perl.org> wrote:

Let's clear the easiest issue out of the way first:

> I thought about this. I would suggest that things be named as clearly as possible. None of the OOP solutions in perl use clear names:
>
> * bless
> * Moose
> * Util::H2O
> * Zydaco
> * Co/Corinna
> * Object::Pad

The proposal is for this to be named `use feature 'class'`. I can't
think how that could be clarified, but I think we all welcome suggestions.

Now to the real discussion.

> What would it take for us to go from "bless" to Corinna?

The conceptual framework behind bless + packages starts from a fundamentally
different place than Corinna. Corinna starts with objects as primitives, not
hashrefs and packages. You can't get there from here.

>
> It is clear you care. I suppose what I am suggesting is, can we start with addressing the insufficiency of "bless"? It is necessary in what it does, but not sufficient - so in the list of "OOP things we need" how far does "bless" take us? What is missing that "bless" _should_ do; what things in the "OOP things we want list" does bless not address and are not at all appropriate for it to handle? That's what I mean "incremental".
>
> So what do we want:
>
> * more intelligent composition (@ISA) [notable this also requires a 'signatures' component for dispatch/polymorphism]
> * better "introspection"
> * data encapsulation
>
> What else?

While Perl's primitives can emulate a multitude of different systems ...
they're all going to have the same fundamental flaws because they can only be
assembled the same ways. Much the way a cake is more than butter, eggs, sugar,
and flour; an object is a discrete synergy beyond the sum of its parts. Perl
is a stewpot of many different flavors, but it simply cannot bake.

If you prefer an architectural metaphor: we're asking for prairie style housing,
and you're saying how do we build that out of slabs of concrete?

> Maybe a good MVP would be, for example, the introduction of the keyword "class" that is has a well defined behavior defined in terms of "bless", "package", and "parent". "class" would be constrained by the current vision of Corinna, as well. I am not so naive as to suggest "let's implement class then see where we're at". I am suggesting, "is there a way to implement 'class' that is a natural progression from package/bless/parent and a singular step forward?" Furthermore, does it allow us a path forward to the other "general" goals? Or something that would represent a huge improvement and opening up of options - all from a single "class" keyword.

> What can be done to get the best of both worlds?

I'm pretty convinced you cannot have both, because the existing tooling in Perl
is not fit for purpose. Perl has no concept of Records[1], or user-defined data
structures. Perl has five (or seventeen if you read perlapi) kinds of data
structure that can be blessed into an object. Those are the only kinds you can
have.

In my opinion the next natural step from Perl's current object model is to
make Objects a primitive in the language, and Classes as a new type of block to
describe them. The `class` keyword simply cannot be a new kind of `bless`
because it has no relationship to the old kind of `bless`. It's more like a new
kind of `package`, which makes some sense and is probably the logic Larry (or
whomever) used when they decided packages could stand in for classes when Perl
5.000 was being designed.

But `class` also defines a Record, something `package` doesn't do. Nothing in
Perl really does; which is fair a lot of dynamic languages don't bother because
Most, like Perl, have hashes as primitive data structures.

You could argue that the concept of a Record is not Perlish. That might be a
correct argument. I'm not sure either of us gets to be the final arbiter of
that argument.

> I think focusing on proving a more sufficiently power "bless" using the keyword "class" would allow sever things; but most importantly focused discussion around defining what the "means" as a standalone capability. And once this is well defined (again, in terms of bless, etc); then I think you'll find a lot of support.

You're welcome to think that, but it's a fundamentally different discussion
than the one Corinna is having. The problem isn't that `bless` isn't powerful
enough, the problem is that Perl lacks the right primitives.

That's the starting point in the discussion of Corinna. That's the irreducible
piece that if you throw out everything else we still would need to discuss.
Even if you strip away everything else from Corinna you still need something
like (with apologies to John Harper[2]):
```
package LasersAndFeelings;

use strict;
use warnings;
use experimental 'class';
use experiemntal 'signatures';

use Games::Dice 'roll';

class Character {

has $style;
has $role;
has $number;

sub new($class, $s, $r) {
$style = $s;
$roll = $r;
$number = roll '1d4+1';

return bless(__INSTANCE__, $class);
}

sub attempt_move($s, $num_dice=1) {
my $dice = [roll '1d6' x $num_dice];
my $count = scalar grep { $_ > $number } $dice->@*;
for ($count) {
if ($count == $number) { return 'LASER FEELIGNS' } # !!!
if (0) { return 'FAIL' } # critical fail
if (1) { return 'PARTIAL'} # complication
if (2) { return 'SUCCESS' } # everything's fine
if (3) { return 'BOON' } # critical success!
}
}
}

```
The bare minimum is a new kind of scope, a new kind of state, and a new kind of
reference to hold it.

(You might be asking about the `__INSTANCE__` that I've suddenly thrown in, no
it is not part of the Corinna proposal. Perl only has one kind of native object
construction protocol, `bless`, that takes a reference and a package name. Since
this is a new kind of reference I need some mechanism to access it, this
seemed the most straight forward.)

This is much more stripped down than the Corinna proposal because Curtis was
worried he needed to have feature parity with Moo/se otherwise people wouldn't
adopt the new system. In this discussion we don't seem to care about adoption
just the primitives that we can iterate on later, so I threw out everything but
what I saw as the bare minimum for classes and object primitives.

This is a good starting place though. Actually, no. The biggest lesson from
Moo/se was: There will always have a metaobject protocol, some places are lucky
that the protocol is formally defined and well documented. Whatever we build
needs to acknowledge this.

> As I said, my fear is not this "death" of Perl but the undeath. Moose/moo already created this weird schism with its DSL and runtime MOP framework. It also begat some weird ways to handle composition that seemed orthogonal to not only Perl, but Moose/moo itself. In practice it also made testing a nightmare.
>

I kinda need a [citation needed] here, I've been using Moo/se since 2007 in my
own projects and with a large number of other people and I've not found
testing anymore difficult. In some regards it's simpler because there's a
whole class of behavior I know is already tested for me (instantiation,
accessors, etc.).

Finally since there is a lot of yelling about the Elephant in the Room: Perl's
relative market share isn't a problem for perl5-porters. It's not a problem
perl5-porters can or should attempt to solve. A new object system with real
primitives won't give Perl the boost it needs to attract new developers.
Too many people remember 1999 Perl. After two decades of defending it,
I now believe
Perl's existing object system is a shambles and makes writing clean
scalable code
more difficult than it should be. We need to take the lessons we have
learned from Moo/se
and others and improve upon them. That's a problem perl5-porters can solve.

[1]: https://en.wikipedia.org/wiki/Record_(computer_science)
[2]: https://johnharper.itch.io/lasers-feelings
Re: Not an OO RFC, take 2 [ In reply to ]
Ovid

I feel a strong anxiety about you.

Are you afraid of Perl's death?
Re: Not an OO RFC, take 2 [ In reply to ]
On Mon, 21 Jun 2021 at 08:01, Chris Prather <chris@prather.org> wrote:

> On Sun, Jun 20, 2021 at 1:30 PM mah.kitteh via perl5-porters
> > I think focusing on proving a more sufficiently power "bless" using the
> keyword "class" would allow sever things; but most importantly focused
> discussion around defining what the "means" as a standalone capability. And
> once this is well defined (again, in terms of bless, etc); then I think
> you'll find a lot of support.
>
> You're welcome to think that, but it's a fundamentally different discussion
> than the one Corinna is having. The problem isn't that `bless` isn't
> powerful
> enough, the problem is that Perl lacks the right primitives.
>
> That's the starting point in the discussion of Corinna. That's the
> irreducible
> piece that if you throw out everything else we still would need to discuss.
>

Interesting as this suggestion is, I don't think this can be called an
irreducible piece at all - Object::Pad already exists without inventing
these primitives, and has the advantage of being compatible with existing
classes.

What you're proposing seems to be a parallel, *incompatible* class
implementation? If so, I don't see how that would be feasible.
Re: Not an OO RFC, take 2 [ In reply to ]
On Sun, Jun 20, 2021 at 8:35 PM Tom Molesworth <tom@deriv.com> wrote:
>
> Interesting as this suggestion is, I don't think this can be called an irreducible piece at all - Object::Pad already exists without inventing these primitives, and has the advantage of being compatible with existing classes.
>
> What you're proposing seems to be a parallel, *incompatible* class implementation? If so, I don't see how that would be feasible.
>

If that's what I'm proposing, I think I have company:

"[...] Corinna classses cannot inherit from non-Corinna classes due to
difficulties with establishing the base class (UNIVERSAL or
UNIVERSAL::Corinna?)."[1]

"There are a number of details specific to the case of deriving an
Object::Pad class from an existing classic Perl class that is not
implemented using Object::Pad."[2]

Discussing the feasibility is, I believe, why this thread exists.

I'm possibly wrong, reading XS is not my strong suit, but this appears
to be at least close to what Object::Pad does in practice. Instead of
a custom sv_type (can you make a custom sv_type from XS?), Paul is
blessing a AV ref by default and allowing the user to declare a
representation of a HV ref or an AV using magic for the representation
of slot data as a pad for lexicals within the scope of the class
block. Implementation-wise, yes it's reusing natives at the XS layer
to implement new natives at the Perl layer. So at the conceptual level
this is *exactly* what Object::Pad is doing .. at least as far as I
understand things.

From the docs for Object::Pad:

"Behaves similarly to the package keyword, but provides a package that
defines a new class. Such a class provides an automatic constructor
method called new."

"As with package, an optional block may be provided. If so, the
contents of that block define the new class and the preceding package
continues afterwards. If not, it sets the class as the package context
of following keywords and definitions."

"As with package, an optional version declaration may be given. If so,
this sets the value of the package's $VERSION variable."

Paul is documenting a class as something conceptually distinct from a
package. When it comes to Objects no where does Paul document that
`use Object::Pad; class Foo { has $bar = 1; } say for
Foo->new()->[0];` is expected to work. He explicitly says the opposite
in fact:

"This is an opaque representation type whose contents are not
specified. It only works for classes whose entire inheritence
hierarchy is built only from classes based on Object::Pad."

It seems to me that the fact that it happens to work is a side effect
of the implementation. An opaque representation whose contents are not
specified explicitly isn't an AV ref.

Maybe I have this all wrong. I was basing the ideas I've written in
this thread on the discussions surrounding Object::Pad and Corinna's
development (and on wikipedia's description of metamodernism). So if
I'm that far off I'd love for someone to set me straight.

From where we started, I really would hope that the process of the RFC
helps point to a better implementation than Object::Pad and Corinna's
current expectations. I would love to have these new classes and
instances be able to inherit seamlessly from the existing Perl object
system. There are a number of technical hurdles surrounding that
implementation that are challenging at best, and aren't at all
relevant to the question of: is this even a reasonable goal?

-Chris

[1]: https://github.com/Ovid/Cor/wiki/Corinna-Overview
[2]: https://metacpan.org/pod/Object::Pad#SUBCLASSING-CLASSIC-PERL-CLASSES
Re: Not an OO RFC, take 2 [ In reply to ]
On Mon, 21 Jun 2021 at 10:02, Chris Prather <chris@prather.org> wrote:

> On Sun, Jun 20, 2021 at 8:35 PM Tom Molesworth <tom@deriv.com> wrote:
> >
> > Interesting as this suggestion is, I don't think this can be called an
> irreducible piece at all - Object::Pad already exists without inventing
> these primitives, and has the advantage of being compatible with existing
> classes.
> >
> > What you're proposing seems to be a parallel, *incompatible* class
> implementation? If so, I don't see how that would be feasible.
> >
>
> If that's what I'm proposing, I think I have company:
>
> "[...] Corinna classses cannot inherit from non-Corinna classes due to
> difficulties with establishing the base class (UNIVERSAL or
> UNIVERSAL::Corinna?)."[1]
>

If Corinna does take that route, I believe it would be a big mistake....


> "There are a number of details specific to the case of deriving an
> Object::Pad class from an existing classic Perl class that is not
> implemented using Object::Pad."[2]
>

... so the wording there could be improved, but fortunately Object::Pad
inheriting from other classes already works. :repr(HASH) is applied
automatically when extending a hashref-based class, for example.

We're actively using this in both directions - lots of Object::Pad-based
code inheriting from IO::Async::Notifier, for example, and in the other
direction there's plain hashref-based OO inheriting from Tickit::Widget
Object::Pad OO which inherits from plain hashref OO again - see
https://metacpan.org/module/Tickit::Widget::VBox/requires for examples.

Method resolution, sub injection plus the usual features such as `->can()`
and `->DOES` Just Work already - so far I've found that the existing
Object::Pad implementation is quite effectively cross-compatible with plain
OO.

It's probable that large parts of the core implementation would be based on
this, so I'd hope that this level of compatibility is preserved. If not,
that'd be a much harder sell for anyone who has any existing code.


> Paul is documenting a class as something conceptually distinct from a
> package. When it comes to Objects no where does Paul document that
> `use Object::Pad; class Foo { has $bar = 1; } say for
> Foo->new()->[0];` is expected to work. He explicitly says the opposite
> in fact:
>
> "This is an opaque representation type whose contents are not
> specified. It only works for classes whose entire inheritence
> hierarchy is built only from classes based on Object::Pad."
>
> It seems to me that the fact that it happens to work is a side effect
> of the implementation. An opaque representation whose contents are not
> specified explicitly isn't an AV ref.
>

Right - but most classes provide few guarantees about internals. The
guarantees for classes that are intended for inheritance are typically not
much more than "it's a hashref"; the keys could change or someone could
decide that it's time to revisit inside-out objects again. You could say
the same about `->{key}` for any of those: unless explicitly documented,
it's a side effect of the implementation. There are other classes which use
blessed arrayrefs, coderefs, scalar refs or other types... each class has
its own implementation details for that data.

The guarantees are around things like blessed() providing the class name,
ref() returning true, methods available via ->method_name, ability to check
for presence of a method via ->can($method_name)... I'd expect all of these
to be preserved.
Re: Not an OO RFC, take 2 [ In reply to ]
> On Jun 20, 2021, at 10:37 PM, Tom Molesworth <tom@binary.com> wrote:
>

[…]
> Right - but most classes provide few guarantees about internals. The guarantees for classes that are intended for inheritance are typically not much more than "it's a hashref"; the keys could change or someone could decide that it's time to revisit inside-out objects again. You could say the same about `->{key}` for any of those: unless explicitly documented, it's a side effect of the implementation. There are other classes which use blessed arrayrefs, coderefs, scalar refs or other types... each class has its own implementation details for that data.
>
> The guarantees are around things like blessed() providing the class name, ref() returning true, methods available via ->method_name, ability to check for presence of a method via ->can($method_name)... I'd expect all of these to be preserved.
>

Yeah y’all have done an excellent job with Object::Pad. I think we are in vigorous agreement from different ends of the elephant.

My point is that from the conceptual level we need to have a new Object primitive that encourage the opacity of the instance representation. The current OO system in Perl encourages the opposite in my experience.

That we need a new scope primitive that focuses on the aggregation of data as well as behavior, rather than the current package primitive that focuses on the aggregation of behavior (even though I was reminded that packages are in-fact all state and the behavior is just a special kind of state).

Object::Pad does both of these. And based on what Paul said elsewhere in this thread, the plan is to use Object::Pad as the start for implementation. I think there are some edges that need polishing … the array ref shouldn’t be exposed for example. I’d like to see an expansion of the MOP too.

-Chris
Re: Not an OO RFC, take 2 [ In reply to ]
??????? Original Message ???????
On Sunday, June 20th, 2021 at 2:11 PM, Ovid <publiustemp-p5p3@yahoo.com> wrote:

> On Sunday, 20 June 2021, 19:30:08 CEST, mah.kitteh via perl5-porters <perl5-porters@perl.org> wrote:
>
> mah.kitteh wrote:
>
>> I am suggesting, "is there a way to implement 'class' that is a natural progression from package/bless/parent and a singular step forward?"
>
> I'm skipping all the rest because this one question distills everything.
>
> Do you know why high-risk Hail Mary passes are thrown in American football? Either you're near the end of the game and you have nothing to lose, or it's in a game with an opponent so dominating that you know you can't win otherwise.

Sportsball analogies are not lost on me, but usually said Hail Mary results in an incomplete pass or worse, an interception. Or *even* worse a "pick six" - where the opponent intercepts and scores to add insult to injury. But if you're interested in "miracle endings" you should check out the Auburn/Alabama game played on November 30, 2013. If you're a Bama fan, it didn't end so well. But the same can be said of "on side kicks". Unless you're the 2009 New Orleans Saints and decide to open the second half of the Super Bowl against a strongly favored Indianopolis Colts with such a kick. One was an improbably outcome at the end, one was simply "unexpected" and caught them offguard - and they never recovered.

In any case, i don't share the view we're at the "end game". It does seem like a time to act.

> We can go ahead and be timid. Or we can take a chance at doing something good. Perl's dying. I've tried to avoid saying that for years, but I can't do that any longer. Too many companies are asking us "how do we get rid of Perl?"

I get it. I like the zeal.

> We've been timid for a long, long time. Much of that is because we're afraid of saying it out loud. Much of that is because we don't have as many core developers involved. Much of that is because we don't want people attacking us for saying the emperor has no clothes. I'm done with that.

Good for you :) (I mean that sincerely, I am not being sarcastic).

> I have no interest in arguments from timidity. The emperor has no clothes.
>
> A while ago, I was offered a job as a senior Python dev. It was paying less than half of what I typically charge. I was offended. I was tempted. I said "no." Please don't tell me I made a mistake.
>
> Effective OOP isn't going to save Perl, any more than a single bullet in a gun will win a war. But it's a bullet we need.

I agree, and I am not arguing against this. But since we're speaking in more analogies I know a little about; I can say that both hesitation and rash action can lead to bad and unintended consequences.

So to be clear, I empathize deeply with you. But I do not share your anxiety. This is to say nothing about the actual topic of this thread. It'll all be okay. And like I said some regular Hail Marys or "Moon Shots" as Google/Alphabet I think calls them may be part of a good long term strategy.

What does that mean? You're testing the waters to send just a pre-RFC. It's like a pre-pre-RFC so it's hard to figure out where we are in the process. As Nike says, "just do it!" - I do thing that this would be a good time to call for "organized" feedback. Clearly certain topics can go off the rails quickly.

Cheers,
Brett

> Best,
> Ovid
> --
> IT consulting, training, specializing in Perl, databases, and agile development
> http://www.allaroundtheworld.fr/.
>
> Buy my book! - http://bit.ly/beginning_perl
Re: Not an OO RFC, take 2 [ In reply to ]
Thank you, Chris.

This is the kind of well done opion I'd love to see come forth and collected during an official RFC period.

..rest inline.

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

On Sunday, June 20th, 2021 at 7:00 PM, Chris Prather <chris@prather.org> wrote:

> I'll try to be a bit less prosaic this time and leave the literary
>
> criticism behind. Maybe.
>
> Taking a cue from Nicholas, I've re-organized your email to make my reply
>
> more coherent. You basically ask the same question several different ways

Np, I've <snip>'d about 90% of your email. We do what we have to do.

>
> because (I assume) you think there's a communication error on your part ... I'm
>
> pretty sure the communication error is coming from us (or me).
>
> Also you describe yourself as a Perl programmer willing to change jobs
>
> before learning
>
> another language so I'm going to assume (possibly wrongly) you don't
>
> have a lot of
>
> experience with many object systems other than the plethora Perl has built on
>
> it's primitives. If this is true, you're working at a disadvantage.
>
> Perl's simplicity warps
>
> the conversation around the primitives in OO.

I'd leave the assumptions to things you know or have observed directly. I mean, how do you know I don't have a tremendous amount of experience with OOP Fortran and was really sad when it was no longer supported [1]? I don't have this experience, but I did know it was tried and is no longer supported. I am not saddened by this, though.

It is true I can repeat myself, especially when I feel like I'm talking to a wall. You replies are appreciated. I might write a lot less if I observed more thoughtful and higher quality discussions around here. But that's part of the intent of me suggesting we nurture this as part of the RFC process.

>
> On Sun, Jun 20, 2021 at 1:30 PM mah.kitteh via perl5-porters
>
> perl5-porters@perl.org wrote:
>
> Let's clear the easiest issue out of the way first:
>
> > I thought about this. I would suggest that things be named as clearly as possible. None of the OOP solutions in perl use clear names:

<snip>

> The proposal is for this to be named `use feature 'class'`. I can't
>
> think how that could be clarified, but I think we all welcome suggestions.

I guess I am confused. All I know about is a pre-pre-RFC. Pardon me if I missed this along the way. I am still trying to wrap my head around Cor, Corinna, and Object::Pad. I just recently stopped confusing Rakudo with PUGs.

>
> Now to the real discussion.

<snip>

Thank you for all the content you snipped. That indeed was a real discussion! I have read through it and will likely continue to study it more over RFC period.

> I kinda need a [citation needed] here, I've been using Moo/se since 2007 in my

I've seen some untestable sh*t in my day; for some reason untestable sh*t written using a MOP is worse than when it's not. Is that good enough? :-)

Cheers,
Brett

1. https://en.wikipedia.org/wiki/Fortran#Specific_variants
Re: Not an OO RFC, take 2 [ In reply to ]
On Monday, 21 June 2021, 02:34:10 CEST, Yuki Kimoto <kimoto.yuki@gmail.com> wrote:
> Ovid>
> I feel a strong anxiety about you.
>
> Are you afraid of Perl's death?
More and more we get companies contacting us who are actively purging all Perl from their code bases. Some are well-known companies, some are small, but it's happening widely. Perl is dying. Oh, it will still be around in 20 years time, but at the current rate, it will be some obscure little hobby, maybe running a few legacy Linux tools that we've mostly forgotten about, and it will move on from being your grandparent's language to your great-grandparent's language. 2040: "Perl? Yeah, I heard about it. Does that even compile any more?" Perl will be a curiosity in a technology museum.
Now, I don't want to relitigate the past—that would reopen too many wounds—but we've known about this mess since 2000. That's 21 years ago.

Recently, on a Facebook Perl group, someone asked (paraphrasing) about how bad a programmer you would have to be if you can't figure out `my ($foo,$bar) = @_;`.
Yeah, so @_ is a wart. Signatures are so useful that I've plenty of clients using them in production systems now. But we still can't have them.
`bless` seems kinda useful, though painful. Another small wart on the language.
People see things like Foo::->bar() and wonder what the heck is that ugliness?
And I must be a rubbish programmer because after decades of working with Perl, I still forget how to get a slice of a hash reference. It's easy, I know. But I forget it.
Calling a function with a leading a ampersand is allowed, but ask the average user what's the difference between &function and &function()? More warts, and pretty important ones.
wantarray and context. Ugh.

SUPER is bound at compile-time and we're stuck with that. Decades of the SUPER bug hanging around our necks.

We have threads, but we're told not to use them. People still do and then stuff breaks.

And we don't get used to nice techniques like inversion of control because we're so used to ignoring encapsulation and using abominations like Sub::Override (I wrote that). It seems that very few people in Perl really "get" OO and developers who get OO probably won't reach for that write-only language we love.

Not one of those things is a language killer in and of itself. All them piled on top of one another, along with many, many other things we could cover, along with a rabid community of users who revel in writing arcane code, means that Perl is not a welcoming language.
But we are stuck with that and we can't break existing code. So where do we want to go from here and how do we get there? Corinna isn't the answer. But I think it (or something like it) is a huge part of the answer.
We have try/catch now. We need exceptions.
We need asynchrony.
We need signatures (damn it!)

We need the beginning of a type system—something useful for humans, not just computers. UInt is great for optimization the sofware, but creating a "Celsius" type for a weather app is great for optimizing the wetware.

We need so many things it's not even funny, but we're not going to get to them unless we change our mindset. Perl 7 was a brilliant idea. This RFC process is also brilliant. There are many more things needed, but this is a good start.
I worked years on Corinna and her design. I opened up the process and had many other people help. That was humbling, seeing all of the mistakes I made, but it's made Corinna even better. I've poured through arcane programming languages, seeing how they handle some of the issues we face. I've read books on OO programming best practices (and find myself envying Java at times). I've juggled various ideas, wrote software to help explore some thoughts, stripped out everything I could to distill a viable MVP. And in various forums (not here, thank goodness), I still keep running into people saying "bless" is all you need!

So that's what's bugging me.
Best,Ovid
-- IT consulting, training, specializing in Perl, databases, and agile developmenthttp://www.allaroundtheworld.fr/. 
Buy my book! - http://bit.ly/beginning_perl
Re: Not an OO RFC, take 2 [ In reply to ]
Ovid

Is it possible to focus on the good points of Perl?

Perl is a very good language.

Hmm, there are some things that are a little lacking.

How about a constructive and short conversation?

Like when we meet face to face.
Re: Not an OO RFC, take 2 [ In reply to ]
On Monday, 21 June 2021, 02:01:17 CEST, Chris Prather <chris@prather.org> wrote:
>
> That's the starting point in the discussion of Corinna. That's the irreducible
> piece that if you throw out everything else we still would need to discuss.
> Even if you strip away everything else from Corinna you still need something
> like (with apologies to John Harper[2]):
> ```
> package LasersAndFeelings;
>
> use strict;
> use warnings;
> use experimental 'class';
> use experiemntal 'signatures';
>
> use Games::Dice 'roll';
>
> class Character {
>
>     has $style;
>     has $role;
>     has $number;
>
>     sub new($class, $s, $r) {
>       $style = $s;
>       $roll = $r;
>       $number = roll '1d4+1';
>
>       return bless(__INSTANCE__, $class);
>     }
>
>     sub attempt_move($s, $num_dice=1) {
>         my $dice = [roll '1d6' x $num_dice];
>         my $count = scalar grep { $_ > $number } $dice->@*;
>         for ($count) {
>             if ($count == $number) { return 'LASER FEELIGNS' } # !!!
>             if (0) { return 'FAIL' }  # critical fail
>             if (1) { return 'PARTIAL'} # complication
>             if (2) { return 'SUCCESS' } # everything's fine
>             if (3) { return 'BOON' } # critical success!
>         }
>     }
> }
>
> ```
> The bare minimum is a new kind of scope, a new kind of state, and a new kind of
> reference to hold it.

I've seen you write `sub new ...` a couple of times an even more stripped-down version of Corinna. When I was ripping things out for the MVP, I found myself asking a few questions.

- How do we get the behavior I'm removing?
- Can we safely add the behavior back after the MVP?

Your constructor is a great example of something we shouldn't do, for two reasons. If you read the construction detail (pseudo-code at https://gist.github.com/Ovid/accb0c7c8444bdd150b5c7509809477f), you see that superclass constructors are called for you, as they should be. The variable assignment is done for you, as it should be. These are extremely important design goals because anything the language can do safely, it should. Perl devs should stop needing to wire things together manually. It's grunt work that distracts from what we're actually trying to do. That's why I didn't remove the `:reader` and  `:writer` attributes: we shouldn't devs creating have multiple broken implementations with different ideas about how they should work.

Further, if we use this stripped down version, we can't add new() back into Corinna safely without potentially breaking a lot of code that already has new(). Worse, we're trapped with `sub` instead of `method` because switching to that later means that people using older versions of Corinna suddenly find it won't work with newer versions because Corinna doesn't allow you to call subs with the $object-> syntax. It actually knows the difference between subs and methods.

This was part of the "irreducible complexity" I've struggled with.
 
> This is much more stripped down than the Corinna proposal because Curtis was
> worried he needed to have feature parity with Moo/se otherwise people wouldn't
> adopt the new system.

Aside from the fact that people have said this (sometimes yelled this) to me often, this isn't entirely true. See my discussion above about creating an irreducibly complex MVP. Also, consider that I removed `:builder`. This pissed off some people, but I still contend it was the right thing to do. (https://ovid.github.io/articles/the-problem-with-builder.html)
> After two decades of defending it,
> I now believe  Perl's existing object system is a shambles and makes writing clean
> scalable code more difficult than it should be. We need to take the lessons we have
> learned from Moo/se and others and improve upon them. That's a problem perl5-porters can solve.

You want to know whose object system is a shambles? Python. It's a steaming pile of ones and zeros. The addition of dataclasses helps, but seriously, Python's OO is a joke. But nobody in Python reaches for better solutions because Python's OO is core. And they're kicking our ass.
Best,Ovid
Re: Not an OO RFC, take 2 [ In reply to ]
??????? Original Message ???????
On Monday, June 21st, 2021 at 1:14 AM, Ovid via perl5-porters <perl5-porters@perl.org> wrote:

> On Monday, 21 June 2021, 02:01:17 CEST, Chris Prather <chris@prather.org> wrote:
>>
>> That's the starting point in the discussion of Corinna. That's the irreducible
>> piece that if you throw out everything else we still would need to discuss.
>> Even if you strip away everything else from Corinna you still need something
>> like (with apologies to John Harper[2]):
>> ```
>> package LasersAndFeelings;
>>
>> use strict;
>> use warnings;
>> use experimental 'class';
>> use experiemntal 'signatures';
>>
>> use Games::Dice 'roll';
>>
>> class Character {
>>
>> has $style;
>> has $role;
>> has $number;
>>
>> sub new($class, $s, $r) {
>> $style = $s;
>> $roll = $r;
>> $number = roll '1d4+1';
>>
>> return bless(__INSTANCE__, $class);
>> }
>>
>> sub attempt_move($s, $num_dice=1) {
>> my $dice = [roll '1d6' x $num_dice];
>> my $count = scalar grep { $_ > $number } $dice->@*;
>> for ($count) {
>> if ($count == $number) { return 'LASER FEELIGNS' } # !!!
>> if (0) { return 'FAIL' } # critical fail
>> if (1) { return 'PARTIAL'} # complication
>> if (2) { return 'SUCCESS' } # everything's fine
>> if (3) { return 'BOON' } # critical success!
>> }
>> }
>> }
>>
>> ```
>> The bare minimum is a new kind of scope, a new kind of state, and a new kind of
>> reference to hold it.
>
> I've seen you write `sub new ...` a couple of times an even more stripped-down version of Corinna. When I was ripping things out for the MVP, I found myself asking a few questions.
>
> - How do we get the behavior I'm removing?
> - Can we safely add the behavior back after the MVP?
>
> Your constructor is a great example of something we shouldn't do, for two reasons. If you read the construction detail (pseudo-code at https://gist.github.com/Ovid/accb0c7c8444bdd150b5c7509809477f), you see that superclass constructors are called for you, as they should be. The variable assignment is done for you, as it should be. These are extremely important design goals because anything the language can do safely, it should. Perl devs should stop needing to wire things together manually. It's grunt work that distracts from what we're actually trying to do. That's why I didn't remove the `:reader` and `:writer` attributes: we shouldn't devs creating have multiple broken implementations with different ideas about how they should work.
>
> Further, if we use this stripped down version, we can't add new() back into Corinna safely without potentially breaking a lot of code that already has new(). Worse, we're trapped with `sub` instead of `method` because switching to that later means that people using older versions of Corinna suddenly find it won't work with newer versions because Corinna doesn't allow you to call subs with the $object-> syntax. It actually knows the difference between subs and methods.
>
> This was part of the "irreducible complexity" I've struggled with.
>
>> This is much more stripped down than the Corinna proposal because Curtis was
>> worried he needed to have feature parity with Moo/se otherwise people wouldn't
>> adopt the new system.
>
> Aside from the fact that people have said this (sometimes yelled this) to me often, this isn't entirely true. See my discussion above about creating an irreducibly complex MVP. Also, consider that I removed `:builder`. This pissed off some people, but I still contend it was the right thing to do. (https://ovid.github.io/articles/the-problem-with-builder.html)
>
>> After two decades of defending it,
>> I now believe Perl's existing object system is a shambles and makes writing clean
>> scalable code more difficult than it should be. We need to take the lessons we have
>> learned from Moo/se and others and improve upon them. That's a problem perl5-porters can solve.
>
> You want to know whose object system is a shambles? Python. It's a steaming pile of ones and zeros. The addition of dataclasses helps, but seriously, Python's OO is a joke. But nobody in Python reaches for better solutions because Python's OO is core. And they're kicking our ass.

Python's also kicking our ass in things like heavily funded application areas, just to add to the poop-pile. It's been said often that many people would prefer to use Perl for things like machine learning and "big data", but they have to use Python because of the enormous support available. I think there are quite a few lessons to learn with Python's OO - I can't properly make the claim, but I've heard others bemoan something related Python lambda functions not being useful with their OOP - which I think are really just what we know as "anonymous" subroutines.

If what I am reading is tending towards a lot of new code paths and other fundamental things in perl core (like a new SV structure thing), I'd like to add that in addition to "things the language can do safely" that "anything the language can do "real OS" _thread_ safely, it should". Is that out of scope? Yes. Is it out of scope to try to not make things impossible to make thread safe in the future? I don't think so, but I could be wrong. Honestly, I'd use any feature of Perl/perl if it offered some window into light weight threading, even if this meant I learned to write proper OOP code.

Finally, I'd like to just mention that testing is greatly aided by the ability to mock things. I even find it handy occasionally to skip a constructor and pass in a string of the package directly, e.g.,

Foo::do_thing(q{Foo},$something);

Similarly,

my $foo = bless {}, q[Foo};
$foo->do_thing($something);

What are the thoughs on this kind of subversion? I suppose this goes into the "introspection" bucket. In any case, it's handy but strikes me as something that fundamentally violates data encapsulation.

Cheers,
Brett

> Best,
> Ovid
Re: Not an OO RFC, take 2 [ In reply to ]
On Monday, 21 June 2021, 04:37:53 CEST, Tom Molesworth via perl5-porters <perl5-porters@perl.org> wrote:

> On Mon, 21 Jun 2021 at 10:02, Chris Prather <chris@prather.org> wrote:
>
>     On Sun, Jun 20, 2021 at 8:35 PM Tom Molesworth <tom@deriv.com> wrote:
>     >
>     > Interesting as this suggestion is, I don't think this can be called an irreducible piece at all - Object::Pad already exists without inventing these primitives, and has the advantage of being compatible with existing classes.
>     >
>     > What you're proposing seems to be a parallel, *incompatible* class implementation? If so, I don't see how that would be feasible.
>     >
>
>     If that's what I'm proposing, I think I have company:
>
>     "[...] Corinna classses cannot inherit from non-Corinna classes due to
>     difficulties with establishing the base class (UNIVERSAL or
>     UNIVERSAL::Corinna?)."[1]
>
> If Corinna does take that route, I believe it would be a big mistake....

I need to touch on this one briefly because it was also a strong source of concern in the design. In a nutshell: maybe later we can add in the ability to inherit from non-Corinna classes. But if we provide that ability up front and later realize it was a mistake, we're stuck. Even if we call Corinna an experiment and warn people heavily that the syntax will change, I see this like signatures: people can and will use it in production because the gains are so great that the risk seems worth it.

But I'm *not* ignoring the issue. In fact, Damian suggested an interesting workaround and I kinda like it.

    class Game::Character {
        use Some::ORM;
        has $some_orm :handles(*);

        has $table :reader = 'characters';

        has $character_id ...;
        has $name         ...;
        has $strength     ...;
        has $agility      ...;
        has $wisdom       ...;

        ADJUST {
            $some_orm = Some::ORM->new(...)
        }
    }

In the above hypothetical example, we can't inherit from the ORM class because
it's "vintage" Perl, but we can instantiate the instance in ADJUST phaser and
the `:handles(*)` says "delegate *every* method we don't have to the $some_orm
class."

Yeah, ORMs are probably a lousy example, but the above effectively gets you
inheritance. Want multiple inheritance?

    class Foo {
        use DateTime;
        use Some::Other::Class;
        has $created :handles(*) = DateTime->now;
        has $other   :handles(*) = Some::Other::Class->new($created);
        ...
    }

That's effectively LIFO order MI. It's also a spectacularly bad idea, but we
provide the syntax. (I just hate that `*` is only used here. That feels wrong)

Also, because Corinna knows that subroutines aren't methods, you can't import
&List::Util::sum and suddenly get a broken $object->sum method (no more
namespace::autoclean, the sort of module we write because Perl is so limited).
Thus, if we inherited from DateTime, how would Corinna even know what methods
to call?

Best,
Ovid
--
IT consulting, training, specializing in Perl, databases, and agile development
http://www.allaroundtheworld.fr/.

Buy my book! - http://bit.ly/beginning_perl
Re: Not an OO RFC, take 2 [ In reply to ]
On Sun, Jun 20, 2021 at 08:00:47PM -0400, Chris Prather wrote:

> Taking a cue from Nicholas, I've re-organized your email to make my reply

I'm finding it slightly unsettling how many folks are quoting me these days.
I'm pretty sure I'm not the messiah. I'm far more likely to be the "naughty
boy" (or at least, the semi-professional trouble maker/agent provocateur)

I intended to demonstrate this below:

> I'm pretty convinced you cannot have both, because the existing tooling in Perl
> is not fit for purpose. Perl has no concept of Records[1], or user-defined data
> structures. Perl has five (or seventeen if you read perlapi) kinds of data
> structure that can be blessed into an object. Those are the only kinds you can
> have.

Five?

Surely it's (at least) six. The obvious four are scalars, AV, HV and CV.

And then I can bless FORMATs:

$ perl -MDevel::Peek -e 'format STDOUT =' -e 'Hello world' -e. -e '$a = bless *STDOUT{FORMAT}, "gotcha"; Dump($a); Dump($$a)'
SV = IV(0x55a5662801c0) at 0x55a5662801d0
REFCNT = 1
FLAGS = (ROK)
RV = 0x55a566280218
SV = PVFM(0x55a56628e9d0) at 0x55a566280218
REFCNT = 2
FLAGS = (OBJECT,DYNFILE)
STASH = 0x55a5662536a0 "gotcha"
COMP_STASH = 0x0
START = 0x55a5662bf180 ===> 1
ROOT = 0x55a5662bf108
GVGV::GV = 0x55a5662775f8 "main" :: "STDOUT"
FILE = "-e"
DEPTH = 0
FLAGS = 0x1000
OUTSIDE_SEQ = 162
PADLIST = 0x55a566285580
PADNAME = 0x55a566272520(0x55a566285cf0) PAD = 0x55a5662801a0(0x55a566286df0)
OUTSIDE = 0x55a5662538e0 (MAIN)
Not a SCALAR reference at -e line 4.

and IOs:

$ perl -MDevel::Peek -e '$a = bless *STDOUT{IO}, "gotcha"; Dump($a); Dump($$a)'
SV = IV(0x55ac738d81f8) at 0x55ac738d8208
REFCNT = 1
FLAGS = (ROK)
RV = 0x55ac738d7c08
SV = PVIO(0x55ac738d6d78) at 0x55ac738d7c08
REFCNT = 3
FLAGS = (OBJECT)
STASH = 0x55ac738ab6a0 "gotcha"
IFP = 0x55ac738cabd0
OFP = 0x55ac738cabd0
DIRP = 0x0
LINES = 0
PAGE = 0
PAGE_LEN = 60
LINES_LEFT = 0
TOP_GV = 0x0
FMT_GV = 0x0
BOTTOM_GV = 0x0
TYPE = '>'
FLAGS = 0x0
Not a SCALAR reference at -e line 1.

and whilst I can bless PVGVs, they behave roughly like scalars, so I wasn't
counting them.

(Sadly I can't see how to split apart file handles and directory handles, so
I can't see how to bless them separately)

> Finally since there is a lot of yelling about the Elephant in the Room: Perl's
> relative market share isn't a problem for perl5-porters. It's not a problem
> perl5-porters can or should attempt to solve. A new object system with real

I'm sort of disagreeing. It's not a problem that we should directly solve.
But we shouldn't hinder folks who are usefully trying to solve it, as it is
to our benefit that they prosper.

I hope that I didn't undermine *too* much that you were trying to say :-)

Nicholas Clark
Re: Not an OO RFC, take 2 [ In reply to ]
On Mon, 21 Jun 2021 at 07:53, Ovid via perl5-porters <perl5-porters@perl.org>
wrote:

> On Monday, 21 June 2021, 02:34:10 CEST, Yuki Kimoto <kimoto.yuki@gmail.com>
> wrote:
>
> > Ovid
> >
> > I feel a strong anxiety about you.
> >
> > Are you afraid of Perl's death?
>
> More and more we get companies contacting us who are actively purging all
> Perl from their code bases. Some are well-known companies, some are small,
> but it's happening widely. Perl is dying. Oh, it will still be around in 20
> years time, but at the current rate, it will be some obscure little hobby,
> maybe running a few legacy Linux tools that we've mostly forgotten about,
> and it will move on from being your grandparent's language to your
> great-grandparent's language. 2040: "Perl? Yeah, I heard about it. Does
> that even compile any more?" Perl will be a curiosity in a technology
> museum.
>

dying - true.
Purging all Perl ... do we have some data why is it so? How it can be
mitigated?


> Now, I *don't* want to relitigate the past—that would reopen too many
> wounds—but we've known about this mess since 2000. That's 21 years ago.
>

... and we are still discussing ...


> People see things like Foo::->bar() and wonder what the heck is that
> ugliness?
>

Ugliness? just lack of "package literal" as first class citizen. And
documentation.


>
> Calling a function with a leading a ampersand is allowed, but ask the
> average user what's the difference between &function and &function()? More
> warts, and pretty important ones.
>

adding "goto &function" and difference between "function 1, 2, 3" and
"&function 1, 2, 3" to the list.

True, it's about consistency and language vision (vision may evolve but
should not be ad-hoc).
Even more, you can create "sub and", you can call it with ampersand or as a
method.
With "my sub and" you can even override keyword and.


>
> wantarray and context. Ugh.
>

Again, mostly consistency. There should be optional keyword for implicit
behaviour.
Eg.
- there should be optional keyword 'then' as counterpart to 'else'
- there should be keywords 'list' and 'void' as counterparts to 'scalar'

Of course then there should be a way to declare implicit context of sub

Also an evolution. What was great idea at the time of implementation may
not be good idea now.,
For example it make look reasonable to switch implicit context of fat comma
rhs to scalar.

For that perl needs language protocols. If it means to stick with "use v",
that's fine. Even better, that can be sold as competitive advantage.


> SUPER is bound at compile-time and we're stuck with that. Decades of the
> SUPER bug hanging around our necks.
>
> We have threads, but we're told not to use them. People still do and then
> stuff breaks.
>

Thread documentation should start with:

Using threads (in any language) is like mixing napalm with atomic bomb,
bare hand, and hoping to survive.


>
> And we don't get used to nice techniques like inversion of control because
> we're so used to ignoring encapsulation and using abominations like
> Sub::Override (I wrote that). It seems that very few people in Perl really
> "get" OO and developers who get OO probably won't reach for that write-only
> language we love.
>

Inversion of control is only subset of something larger.

It has to be part of language, applicable without author's intention. It
should not only inject, it should resolve. It should be even able to
prohibit usage of subset of workflow
(eg: prohibit login/password authentication favouring token based)


>
> Not one of those things is a language killer in and of itself. All them
> piled on top of one another, along with many, many other things we could
> cover, along with a rabid community of users who revel in writing arcane
> code, means that Perl is not a welcoming language.
>
> But we are stuck with that and we can't break existing code. So where do
> we want to go from here and how do we get there? Corinna isn't the answer.
> But I think it (or something like it) is a huge part of the answer.
>
> We have try/catch now. We need exceptions.
>

> We need asynchrony.
>
> We need signatures (damn it!)
>

I disagree.
Explanation:
- we need to tread subs as methods:
https://github.com/happy-barney/perl-poc/blob/perl-features/COP/understanding-subs.md
- we need dependencies: multiple use cases starting at
https://github.com/happy-barney/perl-poc/tree/perl-features/COP#Use-cases


>
> We need the beginning of a type system—something useful for humans, not
> just computers. UInt is great for optimization the sofware, but creating a
> "Celsius" type for a weather app is great for optimizing the wetware.
>

Types are bad. We should use constraints (or contracts).
Difference is: type represents implementation. type behaviour can be
altered (eg: accepting and providing values outside of parents range)
On contrary constraint represents intention. It can be only extended.

Celsius is good example.
Kelvin extends Temperature
Celsius extends Temperature
Fahrenheit extends Temperature

or maybe another structure is more appropriate ?

Kelvin extends Temperature
Celsius extends Kelvin
Fahrenheit extends Celsius


> We need so many things it's not even funny, but we're not going to get to
> them unless we change our mindset. Perl 7 was a brilliant idea. This RFC
> process is also brilliant. There are many more things needed, but this is a
> good start.
>

We need clear statement why to use perl.
We need killer features (in my eyes Domain-Driven Development and
Context-Oriented Programming)

We need to show that perl can handle changes and can help user to do that -
make code maintenance possible (80%+ of costs) instead of making creation of
new code even more sexy.

- "use v"
- "use feature"
both are great start, but should be used extensively, for example, module
like Construct::Syntax should not exist (it should be part of core)


Pluggable keywords are good example: it's important to have them, but
- no tooling support (language server, critic, tidy)
- and second step is still missing (pluggable grammar)


>
> I worked *years* on Corinna and her design. I opened up the process and
> had many other people help. That was humbling, seeing all of the mistakes I
> made, but it's made Corinna even better. I've poured through arcane
> programming languages, seeing how they handle some of the issues we face.
> I've read books on OO programming best practices (and find myself envying
> Java at times). I've juggled various ideas, wrote software to help explore
> some thoughts, stripped out everything I could to distill a viable MVP. And
> in various forums (not here, thank goodness), I still keep running into
> people saying "bless" is all you need!
>
> So that's what's bugging me.
>
> Best,
> Ovid
> --
> IT consulting, training, specializing in Perl, databases, and agile
> development
> http://www.allaroundtheworld.fr/.
>
> Buy my book! - http://bit.ly/beginning_perl
>
>
>