[Top][All Lists]

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

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

From: Cynthia Coan
Subject: Re: feature request: new builtin `defer`, scope delayed eval
Date: Sat, 8 Oct 2022 10:42:45 -0600

Hi Koichi,

> (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. ]

I appreciate this tip, it is one I was aware of, but I appreciate the
callout regardless. I didn't mean to make the error handling mode a
"key point" for adopting defer, it was just a good stand in for
"global state manipulation" in general. I apologize for my wording
errors there, making it seem like a "main motivation" to you.

> > 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.

As much as I agree with you here, unfortunately not all shell scripts
do what they _should_. From this particular codebase example it was
meant to help callers "not worry about the details", as they did have
to deal with scripts not always doing what they should.

> > 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
> 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).
> > Interesting, is this purely about lines of code?
> Of course, no! See the above response about the number of lines.

I'm sorry for my poor word choices here, I adopted your idioms of
using "lines" in place of "complexity", but I like you meant

I also did not mean to imply that defer was in any way hard to
implement, in fact at multiple points in this chain I've admitted how
easy implementing defer, or appending to a trap could be! I didn't
mean to create any sort of impression that creating a defer would be
hard, long, or tedious. In fact, much the opposite! The original email
at the very very beginning of this thread, I tried to word quite
carefully to show how defer could be a more elegant simple solution,
to other solutions which can remain at times tedious. Because it is a
simple feature that might be generally useful we should just give it
to folks. Rather than having it written in a bunch of different
places, making it a hopefully fairly easy change to adopt. I truly
apologize if I implied in any form that creating "defer" would be
complex, or difficult. I am in complete agreement with you on this

However, I would also like to reiterate how I think "how un-complex
something can be" should not be a blocker for inclusion. We might miss
something like the next `local var=` change, after all bash is quite
powerful which is why it is used. It should be our goal to allow
making bash scripts easier to write correctly overall, even if some
features may be simple if they're generally useful saving lots of
folks from each having their own copy of a thing, or starting a
project writing a "small, simple" version of it might be worthwhile. I
would also like to reiterate `defer` is sounding to not meet this bar,
and that's okay. I think `defer` at this point has pretty much been
killed based on feedback, but I just don't want us to miss that next
thing that isn't `defer` as it comes up.

> > 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

I think there are subtle differences here, but since `defer` has gone
through much feedback saying no, I don't feel it would be worthwhile
to drone on here.

> > 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'.

Yes I was planning on creating a new thread, but I appreciate the tip.


reply via email to

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