FINALLY - ready for comments/review

Yes, I've renamed it again ;) I was eventually convinced that because
it's so similar in semantics to try/finally syntax, that we'd probably
be best off calling it `FINALLY { ... }`. So, here it is.

The branch overall is now at

  https://github.com/Perl/perl5/tree/leonerd/finally_block

It is now ready for general comment and review; I'll make a PR for it
soon.

In particular, one thing I'd like comment on is the documentation. So
far it's a fairly minimal "bare-bones" description of what it does, but
not really going into why, or suggestions on how it should be used:

  https://github.com/Perl/perl5/blob/leonerd/finally_block/pod/perlsyn.pod#finally-blocks-

Suggestions on more/better docs would be most welcome. I often find
that, as the person who implemented it, having my nose so close to the
ground makes me less than ideal to write documentation about it, and a
fresh perspective from others would help there.

When it comes to a technical review of the implementation code, I have
a bunch more comments to make, but I'll add them in a separate mail.

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/
0
leonerd
7/21/2020 10:47:55 PM
perl.perl5.porters 48172 articles. 1 followers. Follow

22 Replies
37 Views

Similar Articles

[PageSpeed] 20

Hi Paul,

	I find your documentation clear enough. I particularly =
appreciated that compare/contrast with END blocks.

	The only potential =E2=80=9Cshin-bumper=E2=80=9D that stood out =
to me was the undefined behavior when an exception escapes a FINALLY =
that=E2=80=99s already called from an exception. Was this to leave =
leeway for defining the behavior later?

-F

> On Jul 21, 2020, at 6:47 PM, Paul LeoNerd Evans =
<leonerd@leonerd.org.uk> wrote:
>=20
> Yes, I've renamed it again ;) I was eventually convinced that because
> it's so similar in semantics to try/finally syntax, that we'd probably
> be best off calling it `FINALLY { ... }`. So, here it is.
>=20
> The branch overall is now at
>=20
>  https://github.com/Perl/perl5/tree/leonerd/finally_block
>=20
> It is now ready for general comment and review; I'll make a PR for it
> soon.
>=20
> In particular, one thing I'd like comment on is the documentation. So
> far it's a fairly minimal "bare-bones" description of what it does, =
but
> not really going into why, or suggestions on how it should be used:
>=20
>  =
https://github.com/Perl/perl5/blob/leonerd/finally_block/pod/perlsyn.pod#f=
inally-blocks-
>=20
> Suggestions on more/better docs would be most welcome. I often find
> that, as the person who implemented it, having my nose so close to the
> ground makes me less than ideal to write documentation about it, and a
> fresh perspective from others would help there.
>=20
> When it comes to a technical review of the implementation code, I have
> a bunch more comments to make, but I'll add them in a separate mail.
>=20
> --=20
> Paul "LeoNerd" Evans
>=20
> leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
> http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/
0
felipe
7/22/2020 12:02:00 AM
"Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk> wrote:
:Yes, I've renamed it again ;) I was eventually convinced that because
:it's so similar in semantics to try/finally syntax, that we'd probably
:be best off calling it `FINALLY { ... }`. So, here it is.

I'm concerned (sorry) about the name - it gives no intrinsic hint how
it might be different from END. I liked the original name (which I've
forgotten after all the discussion: I think it was SCOPED, but it
certainly had SCOPE in the name).

I think it would be really helpful for the name to give some intrinsic
hint to how it differs from other phasers.

I do not personally see it as a huge benefit per se to have a name used
for something similar in other languages unless they do so because it
gives a clear indication either of how it is applied or how it is to be
used. 

If comparing it to other languages, please consider whether those
languages also have END, and if not whether the meaning of FINALLY
would be as obvious if they did.

Hugo
0
hv
7/22/2020 12:57:46 AM
--000000000000cabe1c05aafdb66a
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tue, Jul 21, 2020 at 8:02 PM Felipe Gasper <felipe@felipegasper.com>
wrote:

> Hi Paul,
>
>         I find your documentation clear enough. I particularly appreciate=
d
> that compare/contrast with END blocks.
>
>         The only potential =E2=80=9Cshin-bumper=E2=80=9D that stood out t=
o me was the
> undefined behavior when an exception escapes a FINALLY that=E2=80=99s alr=
eady
> called from an exception. Was this to leave leeway for defining the
> behavior later?
>

It's hard to say either what *should* happen here design wise, or what
would be most useful to the most people. Mainly there are three options:
the original exception continues to propagate and the new one is turned
into a warning; the original exception is turned into a warning and the new
one propagates; or they are combined into a new exception. This last
option, while cleanest, is pretty much impossible to get right with the
current string based (but other things allowed) exception system.

-Dan

--000000000000cabe1c05aafdb66a
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr">On Tue, Jul 21, 2020 at 8:02 PM Felipe Ga=
sper &lt;<a href=3D"mailto:felipe@felipegasper.com">felipe@felipegasper.com=
</a>&gt; wrote:<br></div><div class=3D"gmail_quote"><blockquote class=3D"gm=
ail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,=
204,204);padding-left:1ex">Hi Paul,<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 I find your documentation clear enough. I parti=
cularly appreciated that compare/contrast with END blocks.<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 The only potential =E2=80=9Cshin-bumper=E2=80=
=9D that stood out to me was the undefined behavior when an exception escap=
es a FINALLY that=E2=80=99s already called from an exception. Was this to l=
eave leeway for defining the behavior later?<br></blockquote><div><br></div=
><div>It&#39;s hard to say either what *should* happen here design wise, or=
 what would be most useful to the most people. Mainly there are three optio=
ns: the original exception continues to propagate and the new one is turned=
 into a warning; the original exception is turned into a warning and the ne=
