zsh-workers
 help / color / mirror / code / Atom feed
From: Stephane Chazelas <stephane@chazelas.org>
To: Bart Schaefer <schaefer@brasslantern.com>
Cc: Zsh hackers list <zsh-workers@zsh.org>
Subject: Re: Up-scope named references, vs. ksh
Date: Sun, 3 Mar 2024 20:27:56 +0000	[thread overview]
Message-ID: <20240303202756.7axmzy6gkohza2ra@chazelas.org> (raw)
In-Reply-To: <CAH+w=7ZZjS3QZeK8R8Zy_ACHeJsFj_YoKk22R3EG0NhXaQHjFA@mail.gmail.com>

2024-03-03 11:04:03 -0800, Bart Schaefer:
[...]
> >   typeset -n var=$1
> >   typeset    value=$2
> 
> If the parameter is magically created "in advance" (at the point of
> "typeset -n") then it only works for global scalars

Why would we need it for any other scope? If the parameter is
not found in any scope, then it must be created in global scope.

That's what "read var" does. Many if not most of the usages of
namerefs I've come across were to implement "read"-like commands
that return or can return something in a variable whose name is given by the
caller (and that can create the variable if needed).

> if you try to
> create an array using "var" you run into baffling stuff like this:
> 
> assign:3: value: attempt to assign array value to non-array
> 

assign() {
  if [[ -v $1 ]]; then
    typeset -n var=$1
  else
    eval "$1="
    typeset -n var=$1
    unset var
  fi
  typeset value=$2
  var=(var now set with value $value)
}
assign value x
typeset -p value


Where an approximation of what I'm suggesting is implemented in
zsh seems to work fine (with your patch applied).

It segfaults with zsh -x though

$ ./Src/zsh  ~/a
typeset -a value=( var now set with value x )
$ gdb -q --args ./Src/zsh -x  ~/a
Reading symbols from ./Src/zsh...
(gdb) r
Starting program: /home/chazelas/install/cvs/zsh/Src/zsh -x /home/chazelas/a
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
+/home/chazelas/a:12> assign value x
+assign:1> [[ -v value ]]
+assign:4> eval 'value='
+(eval):1> value=''
+assign:5> typeset -n var=value
+assign:6> unset var
+assign:8> typeset value=x

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7cfb3fe in __GI___libc_free (mem=0x555555600) at ./malloc/malloc.c:3368
3368    ./malloc/malloc.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7cfb3fe in __GI___libc_free (mem=0x555555600) at ./malloc/malloc.c:3368
#1  0x00005555555d5105 in zsfree (p=0x555555600 <error: Cannot access memory at address 0x555555600>) at mem.c:1878
#2  0x0000555555625482 in freearray (s=0x555555683d88) at utils.c:4100
#3  0x00005555555ea0e6 in arrsetfn (pm=0x555555683da0, x=0x555555683f40) at params.c:3996
#4  0x00005555555e5691 in setarrvalue (v=0x7fffffffc360, val=0x555555683f40) at params.c:2889
#5  0x00005555555e8537 in assignaparam (s=0x7ffff7fac733 "", val=0x555555683f40, flags=6) at params.c:3538
#6  0x00005555555943f7 in addvars (state=0x7fffffffcda0, pc=0x55555567d508, addflags=0) at exec.c:2631
#7  0x000055555559639b in execcmd_exec (state=0x7fffffffcda0, eparams=0x7fffffffc9b0, input=0, output=0, how=18, last1=2, close_if_forked=-1) at exec.c:3363
#8  0x00005555555926c8 in execpline2 (state=0x7fffffffcda0, pcode=643, how=18, input=0, output=0, last1=0) at exec.c:2016
#9  0x000055555559125c in execpline (state=0x7fffffffcda0, slcode=10242, how=18, last1=0) at exec.c:1741
#10 0x000055555559049e in execlist (state=0x7fffffffcda0, dont_change_job=1, exiting=0) at exec.c:1495
#11 0x000055555558fabe in execode (p=0x55555567d3f0, dont_change_job=1, exiting=0, context=0x5555556310da "shfunc") at exec.c:1276
#12 0x000055555559e87a in runshfunc (prog=0x55555567d3f0, wrap=0x0, name=0x7ffff7fac170 "assign") at exec.c:6164
#13 0x000055555559dd8a in doshfunc (shfunc=0x55555567d570, doshargs=0x7ffff7fb7b18, noreturnval=0) at exec.c:6010
#14 0x000055555559ca1d in execshfunc (shf=0x55555567d570, args=0x7ffff7fb7b18) at exec.c:5548
#15 0x0000555555598a9c in execcmd_exec (state=0x7fffffffdad0, eparams=0x7fffffffd6e0, input=0, output=0, how=18, last1=2, close_if_forked=-1) at exec.c:4075
#16 0x00005555555926c8 in execpline2 (state=0x7fffffffdad0, pcode=835, how=18, input=0, output=0, last1=0) at exec.c:2016
#17 0x000055555559125c in execpline (state=0x7fffffffdad0, slcode=5122, how=18, last1=0) at exec.c:1741
#18 0x000055555559049e in execlist (state=0x7fffffffdad0, dont_change_job=0, exiting=0) at exec.c:1495
#19 0x000055555558fabe in execode (p=0x7ffff7fb7a30, dont_change_job=0, exiting=0, context=0x555555632b86 "toplevel") at exec.c:1276
#20 0x00005555555b7cb0 in loop (toplevel=1, justonce=0) at init.c:212
#21 0x00005555555bc7a9 in zsh_main (argc=3, argv=0x7fffffffddf8) at init.c:1934
#22 0x000055555556c99d in main (argc=3, argv=0x7fffffffddf8) at ./main.c:93
(gdb)

