From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, MAILING_LIST_MULTI autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 9452 invoked from network); 11 Feb 2023 23:43:43 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 11 Feb 2023 23:43:43 -0000 ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1676159023; b=lkBvzREaGpVoGnVQG+MMObcBwAcv7sz/OsG6AntGiMozZoMi3qVPWVl1JZQ/o8sVnKdFNYAay1 vZQ8yxThOBsgm3bx3P3X5SfhFdTS+k/4Et0oynWizA6ViJ5qe0qZm6NTddBMye2UUh9Vn0EOb0 4n2kjg+o1cxoAIxwlel1ZT00DxAyYgz+JJmY/ntCIiomMovpm3ImQx4OqPKA85x1uDrn+EU+S6 tHqlHWroHaA4+qhEcLwG7zsdv7IRaEtZgld1bLeeiEEy2IrQ/DkH8mK/6aYlXxKaWpW3iG9M9t r+SeIpTUvHqaQGR+NyyuazyyjMj5aijiqNnmCm4cvptrFw==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (mail-ej1-f48.google.com) smtp.remote-ip=209.85.218.48; dkim=pass header.d=brasslantern-com.20210112.gappssmtp.com header.s=20210112 header.a=rsa-sha256; dmarc=none header.from=brasslantern.com; arc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20210803; t=1676159023; bh=Vy16eUae/NhWO4EFjiOdll8965c5/Q7byfZT8A2KnEc=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:Content-Type:To:Subject:Message-ID:Date:From:In-Reply-To: References:MIME-Version:DKIM-Signature:DKIM-Signature; b=cfKGkLGb7gBJAtREpW8MsvdP78605uMLLKlGObPZ8b4lpRjP6AGrKwkoa48w85k3HCcDdiBdx3 Tm5EZNcuu4tN2l8KUzVccRirMaL0VGhvj5CiNEMAeuYsfCKK1rfct3q48RDRLjz288tBKT3KVT gYvTiUdfA9zegNOu6moqVWxAl5I2PXyuzBeIOvCblyjsz4vykVbqBulDTVPAXjGHegxFeCyEx3 45YwH3GSzlEz4VBUhOlcvg1lqXqFiatUj1cgUKfYhbcMx6rAeV1s9nGcilI/NcIYECIVAZ3tnr 3A7X5Tv7iZ58EN0llcjqGLatzyTLNxsqxy/1i8Nd2oo1gA==; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Content-Type:To:Subject:Message-ID: Date:From:In-Reply-To:References:MIME-Version:Reply-To:Cc: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=k54fZfWxqbQNGuLQt3yxhx8YulErtGM6RaVpw1VGMKc=; b=huFxe/X7fEP6KA58xWPe2/M4jS mAoLckuJ84JhbMSJBSQT/57J2S3Wy7YiyrqelcLaK42QdWdY50ftCh4xICfg0dfZNSHsp6abrJhMm Rwcvl5evIAytPn7QhgjTcq8mNGONDASiyURLixdU5u/43HUbI9BeQCudSwS0/GaXfcvegXXbIKjOc IVq02Y0UTBrtEvhnclIGpqtZuKTGpORNpxyj/8BR9sUIiNRzqOBhlK1r2yUXlT3mil3rSPC1BfRs5 2Pn/byFvGQIs0146SgNLYxMPUbSa0iGruWGQw38aaLYrK8i78XeWMEHXjYnR/VIBDl/mstVb8XbYe FCb8AuQQ==; Received: by zero.zsh.org with local id 1pQzWw-0001mw-3U; Sat, 11 Feb 2023 23:43:42 +0000 Authentication-Results: zsh.org; iprev=pass (mail-ej1-f48.google.com) smtp.remote-ip=209.85.218.48; dkim=pass header.d=brasslantern-com.20210112.gappssmtp.com header.s=20210112 header.a=rsa-sha256; dmarc=none header.from=brasslantern.com; arc=none Received: from mail-ej1-f48.google.com ([209.85.218.48]:46611) by zero.zsh.org with esmtps (TLS1.3:TLS_AES_128_GCM_SHA256:128) id 1pQzWf-0001Tp-OE; Sat, 11 Feb 2023 23:43:26 +0000 Received: by mail-ej1-f48.google.com with SMTP id p26so23960540ejx.13 for ; Sat, 11 Feb 2023 15:43:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brasslantern-com.20210112.gappssmtp.com; s=20210112; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=k54fZfWxqbQNGuLQt3yxhx8YulErtGM6RaVpw1VGMKc=; b=Jl2hv5BF1Q6Cu/Gvjwq3QDLB74FqGEJDpnCOvyxWhV5R9o9Vs3bIX+xIu7u2iQcv/v fTb0U05L15qPRcRap6wDKYxjoGgrf5o2+qF1eGmhiiwYQhF4U9Z9l+I6ThFZvyfzR0YI /E51B6BFA9f/oTURTjuhD69YxD9CVP84ZDoJMZyulXbkzNQ2cOB9KbkPrxesrpm2WzW7 ds7FSxx9LNHYQM7LaNQ1EzFyIGHcNMHZRqW23l3J45Mk5RgQsoK38oGd1i7PmMnsOesP UqC1hZpmWaF9UAEc2WCZ0Wxqb35xZ2nGKmK3luiLqfchvkJcyhNIU2J/FzAZljZNPO8j 5Vuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=k54fZfWxqbQNGuLQt3yxhx8YulErtGM6RaVpw1VGMKc=; b=TChLTd1t25lxAjYR1N8ztlnFSERgmsmX3P3k3zTltxOE4RI/aif0F48OZ6g41QaMGy ANJ/LuqvbaX+AUAOjB56YsVB4g4bNJyLtBvA77FGgDmHImKq1YTCrmaS/HtL5xzOvOW5 t0ePNk3qZCsdenMd4QAOUNn9aUqI1wtTFWFeo7Tot8TeGVbK5GMqlhCa+grbkTrR8pRM hyhHsZyX8eFyd2LEdBrFsgAJFVZa3TtY0qUYmJrALU1eQNHC/J54nVcSFmE2teoqAGs/ 3jNwD3lJoAVuEYKOXTWr0HKQjETITPEJzTxfXUH7LRGfqnJ4IO9D71sL+qOJPERjrUrm FI5w== X-Gm-Message-State: AO0yUKWn35kVKUgmrh72XmqtH+GhcjxZQQXL9mfr+FGbtzyDcBtcbmLb j2hda2dtnlK8RjxxpP7k7/wEuyc0CmOk3gCxPG6gYY0nH8AMcZBK X-Google-Smtp-Source: AK7set8ku2tX+h8+0TjAr/sv6XQb5n4ZuWHv0ci0pYhf9h6Srp7y8dtGAk0wgRhVk9DyU2z9BKxLP1480Ej8/tUuWgo= X-Received: by 2002:a17:906:7154:b0:888:dc91:ece6 with SMTP id z20-20020a170906715400b00888dc91ece6mr2760174ejj.6.1676159005022; Sat, 11 Feb 2023 15:43:25 -0800 (PST) MIME-Version: 1.0 References: <67689-1675827940.088548@BxvG.D9_b.7RzI> <12608-1675903622.800470@Xj82.e3y1.svhG> <66045-1675975796.128039@FBF_.0yMO.Y8fk> <40726-1676098925.110777@U2kb.d0Pd.I9ml> In-Reply-To: From: Bart Schaefer Date: Sat, 11 Feb 2023 15:43:13 -0800 Message-ID: Subject: Re: [PATCH 1/3]: Add named references To: Zsh hackers list Content-Type: text/plain; charset="UTF-8" X-Seq: 51400 Archived-At: X-Loop: zsh-workers@zsh.org Errors-To: zsh-workers-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-workers-request@zsh.org X-no-archive: yes List-Id: List-Help: , List-Subscribe: , List-Unsubscribe: , List-Post: List-Owner: List-Archive: On Fri, Feb 10, 2023 at 11:45 PM Bart Schaefer wrote: > > On Fri, Feb 10, 2023 at 11:02 PM Oliver Kiddle wrote: > > > > I'd be > > fine with the reference becoming unset at the time of the return if it > > refers to a variable that is going out of scope. Can that be done as > > part of the same code that drops the local variables? That's actually a little startling given dynamic scoping. It leads to this: { typeset -n ref=var () { var=FUNC1 typeset -p ref } typeset -p ref } Output: typeset -g -n ref=var typeset: no such variable: ref If the called function were a blackbox, it would be extremely puzzling why "ref" became unset. The additional complication is that the parameter table is a hash, so it's scanned in random order; we can't be sure that the referent local $var will be found and unset before the referring $ref is examined. I suppose we could scan twice (ick). Instead let's think for a moment about how the dynamic scoping works. "ref" has two properties: The locallevel at which it was declared, and the locallevel at which it prefers to find a referent. Any time you use $ref (or assign to ref) the search starts at the current locallevel and proceeds upward until either the preferred level is reached or the "topmost" defined parameter is found, whichever comes first. So ... if endparamscope() walks the preferred referent locallevel upward as the scope unwinds, we get (using your earlier example with my addition): { var=hello typeset -n ref () { typeset var=x ref=var echo $ref } typeset -p ref echo $ref () { typeset var=y echo $ref () { typeset var=z echo $ref } } } Output: x typeset -n ref=var hello hello hello The inner assignment to ref changes the scope , but it then unwinds so in the second function (which does not assign to ref) it is back to pointing at the original scope, and finds $var there. If "var=hello" is replaced by "unset var" (so there is no parameter at the original scope), then the output is: x typeset -n ref=var y y This is because the assignment "ref=var" has initialized the name to which "ref" points, but there is no such name at the same level, so the nearest parameter of the same name is chosen. If "typeset -n ref" at the top level is replaced by "typeset -n ref=var" then the "ref=var" assignment in the first function changes the value of either the global $var or the local $var from "x" to "var" (depending on which existed first) because ref already has a referent name. So the output could be either: # with var=hello var typeset -n ref=var var var var # with var unset var typeset -n ref=var y y Given the requirements that (1) assigning a value to a nameref that has no referent initializes the nameref (required for "for" loop) and (2) dynamic scoping selects the best referent by name, I think this is the best I can do without something even more surprising. The other option that occurs to me is for the assignment ref=var to automatically create a local $ref (as if "typeset ref=var" had been used). That would then be unwound and we'd end up back in the original state. But that would also be unexpected behavior in dynamic scopes.