Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Combinatory programing offers functional control flow. (Here is a straight forward explanation: https://blog.zdsmith.com/series/combinatory-programming.html ) I was inspired to write `better-cond` in Janet:

    (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


This looks great, I'm still learning Janet and couldn't write it myself.

I only know about: https://github.com/Engelberg/better-cond in clojure which is different it adds syntax enhancement + control flow convenience.

Similar better-cond can be written in clojure too:

  (defn better-cond [& clauses]
    (fn [& args]
      (some (fn [[pred result]]
              (when (apply pred args)
                (if (fn? result)
                  (apply result args)
                  result)))
            (partition 2 clauses))))
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.


J and BQN (APL has off-ramps...)

https://code.jsoftware.com/wiki/Essays/Tacit_Expressions

https://mlochbaum.github.io/BQN/doc/tacit.html and https://mlochbaum.github.io/BQN/doc/control.html

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!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: