(defn better-cond
[& pairs]
(fn [& arg]
(label result
(defn argy [f] (if (> (length arg) 0) (f ;arg) (f arg))) # naming is hard
(each [pred body] (partition 2 pairs)
(when (argy pred)
(return result (if (function? body)
(argy body) # calls body on args
body)))))))
Most Lisps have `cond` like this:
(def x 5)
(cond
((odd? x) "odd") ; note wrapping around each test-result pair
((even? x) "even"))
Clojure (and children Fennel and Janet) don't require wrapping the pairs:
(def x 5)
(cond
(odd? x) "odd"
(even? x) "even")
My combinatoresque `better-cond` doesn't require a variable at all and is simply a function call which you can `map` over etc.:
((better-cond
(fn [x] (> 3 x)) "not a number" # just showing that it can accept other structures
odd? "odd"
even? "even") 5)
Of course, it can work over multiple variables too and have cool function output:
(defn recombine # 3 train in APL or ϕ combinator
[f g h]
(fn (& x) (f (g ;x) (h ;x))))
(((better-cond
|(function? (constant ;$&))
|($ array + -)) recombine) 1 2) # |( ) is Janet's short function syntax with $ as vars
But it's not composable as Janet's version, it will fail when mapped over, because it may return a plain value instead of a callable one. In Janet, all values can naturally participate in higher-order contexts due to its uniform treatment of callables, while in Clojure, only actual functions can be composed or mapped.
Do you have any recommendations for a language where you _have to_ use these concepts. I love playing with them but I find that unless i’m paying a lot of attention in most cases I fall back to a less functional style even in a language like Janet. I’d love to find a language where you largely have to use these combinatorial logic style functions so I can’t just default back to other styles.
Forth, Factor and Uiua (which combines the above approach) don't use these concepts yet are also inherently point-free, and without lambdas so you definitely wouldn't be able to rely on functional techniques!