develooper Front page | perl.perl5.porters | Postings from June 2021

Re: RFC 0004 - defer {} syntax

Thread Previous | Thread Next
From:
Paul "LeoNerd" Evans
Date:
June 17, 2021 11:40
Subject:
Re: RFC 0004 - defer {} syntax
Message ID:
20210617124008.0109cc91@shy.leonerd.org.uk
On Thu, 17 Jun 2021 12:16:01 +0300
Sergey Aleynikov <sergey.aleynikov@gmail.com> wrote:

> - why invent a new verb for already existing semantic?
> - what do all current CPAN implementations lack, thus requiring this
> feature?
> - why has this to be a core feature, compared to yet another CPAN
> module?
> - why any existing module can't be bundled with Perl, achieving this
> functionality?

First I'm going to quote Nicholas Clark's lovely reply to this on a
different thread:

>> Trouble is, that Perl is a Turing complete language. Meaning that
>> *any* possible new feature that could be proposed can already be
>> implemented with existing functionality.

>> So arguing against a new feature because it is already possible is,
>> well, tautological.

Secondly I'm going to point out a few things:

 * Aside from Syntax::Keyword::Defer, every other solution to this in
   CPAN all wraps the deferred code in an anon sub. Core's defer, and
   S-K-D do not. This has many effects but means, for example, that @_
   behaves "unexpectedly"; and caller() gets confused.

 * Additionally, all of the CPAN implementations besides S-K-D
   implement the deferred code by either DESTROY on an object, or using
   SAVEDESTRUCTOR_X to call_cv() an anon CV later on. In both of these
   cases, the deferred code could throw an exception, which by
   necessity is non-fatal to the surrounding code and is either
   ignored, or simply printed with a warning. S-K-D, and my core
   implementation, do not do this. They nest an inner RUNOPS loop,
   meaning that exceptions behave "as expected" - a `die` inside
   `defer` is thrown to the caller much like a `die` anywhere else.

 * All of the CPAN implementations, including S-K-D, have unfortunate
   interactions between next/last/redo (the "loopex" ops) and the defer
   block. A true core implementation can forbid these.

     while(1) {
       defer { last }
     }

   will cause core to die with "Unable to 'last' out of a defer block"

   whereas, any of the CPAN versions will either permit it but cause
   further confusions, or outright segfault the interpreter.

In summary, *all* of the CPAN solutions are worse than core can
provide, because core can do things no CPAN solution (including
pluggable keywords) can do. Specifically in this case, the core
solution adds a whole new context stack type (CXt_DEFER) that the
loopex ops can inspect to complain about trying to next/last/redo
out of. Also `goto`.

Thirdly, to answer your final point about why not just bundle the syntax
module with core perl: If the module were able to *perfectly* perform
the same work as core perl, this could technically work. However, note
above that it can't (CXt_DEFER). But even if this were possible, I
don't think that is a very nice way forward. The entire point of
pluggable syntax modules is to allow CPAN-based experimentation of new
features (Function::Parameters became feature 'signature';
Syntax::Keyword::Try became feature 'try'). The successful end-goal of
that experimentation is promoting the feature to becoming true core
syntax. There is no point in core shipping a syntax plugin module,
because core can just do core things.

This third point will always be my answer whenever anyone says "well
why can't we just ship that syntax module with core".

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About