w one propagates; or they are combined into a new exception. This last opti=
on, while cleanest, is pretty much impossible to get right with the current=
 string based (but other things allowed) exception system.</div><div><br></=
div><div>-Dan</div></div></div>

--000000000000cabe1c05aafdb66a--
0
grinnz
7/22/2020 1:32:18 AM
On Tue, 21 Jul 2020 21:32:18 -0400
Dan Book <grinnz@gmail.com> wrote:

> On Tue, Jul 21, 2020 at 8:02 PM Felipe Gasper
> <felipe@felipegasper.com> wrote:
> >         The only potential =E2=80=9Cshin-bumper=E2=80=9D that stood out=
 to me was
> > the undefined behavior when an exception escapes a FINALLY that=E2=80=
=99s
> > already called from an exception. Was this to leave leeway for
> > defining the behavior later?
>=20
> It's hard to say either what *should* happen here design wise, or what
> would be most useful to the most people. Mainly there are three
> options: the original exception continues to propagate and the new
> one is turned into a warning; the original exception is turned into a
> warning and the new one propagates; or they are combined into a new
> exception. This last option, while cleanest, is pretty much
> impossible to get right with the current string based (but other
> things allowed) exception system.

Indeed - the current wording is to allow the room in future to adjust
it into a better form.

Right now it takes the later of the two exceptions but I am hoping that
somewhere down the line when we have real first-class exception types,
it can be turned into a combined "B happened because of A" double-fault
exception.


Also in general, prettymuch the only time that I *specify* that
something is unspecified is because I wish to have the freedom to
change it in future. It becomes one of those "known unknown" situations
that draws attention to itself because of that. ;) Whereas, if I had
just not mentioned something, that's probably because I forgot to write
about it.

--=20
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/
0
leonerd
7/22/2020 8:55:01 AM

> On Jul 21, 2020, at 9:32 PM, Dan Book <grinnz@gmail.com> wrote:
>=20
> On Tue, Jul 21, 2020 at 8:02 PM Felipe Gasper =
<felipe@felipegasper.com> wrote:
> Hi Paul,
>=20
>         I find your documentation clear enough. I particularly =
appreciated that compare/contrast with END blocks.
>=20
>         The only potential =E2=80=9Cshin-bumper=E2=80=9D that stood =
out to me was the undefined behavior when an exception escapes a FINALLY =
that=E2=80=99s already called from an exception. Was this to leave =
leeway for defining the behavior later?
>=20
> It's hard to say either what *should* happen here design wise, or what =
would be most useful to the most people. Mainly there are three options: =
the original exception continues to propagate and the new one is turned =
into a warning; the original exception is turned into a warning and the =
new one propagates; or they are combined into a new exception. This last =
option, while cleanest, is pretty much impossible to get right with the =
current string based (but other things allowed) exception system.

I get that, but is it better to have =E2=80=9Cnasal demons=E2=80=9D or =
just to pick A or B?

Regarding C: spitballing a bit =E2=80=A6

-----
FINALLY {
    my $second =3D MyError->new('from finally');
    die $second;
}

my $first =3D MyError->new('from parent');
die $first;
-----

What if $first->TRAP($second) were called here, and $first continued to =
propagate? Or, $second->CLOBBER($first) were called, and $second =
propagated?

-F=
0
felipe
7/22/2020 11:09:21 AM
On Wed, 22 Jul 2020 07:09:21 -0400
Felipe Gasper <felipe@felipegasper.com> wrote:

> Regarding C: spitballing a bit =E2=80=A6
>=20
> -----
> FINALLY {
>     my $second =3D MyError->new('from finally');
>     die $second;
> }
>=20
> my $first =3D MyError->new('from parent');
> die $first;
> -----
>=20
> What if $first->TRAP($second) were called here, and $first continued
> to propagate? Or, $second->CLOBBER($first) were called, and $second
> propagated?

None of that is possible right now, because the vast majority of
exceptions are plain strings.

Things like that could be looked into later when exceptions are not
just plain strings.

--=20
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/
0
leonerd
7/22/2020 12:33:33 PM
On Wed, 22 Jul 2020 01:57:46 +0100
hv@crypt.org wrote:

> I'm concerned (sorry) about the name - it gives no intrinsic hint how
> it might be different from END. I liked the original name (which I've
> forgotten after all the discussion: I think it was SCOPED, but it
> certainly had SCOPE in the name).

Originally it was `LEAVE` because it was following Raku's idea. But
then I changed it to `CLEANUP` because it no longer had the same
semantics. Already someone objected to that:

  On Thu, 16 Jul 2020 12:49:23 +1200
  Kent Fredric <kentfredric@gmail.com> wrote:

  > My main objection to calling it "CLEANUP" is it seems to indicate
  > "how you should use this", as opposed to being an indicative
  > mechanic of "this is how this code block executes".

On a list this size it seems impossible to please everyone ;)

> I think it would be really helpful for the name to give some intrinsic
> hint to how it differs from other phasers.

  WHEN_LEAVING_THIS_SCOPE { ... }

Could be shorter...

> I do not personally see it as a huge benefit per se to have a name
> used for something similar in other languages unless they do so
> because it gives a clear indication either of how it is applied or
> how it is to be used. 
> 
> If comparing it to other languages, please consider whether those
> languages also have END, and if not whether the meaning of FINALLY
> would be as obvious if they did.

We still need *a* name. LEAVE and CLEANUP are no good, the next idea
was FINALLY, inspired by quite a few other languages. Short of opening
a vote [for which this mailing list is a terrible implementation] on a
few other candidates, I can't see much other option.

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/
0
leonerd
7/22/2020 12:41:40 PM

