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 +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))
|