AtlatestRepositorysigil-fp
1# sigil-fp
2
3Functional programming utilities for [Sigil](https://codeberg.org/sigil/sigil), providing function composition, partial application, and threading macros.
4
5## Installation
6
7Add to your `package.sgl` dependencies:
8
9```scheme
10(from-git url: "codeberg:sigil/sigil-fp")
11```
13## Modules
15### (sigil fp fn) - Function Composition
17Utilities for composing and partially applying functions.
19```scheme
20(import (sigil fp fn))
21```
23#### partial / partial-right
25Create new functions by fixing arguments:
27```scheme
28(define add10 (partial + 10))
29(add10 5) ; => 15
30(add10 1 2 3) ; => 16
32(define div-by-2 (partial-right / 2))
33(div-by-2 10) ; => 5
34```
36#### compose
38Right-to-left function composition:
40```scheme
41(define process (compose string-upcase string-trim))
42(process " hello ") ; => "HELLO"
44((compose) 42) ; => 42 (identity)
45```
47#### pipe
49Left-to-right function composition (pipeline style):
51```scheme
52(define process (pipe string-trim string-upcase))
53(process " hello ") ; => "HELLO"
54```
56#### const
58Return a function that always returns the given value:
60```scheme
61(map (const 0) '(a b c)) ; => (0 0 0)
62```
64#### flip
66Swap the first two arguments of a function:
68```scheme
69((flip cons) '(1 2) 'a) ; => (a 1 2)
70((flip -) 3 10) ; => 7
71```
73#### complement
75Return the logical complement of a predicate:
77```scheme
78(filter (complement zero?) '(0 1 0 2 0 3)) ; => (1 2 3)
79```
81#### juxt
83Apply multiple functions to the same arguments, returning a list of results:
85```scheme
86((juxt car cdr) '(1 2 3)) ; => (1 (2 3))
87((juxt + - *) 3 4) ; => (7 -1 12)
88```
90### (sigil fp chain) - Threading Macros
92Thread values through sequences of expressions, similar to Clojure's threading macros and SRFI-197.
94> **These macros live in `(sigil core)` now.** `chain`, `->`, and `some->` are
95> part of core, which is auto-imported into every module, so every program
96> already has them in scope without importing anything. `(sigil fp chain)`
97> re-exports them from core purely for backward compatibility, so existing
98> `(import (sigil fp chain))` / `(import (sigil fp))` code keeps working.
100```scheme
101;; No import needed — these come from core:
102(-> 5 (+ 3) (* 2))
104;; Or, for backward compatibility:
105(import (sigil fp chain))
106```
108#### chain / ->
110Thread a value through expressions. Uses `_` as a placeholder for the threaded value. When no `_` is present, the value is inserted as the first argument.
112```scheme
113;; Thread-first (no placeholder)
114(chain 5 (+ 3) (* 2))
115; => 16
117;; Explicit placeholder
118(chain '(1 2 3)
119 (map (lambda (x) (* x 2)) _)
120 (apply + _))
121; => 12
123;; Placeholder in various positions
124(chain 10 (- 20 _)) ; => 10
125(chain 5 (list 1 2 _ 4)) ; => (1 2 5 4)
127;; -> is an alias for chain
128(-> 5 (+ 3) (* 2)) ; => 16
129```
131#### some->
133Like `->`, but short-circuits and returns `#f` if any step produces `#f`:
135```scheme
136;; Short-circuits on #f
137(some-> #f (+ 1 _)) ; => #f
139;; Continues while truthy
140(some-> 5 (+ 1 _) (* 2 _)) ; => 12
142;; Useful for nullable pipelines
143(some-> user
144 (dict-ref _ name:)
145 (string-split " " _)
146 car)
147```
149## Building
151```
152sigil deps install
153sigil build
154sigil test
155```
157## License
159BSD-3-Clause