> On Jul 22, 2020, at 8:33 AM, Paul LeoNerd Evans =
<leonerd@leonerd.org.uk> wrote:
>=20
> On Wed, 22 Jul 2020 07:09:21 -0400
> Felipe Gasper <felipe@felipegasper.com> wrote:
>=20
>> Regarding C: spitballing a bit =E2=80=A6
>>=20
>> -----
>> FINALLY {
>>    my $second =3D MyError->new('from finally');
>>    die $second;
>> }
>>=20
>> my $first =3D MyError->new('from parent');
>> die $first;
>> -----
>>=20
>> What if $first->TRAP($second) were called here, and $first continued
>> to propagate? Or, $second->CLOBBER($first) were called, and $second
>> propagated?
>=20
> None of that is possible right now, because the vast majority of
> exceptions are plain strings.
>=20
> Things like that could be looked into later when exceptions are not
> just plain strings.

My thought was: would the pattern from PROPAGATE() work? That=E2=80=99s =
an example of Perl =E2=80=9Cdoing the OO thing=E2=80=9D when an =
exception is an object but ignoring it otherwise.

-F=
0
felipe
7/22/2020 2:07:35 PM
"Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk> wrote:
:On Wed, 22 Jul 2020 01:57:46 +0100
:hv@crypt.org wrote:
:
:> I'm concerned (sorry) about the name - it gives no intrinsic hint how
:> it might be different from END. I liked the original name (which I've
:> forgotten after all the discussion: I think it was SCOPED, but it
:> certainly had SCOPE in the name).
:
:Originally it was `LEAVE` because it was following Raku's idea. But
:then I changed it to `CLEANUP` because it no longer had the same
:semantics. Already someone objected to that:

Thanks, I stand corrected.

:On a list this size it seems impossible to please everyone ;)

This is established fact.

:> If comparing it to other languages, please consider whether those
:> languages also have END, and if not whether the meaning of FINALLY
:> would be as obvious if they did.
:
:We still need *a* name. LEAVE and CLEANUP are no good, the next idea
:was FINALLY, inspired by quite a few other languages. Short of opening
:a vote [for which this mailing list is a terrible implementation] on a
:few other candidates, I can't see much other option.

I agree that naming things is hard. I think it would help hugely if
the chosen name, placed next to 'END', would give an obvious hint which
one triggered at the end of the scope and which at the end of the program.

Maybe it matters less than I think: I can certainly imagine this being
used far more heavily than things like CHECK and INIT, and it's entirely
possible that I never had a clue when those 2 fired less because of their
names and more because of how rarely I found a use for them. But I suspect,
conversely, that I rarely found a use for them because I never got straight
when they fired, and that the lack of distinction in the names was a
primary contributor to that state of affairs.

Hugo
0
hv
7/22/2020 3:00:48 PM
On Tue, 21 Jul 2020 23:47:55 +0100
"Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk> wrote:

> When it comes to a technical review of the implementation code, I have
> a bunch more comments to make, but I'll add them in a separate mail.

Here:

In order to provide this, I've had to touch quite a few bits of core
perl innards. I've had to create a new

  * keyword (`KEY_FINALLY`)

  * named feature (`use feature 'finally_block'`)

  * named warning (`no warnings 'experimental::finally_block'`)

  * opcode (`OP_PUSHFINALLY`)

  * context stack type (`CXt_FINALLY`)

The first four are fairly standard things to do for new core syntax,
but reason for adding a new context stack type requires a bit more
explaining:

  Due to the way that FINALLY blocks are invoked on stack unwind,
  allowing them to act as bare blocks rather than self-contained subs
  means they can't be CV-wrapped and have to be invoked as an OP chain.
  Because of this, they can't be invoked by call_sv() but instead have
  to be invoked directly with CALLRUNOPS() on its opchain. Without
  additional information, the block inside would be able to break the
  interpreter in a segfaulty way by using `return`, `goto` or one of
  the loop controls (next/last/redo). This must be prevented.

  To detect this, I have added a CXt_FINALLY context stack type, which
  those forbidden controls can then use to realise they would otherwise
  be about to unwind past the CXt_FINALLY frame, and prevent it from
  doing so.

In addition, on the subject of opcode and its OP representation:

  While OP_PUSHFINALLY is a PVOP type, its value doesn't actually store
  a PV, but instead a pair of OP pointers. It is currently slightly
  messy to do this, but since elsewise not many other things use a PVOP
  it didn't seem too problematic to extend its definition in this way.

  An alternative approach would have been to create an entire new OP
  class, probably named something odd like an OPOP, to store a subtree
  not intended for inline execution. I judged that adding an entire on
  OP class would be a lot more work and disturb even more code than the
  limited amount already done. This new op class would only be used for
  this single OP_PUSHFINALLY case, so it currently doesn't feel
  justified.

  If reviewers would prefer, I can look into that instead; though that
  would lead to an even larger set of changes.


Finally[1] as an overall comment I would like to add that if this
branch gets merged, I would like to be able to use it as some teaching
examples. Since it touches on so many parts of the interpreter, in a
fairly self-contained and neat manner, it could serve well for a series
of "how to add stuff" tutorials, to explain to new would-be core
maintainers how to perform these substantial kinds of additions. If it
is to serve as a good example, it should do things Properly.


[1]: Pardon the pun ;)

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/
0
leonerd
7/22/2020 9:04:06 PM
On 2020-07-22 6:41 am, Paul "LeoNerd" Evans wrote:
>    WHEN_LEAVING_THIS_SCOPE { ... }
> Could be shorter...

Eh, that's what editor macros are for....


