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 +4 -4
- data/LICENSE.txt +1 -1
- data/bin/nydp +1 -1
- data/lib/lisp/core-010-precompile.nydp +0 -1
- data/lib/lisp/core-015-documentation.nydp +7 -10
- data/lib/lisp/core-020-utils.nydp +2 -2
- data/lib/lisp/core-030-syntax.nydp +35 -8
- data/lib/lisp/core-035-flow-control.nydp +50 -0
- data/lib/lisp/core-037-list-utils.nydp +38 -0
- data/lib/lisp/core-040-utils.nydp +26 -257
- data/lib/lisp/core-041-string-utils.nydp +28 -0
- data/lib/lisp/core-042-date-utils.nydp +5 -0
- data/lib/lisp/core-043-list-utils.nydp +157 -0
- data/lib/lisp/core-060-benchmarking.nydp +105 -96
- data/lib/lisp/core-090-hook.nydp +4 -1
- data/lib/lisp/tests/list-tests.nydp +34 -0
- data/lib/lisp/tests/orequal-examples.nydp +20 -0
- data/lib/nydp.rb +17 -34
- data/lib/nydp/builtin.rb +0 -3
- data/lib/nydp/core.rb +1 -1
- data/lib/nydp/function_invocation.rb +47 -0
- data/lib/nydp/plugin.rb +33 -0
- data/lib/nydp/symbol.rb +8 -8
- data/lib/nydp/tokeniser.rb +26 -14
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp/vm.rb +4 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 546120f25e3fa424942cb1d4f6296da7007fa3a1
|
4
|
+
data.tar.gz: afc6a8ac316812422abd8b4d8aa0e7c870ab73fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8d144329085f686df6e0b3b12be6fb207e08fe0edca7633088d3a59095cdf1c0953636b8faf352037bdd22fc13dbc822604a76b6f6709b1e3d74787362ad34c
|
7
|
+
data.tar.gz: 6c0875dfd8712fc2fb22dd987cc4cf323d7e4c39b6444e4da0b6e8790706e3f7714f0e1fdac563edad9ce1104cb1e38600becb3fdcadd668b498d0c2b5c9384c
|
data/LICENSE.txt
CHANGED
data/bin/nydp
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
(def privately () nil)
|
2
2
|
|
3
|
-
((fn (this-chapter-name chapters chapter-new chapter-build 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-
|
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
|
16
|
-
`(cond ,(car
|
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 (
|
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
|
171
|
-
(
|
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
|
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)
|
217
|
-
|
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
|
-
(
|
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)
|
111
|
-
(def sym? (arg)
|
112
|
-
(def string? (arg)
|
113
|
-
(mac just (arg)
|
114
|
-
(def quotify (arg)
|
115
|
-
|
116
|
-
(def
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
(
|
122
|
-
(
|
123
|
-
|
124
|
-
(
|
125
|
-
(
|
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))
|