nydp 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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))