Front page | perl.perl5.porters |
Postings from February 2018
Re: [perl #132760] Blead Breaks CPAN: YANICK/List-Lazy-0.3.0.tar.gz
Thread Previous
|
Thread Next
From:
Sawyer X
Date:
February 18, 2018 21:12
Subject:
Re: [perl #132760] Blead Breaks CPAN: YANICK/List-Lazy-0.3.0.tar.gz
Message ID:
3b9e87e0-456c-8edc-0c6d-0b340713a0da@gmail.com
Nicholas, thank you for replying in such detail. Please forgive my
brevity in return.
On 02/17/2018 12:00 PM, Nicholas Clark wrote:
> [...]
> But the first is that we're seriously proposing to (re-)add a special case.
>
> Yes, the implementation is full of them. But we should be striving to remove
> them, not take the viewpoint that "another one isn't going to make much of a
> difference".
You are right. I thought I had made the decision on changing the syntax
back in haste and decided to pause and take more time to reflect on it.
In retrospective, it might have been done in haste, but it's likely to
be the best of the two options nonetheless.
> [...]
> The second thing that bothers me a lot is this:
>
>> The potential that would be lost is to have attributes affect the
>> compilation of a subroutine's body code. The :lvalue attribute is an
>> instance of that kind of functionality. Another likely instance of it
>> came up in one of the threads about @_ suppression.
> [more detail]
>
>> There's quite a problem here in that it looks somewhat inevitable
>> for there to be some kind of per-sub control over @_ suppression.
>> Lexical flags can set defaults, but there's always going to be
>> the occasional exception. What we find here is that if subroutine
>> attributes preceding the body didn't exist then it would be necessary
>> to invent them. Currently we have them, but if they are abolished again
>> by moving signatures in front of attributes again then this would create
>> some design pressure to invent something new that does a similar job to
>> attributes but appears before a signature.
> Effectively here with lvalues we've already got a non-theoretical use case
> of why attributes need to be known before the signature is parsed.
>
> (Due to how perl 5 compiles code to optrees as soon as it's parsed. And
> *that* isn't going to change without a 7-figure development budget.
> The tokeniser is about 12K lines of code, op.c a further 17K. It's all
> intertwined code with no real documentation, and enough corner cases that
> almost any change will break *something* on CPAN, which requires a human
> to work out which side needs to fix what.)
>
>
> Zefram states another - any pragmatic implementation of @_ suppression is
> going to want to change how the optree is generated, and the signature is
> code and hence makes an optree.
>
>
> Any other functionality that we might want to add that involves
>
> 1) argument parsing
> 2) code that wraps functions
> 3) optree generation
>
>
> needs to be known about before the signature is parsed, which means that
> whatever enables it has to come before it. Whilst most features make sense
> to enable lexically, the ones that make sense *per-subroutine* (rather than
> *per-scope*) belong as attributes.
>
> I tried to think of stuff that we might want to do where they are most
> logically enabled via (core) subroutine attributes and apply to the signature
> too:
>
> sub foo :inlineable {
> ...
> }
>
> to signal that a subroutine should be inlined (where possible, and hence
> assume not to be redefinable or wrapped).
>
> Likely implementing such a feature would need to compile to a different set
> of template OPs, which can then be used to splice into caller subroutines,
> but that requirement for template OPs would apply to a signature too.
>
>
> and then likely rather hard to implement:
>
> sub foo :multimethod(Bar: $bar, Baz: $baz) {
> ...
> }
>
>
> but the declaration of which arguments are part of dispatch likely can't fit
> within the syntax of a signature, as Perl 5 doesn't have the colon available.
>
> (Remember, Perl 6 changes the ternary op to C<?? !!> which frees up the colon
> and hence lot of syntax possibilities which just can't work in Perl 5)
>
> and given that the attribute has declared 2 (or more) arguments, they wouldn't
> be repeated in the signature, but would affect argument processing, and hence
> how @_ is handled and optimised.
>
>
>
> For completeness, but probably not useful:
>
> sub foo :cached {
> ...
> }
>
> a built-in Memoize equivalent. Which logically *should* wrap code in the
> signature too, as signatures can make expensive computations, or hide this
> as calls to functions which are expensive.
>
> and also possibly not useful:
>
> sub foo :method {
> # implicit $self
> ...
> }
>
> sub foo :method(Bar: $this) {
> ...
> }
>
> as it's more logically covered by expanding signatures to take types (if
> there is syntax that is workable) or a keyword.
>
> But such an attribute could prefix the subroutine's code with a check that
> the first argument is an object (or an object of the correct type), and
> throw a meaningful exception if not, instead of generating a "cryptic"
> "Can't call method "..." without a package or object reference" from the
> code inside the signature or sub body. And again like the multimethod
> attribute, one wouldn't repeat the argument declaration in the signature.
>
> [Sawyer]:
> [Zefram]:
>>> This isn't the cost of not moving them. The cost is a narrow case of:
>> I'm not clear what you're trying to say here. You seem to be trying to
>> say that the situation I described doesn't apply to the lvalue issue?
>> It would be incorrect to say that. I described costs of having to
>> move parameter defaulting logic from a signature into the body block.
>> Putting signatures before attributes of course does not mean that *all*
>> defaulting logic would have to be moved. It only affects some subset
>> of default value expressions, likely just those containing return
>> expressions. Maybe even only on lvalue subs, though implementing that
>> would be an extra level of trickiness because of the :lvalue attribute
>> coming late. In the affected situations, the issues that I described
>> would be free to occur.
> I'm not sure either.
>
> But there is a clear cost here of preventing a whole class of future
> improvements. It's not just the narrow case of lvalue subroutines.
>
> [...]
I appreciate the time and effort you took in writing this. The points
both Zefram and yourself raise provide a solid case and we should indeed
keep it the way it is right now.
Thank you, Nick, Zefram, and Yves.
Thread Previous
|
Thread Next