Skip to content

Commit 5d76153

Browse files
authored
Rework handling of if expressions (#80)
Closes #75. Repeat attempt of #77, this time without the splash damage on normal function application. --------- Also thanks to Rebecca Turner (@9999years) who made the initial fix.
1 parent ef042e5 commit 5d76153

File tree

9 files changed

+1032
-462
lines changed

9 files changed

+1032
-462
lines changed

conventions.rkt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,22 @@
272272
((format-horizontal/helper) xs))))]
273273
[_ (pretty doc)]))
274274

275-
(define format-if (format-if-like/helper format-#%app))
275+
276+
(define-pretty format-if
277+
#:type node?
278+
(match/extract (node-content doc) #:as unfits tail
279+
[([-if #t] [-conditional #f])
280+
(define args-list (cons -conditional tail))
281+
(define multi-line-args ((format-vertical/helper) args-list))
282+
(define single-line-args (flatten (as-concat (map pretty args-list))))
283+
(define args-doc
284+
(if (ormap node? tail)
285+
multi-line-args
286+
(alt multi-line-args single-line-args)))
287+
(pretty-node #:unfits unfits
288+
#:adjust '("(" ")")
289+
(<+s> (flatten (pretty -if)) (try-indent #:n 0 #:because-of args-list args-doc)))]
290+
[#:else (format-#%app doc)]))
276291

277292
;; try to fit in one line if the body has exactly one form,
278293
;; else will be multiple lines

tests/benchmarks/class-internal.rkt.out

Lines changed: 188 additions & 82 deletions
Large diffs are not rendered by default.

tests/benchmarks/hash.rkt.out

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@
66

77
(define (merge one two combine/key)
88
(for/fold ([one one]) ([(k v) (in-hash two)])
9-
(hash-set one k (if (hash-has-key? one k) (combine/key k (hash-ref one k) v) v))))
9+
(hash-set one
10+
k
11+
(if (hash-has-key? one k)
12+
(combine/key k (hash-ref one k) v)
13+
v))))
1014

1115
(define (hash-union #:combine [combine #f]
12-
#:combine/key
13-
[combine/key
14-
(if combine (lambda (_ x y) (combine x y)) (hash-duplicate-error 'hash-union))]
16+
#:combine/key [combine/key
17+
(if combine
18+
(lambda (_ x y) (combine x y))
19+
(hash-duplicate-error 'hash-union))]
1520
one
1621
. rest)
1722
(define one-empty (hash-clear one))
@@ -24,21 +29,27 @@
2429
[else (merge one two combine/key)])))
2530

2631
(define (hash-union! #:combine [combine #f]
27-
#:combine/key
28-
[combine/key
29-
(if combine (lambda (_ x y) (combine x y)) (hash-duplicate-error 'hash-union!))]
32+
#:combine/key [combine/key
33+
(if combine
34+
(lambda (_ x y) (combine x y))
35+
(hash-duplicate-error 'hash-union!))]
3036
one
3137
. rest)
3238
(for* ([two (in-list rest)]
3339
[(k v) (in-hash two)])
34-
(hash-set! one k (if (hash-has-key? one k) (combine/key k (hash-ref one k) v) v))))
40+
(hash-set! one
41+
k
42+
(if (hash-has-key? one k)
43+
(combine/key k (hash-ref one k) v)
44+
v))))
3545

36-
(define (hash-intersect
37-
#:combine [combine #f]
38-
#:combine/key
39-
[combine/key (if combine (λ (_ x y) (combine x y)) (hash-duplicate-error 'hash-intersect))]
40-
one
41-
. rest)
46+
(define (hash-intersect #:combine [combine #f]
47+
#:combine/key [combine/key
48+
(if combine
49+
(λ (_ x y) (combine x y))
50+
(hash-duplicate-error 'hash-intersect))]
51+
one
52+
. rest)
4253
(define hashes (cons one rest))
4354
(define empty-h (hash-clear one)) ;; empty hash of same type as one
4455
(define (argmin f lst) ;; avoid racket/list to improve loading time
@@ -47,7 +58,9 @@
4758
#:result best)
4859
([x (in-list lst)])
4960
(define fx (f x))
50-
(if (< fx fbest) (values x fx) (values best fbest))))
61+
(if (< fx fbest)
62+
(values x fx)
63+
(values best fbest))))
5164
(for/fold ([res empty-h]) ([k (in-hash-keys (argmin hash-count hashes))])
5265
(if (for/and ([h (in-list hashes)])
5366
(hash-has-key? h k))

tests/benchmarks/list.rkt.out

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@
8989
(let loop ([l l0]
9090
[pos npos])
9191
(if (pair? l)
92-
(if (eq? pos 1) (car l) (loop (cdr l) (sub1 pos)))
92+
(if (eq? pos 1)
93+
(car l)
94+
(loop (cdr l) (sub1 pos)))
9395
(raise-arguments-error 'name "list contains too few elements" "list" l0)))
9496
(raise-argument-error 'name "list?" l0)))]))
9597
(define-lgetter second 2)
@@ -106,14 +108,18 @@
106108
(if (pair? l)
107109
(let loop ([l l]
108110
[x (cdr l)])
109-
(if (pair? x) (loop x (cdr x)) l))
111+
(if (pair? x)
112+
(loop x (cdr x))
113+
l))
110114
(raise-argument-error 'last-pair "pair?" l)))
111115

112116
(define (last l)
113117
(if (and (pair? l) (list? l))
114118
(let loop ([l l]
115119
[x (cdr l)])
116-
(if (pair? x) (loop x (cdr x)) (car l)))
120+
(if (pair? x)
121+
(loop x (cdr x))
122+
(car l)))
117123
(raise-argument-error 'last "(and/c list? (not/c empty?))" l)))
118124

119125
(define (rest l)
@@ -128,7 +134,9 @@
128134
(raise-argument-error 'make-list "exact-nonnegative-integer?" 0 n x))
129135
(let loop ([n n]
130136
[r '()])
131-
(if (zero? n) r (loop (sub1 n) (cons x r)))))
137+
(if (zero? n)
138+
r
139+
(loop (sub1 n) (cons x r)))))
132140

133141
(define (list-update l i f)
134142
(unless (list? l)
@@ -150,7 +158,9 @@
150158

151159
;; internal use below
152160
(define (drop* list n) ; no error checking, returns #f if index is too large
153-
(if (zero? n) list (and (pair? list) (drop* (cdr list) (sub1 n)))))
161+
(if (zero? n)
162+
list
163+
(and (pair? list) (drop* (cdr list) (sub1 n)))))
154164
(define (too-large who list n)
155165
(define proper? (list? list))
156166
(raise-argument-error who
@@ -192,7 +202,10 @@
192202
(raise-argument-error 'takef "procedure?" 1 list pred))
193203
(let loop ([list list])
194204
(if (pair? list)
195-
(let ([x (car list)]) (if (pred x) (cons x (loop (cdr list))) '()))
205+
(let ([x (car list)])
206+
(if (pred x)
207+
(cons x (loop (cdr list)))
208+
'()))
196209
;; could return `list' here, but make it behave like `take'
197210
;; example: (takef '(a b c . d) symbol?) should be similar
198211
;; to (take '(a b c . d) 3)
@@ -202,7 +215,9 @@
202215
(unless (procedure? pred)
203216
(raise-argument-error 'dropf "procedure?" 1 list pred))
204217
(let loop ([list list])
205-
(if (and (pair? list) (pred (car list))) (loop (cdr list)) list)))
218+
(if (and (pair? list) (pred (car list)))
219+
(loop (cdr list))
220+
list)))
206221

207222
(define (splitf-at list pred)
208223
(unless (procedure? pred)
@@ -221,15 +236,19 @@
221236
(let loop ([list list]
222237
[lead (or (drop* list n) (too-large 'take-right list n))])
223238
;; could throw an error for non-lists, but be more like `take'
224-
(if (pair? lead) (loop (cdr list) (cdr lead)) list)))
239+
(if (pair? lead)
240+
(loop (cdr list) (cdr lead))
241+
list)))
225242

226243
(define (drop-right list n)
227244
(unless (exact-nonnegative-integer? n)
228245
(raise-argument-error 'drop-right "exact-nonnegative-integer?" 1 list n))
229246
(let loop ([list list]
230247
[lead (or (drop* list n) (too-large 'drop-right list n))])
231248
;; could throw an error for non-lists, but be more like `drop'
232-
(if (pair? lead) (cons (car list) (loop (cdr list) (cdr lead))) '())))
249+
(if (pair? lead)
250+
(cons (car list) (loop (cdr list) (cdr lead)))
251+
'())))
233252

234253
(define (split-at-right list n)
235254
(unless (exact-nonnegative-integer? n)
@@ -238,7 +257,9 @@
238257
[lead (or (drop* list n) (too-large 'split-at-right list n))]
239258
[pfx '()])
240259
;; could throw an error for non-lists, but be more like `split-at'
241-
(if (pair? lead) (loop (cdr list) (cdr lead) (cons (car list) pfx)) (values (reverse pfx) list))))
260+
(if (pair? lead)
261+
(loop (cdr list) (cdr lead) (cons (car list) pfx))
262+
(values (reverse pfx) list))))
242263

243264
;; For just `takef-right', it's possible to do something smart that
244265
;; scans the list in order, keeping a pointer to the beginning of the
@@ -265,7 +286,9 @@
265286
(loop (cdr list) (cons (car list) rev) (add1 n))
266287
(let loop ([n n]
267288
[list rev])
268-
(if (and (pair? list) (pred (car list))) (loop (sub1 n) (cdr list)) n)))))
289+
(if (and (pair? list) (pred (car list)))
290+
(loop (sub1 n) (cdr list))
291+
n)))))
269292

270293
(define (takef-right list pred)
271294
(drop list (count-from-right 'takef-right list pred)))
@@ -371,7 +394,10 @@
371394
(check-not-given before-first "#:before-first")
372395
(check-not-given after-last "#:after-last")])
373396
(cond
374-
[(or (null? l) (null? (cdr l))) (if splice? (append before-first l after-last) l)]
397+
[(or (null? l) (null? (cdr l)))
398+
(if splice?
399+
(append before-first l after-last)
400+
l)]
375401
;; two cases for efficiency, maybe not needed
376402
[splice?
377403
(let* ([x (reverse x)]
@@ -452,7 +478,9 @@
452478
(begin
453479
(hash-set! h k #t)
454480
(cons x (loop l)))))))])])
455-
(if key (loop key) (loop no-key)))])))
481+
(if key
482+
(loop key)
483+
(loop no-key)))])))
456484

457485
;; check-duplicates : (listof X)
458486
;; [(K K -> bool)]
@@ -466,7 +494,9 @@
466494
(raise-argument-error 'check-duplicates "list?" 0 items))
467495
(unless (and (procedure? key) (procedure-arity-includes? key 1))
468496
(raise-argument-error 'check-duplicates "(-> any/c any/c)" key))
469-
(let ([fail-k (if (procedure? failure-result) failure-result (λ () failure-result))])
497+
(let ([fail-k (if (procedure? failure-result)
498+
failure-result
499+
(λ () failure-result))])
470500
(cond
471501
[(eq? same? equal?) (check-duplicates/t items key (make-hash) fail-k)]
472502
[(eq? same? eq?) (check-duplicates/t items key (make-hasheq) fail-k)]
@@ -532,10 +562,17 @@
532562
(if (null? l)
533563
null
534564
(let ([x (apply f (car l) (map car ls))])
535-
(if x (cons x (loop (cdr l) (map cdr ls))) (loop (cdr l) (map cdr ls))))))
565+
(if x
566+
(cons x (loop (cdr l) (map cdr ls)))
567+
(loop (cdr l) (map cdr ls))))))
536568
(raise-arguments-error 'filter-map "all lists must have same size")))
537569
(let loop ([l l])
538-
(if (null? l) null (let ([x (f (car l))]) (if x (cons x (loop (cdr l))) (loop (cdr l))))))))
570+
(if (null? l)
571+
null
572+
(let ([x (f (car l))])
573+
(if x
574+
(cons x (loop (cdr l)))
575+
(loop (cdr l))))))))
539576

540577
;; very similar to `filter-map', one more such function will justify some macro
541578
(define (count f l . ls)
@@ -548,11 +585,20 @@
548585
[c 0])
549586
(if (null? l)
550587
c
551-
(loop (cdr l) (map cdr ls) (if (apply f (car l) (map car ls)) (add1 c) c))))
588+
(loop (cdr l)
589+
(map cdr ls)
590+
(if (apply f (car l) (map car ls))
591+
(add1 c)
592+
c))))
552593
(raise-arguments-error 'count "all lists must have same size")))
553594
(let loop ([l l]
554595
[c 0])
555-
(if (null? l) c (loop (cdr l) (if (f (car l)) (add1 c) c))))))
596+
(if (null? l)
597+
c
598+
(loop (cdr l)
599+
(if (f (car l))
600+
(add1 c)
601+
c))))))
556602

557603
;; Originally from srfi-1 -- shares common tail with the input when possible
558604
;; (define (partition f l)
@@ -581,7 +627,9 @@
581627
(values (reverse i) (reverse o))
582628
(let ([x (car l)]
583629
[l (cdr l)])
584-
(if (pred x) (loop l (cons x i) o) (loop l i (cons x o)))))))
630+
(if (pred x)
631+
(loop l (cons x i) o)
632+
(loop l i (cons x o)))))))
585633

586634
;; similar to in-range, but returns a list
587635
(define range-proc
@@ -647,7 +695,12 @@
647695
;; faster than a plain loop
648696
(let loop ([l list]
649697
[result null])
650-
(if (null? l) (reverse result) (loop (cdr l) (if (f (car l)) result (cons (car l) result))))))
698+
(if (null? l)
699+
(reverse result)
700+
(loop (cdr l)
701+
(if (f (car l))
702+
result
703+
(cons (car l) result))))))
651704

652705
;; Fisher-Yates Shuffle
653706
(define (shuffle l)
@@ -689,7 +742,9 @@
689742
(let ([curr (unbox curr-box)])
690743
(if (< curr limit)
691744
(begin0 (for/fold ([acc '()]) ([i (in-range N-1 -1 -1)])
692-
(if (bitwise-bit-set? curr i) (cons (vector-ref v i) acc) acc))
745+
(if (bitwise-bit-set? curr i)
746+
(cons (vector-ref v i) acc)
747+
acc))
693748
(set-box! curr-box (+ curr 1)))
694749
#f)))]
695750
[(< N k) (lambda () #f)]

0 commit comments

Comments
 (0)