LEAVING    # kind of like Raku's LEAVE but not quite the same
WRAPUP     # like CLEANUP but doesn't require actual cleaning
FINISH     # less "final" than FINALLY?
DESCOPE    # ugh!
CLOSE      # sounds too much like a filehandle?
CEASE      # will result in lots of CEASEr puns
CONCLUDE   # in case of error, jump to conclusions
DEPART     # begone! (hey, BEGONE could work too)
FULFIL     # or is that FULFILL?
CAP_OFF    # caps off to Larry!
WINDUP     # well, one...
WINDDOWN   # ...or the other has to work, right?
GOODBYE    # aka LOGOUT
CONSUMMATE # poetical... maybe too much so
RESOLUTION # be it affirmed this block of code will run
END_BLOCK  # like END but for a block
0
david
7/23/2020 4:43:31 AM
On 23/7/20 6:43, David Green wrote:
 > On 2020-07-22 6:41 am, Paul "LeoNerd" Evans wrote:
 >>    WHEN_LEAVING_THIS_SCOPE { ... }
 >> Could be shorter...
 >
 > Eh, that's what editor macros are for....
 >
 >
 > LEAVING    # kind of like Raku's LEAVE but not quite the same
 > WRAPUP     # like CLEANUP but doesn't require actual cleaning
 > FINISH     # less "final" than FINALLY?
 > DESCOPE    # ugh!
 > CLOSE      # sounds too much like a filehandle?
 > CEASE      # will result in lots of CEASEr puns
 > CONCLUDE   # in case of error, jump to conclusions
 > DEPART     # begone! (hey, BEGONE could work too)
 > FULFIL     # or is that FULFILL?
 > CAP_OFF    # caps off to Larry!
 > WINDUP     # well, one...
 > WINDDOWN   # ...or the other has to work, right?
 > GOODBYE    # aka LOGOUT
 > CONSUMMATE # poetical... maybe too much so
 > RESOLUTION # be it affirmed this block of code will run
 > END_BLOCK  # like END but for a block

ANYWAY
ALWAYS
LATER
my END { ... }
0
sfandino
7/23/2020 11:15:51 AM
--000000000000565bbe05ab1adf67
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

UNWIND still has the most RAM (or is it mauve...)

On Thu, Jul 23, 2020 at 2:15 PM Salvador Fandi=C3=B1o <sfandino@gmail.com> =
wrote:

> On 23/7/20 6:43, David Green wrote:
>  > On 2020-07-22 6:41 am, Paul "LeoNerd" Evans wrote:
>  >>    WHEN_LEAVING_THIS_SCOPE { ... }
>  >> Could be shorter...
>  >
>  > Eh, that's what editor macros are for....
>  >
>  >
>  > LEAVING    # kind of like Raku's LEAVE but not quite the same
>  > WRAPUP     # like CLEANUP but doesn't require actual cleaning
>  > FINISH     # less "final" than FINALLY?
>  > DESCOPE    # ugh!
>  > CLOSE      # sounds too much like a filehandle?
>  > CEASE      # will result in lots of CEASEr puns
>  > CONCLUDE   # in case of error, jump to conclusions
>  > DEPART     # begone! (hey, BEGONE could work too)
>  > FULFIL     # or is that FULFILL?
>  > CAP_OFF    # caps off to Larry!
>  > WINDUP     # well, one...
>  > WINDDOWN   # ...or the other has to work, right?
>  > GOODBYE    # aka LOGOUT
>  > CONSUMMATE # poetical... maybe too much so
>  > RESOLUTION # be it affirmed this block of code will run
>  > END_BLOCK  # like END but for a block
>
> ANYWAY
> ALWAYS
> LATER
> my END { ... }
>

--000000000000565bbe05ab1adf67
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">UNWIND still has the most RAM (or is it mauve...)<br></div=
><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Th=
u, Jul 23, 2020 at 2:15 PM Salvador Fandi=C3=B1o &lt;<a href=3D"mailto:sfan=
dino@gmail.com">sfandino@gmail.com</a>&gt; wrote:<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid r=
gb(204,204,204);padding-left:1ex">On 23/7/20 6:43, David Green wrote:<br>
=C2=A0&gt; On 2020-07-22 6:41 am, Paul &quot;LeoNerd&quot; Evans wrote:<br>
=C2=A0&gt;&gt;=C2=A0 =C2=A0 WHEN_LEAVING_THIS_SCOPE { ... }<br>
=C2=A0&gt;&gt; Could be shorter...<br>
=C2=A0&gt;<br>
=C2=A0&gt; Eh, that&#39;s what editor macros are for....<br>
=C2=A0&gt;<br>
=C2=A0&gt;<br>
=C2=A0&gt; LEAVING=C2=A0 =C2=A0 # kind of like Raku&#39;s LEAVE but not qui=
te the same<br>
=C2=A0&gt; WRAPUP=C2=A0 =C2=A0 =C2=A0# like CLEANUP but doesn&#39;t require=
 actual cleaning<br>
=C2=A0&gt; FINISH=C2=A0 =C2=A0 =C2=A0# less &quot;final&quot; than FINALLY?=
<br>
=C2=A0&gt; DESCOPE=C2=A0 =C2=A0 # ugh!<br>
=C2=A0&gt; CLOSE=C2=A0 =C2=A0 =C2=A0 # sounds too much like a filehandle?<b=
r>
=C2=A0&gt; CEASE=C2=A0 =C2=A0 =C2=A0 # will result in lots of CEASEr puns<b=
r>
=C2=A0&gt; CONCLUDE=C2=A0 =C2=A0# in case of error, jump to conclusions<br>
=C2=A0&gt; DEPART=C2=A0 =C2=A0 =C2=A0# begone! (hey, BEGONE could work too)=
<br>
=C2=A0&gt; FULFIL=C2=A0 =C2=A0 =C2=A0# or is that FULFILL?<br>
=C2=A0&gt; CAP_OFF=C2=A0 =C2=A0 # caps off to Larry!<br>
=C2=A0&gt; WINDUP=C2=A0 =C2=A0 =C2=A0# well, one...<br>
=C2=A0&gt; WINDDOWN=C2=A0 =C2=A0# ...or the other has to work, right?<br>
=C2=A0&gt; GOODBYE=C2=A0 =C2=A0 # aka LOGOUT<br>
=C2=A0&gt; CONSUMMATE # poetical... maybe too much so<br>
=C2=A0&gt; RESOLUTION # be it affirmed this block of code will run<br>
=C2=A0&gt; END_BLOCK=C2=A0 # like END but for a block<br>
<br>
ANYWAY<br>
ALWAYS<br>
LATER<br>
my END { ... }<br>
</blockquote></div>

