bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: feature request: new builtin `defer`, scope delayed eval


From: Koichi Murase
Subject: Re: feature request: new builtin `defer`, scope delayed eval
Date: Sat, 8 Oct 2022 20:57:13 +0900

Hi Cynthia, thank you for your reply.

2022年10月8日(土) 17:26 Cynthia Coan <cynthia@coan.dev>:
> > I agree the proper implementation of `defer' by the RETURN trap could
> > be tricky (as described in "notes" in my previous reply), but it's
> > definitely not as hard as you initially posted (one 12-line function
> > vs 244-line defer.sh).
>
> [...] the reason it implements the "function local" state
> itself is because for quickness of a PoC it was copied from an "error
> mode" example

(This is just a side note about `local -' but unrelated to the main
discussion): I didn't mention it because I thought `set -e' is merely
an example to demonstrate the behavior of `defer', but if the handling
of `set -e' is one of the main motivations for requesting `defer', I
suggest trying Bash 4.4's `local -', which localizes the shell-option
changes within the function. If the function doesn't want to change
the shell option of the caller, it can just declare `local -' before
changing any shell options. [ It is unavailable in Bash 4.3 or below,
but the suggested `defer' builtin would neither be available in older
versions of Bash, so we can forget about the support of `local -' of
older Bash in the discussion of the new feature. ]

> which does need to implement function local checks
> itself (with functrace), as if  the function "sets error mode", and
> than calls another function which changes the error mode not through a
> wrapper you'd be in the wrong state for the rest of the function. So
> you always need to check where you are.

I think you might be caring about the cases the callee changes the
error mode without restoring it, but I would say that restoring the
error mode to the original is the responsibility of the callee
function, but it's not what the caller or the entire execution system
of Bash should take care. Also, how to distinguish them from the
functions that want to intensionally change the error mode of
outer/global scope (such as functions similar to
`__{push,pop}_error_stack' in other codebases)? Here, I still think we
do not need to re-implement the function-local traps other than the
already built-in one even for the `set -e' handling.

> I'd prefer we don't focus on any particular implementations, or how
> many lines they end up being.

Obviously, the number of lines itself is not important. I mentioned
the number of lines because you seemed to present the idea that "the
implementation can be harder than they need to be" mentioning the
original email [2].

[2] https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00036.html
>>> In fact some of the things you mentioned you can do today, are also
>>> outlined in the original email as things that can be "harder than they
>>> need to be"

But I don't think it is hard to implement it in a shell script as said
in the original email, so I just used the number of lines as an
``approximate'' measure of how hard the code is. If both codes had
similar numbers of lines, it wouldn't correctly compare the actual
complexity of the codes as you think, but I think the number of about
10 lines is clear to show that the implementation is not that hard (as
far as one understands the usage of the RETURN trap) compared to what
the original email seemed to convince us with the link to 244 lines of
code (regardless of the intention).

> I'm not saying
> defer necessarily meets the same bar as usefulness, but I think it'd
> be wrong to dismiss new features just because they can be accomplished
> today, with relatively few lines.

In my point of view, the suggested "new" feature is *already
implemented in Bash as the RETURN trap*, and there is no reason to add
the same feature twice. These "relatively few lines" (including
`declare -ft' and the FUNCNAME check) are just needed to adjust the
usage to your taste as the wrapper `defer'. If we do not use `defer',
we could naturally write it like

eval "original=($(trap -p RETURN))"
trap "trap - RETURN;xxxx;${original[2]}" RETURN

If `trap -P' suggested by Oğuz would be supported, it can even be simplified as

trap "trap - RETURN;xxxx;$(trap -P RETURN)" RETURN

The remaining complication is actually caused by the lack of support
for the multiple trap handlers and is unrelated to `defer'. Of course,
if one wants to use the above idiom multiple times, it may not be
useful to write it every time. In that case, one can define a
function. If it needed to implement the essential parts of the
processing as in defer.sh, it might have been better implemented as a
built-in feature, but I don't think the wrapper of the above one or
two lines should be a separate builtin command. A shell function is
sufficient.

> Interesting, is this purely about lines of code?

Of course, no! See the above response about the number of lines.

> On the traps append/prepend point I will have to
> do some thinking on that, I'll take the weekend/beginning of the week
> to think of what I can, but if someone else has ideas I would love to
> hear those too.

I think this is a more general topic than defer, so I think you can
create a separate thread for it. Also, I guess more people are
interested in the multiple trap handlers compared to `defer'.

--
Koichi



reply via email to

[Prev in Thread] Current Thread [Next in Thread]