AtlatestRepositorysigil-web-styles
sigil-web-styles / tree / build / dev / lib / _pkg / sigil-stdlib / styleidioms.md
2
# Idioms4
> Common patterns and best practices for idiomatic Sigil code.6
## Output8
Use `print`/`println` with format strings, not `display`/`newline`:10
```scheme11
;; Idiomatic12
(println "Hello, ~a!" name)13
(println "Got ~a items" (length items))15
;; Avoid (R7RS compatibility only)16
(display "Hello, ") (display name) (newline)17
```19
## Threading Pipelines21
Use `->` for data transformation pipelines instead of nested calls:23
```scheme24
;; Idiomatic - reads top to bottom25
(-> data26
(filter positive? _)27
(map square _)28
(take 10 _))30
;; Avoid - reads inside out31
(take 10 (map square (filter positive? data)))32
```34
The `_` placeholder marks where the threaded value goes. Use `some->` for nil-short-circuiting:36
```scheme37
(some-> user38
(dict-ref _ email:)39
validate-email40
send-confirmation) ; stops if any step returns #f41
```43
## Pattern Matching45
Use `match` for type/shape dispatch instead of nested `cond`:47
```scheme48
(match cmd49
(('add x y) (+ x y))50
(('quit) (exit 0))51
((? string? s) (parse-string s))52
(_ (error "Unknown command")))53
```55
Use `match-lambda` for inline match functions:57
```scheme58
(map (match-lambda59
((name . value) (format "~a=~a" name value)))60
alist)61
```63
Use `match-let` for destructuring binds:65
```scheme66
(match-let (((x y) point)67
((w h) size))68
(* (+ x w) (+ y h)))69
```71
## Polymorphic Collections73
Import `(sigil seq)` for operations that work on lists, vectors, arrays, and dicts:75
```scheme76
(import (sigil seq))78
(map square '(1 2 3)) ; => (1 4 9)79
(map square #(1 2 3)) ; => #(1 4 9)80
(filter even? #(1 2 3 4)) ; => #(2 4)81
(fold + 0 '(1 2 3 4)) ; => 1082
```84
## Transducers86
For complex transformations, compose transducers:88
```scheme89
(import (sigil seq))91
(define xform92
(comp (filtering even?)93
(mapping square)94
(taking 5)))96
(sequence xform (iota 100)) ; => (0 4 16 36 64)97
(into #() xform '(1 2 3 4)) ; => #(4 16)98
```100
## Function Composition102
Import `(sigil fn)` for point-free style:104
```scheme105
(import (sigil fn))107
(define add1 (partial + 1))108
(define process (pipe string-trim string-upcase))109
(filter (complement null?) items)110
```112
## Higher-Order Functions114
Prefer HOFs over manual recursion:116
```scheme117
;; Good118
(filter even? numbers)119
(map string-upcase names)120
(fold + 0 values)121
(filter-map maybe-transform items)123
;; Avoid manual recursion for simple cases124
```126
Use named `let` for complex loops:128
```scheme129
(let loop ((items items) (acc '()))130
(cond131
((null? items) (reverse acc))132
((valid? (car items))133
(loop (cdr items) (cons (transform (car items)) acc)))134
(else (loop (cdr items) acc))))135
```137
## Dicts139
Prefer dicts over alists for data:141
```scheme142
(define config143
#{ host: "localhost"144
port: 8080145
debug: #f })147
(dict-ref config port:) ; => 8080148
(dict-set config debug: #t) ; => new dict149
(dict-merge defaults user-config) ; => merged dict150
```152
Use `dict-get-in` for nested access:154
```scheme155
(dict-get-in response '(body: data: items:))156
```158
## Keyword Arguments160
Use keywords for optional parameters:162
```scheme163
(define (connect host (keys: (port 80) (timeout 30)))164
...)166
(connect "localhost")167
(connect "localhost" port: 443 timeout: 60)168
```170
## Error Handling172
Use `guard` for expected errors:174
```scheme175
(guard (e ((file-error? e) #f))176
(read-file-string path))177
```179
Use `error` for unexpected conditions:181
```scheme182
(unless user183
(error "User not found: ~a" id))184
```186
## Boolean Expressions188
Use `and`/`or` for short-circuit logic:190
```scheme191
(or (find-cached key) (compute-value key))192
(and (valid? x) (authorized? user) (process x))193
```195
Avoid redundant boolean conversion:197
```scheme198
;; Good199
(not (null? items))201
;; Bad202
(if (not (null? items)) #t #f)203
```205
## Multi-List Operations207
For iterating multiple lists together, use `(sigil list)`:209
```scheme210
(import (sigil list))212
(list-map + '(1 2 3) '(10 20 30)) ; => (11 22 33)213
(list-fold (lambda (a b acc) (cons (+ a b) acc))214
'() '(1 2) '(10 20)) ; => (22 11)215
```217
## Module Organization219
```scheme220
(define-library (myapp feature)221
(import (sigil string))222
(export public-api)223
(begin224
;; Private helpers first225
(define (helper x) ...)227
;; Public API228
(define (public-api x)229
(helper x))))230
```