Hi,
I just released the invoker module on cpan, and i'd like to
propose the syntax to be included in future perls.
why: with the blooming modules providing the "method" keyword, we
no longer need to have "my $self = shift" everywhere. however
this makes "$self" now the most repeated code.
Here's the idea:
"use feature 'invocant'" enables the $-> operator. There are two
variants:
- "use invocant '$self" looks for the specific lexical variable
named $self in the current context, and bails out in compile
time if not found.
- "use invocant 'auto'" looks for the first real pad entry in the
nearest scope as the default invocant.
I am not sure which one suites as better default behaviour. the
latter seems less intrusive on insisiting variable names by can
be a bit confusing.
Conflicts:
$-> can be parsed as $- > ($- greater than .. ), so we need to
deprecate the use of $- (and hopefully the whole format system by
requiring use of formats to add additional "use format" line.)
the feature can install a warning when accessing $- before such
deprecation.
What do people think?
Cheers,
CLK
[P5P] Proposal: "$->" for implicit invocant
| Tweet |
|
Search Discussions
-
H.Merijn Brand at Jan 16, 2011 at 8:12 am ⇧
This alone would cause me to try to issue a veto. Perl5 has format.On Sun, 16 Jan 2011 15:06:03 +0800, Chia-liang Kao wrote:
Hi,
I just released the invoker module on cpan, and i'd like to
propose the syntax to be included in future perls.
why: with the blooming modules providing the "method" keyword, we
no longer need to have "my $self = shift" everywhere. however
this makes "$self" now the most repeated code.
Here's the idea:
"use feature 'invocant'" enables the $-> operator. There are two
variants:
- "use invocant '$self" looks for the specific lexical variable
named $self in the current context, and bails out in compile
time if not found.
- "use invocant 'auto'" looks for the first real pad entry in the
nearest scope as the default invocant.
I am not sure which one suites as better default behaviour. the
latter seems less intrusive on insisiting variable names by can
be a bit confusing.
Conflicts:
$-> can be parsed as $- > ($- greater than .. ), so we need to
deprecate the use of $- (and hopefully the whole format system by
requiring use of formats to add additional "use format" line.)
Period. And I use it. A lot.the feature can install a warning when accessing $- before such
deprecation.
What do people think?
Cheers,
CLK
--
H.Merijn Brand http://tux.nl Perl Monger http://amsterdam.pm.org/
using 5.00307 through 5.12 and porting perl5.13.x on HP-UX 10.20, 11.00,
11.11, 11.23 and 11.31, OpenSuSE 10.1, 11.0 .. 11.3 and AIX 5.2 and 5.3.
http://mirrors.develooper.com/hpux/ http://www.test-smoke.org/
http://qa.perl.org http://www.goldmark.org/jeff/stupid-disclaimers/ -
David Golden at Jan 17, 2011 at 12:12 am ⇧
If we're really pondering this sort of thing, why not think moreOn Sun, Jan 16, 2011 at 2:06 AM, Chia-liang Kao wrote:
"use feature 'invocant'" enables the $-> operator. There are two
variants:
broadly and finally get around to dealing with method/object syntax?
(Like some of the syntax manglers on CPAN do.)
Hypothetically:
use feature 'method';
method foo {
self->wibble($_) for @_;
}
I.e. Given a "method" keyword, set up the invocant in some way and
leave it out of @_. People can bikeshed the most efficient way to set
up the invocant -- in my example I have a bareword, but it could be
"$self" or "$*" (available now without a deprecation cycle) or
whatever else people dream up.
-- David
-
Johan Vromans at Jan 17, 2011 at 8:04 am ⇧
-
Chromatic at Jan 20, 2011 at 6:27 pm ⇧
This proof of concept patch enables that, with $self as the invocant. ItOn Sunday 16 January 2011 at 16:11, David Golden wrote:
If we're really pondering this sort of thing, why not think more
broadly and finally get around to dealing with method/object syntax?
(Like some of the syntax manglers on CPAN do.)
Hypothetically:
use feature 'method';
method foo {
self->wibble($_) for @_;
}
could use more robust testing, but all existing tests pass.
The trick of using lex_stuff_pvs() seems grotty, but it's far, far easier than
building a new optree with the appropriate lexical bindings within the method
production in perly.y.
The patch needs make regen_perly after applying.
-- c
-
Zefram at Jan 20, 2011 at 6:32 pm ⇧
As something to go in the core, I do not approve of this shortcut.chromatic wrote:
This proof of concept patch enables that, with $self as the invocant. It
could use more robust testing, but all existing tests pass.
You should prototype this as a CPAN module, using the keyword hook.
The trick of using lex_stuff_pvs() seems grotty, but it's far, far easier than
building a new optree with the appropriate lexical bindings within the method
production in perly.y.
You should definitely build the optree rather than stuff source.
It also seems very unwise for the core to take the keyword "method" at
this stage. We have several CPAN modules supplying "method" keywords
with various semantics, it's an unresolved area.
-zefram
-
David E. Wheeler at Jan 20, 2011 at 6:50 pm ⇧
Tie it to `use 5.14.0;` or, more likely, `use 5.16.0;`?On Jan 20, 2011, at 10:32 AM, Zefram wrote:
It also seems very unwise for the core to take the keyword "method" at
this stage. We have several CPAN modules supplying "method" keywords
with various semantics, it's an unresolved area.
Oh, and the class keyword would be handy to have too, if we're gonna have `method`.
Best,
David
-
David Golden at Jan 20, 2011 at 7:00 pm ⇧
-
Chromatic at Jan 20, 2011 at 7:29 pm ⇧
That means:On Thursday 20 January 2011 at 10:32, Zefram wrote:
You should prototype this as a CPAN module, using the keyword hook.
How do you use keyword hooks to add 'method' to the imports of feature.pm?
It also seems very unwise for the core to take the keyword "method" at
this stage. We have several CPAN modules supplying "method" keywords
with various semantics, it's an unresolved area.
To my knowledge, none of them import 'method' from feature.pm.
As something to go in the core, I do not approve of this shortcut.
You should definitely build the optree rather than stuff source.
* grabbing the optree *already generated* for the body of the sub
* creating a new lexical $self binding in that optree
* rummaging through every variable access in that entire optree to find $self,
if it exists
* rebinding those package globals to the lexical
* building up the appropriate optree for 'my $self = shift';
* splicing the new optree to the existing optree
I've done all of this before with B::Generate activated by a new :method
attribute on existing subs. It's fragile and unpleasant enough in Perl, and
it's a lot of special-purpose code to stuff into perly.y.
The worst part is doing this all in a way that doesn't trip the strict pragma.
I don't know how to do that.
Alternately, you could take the approach that doesn't add at least a few
hundred lines of new code to the parser for a special case. You could use as
much existing code as possible (code that knows how to build an optree, code
that knows how to create lexicals, code that knows how to decide $self is
lexical, et cetera).
-- c
-
David Golden at Jan 20, 2011 at 8:15 pm ⇧
This is why I was pondering a "self" keyword. If it could access theOn Thu, Jan 20, 2011 at 2:28 PM, chromatic wrote:
* grabbing the optree *already generated* for the body of the sub
* creating a new lexical $self binding in that optree
* rummaging through every variable access in that entire optree to find $self,
if it exists
right reference at runtime you wouldn't need to worry about the
existing bindings.
Imagine:
* method { ... } somehow marks the subroutine body as a method
* dispatch to such a marked method doesn't put the invocant in @_
but puts it "somewhere else" (big hand-waving here)
* keyword self retrieves invocant from wherever it got put
I leave it to people who know the guts in detail to explain why that
is doomed to fail. :-)
-- David
-
Steffen Mueller at Jan 20, 2011 at 9:43 pm ⇧
"wherever" would likely still be the stack, except @_ is populated onlyOn 01/20/2011 09:14 PM, David Golden wrote:
On Thu, Jan 20, 2011 at 2:28 PM, chromaticwrote:* grabbing the optree *already generated* for the body of the subThis is why I was pondering a "self" keyword. If it could access the
* creating a new lexical $self binding in that optree
* rummaging through every variable access in that entire optree to find $self,
if it exists
right reference at runtime you wouldn't need to worry about the
existing bindings.
Imagine:
* method { ... } somehow marks the subroutine body as a method
* dispatch to such a marked method doesn't put the invocant in @_
but puts it "somewhere else" (big hand-waving here)
* keyword self retrieves invocant from wherever it got put
with the elements after the invocant.
The little understanding I have of these matters suggests that arguments
will be passed via the stack no matter what and @_ is then "aliased"
(SV* copy? Too lazy to check.) to the elements since the last pushmark.
If there was a flag to start only after the first element and make the
sp accessible via "self" by some mechanism, that might just do it.I leave it to people who know the guts in detail to explain why thatYes, it is now up to them :)
is doomed to fail. :-)
Cheers,
Steffen
-
Reini Urban at Jan 20, 2011 at 9:07 pm ⇧
I'm completely with chromatic here.2011/1/20 chromatic <chromatic@wgz.org>:On Thursday 20 January 2011 at 10:32, Zefram wrote:That means:
You should prototype this as a CPAN module, using the keyword hook.
How do you use keyword hooks to add 'method' to the imports of feature.pm?
It also seems very unwise for the core to take the keyword "method" at
this stage. We have several CPAN modules supplying "method" keywords
with various semantics, it's an unresolved area.
To my knowledge, none of them import 'method' from feature.pm.
As something to go in the core, I do not approve of this shortcut.
You should definitely build the optree rather than stuff source.
* grabbing the optree *already generated* for the body of the sub
* creating a new lexical $self binding in that optree
* rummaging through every variable access in that entire optree to find $self,
if it exists
* rebinding those package globals to the lexical
* building up the appropriate optree for 'my $self = shift';
* splicing the new optree to the existing optree
I've done all of this before with B::Generate activated by a new :method
attribute on existing subs. It's fragile and unpleasant enough in Perl, and
it's a lot of special-purpose code to stuff into perly.y.
The worst part is doing this all in a way that doesn't trip the strict pragma.
I don't know how to do that.
Alternately, you could take the approach that doesn't add at least a few
hundred lines of new code to the parser for a special case. You could use as
much existing code as possible (code that knows how to build an optree, code
that knows how to create lexicals, code that knows how to decide $self is
lexical, et cetera).
Maybe Zefram could help hooking into the lexer to make that patch work
as module,
but currently it's not possible.
And suggesting the optree manipulation is not stable and also not clever.
It would be good to have better optree manipulation methods, but they
do not exist yet.
Stuffing the core source is definitely easier, and for this case
a new self or this keyword is definitely something we need in core
sooner or later. We already have the modules. They have no impact.
core must lead.--
Reini -
Eric Brine at Jan 20, 2011 at 11:43 pm ⇧
If you can write the following to define a class, no problem.On Thu, Jan 20, 2011 at 2:28 PM, chromatic wrote:
On Thursday 20 January 2011 at 10:32, Zefram wrote:
It also seems very unwise for the core to take the keyword "method" atthis stage. We have several CPAN modules supplying "method" keywordsTo my knowledge, none of them import 'method' from feature.pm.
with various semantics, it's an unresolved area.
use 5.016;
use Something::Which::Provides::Method;
If you have to write the following to define a class using another module,
maybe "method" is not the best choice of keyword.
use 5.016;
no feature 'method';
use Something::Which::Provides::Method;* ...As something to go in the core, I do not approve of this shortcut.That means:
You should definitely build the optree rather than stuff source.
* grabbing the optree *already generated* for the body of the sub
>
Why can't the parser handle it when generating the optree in the first
place? The parser knows that the block will be a method body before the
block is parsed.
- Eric
-
Zefram at Jan 21, 2011 at 3:05 am ⇧
You don't. But there's no reason for your particular version of "method"chromatic wrote:
How do you use keyword hooks to add 'method' to the imports of feature.pm?
to be controlled by feature.pm.* grabbing the optree *already generated* for the body of the subNo. You add the pad entry *before* parsing the body. It's not as
difficult as you make out.You could use asThe code that you're referring to there doesn't just generate ops and pad
much existing code as possible (code that knows how to build an optree, code
that knows how to create lexicals, code that knows how to decide $self is
lexical, et cetera).
entries, it also parses general Perl code, in which (for example) "shift"
could mean all sorts of things. Using lex_stuff, your implementation
is liable to be broken by local redefinition of a keyword that doesn't
appear in the user's source. That's OK for a prototype, but not at all
OK for a serious language feature.
-zefram
-
Chromatic at Jan 31, 2011 at 11:59 pm ⇧
-
Zefram at Feb 2, 2011 at 10:10 pm ⇧
Reasonably sane implementation. Though I strongly suspect you couldchromatic wrote:
but this swatch of optree building seems to do the trick.
replace quite a bit of your added code with more reuse of existing code.
I remain opposed to actually adding this to core. I don't see a
justification for favouring this particular set of semantics for the
"method" keyword over any of the other proposals; there's certainly
no consensus yet about which version of it from CPAN is preferred.
And of course it doesn't need to be in core to work.
-zefram
-
David E. Wheeler at Feb 2, 2011 at 11:15 pm ⇧
Do you have a favorite, Zefram?On Feb 2, 2011, at 2:10 PM, Zefram wrote:
chromatic wrote:but this swatch of optree building seems to do the trick.Reasonably sane implementation. Though I strongly suspect you could
replace quite a bit of your added code with more reuse of existing code.
I remain opposed to actually adding this to core. I don't see a
justification for favouring this particular set of semantics for the
"method" keyword over any of the other proposals; there's certainly
no consensus yet about which version of it from CPAN is preferred.
And of course it doesn't need to be in core to work.
Best,
David
-
Zefram at Feb 2, 2011 at 11:23 pm ⇧
Not of the currently-available ones, and I don't think we've yet got theDavid E. Wheeler wrote:
Do you have a favorite, Zefram?
facilities to design one that will stand the test of time. I want to
see a proper signature system implemented, and then a round of designs
for "method" built around that. *Then* we'll be in a position to start
talking about blessing one.
-zefram
-
Matt Sergeant at Feb 3, 2011 at 1:13 am ⇧
Is there any reason method signatures (or attributes) wouldn't work onZefram wrote:
Not of the currently-available ones, and I don't think we've yet got the
facilities to design one that will stand the test of time. I want to
see a proper signature system implemented, and then a round of designs
for "method" built around that.*Then* we'll be in a position to start
talking about blessing one.
top of this implementation?
-
Chromatic at Feb 3, 2011 at 1:20 am ⇧
Attributes work, but the tokenizer deliberately rejects prototype syntax afterOn Wednesday 02 February 2011 at 17:12, Matt Sergeant wrote:
Is there any reason method signatures (or attributes) wouldn't work on
top of this implementation?
a method keyword (given the uselessness of prototypes for methods). This
implementation is certainly compatible with a general signature system added
for both methods and subs.
-- c
-
David Golden at Feb 3, 2011 at 7:44 am ⇧
FWIW, I would be happy to see 'method' added without signatures. Or,On Wed, Feb 2, 2011 at 6:23 PM, Zefram wrote:
Not of the currently-available ones, and I don't think we've yet got the
facilities to design one that will stand the test of time. I want to
see a proper signature system implemented, and then a round of designs
for "method" built around that. *Then* we'll be in a position to start
talking about blessing one.
put differently, I'd hate to see 'method' not happen because we're
waiting for an officially sanctioned implementation of signatures.
Since I'd want signatures for regular (non-method) subroutines, too,
I'd prefer to see the two concepts separated so I can have my cake and
eat it while waiting for the next cake to arrive.
-- David
-
David E. Wheeler at Feb 3, 2011 at 4:50 pm ⇧
This seems entirely reasonable to me. I wouldn't mind seen a design spec for signatures, too, but that needn't hold up adding the method keyword any more than it would hold up the sub keyword. N'est pas?On Feb 2, 2011, at 11:44 PM, David Golden wrote:
FWIW, I would be happy to see 'method' added without signatures. Or,
put differently, I'd hate to see 'method' not happen because we're
waiting for an officially sanctioned implementation of signatures.
Since I'd want signatures for regular (non-method) subroutines, too,
I'd prefer to see the two concepts separated so I can have my cake and
eat it while waiting for the next cake to arrive.
Best,
David
-
Sam Vilain at Feb 3, 2011 at 1:54 am ⇧
MooseX::Method::Signatures suffers from huge performance problems,On 03/02/11 11:10, Zefram wrote:
chromatic wrote:but this swatch of optree building seems to do the trick.Reasonably sane implementation. Though I strongly suspect you could
replace quite a bit of your added code with more reuse of existing code.
I remain opposed to actually adding this to core. I don't see a
justification for favouring this particular set of semantics for the
"method" keyword over any of the other proposals; there's certainly
no consensus yet about which version of it from CPAN is preferred.
And of course it doesn't need to be in core to work.
precisely because it is *not* in core - it has to use PPI to parse the
signatures. That sucks very very much. It also has to try and apply
those signatures using very hairy code. There is absolutely zero way
that these type constraints can be proved at compile time even when you
declare variables' types so you pay a huge runtime penalty.
A project I worked on had to back out some very elegant (IMHO) use of
MXMS because it was simply too slow and had a huge number of dependencies.
Adding type constraints is supposed to help the computer execute the
code faster, not slower. This needs to be on Perl's long-term roadmap IMHO.
I think that we already have a great "preferred" approach for method
signatures. All of the modules on CPAN that I have looked at simply
choose a subset of MXMS as a compromise position to be faster.
If declared well enough in advance, "use 5.014" implies "use feature
'method'" is fair game IMHO. So long as there is a new API to access
the parsed signature (yay, finally) and/or influence parsing (yuck) then
the modules can adapt appropriately for the way forward.
Sam
-
Reverend Chip at Feb 3, 2011 at 6:22 am ⇧
Indeed, these latter problems are why I like Method::Signatures (whichOn 2/2/2011 5:54 PM, Sam Vilain wrote:
MooseX::Method::Signatures suffers from huge performance problems,
precisely because it is *not* in core - it has to use PPI to parse the
signatures. That sucks very very much. It also has to try and apply
those signatures using very hairy code. There is absolutely zero way
that these type constraints can be proved at compile time even when you
declare variables' types so you pay a huge runtime penalty.
amounts to 'just' syntactic sugar), but not its MooseX sibling.
-
Zefram at Feb 3, 2011 at 11:04 am ⇧
That's going to get a lot better with the new parser callback interfacesSam Vilain wrote:
MooseX::Method::Signatures suffers from huge performance problems,
precisely because it is *not* in core - it has to use PPI to parse the
signatures.
in 5.14. No more PPI, you can call into the real parser.There is absolutely zero wayThat wouldn't change if it were in the core.
that these type constraints can be proved at compile time even when you
declare variables' types so you pay a huge runtime penalty.
-zefram
-
Sam Vilain at Feb 4, 2011 at 1:30 am ⇧
Not instantly, no - but it would be nice to be able to move towards aOn 04/02/11 00:04, Zefram wrote:That wouldn't change if it were in the core.
There is absolutely zero way
that these type constraints can be proved at compile time even when you
declare variables' types so you pay a huge runtime penalty.
world where Perl is actually capable of skipping some run-time type
checks because it already knows that they can't be violated. I'm not
saying this is going to be easy!
Sam
-
Chris Prather at Jan 20, 2011 at 9:16 pm ⇧
Conceptually this is is a subset of MooseX::Method::Signatures[1],On Thu, Jan 20, 2011 at 1:32 PM, Zefram wrote:
You should prototype this as a CPAN module, using the keyword hook.
Method::Signatures::Simple[2] Method::Signatures[3], Perl6::Subs[4],
as well as similar in principle to selfvars[5], self[6], and
Object::LocalVars[7].
What exactly are you looking for from a prototype that isn't provided
in one of those seven (7!) modules?
-Chris
Note: I generated this list with a quick search for "self" and
"method" on CPAN. Two of these modules I knew existed because various
members of the Moose community use them in production environments
(specifically MooseX::Method::Signatures and
Method::Signatures::Simple). There may be other modules which
replicate this behavior as well, I gave up when I found the two I knew
about ... and five more.
[1]: http://search.cpan.org/dist/MooseX-Method-Signatures
[2]: http://search.cpan.org/dist/Method-Signatures-Simple
[3]: http://search.cpan.org/dist/Method-Signatures
[4]: http://search.cpan.org/dist/Perl6-Subs
[5]: http://search.cpan.org/dist/selfvars
[6]: http://search.cpan.org/dist/self
[7]: http://search.cpan.org/dist/Object-LocalVars
Related Discussions
Discussion Navigation
| view | thread | post |
Discussion Overview
| group | perl5-porters
|
| categories | perl |
| posted | Jan 16, '11 at 7:06a |
| active | Feb 4, '11 at 1:30a |
| posts | 29 |
| users | 14 |
| website | perl.org |
