New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wishlist: Overridable keywords #11869
Comments
From @cpansproutThis touches on issues in tickets #84690, #94480, #96116, #105924, #105926 and #105928. I have been thinking about this from time to time, and I think I finally have all the edge cases worked out: Proposal I propose that we make �use feature "overrides"� allow all keywords to be overridden. Infix operators like �and� will continue to be overridable only in non-infix positions. I.e., �use subs "and"; sub and () {} and and and� will continue to parse as �&and && &and�, as it currently does. Allowing overridable infix operators would be nice, but is not part of this proposal. Maybe that can come later. The keywords do, require and glob are currently not overridable as keywords. Overrides cannot change their syntax, but only their behaviour. In other words, overrides of these keywords are actually callbacks, rather than overrides. I propose that whether overrides of those three keywords are actual keyword overrides depend on whether the �overrides� feature is enabled in the scope where the subroutine is defined, not where it is used. For XS functions, I don�t know which way we should do it. We probably need a new XS keyword, similar to PROTOTYPE. I also propose that we add an :iter attribute, that will allow custom subs to get the special defined() treatment that glob and readline get inside a while() condition. (while(glob "foo") is equivalent to while(defined(glob "foo")).) All special-casing for parsing require VERSION should be removed from the tokenizer. ck_require can flag the op if it has a single unfolded numeric or vstring constant for its kidop. require VERSION should not delegate to a callback (�override�) any more. glob overrides should no longer be passed a second argument. The only code using the undocumented second argument anywhere on CPAN is in the core and can be changed. <> should continue to call glob and readline overrides automatically. Reasoning This should be in a feature feature, because otherwise the existence of a length method will cause every subsequent use of length() in the same file to produce a warning. do, glob, and require should be overridable based on the hints where the sub is defined, not where the sub is used, because otherwise this would violate existing subs� expectations. Existing require subs expect to receive "Foo/Bar.pm" rather than "Foo::Bar". A true override (with a * prototype) would leave it as "Foo::Bar". Similarly for glob overrides: an existing custom glob function might expect the automatic defined() in while(glob()). The purpose of the :iter attribute is to avoid adding too many more hacks to fix bug #84690. It also allows true glob overrides to retain that feature. Parsing of require VERSION is currently very screwy. It is not even consistent with itself. require also has the num/str bug, in that it tries to decide based on the type of its operand whether it will be a version number or a file name. We cannot fix that bug unless we make require VERSION a *syntactic* special case. In that case require $version would no longer work (thank goodness!). That means that require overrides would no longer be able to do CORE::require($_[0]), unless we stop calling the override in the case of a version number. That would apply only to �callback-style� overrides; i.e., the old kind. require overrides defined under �use feature "overrides"� would be true overrides which would not go through the special parsing at all, but would be required (i.e., allowed) to implement it themselves, if at all. My reason for putting require parsing in this ticket is that it is inextricably linked to the overrides feature. It�s hard to change one without the other. The reason for eliminating the second argument to glob() (did you even know about it?) is that <> will continue to call glob overrides, and glob implementations that want to accept lists will still be expected to handle <>�s calling convention. Flags: Site configuration information for perl 5.15.6: Configured by sprout at Sat Dec 31 10:12:16 PST 2011. Summary of my perl5 (revision 5 version 15 subversion 6) configuration: Locally applied patches: @INC for perl 5.15.6: Environment for perl 5.15.6: |
From @sciuriusFather Chrysostomos (via RT) <perlbug-followup@perl.org> writes:
I'll bite... I think it's a good plan. -- Johan |
The RT System itself - Status changed from 'new' to 'open' |
From @cpansproutOn Mon Jan 16 10:35:58 2012, jv wrote:
I plan to implement it for 5.18. -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Mon Jan 16 10:35:58 2012, jv wrote:
I plan to implement it for 5.18. -- Father Chrysostomos |
From @rjbs* Father Chrysostomos via RT <perlbug-comment@perl.org> [2012-01-16T16:28:49]
I look forward to thinking more about it and poking at your work :) -- |
From @cpansproutOn Mon Jan 16 10:35:58 2012, jv wrote:
But there is one thing my plans did not address: How should elsif and use feature 'overrides'; Is else considered part of the if() statement, such that the presence of Or is else a keyword in its own right, so the override kicks in, if ($x) { } ? If the former, then is there any need for else and elsif to be -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Mon Jan 16 10:35:58 2012, jv wrote:
But there is one thing my plans did not address: How should elsif and use feature 'overrides'; Is else considered part of the if() statement, such that the presence of Or is else a keyword in its own right, so the override kicks in, if ($x) { } ? If the former, then is there any need for else and elsif to be -- Father Chrysostomos |
From @sciurius"Father Chrysostomos via RT" <perlbug-comment@perl.org> writes:
Suggestion: Do not allow if, else, elseif to be overridden independently So you either override them all, or none. Does that make sense? -- Johan |
From j.imrie1@virginmedia.comOn 04/04/2012 19:58, Johan Vromans wrote:
CORE::KEYWORD::if etc. have the default semantics. John |
From @ikegamiOn Sun, Jan 15, 2012 at 3:51 PM, Father Chrysostomos <
What do you mean by overriding a keyword? Do you mean a Perl-accessible |
From @ikegamiOn Wed, Apr 4, 2012 at 11:50 AM, Father Chrysostomos via RT <
The builtin "if" should expect the following to follow it (ignoring "(" EXPR ")" BLOCK ( "elsif" "(" EXPR ")" BLOCK )* ( "else" BLOCK )? None of those tokens should be overridable when parsing that rule (although If by overriding a keyword you mean altering its syntax to something of the If by overriding a keyword you mean giving the ability to create functions - Eric |
From @cpansproutOn Wed Apr 04 13:53:55 2012, ikegami@adaelis.com wrote:
That is what I mean.
Your suggestion sounds good to me. -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Wed Apr 04 13:53:55 2012, ikegami@adaelis.com wrote:
That is what I mean.
Your suggestion sounds good to me. -- Father Chrysostomos |
From @cpansproutOn Wed Apr 04 13:53:55 2012, ikegami@adaelis.com wrote:
In that case, is there any reason why elsif needs to be a reserved word I�m also trying to plan ahead with regard to adding all keywords to the It should be possible in the future for the �if� keyword to be But it won�t make much sense for there to be a &CORE::elsif subroutine. -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Wed Apr 04 13:53:55 2012, ikegami@adaelis.com wrote:
In that case, is there any reason why elsif needs to be a reserved word I�m also trying to plan ahead with regard to adding all keywords to the It should be possible in the future for the �if� keyword to be But it won�t make much sense for there to be a &CORE::elsif subroutine. -- Father Chrysostomos |
From @ikegamiOn Sun, Apr 22, 2012 at 1:41 AM, Father Chrysostomos via RT <
I was wondering that myself when I typed the above. We allow C<< sub if { }
I'm not seeing the value of C<< elsif(); >> being a syntax error. The two |
From @cpansproutOn Sun Apr 22 13:25:19 2012, ikegami@adaelis.com wrote:
Allowing C<< sub elsif { } >> and having C<< elsif(); >> be a syntax The real question is: Without an imported override named elsif, what Another way of putting it: Should there by a sub named CORE::elsif that I�m leaning toward the former right now, as it avoids changing the
With custom call parsers, elsif(){} could be valid syntax even with a -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Sun Apr 22 13:25:19 2012, ikegami@adaelis.com wrote:
Allowing C<< sub elsif { } >> and having C<< elsif(); >> be a syntax The real question is: Without an imported override named elsif, what Another way of putting it: Should there by a sub named CORE::elsif that I�m leaning toward the former right now, as it avoids changing the
With custom call parsers, elsif(){} could be valid syntax even with a -- Father Chrysostomos |
From @cpansproutOn Sun Jan 15 12:51:08 2012, sprout wrote:
Actually, it�s equivalent to while(defined($_ = glob "foo")). Interestingly, while($x=<foo>) did not get the special treatment until Commit 4b161ae also made while($x=each %foo) get wrapped in Was $_= omitted to avoid backward-compatibility problems, or was it an The reason I ask is that it would be nice if we could make this all I also need to know how this will affect my :iter proposal. Based on Also, as long as �each� follows its own rules, how is one to override it Maybe in the end we need to let the iter sub itself decide, and while() -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Sun Jan 15 12:51:08 2012, sprout wrote:
Actually, it�s equivalent to while(defined($_ = glob "foo")). Interestingly, while($x=<foo>) did not get the special treatment until Commit 4b161ae also made while($x=each %foo) get wrapped in Was $_= omitted to avoid backward-compatibility problems, or was it an The reason I ask is that it would be nice if we could make this all I also need to know how this will affect my :iter proposal. Based on Also, as long as �each� follows its own rules, how is one to override it Maybe in the end we need to let the iter sub itself decide, and while() -- Father Chrysostomos |
From @ikegamiOn Sun, Apr 22, 2012 at 4:56 PM, Father Chrysostomos via RT <
Would you recommend this behaviour to someone else? Say someone introduces It's going to be fun telling people that Perl goes out of its way to make - Eric |
From @ap* Father Chrysostomos via RT <perlbug-comment@perl.org> [2012-04-22 23:45]:
Should it? There is a bit of a problem there, isn�t it? The protocol with undef So you cannot use it to abort iteration� unless you contrive something
I would tend to go with adding the $_ assignment by default, including But, extending its coverage to arbitrary user-defined function concerns while (foo $bar, $baz) { ... } without knowing the definition of `foo` will not tell whether this code
Simple, you have to ensure that your overridden `each` has the exact
Please let�s not. I like this least of all options. Regards, |
From @ap* Aristotle Pagaltzis <pagaltzis@gmx.de> [2012-04-23 12:01]:
Hmm. Now I am wondering how contrived that really is. I wonder if this Then unpacking a scalarref into $_ could be baked right into the `while` Warning: highly experimental. I am a long way from thinking through all But if the pieces come together then I would be eager to prototype this If we could get a solid, supported iteration mechanism right into core Regards, |
From @nwc10On Sun, Apr 22, 2012 at 02:43:25PM -0700, Father Chrysostomos via RT wrote:
I think that $_ = being ommitted on while(each %foo) is not an oversight That commit you quote gets me back to this message from Larry: As usual, when there are long arguments, there are good arguments for both http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-04/msg00133.html Nick Ing-Simmons asks for a clarification: Thanks Larry - that is what the patch I posted does. http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-04/msg00182.html (it's clarified in a later message that Nick I-S hadn't realised that each In turn, the "RULING" dates back to this thread/request: http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-03/msg01630.html which also generates a massive thread, of which this message is probably Pray tell how you can tell that the code is broken without comments in the http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-03/msg01966.html in turn that seems to be a reaction to these warnings added in 5.004 $ ./perl -lwe 'while ($a = each %a) {}' [strictly as far as git has it, most this commit: commit a600677 [inseparable changes from patch from perl5.003_17 to perl5.003_18] Subject: Warn on '{if,while} ($x = X)' where X is glob, readdir, or <FH> ... as determined by .../bisect.pl --end perl-5.004 -lwe 'BEGIN {$SIG{__WARN__} = sub {++$b}}; while ($a = <>) {++$a}; exit $b' </dev/null and the each warning in this commit: commit 68dc074 ... Subject: Warn on C<while ($x = each %y) {}> as determined by .../bisect.pl --end perl-5.004 -lwe 'BEGIN {$SIG{__WARN__} = sub {++$b}}; while ($a = each %a) {}; exit $b' ] The rational for the former commit is detailed in the thread starting here: http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/9612/msg02125.html the latter in these messages http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1997-03/msg01263.html The intent of the changes appears to be to retain the 5.003 and earlier while (OP ...) and while ($var = OP ...) The mail archives from 1997 are fascinating. Lots of messages. Lots of Nicholas Clark |
From dcmertens.perl@gmail.comCan someone point me to the discussion where it was decided that overriding Thanks! -- |
From @cpansproutOn Mon Apr 23 14:20:09 2012, dcmertens.perl@gmail.com wrote:
Overriding if() and being *able* to override if() are two different things. Anyone who overrides if() is probably asking for trouble. But it would be nice to override length() and vec(). Where do we draw I only brought up if() in particular because it can have elsif attached -- Father Chrysostomos |
From @cpansproutOn Mon Apr 23 14:03:27 2012, nicholas wrote:
Except that while($var = each %h) implies defined(), but while(each %h) -- Father Chrysostomos |
From @cpansproutΧ�ι��ὸ� �νέ��η! On Mon Apr 23 03:03:36 2012, aristotle wrote:
This reference interface would make the sub practically unusable outside
I�ve already been thinking about that. This would require hooking
But we may end up with too many variations that are all equally good, -- Father Chrysostomos |
From @cpansproutOn Mon Apr 23 15:19:09 2012, sprout wrote:
In fact, in the process of thinking about this and considering where the -- Father Chrysostomos |
From @doyOn Tue, May 15, 2012 at 05:59:22PM -0400, Eric Brine wrote:
Okay, this is where I was confused then.
Yes, I agree with all this (including making 'else' and 'continue' -doy |
From @doyOn Tue, May 15, 2012 at 05:29:43PM -0500, Jesse Luehrs wrote:
Actually, I'm less sure about 'continue', considering it's use as a flow -doy |
From @cpansproutOn Tue May 15 15:34:13 2012, doy@tozt.net wrote:
Well how about my commit ae8d051 on the sprout/overridesδ branch? Is
I�ve just discovered that this goes all the way back to perl 5.000: $ perl5.6.2 -e 'use subs "continue"; sub continue { warn "@_" } while(1) I think that should stop working, but I just wanted to check. -- Father Chrysostomos |
From @ap* Father Chrysostomos via RT <perlbug-followup@perl.org> [2012-04-26 05:50]:
ΣÏ�γνÏ�μη. Î�εγάλÏ�Ï�α εκÏ�Ï�Ï� Î�λλάδαÏ� Ï�ε μη οÏ�θÏ�δοξη οικογÎνεια και Ï�ολλÎÏ� -- |
From @cpansproutOn Wed May 16 17:24:55 2012, aristotle wrote:
�α�άλαβα. �ὲ ��γ���ε��ε. -- Father Chrysostomos |
From @cpansproutOn Sun Jan 15 12:51:08 2012, sprout wrote:
perlsub has this to say about do�s prototype: The built-ins C<do>, C<require> and C<glob> can also be overridden, but due What happens in reality is different: $ perl -le 'do("foo","bar")' $ perl -le 'use subs "do"; sub do {warn @_}; do("foo","bar")' So it actually does take a list with no prototype. With a scalar prototype, I get this: $ perl -le 'use subs "do"; sub do($) {warn @_}; do("foo","bar")' So the entire argument list is being treated as one of the arguments and $ perl -le 'use subs "do"; sub do($$) {warn @_}; do("foo","bar")' And this: $ perl -le 'use subs "do"; sub do($@) {warn @_}; do("foo","bar")' So the only cases that are not buggy are no prototype (or @_), and ($) Hence, should I make it so that the prototype simply does apply properly -- Father Chrysostomos |
From @cpansproutOn Sun Jan 15 12:51:08 2012, sprout wrote:
...
...
...
I�ve just realised that a �do� override won�t have this problem, as the Only new code can have �use feature "overrides"�, so, if it imports a In fact, if �do� could go one way or the other, then so could any of the We still have a problem with XSUBs, though. So, should this actually be I would prefer not to have a sub attribute, because eventually, when all Should we assume that XS overrides for glob and require were declared BTW, I have implemented my original suggestion, which can be found on -- Father Chrysostomos |
From zefram@fysh.orgEric Brine wrote:
I think the best way to do this (in the long run) is that the code to -zefram |
From zefram@fysh.orgEric Brine wrote:
The intention is to migrate Devel::CallParser into the core. I'm actually Generally, the paradigm I'm aiming for is to merge the keyword namespace The PL_keyword_plugin mechanism, to the extent that it supplies any I've been putting off reading this thread for ages, sorry. Originally I -zefram |
From zefram@fysh.orgFather Chrysostomos via RT wrote:
I am troubled by the implications of this sort of condition. What does
If you have a sub ref \&CORE::require, it must behave as a pure subroutine
Where exactly does the problem arise? I see no categorical problem with -zefram |
From zefram@fysh.orgFather Chrysostomos via RT wrote:
No, they're different. A Devel::Declare parser doesn't get to return
Yes. It is very much intended that many subs with a D:CP parser will -zefram |
From @cpansproutOn Sun May 20 04:41:46 2012, zefram@fysh.org wrote:
That�s a nice solution that solves all the problems I brought up.. -- Father Chrysostomos |
From @cpansproutOn Sun May 20 04:59:39 2012, zefram@fysh.org wrote:
And then I can finish adding subs to the CORE:: namespace.
I�d love to hear them. What I�ve come up with does have a few rough I�m not so certain we can eliminate the keyword category altogether. � Even in the presence of a sub �foo�, a package �Foo� will cause �foo One idea I�ve had, which I don�t like very much, is to create a pragma -- Father Chrysostomos |
From @cpansproutOn Sun May 20 05:09:10 2012, zefram@fysh.org wrote:
To use the built-in parser for that keyword.
Being overridden, including the parsing. In the current implementation, require is not overridable, at least (The fact that an �overridden� require is compiled to an entersub op is There is currently an ugly parser hack that makes �require� and So we have a single core function that behaves differently depending on
I was using \& to refer to it, in an attempt to clarify that I was What I was trying to ask was: Should an inlined CORE::require CV
As I mentioned above, it�s all about the discrepancy between �require� -- Father Chrysostomos |
From zefram@fysh.orgFather Chrysostomos via RT wrote:
This shouldn't be distinguishable from using an appropriate custom parser
I think here you're talking about the difference that arises if a As it is, "CORE::require", used without sigil, always refers to the
(supposing that by "callbacks" you're referring to the CORE::GLOBAL:: This also immediately leads us to the blindingly obvious realisation Same goes for everything that's currently subject to CORE::GLOBAL::. Is this the problem you were referring to? If you meant something else, -zefram |
From @cpansproutOn Sun May 20 15:11:05 2012, zefram@fysh.org wrote:
I�m referring to that and �use subs�, as used by require, glob, do, qx
Even if we don�t reify it (and I don�t see the practical application of
I presume you mean that the parser invokes CORE::DEFAULT::* to decide For most built-in functions, CORE::DEFAULT::foo simply delegates to an CORE::DEFAULT::require delegates to CORE::require in the absence of an CORE::DEFAULT::qx delegates to CORE::qx. And then CORE::qx invokes a $ ./perl -Ilib -e 'use subs "readpipe"; sub readpipe{warn "called"} It used to be that CORE::glob would invoke CORE::GLOBAL::glob, but I So we have things in CORE:: that look at CORE::GLOBAL. That�s why I came That�s the discrepancy I was trying to describe. We really have quite a (In all those cases where I have talked about bypassing the call checker -- Father Chrysostomos |
From zefram@fysh.orgFather Chrysostomos via RT wrote:
Obvious practical application is to be able to get the default behaviour
Yes.
Right, the complication is that it isn't a *complete* delegation to
Yes, and we must maintain all, or at least most, of those oddities.
This behaviour is up for negotiation. I think it makes most sense -zefram |
From zefram@fysh.orgFather Chrysostomos via RT wrote:
My basic concept is that the keyword-style name lookup searches through Where we currently have feature flags that make additional keywords You'd be able to completely replace the default set of keywords by Your "overrides" feature roughly corresponds to putting CORE::DEFAULT
Ooh, interesting difference. This is quite similar to hov "s:" is treated
Yow. We might want to remove that one. -zefram |
From @rjbs* Nicholas Clark <nick@ccl4.org> [2012-04-24T03:39:11]
That is a bug. -- |
From @rjbs* Ricardo Signes <perl.p5p@rjbs.manxome.org> [2012-05-31T22:38:28]
Well, *was* a bug. :) -- |
From @cpansproutOn Mon May 21 05:00:56 2012, zefram@fysh.org wrote:
How exactly would that work in practice? A pragma? �use keywords And where would lexical subs fit into that scheme? Should CORE::glob
What would the public API for that be? CvKEYWORD_on?
But we mustn�t break �require if ...�. On the other hand, I think require VERSION should be a *syntactic*, not -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Mon May 21 05:00:56 2012, zefram@fysh.org wrote:
How exactly would that work in practice? A pragma? �use keywords And where would lexical subs fit into that scheme? Should CORE::glob
What would the public API for that be? CvKEYWORD_on?
But we mustn�t break �require if ...�. On the other hand, I think require VERSION should be a *syntactic*, not -- Father Chrysostomos |
From @cpansproutOn Wed Jul 04 14:24:15 2012, sprout wrote:
I am leaning toward letting lexical subs override anything and be -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Wed Jul 04 14:24:15 2012, sprout wrote:
I am leaning toward letting lexical subs override anything and be -- Father Chrysostomos |
Migrated from rt.perl.org#108286 (status was 'open')
Searchable as RT108286$
The text was updated successfully, but these errors were encountered: