nydp 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0efb226f96102a49ecfc52dcd363de20d26a7f3f
4
- data.tar.gz: f8423c03ffc9f016396d9daf7934f6a3e5df133d
3
+ metadata.gz: 546120f25e3fa424942cb1d4f6296da7007fa3a1
4
+ data.tar.gz: afc6a8ac316812422abd8b4d8aa0e7c870ab73fd
5
5
  SHA512:
6
- metadata.gz: b5c3030351ffef2de2d5e922f1f75c4639ca0ef7a616301335b7c015c172461865421502c0615bd594186702f6fe29244a14ae25a1c9959913a5d457d6eabd9f
7
- data.tar.gz: 87d733099303526473ef61fb7b3e75738b7f2b3f86698fa5bc1f26d811c5fd54c7f359b0fe675ddd521fde85185e3c577bd0c0fae94b57955ae6a5399b5e1bc4
6
+ metadata.gz: a8d144329085f686df6e0b3b12be6fb207e08fe0edca7633088d3a59095cdf1c0953636b8faf352037bdd22fc13dbc822604a76b6f6709b1e3d74787362ad34c
7
+ data.tar.gz: 6c0875dfd8712fc2fb22dd987cc4cf323d7e4c39b6444e4da0b6e8790706e3f7714f0e1fdac563edad9ce1104cb1e38600becb3fdcadd668b498d0c2b5c9384c
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 conanite
1
+ Copyright (c) 2013-2016 Conan Dalton conan@conandalton.net
2
2
 
3
3
  MIT License
4
4
 
data/bin/nydp CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'nydp'
4
4
 