> I think it's much more consistent for dynamic scoping to apply at the
> time $var is referenced or assigned.
> 
> The patch in workers/52650 allows something like this to work:
> 
> assign() {
>   typeset value=$2
>   typeset -nu var=$1 # ignore local $value
>   case ${(t)var} in
>   (*scalar*)  var=$value;;
>   (*array*)  var=( $value );;
>   (*) print -u2 cannot assign;;
>   esac
> }
> declare -a value
> assign value x
> 
> If a function wants to be able to actually add things to its calling
> scope without fear of name clashes, it has to use unique local names
> (e.g., a namespace).  But with dynamic scoping it remains the case
> that you can't add a name to the global scope if any function in the
> call chain has pre-empted that name -- named references don't change
> this basic rule.

I really don't follow, dynamic scoping should make things easier
here.

If the caller does "local var; assign var value", then obviously
they want value to be assigned to their var, not have one
created in the global scope instead. It's easy in a shell with
dynamic scoping as a function sees the local variables of its
caller anyway (for instance, my [[ -v $1 ]] above will see).

That typeset -nu var is useful indeed as it allows one to
declare local variables *before* tying namerefs to variables,
but having namerefs that can't create globals seems like a very
severe limitations to me, all other shells with namerefs can do
it. zsh can do it except for that possible clash with local
variables declared *after* which it seems to me should be
avoidable.

-- 
Stephane


  reply	other threads:[~2024-03-03 20:28 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-06  2:21 [PATCH 1/3]: Add named references Bart Schaefer
2023-02-08  3:45 ` Oliver Kiddle
2023-02-08  4:59   ` Bart Schaefer
2023-02-08 23:16     ` Bart Schaefer
2023-02-09  0:47     ` Oliver Kiddle
2023-02-09  2:01       ` Oliver Kiddle
2023-02-09  5:45         ` Bart Schaefer
2023-02-09  4:49       ` Bart Schaefer
2023-02-09 20:49         ` Oliver Kiddle
2023-02-09 23:07           ` Bart Schaefer
2023-02-11  3:04             ` Bart Schaefer
2023-02-11  3:55               ` Bart Schaefer
2023-02-11  5:36                 ` Speaking of dangerous referents Bart Schaefer
2023-02-12  8:00                   ` Oliver Kiddle
2023-02-12  8:34                     ` Bart Schaefer
2023-02-11  7:02               ` [PATCH 1/3]: Add named references Oliver Kiddle
2023-02-11  7:45                 ` Bart Schaefer
2023-02-11 23:43                   ` Bart Schaefer
2023-02-11 23:45                     ` Bart Schaefer
2023-02-12  7:38                     ` Oliver Kiddle
2024-02-11  7:00                   ` Stephane Chazelas
2024-02-11 16:14                     ` Bart Schaefer
2024-02-11 16:42                       ` Bart Schaefer
2024-02-18  3:26                       ` Up-scope named references, vs. ksh Bart Schaefer
2024-02-20 21:05                         ` Stephane Chazelas
2024-02-20 22:30                           ` Bart Schaefer
2024-02-21 20:12                             ` Stephane Chazelas
2024-02-29  5:16                               ` Bart Schaefer
2024-03-01 18:22                                 ` Stephane Chazelas
2024-03-01 20:34                                   ` Bart Schaefer
2024-03-02  7:29                                     ` Bart Schaefer
2024-03-02 23:55                                       ` [PATCH] "typeset -nu" (was Re: Up-scope named references, vs. ksh) Bart Schaefer
2024-03-01 23:28                                   ` Up-scope named references, vs. ksh Bart Schaefer
2024-03-03 13:44                                     ` Stephane Chazelas
2024-03-03 19:04                                       ` Bart Schaefer
2024-03-03 20:27                                         ` Stephane Chazelas [this message]
2024-03-03 22:58                                           ` Bart Schaefer
2024-03-04 19:59                                             ` Stephane Chazelas
2024-03-05  1:05                                             ` Oliver Kiddle
2024-03-05  2:53                                               ` Bart Schaefer
2024-03-05  5:43                                                 ` Mikael Magnusson
2024-03-05  6:30                                                   ` Stephane Chazelas
2024-03-06  5:04                                                     ` [PATCH] local vs. nameref scoping (was Re: Up-scope named references, vs. ksh) Bart Schaefer
2023-02-12  9:02             ` [PATCH 1/3]: Add named references Oliver Kiddle
2023-02-12 18:59               ` Bart Schaefer
2023-02-12 19:45                 ` PM_* flags in zsh.h (was Re: [PATCH 1/3]: Add named references) Bart Schaefer
2023-02-12 21:01                   ` Oliver Kiddle
2023-02-12 22:54                 ` [PATCH 1/3]: Add named references Oliver Kiddle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240303202756.7axmzy6gkohza2ra@chazelas.org \
    --to=stephane@chazelas.org \
    --cc=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).