Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functional versions of threading macros #1489

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
These streams cannot be directly read to and written from, but can be passed to subprocesses.
- Add `array/join`
- Add `tuple/join`
- Add `fn->` and `fn-?>`

## 1.35.2 - 2024-06-16
- Add `bundle/add-bin` to make installing scripts easier. This also establishes a packaging convention for it.
Expand Down
23 changes: 23 additions & 0 deletions src/boot/boot.janet
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,15 @@
(keep-syntax! n parts))
(reduce fop x forms))

(defn fn->
``Threading function. Calls the first of the functions it's given with x as
the only argument, then calls the second of the functions with the result,
and so on. Useful for expressing pipelines of data.``
[x & funs]
(var x x)
(each fun funs (set x (fun x)))
x)

(defmacro -?>
``Short circuit threading macro. Inserts x as the second value in the first form
in `forms`, and inserts the modified first form into the second form
Expand Down Expand Up @@ -1403,6 +1412,20 @@
~(let [,sym ,last] (if ,sym ,(keep-syntax! n parts))))
(reduce fop x forms))

(defn fn-?>
``Short circuit threading function. Calls the first of the functions it's
given with x as the only argument, then calls the second of the functions
with the result, and so on. The pipeline will return nil if an intermediate
value is nil. Useful for expressing pipelines of data.``
[x & funs]
(var x x)
(var index 0)
(def len (length funs))
(while (not (or (>= index len) (nil? x)))
(set x ((in funs index) x))
(++ index))
x)

(defn- walk-ind [f form]
(def ret @[])
(each x form (array/push ret (f x)))
Expand Down