--000000000000565bbe05ab1adf67--
0
rabbiveesh
7/23/2020 12:19:36 PM
On 7/23/20 6:19 AM, Veesh Goldman wrote:
> UNWIND still has the most RAM (or is it mauve...)
>=20
> On Thu, Jul 23, 2020 at 2:15 PM Salvador Fandi=C3=B1o <sfandino@gmail.c=
om=20
> <mailto:sfandino@gmail.com>> wrote:
>=20
>     On 23/7/20 6:43, David Green wrote:
>      =C2=A0> On 2020-07-22 6:41 am, Paul "LeoNerd" Evans wrote:
>      =C2=A0>>=C2=A0 =C2=A0 WHEN_LEAVING_THIS_SCOPE { ... }
>      =C2=A0>> Could be shorter...
>      =C2=A0>
>      =C2=A0> Eh, that's what editor macros are for....
>      =C2=A0>
>      =C2=A0>
>      =C2=A0> LEAVING=C2=A0 =C2=A0 # kind of like Raku's LEAVE but not q=
uite the same
>      =C2=A0> WRAPUP=C2=A0 =C2=A0 =C2=A0# like CLEANUP but doesn't requi=
re actual cleaning
>      =C2=A0> FINISH=C2=A0 =C2=A0 =C2=A0# less "final" than FINALLY?
>      =C2=A0> DESCOPE=C2=A0 =C2=A0 # ugh!
>      =C2=A0> CLOSE=C2=A0 =C2=A0 =C2=A0 # sounds too much like a filehan=
dle?
>      =C2=A0> CEASE=C2=A0 =C2=A0 =C2=A0 # will result in lots of CEASEr =
puns
>      =C2=A0> CONCLUDE=C2=A0 =C2=A0# in case of error, jump to conclusio=
ns
>      =C2=A0> DEPART=C2=A0 =C2=A0 =C2=A0# begone! (hey, BEGONE could wor=
k too)
>      =C2=A0> FULFIL=C2=A0 =C2=A0 =C2=A0# or is that FULFILL?
>      =C2=A0> CAP_OFF=C2=A0 =C2=A0 # caps off to Larry!
>      =C2=A0> WINDUP=C2=A0 =C2=A0 =C2=A0# well, one...
>      =C2=A0> WINDDOWN=C2=A0 =C2=A0# ...or the other has to work, right?
>      =C2=A0> GOODBYE=C2=A0 =C2=A0 # aka LOGOUT
>      =C2=A0> CONSUMMATE # poetical... maybe too much so
>      =C2=A0> RESOLUTION # be it affirmed this block of code will run
>      =C2=A0> END_BLOCK=C2=A0 # like END but for a block
>=20
>     ANYWAY
>     ALWAYS
>     LATER
>     my END { ... }
>=20

AFTER_ALL_IS_SAID_AND_DONE
LAST_LAUGH
EPILOGUE
AFTERWARD
POSTSCRIPT
PS
GONE
EXIT
AT_EXIT
OUTA_HERE

consider a thesaurus
0
public
7/23/2020 2:06:57 PM
--Sig_/LMWAltq4PCsURC.h_v6V+M6
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thu, 23 Jul 2020 08:06:57 -0600, Karl Williamson
<public@khwilliamson.com> wrote:

> On 7/23/20 6:19 AM, Veesh Goldman wrote:
> > UNWIND still has the most RAM (or is it mauve...)
> >=20
> > On Thu, Jul 23, 2020 at 2:15 PM Salvador Fandi=C3=B1o
> > <sfandino@gmail.com <mailto:sfandino@gmail.com>> wrote:
> >=20
> >     On 23/7/20 6:43, David Green wrote: =20
> >      =C2=A0> On 2020-07-22 6:41 am, Paul "LeoNerd" Evans wrote: =20
>  [...] =20
> >      =C2=A0>
> >      =C2=A0> Eh, that's what editor macros are for....
> >      =C2=A0>
> >      =C2=A0>
> >      =C2=A0> LEAVING=C2=A0 =C2=A0 # kind of like Raku's LEAVE but not q=
uite the
> > same > WRAPUP=C2=A0 =C2=A0 =C2=A0# like CLEANUP but doesn't require act=
ual cleaning
> >      =C2=A0> FINISH=C2=A0 =C2=A0 =C2=A0# less "final" than FINALLY?
> >      =C2=A0> DESCOPE=C2=A0 =C2=A0 # ugh!
> >      =C2=A0> CLOSE=C2=A0 =C2=A0 =C2=A0 # sounds too much like a filehan=
dle?
> >      =C2=A0> CEASE=C2=A0 =C2=A0 =C2=A0 # will result in lots of CEASEr =
puns
> >      =C2=A0> CONCLUDE=C2=A0 =C2=A0# in case of error, jump to conclusio=
ns
> >      =C2=A0> DEPART=C2=A0 =C2=A0 =C2=A0# begone! (hey, BEGONE could wor=
k too)
> >      =C2=A0> FULFIL=C2=A0 =C2=A0 =C2=A0# or is that FULFILL?
> >      =C2=A0> CAP_OFF=C2=A0 =C2=A0 # caps off to Larry!
> >      =C2=A0> WINDUP=C2=A0 =C2=A0 =C2=A0# well, one...
> >      =C2=A0> WINDDOWN=C2=A0 =C2=A0# ...or the other has to work, right?
> >      =C2=A0> GOODBYE=C2=A0 =C2=A0 # aka LOGOUT
> >      =C2=A0> CONSUMMATE # poetical... maybe too much so
> >      =C2=A0> RESOLUTION # be it affirmed this block of code will run
> >      =C2=A0> END_BLOCK=C2=A0 # like END but for a block =20
> >=20
> >     ANYWAY
> >     ALWAYS
> >     LATER
> >     my END { ... }
> >  =20
>=20
> AFTER_ALL_IS_SAID_AND_DONE
> LAST_LAUGH
> EPILOGUE
> AFTERWARD
> POSTSCRIPT
> PS

