https://github.com/exercism/yamlscript/pull/42/files
shows an interesting realization I had where constantly(x) can be written as \(x).
I was annoyed at the 10 char length of constantly for common operations, and was considering the alias give; (like a(thing) is an alias for identity(thing)).
Then I tried the YS anonymous function and it worked.
I was surprised because why wouldn't Clojure use #(x) for (constantly x) , but I realized it was the wrong arity.
YAMLScript couldn't use #(...) for anonymous fns because # is the YAML comment syntax, so \(...) was chosen (languages like Haskell use \ for lambda because is looks a bit like λ but easy to type on typical keyboards).
The YS compiler though couldn't compile \(...) to #(...) for some reason related to reader macros in EDN or pprint (I forget) so it compiles like this:
$ ys -ce '\(%1 + %2)'
(fn [& [_1 _2]] (add+ _1 _2))
$ ys -ce '\(x)'
(fn [& []] x)
with the side effect that it takes any number of args,
thus suitable as a constantly replacement!Noting:
$ bb '(take 5 (map (constantly 42) (range)))'
(42 42 42 42 42)
$ bb '(take 5 (map (fn [& _] 42) (range)))'
(42 42 42 42 42)
$ bb '(take 5 (map (fn[&_] 42) (range)))'
(42 42 42 42 42)
$ bb '(take 5 (map #(and % 42) (range)))'
(42 42 42 42 42)
$ bb '(take 5 (map #(42) (range)))'
----- Error --------------------------------------------------------------------
Type: clojure.lang.ArityException
Message: Wrong number of args (1) passed to: sci.impl.fns/fun/arity-0--1165
(take 5 (repeat 42)) ... Does it happen very often that you find "constantly" coming in handy?
It is an interesting observation! Just amusing!
I'll admit it doesn't annoy me constantly (🤣 )
But that diff I linked to shows it 4 times. I guess update-in and swap! is where I see it most.
It feels ok (needing a fn) for swap! because I'm often doing something like inc but for update-in I almost always have a value to use already.
given the way lets work in YS:
$ cat a.ys
!yamlscript/v0
defn foo(x):
a =: 3
b =: 4
x * a +: b
$ ys -c a.ys
(defn foo [x] (let [a 3 b 4] (add+ (mul+ x a) b)))
one thing I've wanted for a while (that replaces update-in) is
$ cat a.ys
!yamlscript/v0
defn foo(x):
a =: 3
b.foo =: 4
x * a +: b.foo
$ ys -c a.ys
(defn foo [x] (let [a 3 b (update-in b ["foo"] (constantly 4))] (add+ (mul+ x a) b)))(the latter doesn't work yet. hopefully soon)
@phill re
> Does it happen very often that you find "constantly" coming in handy?
A scan of the yamlscript, babashka and clojure repos shows it not be used that often.
Mostly with alter-* swap! and update-in
and also more often in tests for some reason...
Okay! But there's also the free-of-constantly (reset! a 42) and (assoc-in m [k1 k2 k3] 42) .
Wow. I was completely unaware of assoc-in. Nice.
I'll do the above as:
$ cat a.ys
!yamlscript/v0
defn foo(x):
a =: 3
b.foo =: 4
x * a +: b.foo
$ ys -c a.ys
(defn foo [x] (let [a 3 b (assoc-in b ["foo"] 4)] (add+ (mul+ x a) b)))
er
(add+ (mul+ x a) b)
meant to be
(add+ (mul+ x a) (get+ b 'foo))
in above