Perl-Apollo / Corinna

Corinna - Bring Modern OO to the Core of Perl
Artistic License 2.0
157 stars 19 forks source link

Instance data/accessor syntax: self->, $self->, $., setter(newval), lvalue setter, ? #6

Closed cxw42 closed 4 years ago

cxw42 commented 4 years ago

@Ovid I think we could productively build this bikeshed in its own lot rather than overwhelming #4 :) . Feel free to close this issue if you disagree.

There was considerable discussion in the gist about the syntax for accessing slots. Some options are listed below - vote for the ones you like! I have listed them in the order I encountered them in the gist, followed by the ones from the wiki. Apologies if I missed any! These are not necessarily mutually exclusive, so feel free to vote for more than one.

Note that we have the opportunity to use new syntax, since Cor will be written in C rather than Perl.

(For what it's worth, I have changed my mind over the last six months, so don't feel locked in to earlier discussion.)

cxw42 commented 4 years ago

Keyword self: self->attribute (possibly with self->{attribute} as the underlying storage)

cxw42 commented 4 years ago

$self as an automatically-declared variable: $self->attribute

cxw42 commented 4 years ago

Twigil: $.attribute

cxw42 commented 4 years ago

Plain lexical: $attribute

cxw42 commented 4 years ago

Naming convention with a plain lexical: $_attribute (or $O_attribute)

cxw42 commented 4 years ago

Special form: ${^self}->attribute (or ${^attribute})

cxw42 commented 4 years ago

Twigil option 2: $:attribute

cxw42 commented 4 years ago

Twigil option 3: $->attribute

cxw42 commented 4 years ago

New sigil: §attribute (or other alternative punctuation)

cxw42 commented 4 years ago

Position For forms other than lexical/twigil/sigil, accessors as lvalues. E.g., self->x = 42;

cxw42 commented 4 years ago

Position For forms other than lexical/twigil/sigil, setters take a parameter. E.g., self->x(42);

Abigail commented 4 years ago

Keyword self: self->attribute (possibly with self->{attribute} as the underlying storage)

As in storing attributes in a hashref? So you keep all the things which make the current Perl OO bad?

Ovid commented 4 years ago

Unless we come up with a truly compelling reason otherwise, I expect we'll stick with using lexicals and naming conventions will grow organically.

I've taken two (informal) surveys on Facebook and Twitter. Admittedly, those would be biased, but what came out of both is roughly half willing to ditch the current behavior (which is good, because that's what we're going to do), and people strongly favoring lexicals over twigils.

Currently, having a poll doesn't work because there need to be explanations of why different forms would or would not be preferred.

Using the lexical has $x means:

So at this point (this has honestly been a ton of work just to get Cor to this point), I am not inclined to change this part of the proposal based on a vote. I need strong, solid technical reasons why an alternative is better than lexicals.

Side note, Github has a third-party app for polls.

Abigail commented 4 years ago

I'm very much in favour of using lexicals for attribute values (which for me was a major design issue when coming up with Inside Out objects).

I do have a question what has $volume :reader = $height * $width * $depth; means. Does that get evaluated once? Each time volume is queried? That is, is it more equivalent to my $volume = $height * $width * $depth, or to sub volume ($self) {$self -> height * $self -> width * $self -> depth}. The syntax suggests the former, but for an attribute, I expect the latter.

cxw42 commented 4 years ago

@Ovid Thanks for the explanation and summary! I'm sorry for the bother --- I didn't realize I had missed so much of the conversation. Best wishes with the design!

(Leaving open for Abigail's question above --- feel free to close once that's answered.)

Ovid commented 4 years ago

@Abigail

has $volume :reader = $height * $width * $depth;

That's more or less equivalent to the following Moose code.

has 'volume' => (
    is       => 'ro',
    init_arg => undef,
    lazy     => 1,
    default  => sub ($self) {
        return $self->width * $self->height * $self->depth;
    },
);

Thus, it's lazily evaluated once and only once. The main differences are that it's encapsulated (we don't store the data in a hashref) and it's much easier to write.

Ovid commented 4 years ago

Given no follow-up comments are here, I will close this ticket per @cxw42's suggestion.