yamlscript

Ingy döt Net 2024-12-21T19:48:07.627139Z

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!

Ingy döt Net 2024-12-21T20:03:13.923589Z

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

2024-12-21T20:18:32.565809Z

(take 5 (repeat 42)) ... Does it happen very often that you find "constantly" coming in handy?

2024-12-21T20:20:40.828819Z

It is an interesting observation! Just amusing!

Ingy döt Net 2024-12-21T20:28:35.753189Z

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.

Ingy döt Net 2024-12-21T20:35:00.353759Z

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)))

Ingy döt Net 2024-12-21T20:36:56.931799Z

(the latter doesn't work yet. hopefully soon)

Ingy döt Net 2024-12-21T22:18:08.832219Z

@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...

2024-12-22T12:43:06.469249Z

Okay! But there's also the free-of-constantly (reset! a 42) and (assoc-in m [k1 k2 k3] 42) .

Ingy döt Net 2024-12-22T14:25:15.883539Z

Wow. I was completely unaware of assoc-in. Nice.

Ingy döt Net 2024-12-22T14:28:27.814639Z

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)))

Ingy döt Net 2024-12-22T16:36:53.402609Z

er

(add+ (mul+ x a) b)
meant to be
(add+ (mul+ x a) (get+ b 'foo))
in above