I LIKE THAT ONE!

Post Scriptum - PS - Post Scope :)

SCOPE_END / ON_SCOPE_END etc all associate with DESTROY in my head

> GONE
> EXIT
> AT_EXIT
> OUTA_HERE
>=20
> consider a thesaurus

--=20
H.Merijn Brand  http://tux.nl   Perl Monger  http://amsterdam.pm.org/
using perl5.00307 .. 5.31      porting perl5 on HP-UX, AIX, and Linux
https://useplaintext.email  https://tux.nl  http://www.test-smoke.org
http://qa.perl.org   http://www.goldmark.org/jeff/stupid-disclaimers/

--Sig_/LMWAltq4PCsURC.h_v6V+M6
Content-Type: application/pgp-signature
Content-Description: OpenPGP digital signature

-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEGolmczWuFi3lJEbAA6FHoT5dwJgFAl8Zm/0ACgkQA6FHoT5d
wJjJyQgAkZd3YJ7zMcCDc4qtGB4h+6nZ7x0bFY7jg2e+4YA0ShRqF3XxCmeS6Ar5
tmROroSG1XLM0nt/6zxELHcrZZS70G/MPeL+KoiWZrNQ5fmSYzbhJE4a/bZ5toJA
3mu4pYTKq2ip7Gt81GIyJNasltRev98DIyXSkHfTsxqVZL5aDqrAzd9tVZSt2V5D
Q1m4ypl6Nbwdy8OUBviGiNvN2gFnhpjj6mLmx5cOXA+VwJG70UacU9JzN47QtNmS
GxtQLr5XGhMdvpkLq1GgpZSR8PhChow7p3Z2tqnJvsi0kHSBEid0cDQkbB6iG+tQ
Wj6ktnuCpM3G9uktDz0zGIk6qrIXgQ==
=nRYS
-----END PGP SIGNATURE-----

--Sig_/LMWAltq4PCsURC.h_v6V+M6--
0
perl5
7/23/2020 2:17:33 PM
On 2020-07-23 8:17 am, H.Merijn Brand wrote:
 > On Thu, 23 Jul 2020 08:06:57 -0600, Karl Williamson wrote:
 >> PS
 > I LIKE THAT ONE!
 > Post Scriptum - PS - Post Scope :)

I like that too.


On 2020-07-23 5:15 am, Salvador Fandiño wrote:
> ANYWAY

That's quirky, but in a perlish way.


> my END { ... }

This struck me as funny-looking at first glance, but it actually makes a 
*lot* of sense.  Lexical subs have been around for a while now; and 
(even though nobody writes it this way) you *can* write an END block as:

sub END { ... }

I don't know whether we'd have to write it as "my sub END" instead of 
just "my END", but I really like the consistency of applying concepts 
that already exist instead of inventing something new to be learned: 
"sub END" is global, but "my sub END" has the same scoping as any other 
"my sub", only it runs at the end of the scope.
0
david
7/23/2020 4:31:39 PM
On Tue, Jul 21, 2020 at 11:47:55PM +0100, Paul "LeoNerd" Evans wrote:
> It is now ready for general comment and review; I'll make a PR for it
> soon.

Some random comments:

* using a PVOP - this is bad, and you should feel bad!!!! :-)

I'd suggest using a LOGOP instead as a somewhat less torturing approach.
If I understand correctly, the two OP pointers you want to hang off
the OP_PUSHFINALLY are the root op and start op of the block.

making logop->op_first point to the root op of the block is "normal" and
should make everything work just fine: for example at the moment
'perl -DX' and 'perl -MO=Concise' don't appear to display the body of the
block. Similarly, any B-type code will then automatically see the block,
e.g. if scanning the op tree for some reason.

The logop->op_other field is a generic pointer to some other op which
is usually in some way an alternative to op_next under some circumstances;
using this to store the block start is a slight stretch, but will
generally work well;  you just need to ensure that OP_PUSHFINALLY is
treated the same as OP_AND etc in places like Perl_rpeep so that
code within the block gets optimised.

I'd also suggest adding a test to t/perf/opcount.t that with code like
FINALLY { $a[0] } there is 1 aelemfast op present, proving that the code
within the blocjk has been optimised.

Similarly test that the block is processed by Perl_finalize_optree too,
e.g. do eval '{ FINALLY { use strict; foo }' and check that you get
'Bareword "foo" not allowed'. Even if it works at the moment, it might not
in future.

* why not just "use feature 'finally'" rather than 'finally_block'?

* I think pp_pushfinally should be in pp_ctl.c rather than pp.c as it's
related to flow control - its certainly where I would first look for
it.

* your branch doesn't current compile under threads.

* I like the name LEAVE - why was it rejected?

* docs: the opening line:

    A block prefixed by the FINALLY modifier provides a section of code
    which runs at a later time in execution.

I would change that to

    ...  at a later time during scope exit.

to more immediately emphasise what type of beast it is.

* docs: I would put explicit { }'s around your code examples to emphasise
  that things run on scope exit, as opposed to .. what? .. file exit???
  etc.


