From nobody Thu Feb 18 19:27:04 2021 Authentication-Results: mail-b.sr.ht; dkim=pass header.d=gmail.com header.i=@gmail.com Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) by mail-b.sr.ht (Postfix) with ESMTPS id 0B85211F017 for <~technomancy/fennel@lists.sr.ht>; Thu, 18 Feb 2021 19:27:04 +0000 (UTC) Received: by mail-pf1-f171.google.com with SMTP id q20so1962934pfu.8 for <~technomancy/fennel@lists.sr.ht>; Thu, 18 Feb 2021 11:27:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=gMJHR2DTNl4fHWpxvKfZOZgxMHEtjhxKf73zFYGvsoo=; b=rajlUtgFCiyls30mPkX//LhJUL0YbpsbGmixNbPYLHWUPhkqTWKnsL6w/KfLbNqwOc mjdUkjZhE2zldexrAP2l0YBZ7X9yisWXax0TNudzYkj65Nb2bU9RYFe2gXo+ThBXak5c 7yD76lCDabZMmMyLLAnFH68B2dI6yr++SA/o3RCDilLrz9+szfB+fYnkIeFjnmA7mUbL PI8d6JvCDyTWQkwsFizHcm144ppFxr0e4LcuFKQA/hwvSvDO4X5T6MXH1j9TdKy5L5dt 9l3sWT5ChPoS0siK8V2YdCSa6AvBFbdyzM8YU9R1PbJbGMqNd9Tr4rJlaP8nI0n36EtK qMMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=gMJHR2DTNl4fHWpxvKfZOZgxMHEtjhxKf73zFYGvsoo=; b=qJPnMa8/uT4TpS6VR4mXh/aIf8FbufPpN7i1EXLHktWgHR+mUBYeqEQP6YcwAqrnzX oc0pLqPSKaaX59rQ2KTVCAxfPv1Aa7rSycHirIp36zZKFJn8QqjPXCK2DXV/c6eT0hO5 FCd9mf8kIBNWbQ9z9NBV3T5BDiWYfLsChbQzjWE/iVdKVeaJ4Q+8bhCVx8UVB0CRIZI+ 1b2mYAZtTX5n9xQMGSrkBb1CTyy5asBr02tnDCyN76zey/k8OU5aJ51v2nQ56C0MxEIE UKcIaU5hje67ads/cdYIqzhlGyG/f16BXO46EVtuEYfmb/MpQn18v+6y9uCa8Ldula3q 9LKA== X-Gm-Message-State: AOAM532O80THecwT24RZH7CqHakC4R10j9neaPTYiL084pEQ6RUAgLD6 ZqWKs+nhvVeLx87UdpA6knMGVvveL5aWiFn+FrZYx+dB2pZu5A== X-Google-Smtp-Source: ABdhPJyq9dZfzM2gJJOLa/9i7H1O+8noZrTuNfuKWcCNC/TNm0j3Qq44sXc8tgi1jRBUE4uapOGa8L3sQhlmYztNKaM= X-Received: by 2002:a63:fc11:: with SMTP id j17mr5092119pgi.379.1613676423027; Thu, 18 Feb 2021 11:27:03 -0800 (PST) MIME-Version: 1.0 From: Andrey Orst Date: Thu, 18 Feb 2021 22:26:52 +0300 Message-ID: Subject: nil-safe nested table access operator To: ~technomancy/fennel@lists.sr.ht Content-Type: text/plain; charset="UTF-8" Hi I wanted to suggest new operator for Fennel for nil-safe nested table access. Currently Fennel has dot operator to access values stored under keys in tables. This operator accepts several keys to look up value in nested set of tables: >> (local t {:a {:b {:c 42}}}) >> (. t :a :b :c) 42 However if any of keys before :c were not present in respective tables, we will get error of trying to index nil: >> (. t :a :nope :c) ;; error I would like to propose ?. operator which will short-circuit if any of keys are not present. >> (?. t [:a :nope :c]) nil This operator accepts keys in sequential table, because optional default value can be specified as third argument: >> (?. t [:a :nope: :c] 27) 27 This is handy when you're dealing with tables that can be altered over the liftetime of the application. Below are two sample implementations: (fn ?. [tbl keys not-found] (match keys [k] (match (. tbl k) v (if (. keys 2) (?. v [(table.unpack keys 2)] not-found) v) not-found) tbl)) (fn ?. [tbl keys not-found] (var res tbl) (var t tbl) (each [_ k (ipairs keys)] (match (. t k) v (set [res t] [v v]) (do (set res not-found) (lua :break)))) res) The first one is recursive and a bit more verbose after code generation, also constructs new table on each step which may be not optimal. The second one iterates over table of keys directly, but modifies local variables by setting, and uses nasty (lua :break). I'm not sure which one is better, but the second one is prematurely optimized. Maybe a less complex implementation can be made, but I couldn't think of one yet. And maybe this should be a macro instead? As for the name, I think ?. is good name, as it has similar semantics embedded in it as for -?> or -?>>. Some fonts with ligatures have support for this character combination as well. Other variants include get-in, access-in, maybe others have some ideas too? -- Best regards, Andrey Listopadov