This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-06-03
Channels
- # aws (12)
- # beginners (12)
- # biff (10)
- # calva (1)
- # cider (10)
- # cljfx (1)
- # clojure (2)
- # clojure-conj (1)
- # clojure-europe (25)
- # clojure-madison (1)
- # clojure-nl (1)
- # clojure-norway (12)
- # clojure-sweden (4)
- # clojure-uk (6)
- # datomic (11)
- # dev-tooling (3)
- # emacs (5)
- # gratitude (1)
- # introduce-yourself (7)
- # java (3)
- # jobs (1)
- # london-clojurians (2)
- # lsp (23)
- # off-topic (4)
- # practicalli (9)
- # quil (6)
- # re-frame (3)
- # reagent (4)
- # remote-jobs (1)
- # ring (1)
- # shadow-cljs (18)
- # squint (67)
- # tools-deps (5)
- # xtdb (4)
- # yamlscript (12)
Idea: support the optional chaining operator though some syntax
> x = {a: {b: {c: 1}}}
{ a: { b: { c: 1 } } }
> x?.a?.b?.c
1
E.g.:
(def x {:a {:b {:c 1}}})
(.. x ?-a ?-b ?-c)
Right not this conflicts if there is actually a ?-a
etc function.
I've also considered supporting:
(-> x?.a?.b ...)
directly, but this also conflicts if there's already a x?
variable somewhere.
It would be nice to have a unambigious syntax for this, but perhaps it's not worth it.
E.g. (..? x -a -b -c)
how's this different than get-in
early returning on nil
?
it's compiled closer to what a JS engine supports, thus likely far better performance
maybe -?>
or get-in-?
or get?-in
lol
get-in is dynamic, so that doesn't work, the point here is that you know the properties at compile time
i'm suggesting a new function/macro that creates the necessary syntax
maybe ..?
which joins with ?.
instead of .
?
oops 😅
Here's a result from the squint REPL:
user=> (simple-benchmark [x {:a {:b {:c 1}}} f (js/eval "(x) => x?.a?.b?.c")] (f x) 100000000)
[x {:a {:b {:c 1}}} f (js/eval "(x) => x?.a?.b?.c")], (f x), 100000000 runs, 133 msecs
undefined
user=> (simple-benchmark [x {:a {:b {:c 1}}} f #(some-> % :a :b :c)] (f x) 100000000)
[x {:a {:b {:c 1}}} f (fn* [%1] (some-> %1 :a :b :c))], (f x), 100000000 runs, 1813 msecs
and what about allow for this case javascript syntax directly, example:
(def x {:x {:z {}})
(js/alert #js-expr x?.y?.z) -- undefined
how crazy is that?Otherwise, this looks quite good: (..? x -a -b -c)
as suggested above, but may lead to compatibility issue with cljs. Don't know how far you want to have parity.
btw how do you deal with the fact that properties in js can have spaces in them? In fact how the hell is cljs dealing with that? 😄
obj?.["evil trickster"]
compatibility: squint already supports more than CLJS in some areas, so that's not an issue to me
spaces in properties: CLJS is dealing with that in the same way that JS is, you write a string
Right. Also directly is kinda unsafe when it comes to code it can produce. So yeah. ..?
looks the best
properties are munged as well, another source of breakage:
cljs.user=> (str (fn [x] x.dude?.quux))
"function (x){\nreturn x.dude_QMARK_.quux;\n}"
I think ClojureDart has a kind of a.b.c syntax. But personally I think ..?
or ?..
makes most sense in not being too jarring of a syntax compared to the rest.
But -?prop
would also be nice. And technically if that exists, people can build their own ..? or -?> macros no?
So I like how that mimics Clojure's interop more. In that the real interop syntax is -prop and (. obj -prop)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
Aaaah, I was going to say, that looks super ugly IMO, but if it's already a thing in js yeah that might be the simplest all around, especially for js folks
I guess keys that have question marks at the end will just have two question marks? Any risk of clobbering?
Didibus his suggestion suffers from the same conflict issue, namely props kan start with question marks
I personally like the perc https://github.com/johnmn3/perc. More clojurey
too perly for my taste (even though perl may not have this, I think it looks too weird)
What about ?-prop
, that would actually be closer to the JS ?.
operator. So ya it could be ?-?prop
but that's true in JS as well a?.?prop
no ?
Or, instead of touching the prop, like there is .
in Clojure for interop, there could also be ?.
special operator. And again you could then implement whatever macro on top.
The downside is it's harder to combine.
If you want to do:
a.b?.c.d
With the prop syntax you could do:
(.. a -b ?-c -d)
With a different operator you need to do:
(. (?. (. a -b) -c) -d)
You mean from existing code ?
Wouldn't current code have has to be written as -?-prop
I'm thinking Clojurescript, because in Clojurescript you have to use dash for prop access no? Unlike in Clojure
every prop that doesn't start with a dash is handled as a function call in the ..
macro
Right I see. I think I assumed that if squint added ?-
syntax it would also special handle it where it needs too.
Is it the ..
macro that does that? I thought it was .
itself that did that
squint could add special handling in .. for ?
but this would break existing behavior
So the issue with ?-prop
is that it conflicts with functions that start with ?-
if I understand correct?
And so you can't tell if that's a function or a prop anymore?
or maybe there should be a .?
special form then as well (`.` is also a special form, not a macro)
I was thinking there needs to be a special form no? Otherwise how do you know to compile with ?.
instead of .
?
You could also make it a special thread macro, so you can intersperse different logic between the fns in the chain. And then you can use it like a chain if you want.
But I guess we're going for a thing that compiles down optimally to an idiomatic js optional chain
@U0K064KQV you can hack it together without a special form using js*
I believe, but it isn't pretty
Ah I see. Well I guess how it's implemented doesn't matter that much.
I think ..?
would probably be convenient. But like John was saying, I feel ideally (and maybe that's not doable), something that lets me mix and match between accessing Clojure values and JS props and lets me choose which access I'm the chain I want to be null-safe and which I want an error from would be the nicest to have.