Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: All the way up or current scope



A few quick points and then two questions that hopefully will help us converge.

- You are right that in my patch the "upper" field isn't really needed. It's value can always be inferred from the PM_UPPER bit. I added it because I really, really, would like that the upcoming release includes generalized upper references (see question 1). For that, the -u option needs to support an optional integer argument. That's what "upper" was meant to contain but I didn't have time to implement it.

- You are also right that we don't need a new "upper" field. It's just for clarity (and my own sanity) that I added the field. This way it's much easier to track which references to "base" I still need to understand and replace with new code that uses "upper". It think that it also makes it easier to review the code changes. But of course, the final code change would replace "upper" with "base".

- The main attribute of sticky references is that they stick to the variable they referred to after initialization. So "sticky" sounds appropriate to describe them. The main attribute of loose references is that they search for their referent in a scope that is relative to the definition scope of the reference. I couldn't figure out an adjective that describes that. Instead I picked one that describes an outcome of that attribute, namely that the referred variable may change (even without exiting a scope). I agree that "floating" is better but imo even better would be something that describes the nature of being relative to the definition scope.

- The fundamental difference between my "upper" field and the existing "base" field is that the former is a property of the reference (it can be initialized when the reference is defined), while the latter is a property of the referent (it must be initialized when the reference is initialized). It's this difference that opens the door to handling subscripts in the same way as the main variable. With the current implementation handling subscripts in the same way as the main variable would require the ability to store one "base" field for each variable that shows up in the computation of the subscript. I don't think that we would ever want to do something like that. With floating references, no such fields are needed. Thus, at least in principle, it becomes possible to handle subscripts and main variables in the same way. In practice, it may be easier said than done. Definitely not something for the upcoming release but maybe in a future one.

- For upper scope references, sticky vs floating makes no difference. Both implementations lead to the same behavior.

- For my comparison with ksh, I assumed that we would like to be able to run as many ksh scripts as possible in normal Zsh, i.e., in Zsh without ksh emulation. Zsh with ksh emulation may be able to run even more ksh scripts but my understanding is that this should be needed as rarely as possible.

Question 1

Can we add an optional integer argument to the -u option to support generalized upper scope references?

This is something that costs pretty much nothing but in my opinion it would enable a number of very interesting features. If you are not convinced, let me know, so that I can give you concrete examples.

This question is pretty much orthogonal to the sticky vs floating debate. The only intersection is if we also allow -u 0 references. For these sticky vs floating makes a difference. Therefore I suggest that for now we do not allow them; they would be nice but they aren't essential. So I prefer not having them for now so that we can decide later whether they should be sticky or floating.

Question 2

Do we need to support references to nested variables (in the upcoming release)?

Complexity-wise the main difference between sticky and floating references is that the latter simply don't allow references to nested variables. If we don't have to support such references, it eliminates a whole bunch of questions linked to the handling of dangling references. It also makes it easier to specify how named references behave (no need to describe what happens when exiting a nested scope).

So far I haven't seen any use case that requires references to nested variables. In my opnion we could very well specify that "typeset -n ref" always refers to a variable relative to the scope where "ref" is defined. I would agree that these references shoud be sticky.

If we do that, then all the other questions become moot. No need to decide whether to do "all the way up". No need to figure out how to handle chains of references that may contain hidden references. No need to specify how references behave after their first referred variable ceases to exist.

References to nested variables could still be enabled in a future release with an additional option to "typeset -n". Then all these questions would come back. But if nobdoy ever asks for that feature then we can just forget about them.

Philippe


On Mon, May 19, 2025 at 10:01 PM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
On Sun, May 18, 2025 at 2:32 PM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
>
> [...] your implementation of assigning 1 or 0 to a
> new "upper" field and then later using (pm->level - pm->upper) in
> scope resolution is exactly equivalent to assigning (pm->base =
> pm->level - (1 or 0)) and then using pm->base directly

Revising this analysis/opinion somewhat:  The "upper" field isn't
strictly necessary because PM_UPPER can be checked at each point where
pm->upper would be used.

Nevertheless, the "base" field is available and can't otherwise be
"salvaged", so there's still not much reduction in complexity.


Messages sorted by: Reverse Date, Date, Thread, Author