5
- Nydp.repl
5
+ Nydp.repl verbose: ($*.include? "-v")
@@ -1,4 +1,3 @@
1
-
2
1
  (assign mac-expand (fn (names macfn expr)
3
2
  (cond macfn
4
3
  (pre-compile-with names
@@ -1,20 +1,21 @@
1
1
  (def privately () nil)
2
2
 
3
- ((fn (this-chapter-name chapters chapter-new chapter-build chapter-find-by-name chapter-add-to-chapter)
3
+ ((fn (this-chapter-name chapters chapter-new chapter-build chapter-add-to-chapter)
4
4
  (assign chapters (hash))
5
5
 
6
6
  (def chapter-end ()
7
7
  (assign this-chapter-name nil))
8
8
 
9
- (def chapter-start (name description)
10
- (assign this-chapter-name name)
11
- (chapter-describe description))
9
+ (def chapter-start (chapter-name description)
10
+ (assign this-chapter-name chapter-name)
11
+ (chapter-describe description chapter-name))
12
12
 
13
13
  (def chapter-new (hsh name)
14
14
  (hash-set hsh 'name name)
15
15
  hsh)
16
16
 
17
17
  (def chapter-names () (hash-keys chapters))
18
+ (def chapter-current () this-chapter-name)
18
19
 
19
20
  (def chapter-build (name chapter)
20
21
  (cond chapter
@@ -24,11 +25,8 @@
24
25
  name
25
26
  (chapter-new (hash) name)))))
26
27
 
27
- (def chapter-find-by-name (name)
28
- (chapter-build name (hash-get chapters name)))
29
-
30
28
  (def chapter-find (name)
31
- (chapter-find-by-name (cond name name this-chapter-name)))
29
+ (chapter-build name (hash-get chapters name)))
32
30
 
33
31
  (def chapter-add-to-chapter (chapter attribute thing)
34
32
  (cond chapter
@@ -55,7 +53,7 @@
55
53
  (hash-set hsh 'texts texts )
56
54
  (hash-set hsh 'args args )
57
55
  (hash-set hsh 'src src )
58
- (hash-set hsh 'chapters chapters )
56
+ (hash-set hsh 'chapters (cons (chapter-current) chapters))
59
57
  (hash-set hsh 'file this-script )
60
58
  (hash-set hsh 'plugin this-plugin )
61
59
  hsh)
@@ -69,7 +67,6 @@
69
67
  (dox-new (dox-build (hash) name what texts args src chapters))))
70
68
 
71
69
  (def dox-add-to-chapters (item chapters)
72
- (chapter-add-item item)
73
70
  (cond chapters
74
71
  (do (chapter-add-item item (car chapters))
75
72
  (dox-add-to-chapters item (cdr chapters)))
@@ -12,8 +12,8 @@
12
12
  '(cond (no args) nil
13
13
  (cond (cdr args)
14
14
  (cond (cddr args)
15
- `(cond ,(car twargs) ,(cadr twargs) (if ,@(cddr twargs)))
16
- `(cond ,(car twargs) ,(cadr twargs)))
15
+ `(cond ,(car args) ,(cadr args) (if ,@(cddr args)))
16
+ `(cond ,(car args) ,(cadr args)))
17
17
  (car args)))
18
18
  '(flow-control))
19
19
 
@@ -1,3 +1,7 @@
1
+ (chapter-start 'nydp/syntax "Provides core nydp keywords and syntax, including lazy
2
+ boolean expressions, special syntax for symbols and lists, special macros for
3
+ scoping, assignment, anonymous functions and more...")
4
+
1
5
  (mac and args
2
6
  ; returns last arg if all 'args evaluate to non-nil
3
7
  ; nil otherwise
@@ -20,7 +24,7 @@
20
24
  (def caris (obj things)
21
25
  ; returns true if 'things is a list and the first item of the
22
26
  ; list is the given object
23
- (and (isa 'pair things)
27
+ (and (pair? things)
24
28
  (eq? (car things) obj)))
25
29
 
26
30
  (mac unless (arg . body)
@@ -167,8 +171,13 @@
167
171
  (mac hash-lookup (names)
168
172
  (build-hash-getters names nil))
169
173
 
170
- (mac dot-syntax names `(hash-lookup ,names))
171
- (mac dollar-syntax (_ name) `(,name))
174
+ (mac dot-syntax names
175
+ ; parser expands a.b to (dot-syntax a b)
176
+ `(hash-lookup ,names))
177
+
178
+ (mac dollar-syntax (_ name)
179
+ ; parser expands a$b to (dollar-syntax a b)
180
+ `(,name))
172
181
 
173
182
  (def dot-syntax-assignment (names value-expr)
174
183
  (let rnames (rev names)
@@ -180,6 +189,8 @@
180
189
  `(hash-set ,@lookup ,value))
181
190
 
182
191
  (mac = (name value)
192
+ ; generic assignment which unlike builtin 'assign, knows how to assign
193
+ ; to hash keys
183
194
  (if (isa 'symbol name)
184
195
  `(assign ,name ,value)
185
196
  (caris 'dot-syntax name)
@@ -187,7 +198,13 @@
187
198
  (caris 'hash-get name)
188
199
  (hash-get-assignment (cdr name) value)))
189
200
 
190
- (mac def-assign args `(= ,@args))
201
+ (mac def-assign args
202
+ ; override previous definition to allow expressions like (def hsh.foo (arg arg2) ...)
203
+ `(= ,@args))
204
+
205
+ (mac or= (place val)
206
+ ; evaluate ,val and assign result to ,place only if ,place is already nil
207
+ `(or ,place (= ,place ,val)))
191
208
 
192
209
  (def brace-list-hash-key (k)
193
210
  (if (isa 'symbol k) `(quote ,k)
@@ -207,16 +224,23 @@
207
224
  `(fn (obj) ,(build-hash-lookup-from 'obj (list arg)))))
208
225
 
209
226
  (mac ampersand-syntax (pfx . rest)
227
+ ; parser expands a&b to (ampersand-syntax a b)
210
228
  (if (no (eq? pfx '||))
211
229
  (error "Irregular '& syntax: got prefix ~(inspect pfx) in ~(joinstr "&" (cons pfx rest))"))
212
230
  (if (cdr rest)
213
231
  (error "Irregular '& syntax: got suffix ~(inspect (cdr rest)) in ~(joinstr "&" (cons pfx rest))")
214
232
  (build-ampersand-syntax (car rest))))
215
233
 
216
- (mac brace-list-mono (arg) arg)
217
- (mac brace-list-empty () '(hash))
234
+ (mac brace-list-mono (arg)
235
+ ; override 'brace-list-mono in order to provide a useful interpretation for "{ x }" syntax
236
+ arg)
237
+
238
+ (mac brace-list-empty ()
239
+ ; interprets "{ }" as new hash
240
+ '(hash))
218
241
 
219
242
  (mac brace-list args
243
+ ; parser expands { foo bar } to (brace-list foo bar)
220
244
  (if (no args)
221
245
  `(brace-list-empty)
222
246
  (no (cdr args))
@@ -224,9 +248,12 @@
224
248
  (brace-list-build-hash args)))
225
249
 
226
250
  (mac returnlet (var val . body)
227
- ; stores ,val in ,var, executes ,@body, returns ,var
251
+ ; stores ,val in ,var, executes ,@body, returns ,var. Saves a line of code at the end of
252
+ ; 'let. Assumes 'body is going to do something destructive with 'val, but you want 'val before
253
+ ; it gets changed. See also 'returning
228
254
  `(let ,var ,val ,@body ,var))
229
255
 
230
256
  (mac returning (val . body)
231
- ; stores ,val, executes ,@body, and returns ,val.
257
+ ; stores ,val, executes ,@body, and returns ,val. Assumes 'body is going to do something
258
+ ; destructive with 'val, but you want 'val before it gets changed. See also 'returnlet
232
259
  (w/uniq retval `(returnlet ,retval ,val ,@body)))
@@ -0,0 +1,50 @@
1
+ (chapter-start 'flow-control "constructs for looping and error management")
2
+
3
+ (mac on-err (handler . body)
4
+ ; executes 'body. If an error is raised, executes 'handler. Inside
5
+ ; 'handler, the parameter 'err refers to the error that was raised.
6
+ `(handle-error (fn (err) ,handler)
7
+ (fn () ,@body)))
8
+
9
+ (mac ensure (protection . body)
10
+ ; executes 'body. Afterwards, executes 'protection.
11
+ ; 'protection is always executed even if there is an error.
12
+ `(ensuring (fn () ,protection)
13
+ (fn () ,@body)))
14
+
15
+ (mac while (test . body)
16
+ ; tests 'test, as long as 'test is non-nil,
17
+ ; repeatedly executes 'body
18
+ (w/uniq (rfname pred)
19
+ `(rfnwith ,rfname (,pred ,test)
20
+ (when ,pred
21
+ ,@body
22
+ (,rfname ,test)))))
23
+
24
+ (mac loop (start test update . body)
25
+ ; execute 'start, then for as long as 'test returns non-nil,
26
+ ; execute 'body and 'update
27
+ (w/uniq (gfn gparm)
28
+ `(do ,start
29
+ ((rfn ,gfn (,gparm)
30
+ (if ,gparm
31
+ (do ,@body ,update (,gfn ,test))))
32
+ ,test))))
33
+
34
+ (mac for (v init max . body)
35
+ ; assign 'init to 'v, then execute 'body 'max times,
36
+ ; incrementing 'v at each iteration
37
+ (w/uniq (gi gm)
38
+ `(with (,v nil ,gi ,init ,gm (+ ,max 1))
39
+ (loop (assign ,v ,gi) (< ,v ,gm) (assign ,v (+ ,v 1))
40
+ ,@body))))
41
+
42
+ (def curry (func . args1)
43
+ ; return a new function which is the original function with
44
+ ; the given args1 already applied
45
+ ; arguments to the new function are whatever arguments remain
46
+ ; for the old function
47
+ (fn args
48
+ (apply func
49
+ (joinlists args1
50
+ args))))
@@ -0,0 +1,38 @@
1
+ (chapter-start 'list-manipulation "utilities for manipulating and iterating over lists, including filters and transforms")
2
+
3
+ (def zip (a b)
4
+ ; takes two lists, (p q r) and (1 2 3), returns ((p 1) (q 2) (r 3))
5
+ (if a
6
+ (cons (list (car a) (car b))
7
+ (zip (cdr a) (cdr b)))))
8
+
9
+ (def eachr (f things)
10
+ (when things
11
+ (eachr f (cdr things))
12
+ (f (car things))))
13
+
14
+ (mac push (x things)
15
+ `(= ,things (cons ,x ,things)))
16
+
17
+ (def flatten (things)
18
+ (let acc nil
19
+ (rfnwith flattenize (x things)
20
+ (if (pair? x)
21
+ (eachr flattenize x)
22
+ (push x acc)))
23
+ acc))
24
+
25
+ (def assoc (key al)
26
+ ; given a list 'al of form '( (k0 v0) (k1 v1) (k2 v2) ... (kn vn) ) and
27
+ ; a 'key, returns the list (kx vx) from 'al where kx is equal to 'key
28
+ ; #attribution: inspiration from arc.arc
29
+ (if (pair? al)
30
+ (if (caris key (car al))
31
+ (car al)
32
+ (assoc key (cdr al)))))
33
+
34
+ (def alref (key al)
35
+ ; given a list 'al of form '( (k0 v0) (k1 v1) (k2 v2) ... (kn vn) ) and
36
+ ; a 'key, returns vx from 'al where kx is equal to 'key
37
+ ; #attribution: lifted almost directly from arc.arc
38
+ (cadr (assoc key al)))
@@ -1,55 +1,4 @@
1
- (def today ()
2
- ; return a date for the current day
3
- (date))
4
-
5
- (def eachr (f things)
6
- (when things
7
- (eachr f (cdr things))
8
- (f (car things))))
9
-
10
- (def zip (a b)
11
- ; takes two lists, (p q r) and (1 2 3), returns ((p 1) (q 2) (r 3))
12
- (if a
13
- (cons (list (car a) (car b))
14
- (zip (cdr a) (cdr b)))))
15
-
16
- (mac push (x things)
17
- `(= ,things (cons ,x ,things)))
18
-
19
- (def flatten (things)
20
- (let acc nil
21
- (rfnwith flattenize (x things)
22
- (if (pair? x)
23
- (eachr flattenize x)
24
- (push x acc)))
25
- acc))
26
-
27
- (def list-slices (things slice-size)
28
- ; slice 'things into a list of lists each with maximum 'slice-size items
29
- (chapter pagination)
30
- (chapter list-manipulation)
31
- (if (< (len things) slice-size)
32
- (cons things nil)
33
- (cons (firstn slice-size things)
34
- (list-slices (nthcdr slice-size things)
35
- slice-size))))
36
-
37
- (def intersperse (inbetween things)
38
- ; return a new list with 'inbetween in between every element of 'things
39
- (if (and (pair? things) (cdr things))
40
- (apply list (car things) inbetween
41
- (intersperse inbetween (cdr things)))
42
- things))
43
-
44
- (def intersperse-splicing (inbetween things)
45
- ; expects 'things a list of lists, joins the lists
46
- ; placing 'inbetween in between each list.
47
- ; For example (intersperse-splicing 'X '((a b) (c d) (e f)))
48
- ; returns (a b X c d X e f)
49
- (apply joinlists (intersperse (list inbetween) things)))
50
-
51
- (def string-strip (txt)
52
- (string-replace "(^\\s+|\\s+$)" "" txt))
1
+ (chapter-start 'nydp-core "essential functions for getting anything done")
53
2
 
54
3
  (def joinstr (txt . things)
55
4
  ; flatten 'things into a single list (ie unnest lists)
@@ -63,43 +12,6 @@
63
12
  (flatten (zip (map (fn (_) txt) (cdr joinables))
64
13
  (map to-string (cdr joinables)))))))
65
14
 
66
- (def j items
67
- ; delegate to 'joinstr with an empty join string
68
- ; shortcut for (joinstr "" items)
69
- (joinstr "" items))
70
-
71
- (def string-pieces pieces
72
- ; string-interpolation syntax emits this form. Default implementation
73
- ; is to delegate to 'j , but containing forms may use macros that
74
- ; override this in order to provide specific interpolation behaviour
75
- ; (for example, formatting numbers or stripping HTML tags)
76
- (j pieces))
77
-
78
- (def collect (f things)
79
- ; if 'things is a list, return all the items in the list for which 'f returns non-nil
80
- ; otherwise, return 'things if (f things) is non-nil
81
- ; otherwise, nil
82
- (rfnwith collector (items things)
83
- (if (no items)
84
- nil
85
- (pair? items)
86
- (if (f (car items))
87
- (cons (car items)
88
- (collector (cdr items)))
89
- (collector (cdr items)))
90
- (f items)
91
- items)))
92
-
93
- (def reject (f things)
94
- ; return all the items in 'things for which 'f returns nil
95
- (collect !f things))
96
-
97
- (def nth (n things)
98
- ; returns the n-th item in the list 'things
99
- (if (eq? n 0)
100
- (car things)
101
- (nth (- n 1) (cdr things))))
102
-
103
15
  (def iso (x y)
104
16
  (or (eq? x y)
105
17
  (and (pair? x)
@@ -107,22 +19,23 @@
107
19
  (iso (car x) (car y))
108
20
  (iso (cdr x) (cdr y)))))
109
21
 
110
- (def x1 (thing) thing)
111
- (def sym? (arg) (isa 'symbol arg))
112
- (def string? (arg) (isa 'string arg))
113
- (mac just (arg) arg)
114
- (def quotify (arg) `(quote ,arg))
115
-
116
- (def list-length (things)
117
- (if (no things) 0
118
- (atom? things) 1
119
- (+ 1 (list-length:cdr things))))
120
-
121
- (def len (xs)
122
- (if (no xs) 0
123
- (pair? xs) (list-length xs)
124
- (string? xs) (string-length xs)
125
- (hash? xs) (list-length:hash-keys xs)
22
+ (def x1 (thing) thing)
23
+ (def sym? (arg) (isa 'symbol arg))
24
+ (def string? (arg) (isa 'string arg))
25
+ (mac just (arg) arg)
26
+ (def quotify (arg) `(quote ,arg))
27
+
28
+ (def len (things)
29
+ ; return the length of 'things where 'things may be nil, a string, list or hash
30
+ ; length of nil is zero, length of hash is number of keys, length of string
31
+ ; is number of characters, length of list is number of direct items - no recursive counting
32
+ (chapter list-manipulation)
33
+ (chapter string-manipulation)
34
+ (chapter hash-manipulation)
35
+ (if (no things) 0
36
+ (pair? things) (list-length things)
37
+ (string? things) (string-length things)
38
+ (hash? things) (list-length:hash-keys things)
126
39
  nil))
127
40
 
128
41
  (assign dynamics (hash))
@@ -142,53 +55,16 @@
142
55
  ,result))))
143
56
  (def ,name () (hash-get (thread-locals) ',name))))))
144
57
 
145
- (mac on-err (handler . body)
146
- ; executes 'body. If an error is raised, executes 'handler. Inside
147
- ; 'handler, the parameter 'err refers to the error that was raised.
148
- `(handle-error (fn (err) ,handler)
149
- (fn () ,@body)))
150
-
151
- (mac ensure (protection . body)
152
- ; executes 'body. Afterwards, executes 'protection.
153
- ; 'protection is always executed even if there is an error.
154
- `(ensuring (fn () ,protection)
155
- (fn () ,@body)))
156
-
157
- (mac while (test . body)
158
- ; tests 'test, as long as 'test is non-nil,
159
- ; repeatedly executes 'body
160
- (w/uniq (rfname pred)
161
- `(rfnwith ,rfname (,pred ,test)
162
- (when ,pred
163
- ,@body
164
- (,rfname ,test)))))
165
-
166
- (mac loop (start test update . body)
167
- ; execute 'start, then for as long as 'test returns non-nil,
168
- ; execute 'body and 'update
169
- (w/uniq (gfn gparm)
170
- `(do ,start
171
- ((rfn ,gfn (,gparm)
172
- (if ,gparm
173
- (do ,@body ,update (,gfn ,test))))
174
- ,test))))
175
-
176
- (mac for (v init max . body)
177
- ; assign 'init to 'v, then execute 'body 'max times,
178
- ; incrementing 'v at each iteration
179
- (w/uniq (gi gm)
180
- `(with (,v nil ,gi ,init ,gm (+ ,max 1))
181
- (loop (assign ,v ,gi) (< ,v ,gm) (assign ,v (+ ,v 1))
182
- ,@body))))
183
-
184
58
  (mac mapx (things x expr)
185
59
  ; a macro wrapper for 'map
186
60
  ; 'things is a list, 'x is the name of a variable, and 'expr
187
61
  ; is evaluated and collected for each 'x in 'things
62
+ (chapter list-manipulation)
188
63
  `(map (fn (,x) ,expr) ,things))
189
64
 
190
65
  (def atom? (thing)
191
66
  ; 't if 'thing is not a list or a hash
67
+ (chapter nydp-core)
192
68
  (and thing
193
69
  (!pair? thing)
194
70
  (!hash? thing)))
@@ -196,123 +72,16 @@
196
72
  (def empty? (things)
197
73
  ; t if it's nil or an empty list, string, or hash
198
74
  ; nil otherwise
75
+ (chapter list-manipulation)
76
+ (chapter string-manipulation)
77
+ (chapter hash-manipulation)
199
78
  (let l (len things)
200
79
  (and l (eq? l 0))))
201
80
 
202
81
  (def present? (thing)
203
82
  ; t if it's a symbol or number, or a non-empty string, list or hash
204
83
  ; nil otherwise
84
+ (chapter list-manipulation)
85
+ (chapter string-manipulation)
86
+ (chapter hash-manipulation)
205
87
  (!empty? thing))
206
-
207
- (mac each (var things code)
208
- ; repeatedly assigns an element of 'things to 'var,
209
- ; and executes 'code each time
210
- (w/uniq (xs c)
211
- `((rfn ,c (,xs)
212
- (if (pair? ,xs)
213
- (do
214
- (let ,var (car ,xs) ,code)
215
- (,c (cdr ,xs)))))
216
- ,things)))
217
-
218
- (def reduce (f things)
219
- ((rfn rd (acc list)
220
- (if (pair? list)
221
- (rd (f acc (car list))
222
- (cdr list))
223
- acc))
224
- (car things) (cdr things)))
225
-
226
- (def proper? (list)
227
- ; t if this is a proper list (last cdr is nil)
228
- ; nil otherwise (last cdr is neither cons nor nil)
229
- (or (no list)
230
- (and (pair? list)
231
- (proper? (cdr list)))))
232
-
233
- (def firstn (n things)
234
- ; returns the first 'n items in the list 'things
235
- (if (eq? n 0) nil
236
- (cons (car things)
237
- (firstn (- n 1)
238
- (cdr things)))))
239
-
240
- (def nthcdr (n things)
241
- ; returns the nth cdr of the list 'things
242
- (if (> n 0)
243
- (nthcdr (- n 1) (cdr things))
244
- things))
245
-
246
- (def joinlists (things . more-thingses)
247
- ; return a new list which is the concatenation of all the given lists
248
- ; 'things is a list
249
- ; 'more-thingses is a list of lists
250
- ; call like this: (joinlists '(a b c) '(x y z) '(1 2 3))
251
- (if things
252
- (cons (car things)
253
- (apply joinlists
254
- (cdr things)
255
- more-thingses))
256
- more-thingses
257
- (apply joinlists more-thingses)))
258
-
259
- (def curry (func . args1)
260
- ; return a new function which is the original function with
261
- ; the given args1 already applied
262
- ; arguments to the new function are whatever arguments remain
263
- ; for the old function
264
- (fn args
265
- (apply func
266
- (joinlists args1
267
- args))))
268
-
269
- (def detect (f things)
270
- ; if 'f is a function,
271
- ; if 'things is a list, return the first item in the list for which 'f returns non-nil
272
- ; otherwise, return 'things if (f things) is non-nil
273
- ; otherwise, nil
274
- ; if 'f is not a function, self-invoke with a function checking for equality with f
275
- ;
276
- ; WARNING: if the detected thing is nil, returns t instead. A return value of nil
277
- ; means the thing was not found ; non-nil means the thing was found, including when
278
- ; the found thing is itself nil.
279
- (if (isa 'fn f)
280
- (rfnwith d (items things)
281
- (if (pair? items)
282
- (let it (car items)
283
- (or
284
- (and (f it)
285
- (or it t))
286
- (d:cdr items)))
287
- (f items)
288
- items))
289
- (detect (curry eq? f)
290
- things)))
291
-
292
- (def tuples (n things)
293
- ;; split things into a list of lists each n long
294
- (rfnwith _ (list things)
295
- (if (no list)
296
- nil
297
- (cons (firstn n list) (_ (nthcdr n list))))))
298
-
299
- (def range (start stop)
300
- ; return a list containing the range
301
- ; of elements starting with 'start, up
302
- ; to but not including 'stop
303
- (if (< start stop)
304
- (cons start
305
- (range (+ start 1)
306
- stop))))
307
-
308
- (def best (f things)
309
- (if (no things)
310
- nil
311
- (let winner (car things)
312
- (each thing (cdr things)
313
- (if (f thing winner)
314
- (= winner thing)))
315
- winner)))
316
-
317
- (def min things (best < things))
318
- (def max things (best > things))