-- 
But Pity stayed his hand. "It's a pity I've run out of bullets",
he thought. -- "Bored of the Rings"
0
davem
7/27/2020 10:53:52 AM
On Mon, 27 Jul 2020 11:53:52 +0100
Dave Mitchell <davem@iabyn.com> wrote:

> On Tue, Jul 21, 2020 at 11:47:55PM +0100, Paul "LeoNerd" Evans wrote:
> > It is now ready for general comment and review; I'll make a PR for
> > it soon.  
> 
> Some random comments:
> 
> * using a PVOP - this is bad, and you should feel bad!!!! :-)

I do feel bad - that's why I flagged it up in the review ;)

> I'd suggest using a LOGOP instead as a somewhat less torturing
> approach. If I understand correctly, the two OP pointers you want to
> hang off the OP_PUSHFINALLY are the root op and start op of the block.

I did try a logop, but there were problems with connecting it through.
These are related to my having to manually call LINKLIST() and then
subsequently hunt the end of that chain and manually set the ->op_next
of it to NULL.

> making logop->op_first point to the root op of the block is "normal"
> and should make everything work just fine: for example at the moment
> 'perl -DX' and 'perl -MO=Concise' don't appear to display the body of
> the block. Similarly, any B-type code will then automatically see the
> block, e.g. if scanning the op tree for some reason.
> 
> The logop->op_other field is a generic pointer to some other op which
> is usually in some way an alternative to op_next under some
> circumstances; using this to store the block start is a slight
> stretch, but will generally work well;  you just need to ensure that
> OP_PUSHFINALLY is treated the same as OP_AND etc in places like
> Perl_rpeep so that code within the block gets optimised.

Related to above: I tried that, but the main trouble I had was that I
imagined that the ->op_first code would run _before_ pp_pushfinally
itself runs, which isn't what I want here. Isn't that what op_first is
for?

I want the embedded optree to be totally disconnected from the optree
in which the OP_PUSHFINALLY itself finds itself, just attached as some
additional data. Which is why I went with a PVOP - or my other idea of
an OPOP. It's a self-contained chain of ops, ending in a op_first of
NULL.

The required behaviour is that only pp_pushfinally runs, and uses
(currently) SAVEDESTRUCTOR to push to the save stack. The embedded
op(tree,chain?) gets stored on the savestack, for running later.

> I'd also suggest adding a test to t/perf/opcount.t that with code like
> FINALLY { $a[0] } there is 1 aelemfast op present, proving that the
> code within the blocjk has been optimised.

Cando.

> Similarly test that the block is processed by Perl_finalize_optree
> too, e.g. do eval '{ FINALLY { use strict; foo }' and check that you
> get 'Bareword "foo" not allowed'. Even if it works at the moment, it
> might not in future.

Good idea.

> * why not just "use feature 'finally'" rather than 'finally_block'?

I was considering that maybe someone might want a `finally` keyword on
its own, rather than the capitalised FINALLY phaser-type thing, so I
didn't want to hog that name. I guess it seems quite unlikely to have
both, so I could rename it.

> * I think pp_pushfinally should be in pp_ctl.c rather than pp.c as
> it's related to flow control - its certainly where I would first look
> for it.

Good idea.

> * your branch doesn't current compile under threads.

Ooh, huh. I thought I made a habit of testing that as well. I shall
look into it.

> * I like the name LEAVE - why was it rejected?

Difference with Raku's feature of that name.

In brief, in Raku LEAVE is like END, in that it is largely static and
does not depend on the dynamic path of execution:

   {
      return;
      LEAVE { say "This is still executed" }
   }

whereas the equivalent would not be the same of my code. I wanted to
make it safe to do things like

   {
      my $thing = Thing->new;
      FINALLY { $thing->dispose }

      ... use $thing here
   }

so the FINALLY code would *not* execute if Thing->new threw an
exception and therefore the line where the FINALLY appears was never
reached. That makes it different to Raku's LEAVE (and Perl's END), thus
I felt giving it a different name was best.

> * docs: the opening line:
> 
>     A block prefixed by the FINALLY modifier provides a section of
> code which runs at a later time in execution.
> 
> I would change that to
> 
>     ...  at a later time during scope exit.
> 
> to more immediately emphasise what type of beast it is.

Ahyes. Getting "scope exit" in there.

> * docs: I would put explicit { }'s around your code examples to
> emphasise that things run on scope exit, as opposed to .. what? ..
> file exit??? etc.

Yup, good again.

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/
0
leonerd
7/27/2020 12:37:38 PM
On Mon, Jul 27, 2020 at 01:37:38PM +0100, Paul "LeoNerd" Evans wrote:
> I did try a logop, but there were problems with connecting it through.
> These are related to my having to manually call LINKLIST() and then
> subsequently hunt the end of that chain and manually set the ->op_next
> of it to NULL.

I suspect that you were Doing Something Wrong - I can't think of any
particular reason why it being a logop wouldn't work.

I can expand further on what LINKLIST does and what the top subtree node's
op_next point to during compilation if you're unclear.

> > making logop->op_first point to the root op of the block is "normal"
> > and should make everything work just fine: for example at the moment
> > 'perl -DX' and 'perl -MO=Concise' don't appear to display the body of
> > the block. Similarly, any B-type code will then automatically see the
> > block, e.g. if scanning the op tree for some reason.
> > 
> > The logop->op_other field is a generic pointer to some other op which
> > is usually in some way an alternative to op_next under some
> > circumstances; using this to store the block start is a slight
> > stretch, but will generally work well;  you just need to ensure that
> > OP_PUSHFINALLY is treated the samspecified bye as OP_AND etc in places like
> > Perl_rpeep so that code within the block gets optimised.
> 
> Related to above: I tried that, but the main trouble I had was that I
> imagined that the ->op_first code would run _before_ pp_pushfinally
> itself runs, which isn't what I want here. Isn't that what op_first is
> for?
> 
> I want the embedded optree to be totally disconnected from the optree
> in which the OP_PUSHFINALLY itself finds itself, just attached as some
> additional data. Which is why I went with a PVOP - or my other idea of
> an OPOP. It's a self-contained chain of ops, ending in a op_first of
> NULL.

