Functional Threading "Macros"

https://news.ycombinator.com/rss Hits: 4
Summary

I love Common Lisp. But my dayjob is in Clojure (and TypeScript, ugh.) I can’t help but notice the convenience of threading macros. Threading Readability # Compare these two pieces of code: ;; No threading (* (1+ (* significand (flt (/ (expt 2 significand))))) (expt 2 (- exponent (flt bias))) sign) ;; Threading (->> significand (expt 2) / flt (* significand) 1+ (* sign (expt 2 (- exponent (flt bias))))) Threading vs. non-threading Lisp code Threading code is much more readable. It shows the sequence of actions in the order they happen in. It omits the obvious parentheses. It highlights the patterns in function applications. One problem with threading macros though: they are macros. Lisps are good at sophisticated syntax transformations. Other languages—not so much. So we need other ways to thread functions together. Like... combinators? Threading Combinators # The idea is simple: we need several functions that’d pass closures around. Bubbling outward and storing the inner functions for until the outer ones run. (Reversing the applicative inner->outer evaluation order, thus the need for extra closures.) Must look something like: piping 3 : pipe (* 2) : pipe 1+ piped . ;; or, abbreviated --> 3 : -> (* 2) : -> 1+ >-- . ;; or, with colons expanded to parens --> 3 (-> (* 2) (-> 1+ >--)) . Hypothetical threading syntax Note on Lamber syntax The language I’m using in this post is Lamber, my Lambda Calculus compiling language. It features a minimalist syntax with only functions, values, if-s, and operators like Wisp’s colon nesting operator and terminating period (similar to Lua’s end.) First, let’s add a function that’ll initiate the piping. Nothing fancy, just take the initial value and a curried function. And then apply the function to the value. def piping fn (x f) f x . ;; also known as T combinator alias piping T . Simple piping wrapper Now to the workhorse pipe function: def pipe fn (f g x) g : f x . pipe combinator The way this magic works is: We take a function to ...

First seen: 2025-10-07 18:10

Last seen: 2025-10-07 21:11