develooper Front page | perl.perl5.porters | Postings from January 2022

Re: Can't localize lexical variable $x at ...

Thread Previous | Thread Next
From:
Paul "LeoNerd" Evans
Date:
January 25, 2022 17:28
Subject:
Re: Can't localize lexical variable $x at ...
Message ID:
20220125172825.0e685428@shy.leonerd.org.uk
On Tue, 25 Jan 2022 15:59:58 +0000
hv@crypt.org wrote:

> It would probably be useful to have examples where that distinction
> makes a difference - I didn't see any (explicit) mention of that in
> the lengthy perlsub section about local, nor in S::K::D. Are there
> cases where changing an existing valid local() invocation to use
> dynamically() instead would change the behaviour? My guess would be
> that if anything it would revolve around magic.

Anything involving subtle core magic would probably show the
differences. Outside of that it's not visible; even the magic that
implements tie goes to special steps to ensure it is handled in the
manner expected.

See the comments around `mg_localize` in mg.c:

  https://github.com/Perl/perl5/blob/535068756f421813eff4aae3784af48f00ea94b8/mg.c#L500

> I confess I don't understand the choice of "dynamically" for the name:
> "temporarily" would seem the obvious choice to me (and I'd very much
> want to abbreviate that to "temp"). "dynamic" is a concept with a few
> specific meanings in perl jargon and lots more outside of that: I
> think few average perl users would instinctively guess the correct
> meaning in this context.

Temporary is all about time. Dynamic extent isn't quite the same thing.

Without async/await, coroutines, or other such-like ideas, the two
words mean the same thing. But crucially, once you have the idea of a
suspended coroutine (which is what an `async sub` is while it is
waiting), you have the possibility that a single *dynamic* extent can
live across two disjoint regions of time, with a gap in the middle.
Since the assignment is suspended and restored along with this dynamic
extent, the word "dynamically" is a better fit than "temporarily".

Example:

  my $VAR = 1;

  async sub f {
    dynamically $VAR = 2;
    say "VAR is $VAR";

    await Future::IO->sleep(3);

    say "VAR is $VAR";
  }

At both of the `say` lines, the dynamic assignment to VAR has the value
2 visible. But outside of those, the value remains 1. This is true even
if the program pauses an invocation of f() in order to go off and do
other things in the meantime, and comes back to finish running f()
three seconds later. This was one dynamic extent, split across two
separate temporal extents with a 3-second gap.

> As a module it does not appear to require Async even be installed,
> could it not continue to act as it does now? 

That's because it ships with a copy of Future-AsyncAwait's extension
API header file:

  https://metacpan.org/release/PEVANS/Syntax-Keyword-Dynamically-0.09/source/AsyncAwait.h

It builds against that at compiletime, even if the Future::AsyncAwait
module isn't available.

> Or is the problem that
> it could not then easily be adapted (via a new release) to unknown
> future async changes? Or just that it's not the done thing for core
> code to have special handling for non-core modules?

I wouldn't want to have to include AsyncAwait.h with perl 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