I think you're conflating structural op pointers with execution order
pointers.

In general, all ops for a particular sub are in the form of a single tree,
which says nothing about the execution order of the ops, nor which ops are
skipped/executed.

The structure of this tree is specified by op_first, op_sibling and
optionally, op_last. The children of a node are  op_first,
op_first->op->sibling, op_first->op->sibling->op_sibling etc, sometimes
with op_last as a shortcut to the last child.

The execution order of a sub is determined by the chain of op_next
pointers, which snakes its way through the optree (often in the order of a
depth-first search, but not necessarily). Some ops such as logic ops may
have more than one possible 'next' op; in this case they are stored as
op_next and op_other, and the op itslef is responsible for returning what
OP* pointer it thinks is suitable.

It should be completely harmless for a subtree of ops that won't get
called right away to be pointed to by op_first; and in fact this is
beneficial - it means that all the treewalking functions (both in core and
in B or XS code) will see the extra ops without needing special-casing.

See for example the optree for s/abc/$x/e; the sub-optree for the $x
expression is pointed to by op_first of the OP_SUBST, even thought the
expression may be called zero or more than one times. (Actually OP_SUBST
is a bit more complex than that, and is a bit of  messy case, which is one
reason why I'm keen for you to avoid adding another).

-- 
More than any other time in history, mankind faces a crossroads. One path
leads to despair and utter hopelessness. The other, to total extinction.
Let us pray we have the wisdom to choose correctly.
    -- Woody Allen
0
davem
7/27/2020 1:22:37 PM
On Thu, Jul 23, 2020 at 9:07 AM Karl Williamson <public@khwilliamson.com> w=
rote:
>
> On 7/23/20 6:19 AM, Veesh Goldman wrote:
> > UNWIND still has the most RAM (or is it mauve...)
> >
> > On Thu, Jul 23, 2020 at 2:15 PM Salvador Fandi=C3=B1o <sfandino@gmail.c=
om
> > <mailto:sfandino@gmail.com>> wrote:
> >
> >     On 23/7/20 6:43, David Green wrote:
> >       > On 2020-07-22 6:41 am, Paul "LeoNerd" Evans wrote:
> >       >>    WHEN_LEAVING_THIS_SCOPE { ... }
> >       >> Could be shorter...
> >       >
> >       > Eh, that's what editor macros are for....
> >       >
> >       >
> >       > LEAVING    # kind of like Raku's LEAVE but not quite the same
> >       > WRAPUP     # like CLEANUP but doesn't require actual cleaning
> >       > FINISH     # less "final" than FINALLY?
> >       > DESCOPE    # ugh!
> >       > CLOSE      # sounds too much like a filehandle?
> >       > CEASE      # will result in lots of CEASEr puns
> >       > CONCLUDE   # in case of error, jump to conclusions
> >       > DEPART     # begone! (hey, BEGONE could work too)
> >       > FULFIL     # or is that FULFILL?
> >       > CAP_OFF    # caps off to Larry!
> >       > WINDUP     # well, one...
> >       > WINDDOWN   # ...or the other has to work, right?
> >       > GOODBYE    # aka LOGOUT
> >       > CONSUMMATE # poetical... maybe too much so
> >       > RESOLUTION # be it affirmed this block of code will run
> >       > END_BLOCK  # like END but for a block
> >
> >     ANYWAY
> >     ALWAYS
> >     LATER
> >     my END { ... }
> >
>
> AFTER_ALL_IS_SAID_AND_DONE
> LAST_LAUGH
> EPILOGUE
> AFTERWARD
> POSTSCRIPT
> PS
> GONE
> EXIT
> AT_EXIT
> OUTA_HERE

SCOPE_END
END_SCOPE (not to be confused with endoscope)
0
craig
7/27/2020 10:39:47 PM
On 27 Jul 2020, at 13:37, Paul LeoNerd Evans <leonerd@leonerd.org.uk> =
wrote:
> On Mon, 27 Jul 2020 11:53:52 +0100
> Dave Mitchell <davem@iabyn.com> wrote:
>=20
>> * why not just "use feature 'finally'" rather than 'finally_block'?
>=20
> I was considering that maybe someone might want a `finally` keyword on
> its own, rather than the capitalised FINALLY phaser-type thing, so I
> didn't want to hog that name. I guess it seems quite unlikely to have
> both, so I could rename it.

When I first read the documentation, I read =E2=80=9Cfinally_block=E2=80=9D=
 as =E2=80=9Cadverb_verb=E2=80=9D: =E2=80=9Cdo block, finally (whenever =
finally happens)=E2=80=9D. e.g. =E2=80=9Cfinally_phaser=E2=80=9D would =
not have had that problem.

Sam
--=20
Website: http://www.illuminated.co.uk/
0
oldsam
7/28/2020 12:43:29 AM
Op 23-07-20 om 18:31 schreef David Green:
> On 2020-07-23 8:17 am, H.Merijn Brand wrote:
> > On Thu, 23 Jul 2020 08:06:57 -0600, Karl Williamson wrote:
> >> PS
> > I LIKE THAT ONE!
> > Post Scriptum - PS - Post Scope :)
>
> I like that too.
>
>
> On 2020-07-23 5:15 am, Salvador Fandiño wrote:
>> ANYWAY
>
> That's quirky, but in a perlish way.


/delurk


Exactly my thought, this feels very perlish.


M4
0
m
7/30/2020 3:49:27 PM
Reply: