nydp 0.2.6 → 0.3.0
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/README.md +33 -22
- data/lib/lisp/core-000.nydp +2 -0
- data/lib/lisp/core-010-precompile.nydp +5 -1
- data/lib/lisp/core-012-utils.nydp +6 -8
- data/lib/lisp/core-015-documentation.nydp +3 -3
- data/lib/lisp/core-020-utils.nydp +1 -1
- data/lib/lisp/core-030-syntax.nydp +47 -7
- data/lib/lisp/core-040-utils.nydp +1 -3
- data/lib/lisp/core-060-benchmarking.nydp +26 -17
- data/lib/lisp/core-080-pretty-print.nydp +1 -1
- data/lib/lisp/core-100-utils.nydp +33 -0
- data/lib/lisp/tests/aif-examples.nydp +20 -0
- data/lib/lisp/tests/boot-tests.nydp +7 -6
- data/lib/lisp/tests/cycler-examples.nydp +7 -0
- data/lib/lisp/tests/destructuring-examples.nydp +64 -0
- data/lib/lisp/tests/explain-mac-examples.nydp +13 -13
- data/lib/lisp/tests/fill-bucket-examples.nydp +20 -0
- data/lib/lisp/tests/list-tests.nydp +8 -0
- data/lib/nydp/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ca4e399a839f5396035c2e8fe863c35e6c5acc4
|
4
|
+
data.tar.gz: 0e1ae8034c02c3d2401b97082d949bb29345ea5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bf68cd0b9627cf49ea2ddeb0f8ef53344b04576ecd5204dd04b943683b9b2610ba422c83d1ece2a9dc7b89968e2bfa251accad3e2bb9a450539160d660979c2
|
7
|
+
data.tar.gz: 2b40296df57b45e4d9e8be8f73aeecf38c2af80ac67d6da64407d57e69850c99820f582f14be8aa7f459ddc84e21cac6fbfa85759bed549b18474a6699f1524a
|
data/README.md
CHANGED
@@ -46,7 +46,7 @@ Suppose you want to invoke the function named `question` with some arguments. Do
|
|
46
46
|
```ruby
|
47
47
|
ns = Nydp.build_nydp # keep this for later re-use, it's expensive to set up
|
48
48
|
|
49
|
-
answer = Nydp.apply_function ns, :question, :life, ["The Universe"
|
49
|
+
answer = Nydp.apply_function ns, :question, :life, ["The Universe", and_also(everything)]
|
50
50
|
|
51
51
|
==> 42
|
52
52
|
```
|
@@ -55,7 +55,6 @@ answer = Nydp.apply_function ns, :question, :life, ["The Universe" and(everythin
|
|
55
55
|
|
56
56
|
You can maintain multiple `ns` instances without mutual interference. In other words, assigning global variables while one `ns` is in scope will not affect the values of variables in any other `ns` (unless you've specifically arranged it to be so by duplicating namespaces or some such sorcery).
|
57
57
|
|
58
|
-
|
59
58
|
## Different from Arc :
|
60
59
|
|
61
60
|
#### 1. Macro-expansion runs in lisp
|
@@ -175,8 +174,6 @@ nydp > { a 1 b (author-name) }
|
|
175
174
|
|
176
175
|
```
|
177
176
|
|
178
|
-
|
179
|
-
|
180
177
|
#### 4. Sensible, nestable string interpolation
|
181
178
|
|
182
179
|
The parser detects lisp code inside strings. When this happens, instead of emitting a string literal, the parser emits a form whose car is the symbol `string-pieces`.
|
@@ -220,18 +217,6 @@ inside interpolations and report them correctly.
|
|
220
217
|
Sorry. While technically possible ... why bother?
|
221
218
|
|
222
219
|
|
223
|
-
#### 6. No argument destructuring
|
224
|
-
|
225
|
-
However, this doesn't need to be built-in, it can be done with macros alone. On the other hand, "rest" arguments are implicitly available using the same syntax as Arc uses:
|
226
|
-
|
227
|
-
```lisp
|
228
|
-
(def fun (a b . others) ...)
|
229
|
-
```
|
230
|
-
|
231
|
-
In this example, `others` is either nil, or a list containing the third and subsequent arguments to the call to `fun`. For many examples of this kind of invocation, see [invocation-tests](lib/lisp/tests/invocation-tests.nydp) in the `tests` directory.
|
232
|
-
|
233
|
-
|
234
|
-
|
235
220
|
## Besides that, what can Nydp do?
|
236
221
|
|
237
222
|
#### 1. Functions and variables exist in the same namespace.
|
@@ -267,7 +252,33 @@ nydp> (foo)
|
|
267
252
|
==> nil
|
268
253
|
```
|
269
254
|
|
270
|
-
#### 6.
|
255
|
+
#### 6. Argument destructuring
|
256
|
+
|
257
|
+
This is not built-in to the language, but is available via the 'fun macro. Use 'fun as a drop-in replacement for 'fn and you get destructuring.
|
258
|
+
|
259
|
+
```lisp
|
260
|
+
(def funny (a (b c) . others)
|
261
|
+
xxx)
|
262
|
+
```
|
263
|
+
|
264
|
+
Equivalent to, and effectively pre-compiled to:
|
265
|
+
|
266
|
+
```lisp
|
267
|
+
(def funny (a d . others)
|
268
|
+
(with (b (nth 0 d)
|
269
|
+
c (nth 1 d))
|
270
|
+
xxx))
|
271
|
+
```
|
272
|
+
|
273
|
+
Note that `d` in this example will in real-life be a gensym and will not clobber your existing namespace.
|
274
|
+
|
275
|
+
In this example, `others` is either nil, or a list containing the third and subsequent arguments to the call to `funny`. For many examples of this kind of invocation, see [invocation-tests](lib/lisp/tests/invocation-tests.nydp) in the `tests` directory. See also [destructuring-examples](lib/lisp/tests/destructuring-examples.nydp)
|
276
|
+
|
277
|
+
Nested destructuring lists work as expected.
|
278
|
+
|
279
|
+
`def`, 'with', and `let` all expand to forms using `fun`.
|
280
|
+
|
281
|
+
#### 7. Basic error handling
|
271
282
|
|
272
283
|
```lisp
|
273
284
|
nydp> (on-err (p "error")
|
@@ -278,7 +289,7 @@ make sure this happens
|
|
278
289
|
error
|
279
290
|
```
|
280
291
|
|
281
|
-
####
|
292
|
+
#### 8. Intercept comments
|
282
293
|
|
283
294
|
```lisp
|
284
295
|
nydp > (parse "; blah blah")
|
@@ -289,7 +300,7 @@ nydp > (parse "; blah blah")
|
|
289
300
|
Except in 'mac and 'def forms, by default, `comment` is a macro that expands to nil. If you have a better idea, go for it. Any comments present at the
|
290
301
|
beginning of the `body` argument to `mac` or `def` are considered documentation. (See "self-documenting" below).
|
291
302
|
|
292
|
-
####
|
303
|
+
#### 9. Prefix lists
|
293
304
|
|
294
305
|
The parser emits a special form if it detects a prefix-list, that is, a list with non-delimiter characters immediately preceding
|
295
306
|
the opening delimiter. For example:
|
@@ -336,7 +347,7 @@ Use 'define-prefix-list-macro to define a new handler for a prefix-list. Here's
|
|
336
347
|
In this case, the regex matches an initial 'λ ; there is no constraint however on the kind of regex a prefix-list-macro might use.
|
337
348
|
|
338
349
|
|
339
|
-
####
|
350
|
+
#### 10. Self-documenting
|
340
351
|
|
341
352
|
Once the 'dox system is bootstrapped, any further use of 'mac or 'def will create documentation.
|
342
353
|
|
@@ -370,7 +381,7 @@ Not as friendly, but more amenable to programmatic manipulation. Each subsequent
|
|
370
381
|
it as a macro, or define it again in some other context) will generate a new documentation structure, which will simply be preprended to
|
371
382
|
the existing list.
|
372
383
|
|
373
|
-
####
|
384
|
+
#### 11. Pretty-Printing
|
374
385
|
|
375
386
|
'dox above uses the pretty printer to display code source. The pretty-printer is hard-coded to handle some special cases,
|
376
387
|
so it will unparse special syntax, prefix-lists, quote, quasiquote, unquote, and unquote-splicing.
|
@@ -396,7 +407,7 @@ nydp > (p:pp:dox-src 'pp/find-breaks)
|
|
396
407
|
The pretty-printer is still rather primitive in that it only indents according to some hard-coded rules, and according to argument-count
|
397
408
|
for documented macros. It has no means of wrapping forms that get too long, or that extend beyond a certain predefined margin or column number.
|
398
409
|
|
399
|
-
####
|
410
|
+
#### 12. DSLs
|
400
411
|
|
401
412
|
The `pre-compile` system (described earlier in "Macro-expansion runs in lisp") is available for implementing local, mini-languages. To do this, use `pre-compile-with`
|
402
413
|
in a macro. `pre-compile-with` expects a hash with expansion rules, and an expression to expand using these rules. For example, to build a "describe" dsl :
|
data/lib/lisp/core-000.nydp
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
(assign list (fn args args))
|
9
9
|
(assign noop (fn args nil))
|
10
|
+
(assign x1 (fn (arg) arg))
|
10
11
|
(assign caar (fn (arg) (car (car arg))))
|
11
12
|
(assign cadr (fn (arg) (car (cdr arg))))
|
12
13
|
(assign cdar (fn (arg) (cdr (car arg))))
|
@@ -20,3 +21,4 @@
|
|
20
21
|
(assign isa (fn (type obj) (eq? (type-of obj) type)))
|
21
22
|
(assign pair? (fn (arg) (isa 'pair arg)))
|
22
23
|
(assign hash? (fn (arg) (isa 'hash arg)))
|
24
|
+
(assign sym? (fn (arg) (isa 'symbol arg)))
|
@@ -56,12 +56,16 @@
|
|
56
56
|
(fn (arg)
|
57
57
|
(pre-compile-with macs arg)))
|
58
58
|
|
59
|
+
; we override this later to provide argument deconstruction
|
60
|
+
(hash-set macs 'fun
|
61
|
+
(fn args (cons 'fn args)))
|
62
|
+
|
59
63
|
; we override this later to provide automatic documentation
|
60
64
|
(hash-set macs 'def
|
61
65
|
(fn (name args . body)
|
62
66
|
(list 'assign
|
63
67
|
name
|
64
|
-
(+ (list '
|
68
|
+
(+ (list 'fun args)
|
65
69
|
body))))
|
66
70
|
|
67
71
|
(def qq-handle-unquote-splicing (arg rest level)
|
@@ -20,11 +20,9 @@
|
|
20
20
|
; push 'v onto the value for 'k in 'h
|
21
21
|
(hash-set h k (cons v (hash-get h k))))
|
22
22
|
|
23
|
-
(def rev
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
(def rev (things) (rev-accum things nil))
|
23
|
+
(def rev (things last-cdr)
|
24
|
+
; 'things - the list to be reversed
|
25
|
+
; 'last-cdr - (normally nil) - an item (atom, list, nil, anything) to be consed to the end of the reversed list.
|
26
|
+
(if (pair? things)
|
27
|
+
(rev (cdr things) (cons (car things) last-cdr))
|
28
|
+
last-cdr))
|
@@ -144,7 +144,7 @@
|
|
144
144
|
|
145
145
|
(def define-mac-expr (name args body-forms)
|
146
146
|
; used internally by 'mac
|
147
|
-
`(do (hash-set macs ',name (
|
147
|
+
`(do (hash-set macs ',name (fun ,args ,@(hash-get body-forms nil)))
|
148
148
|
(dox-add-doc ',name
|
149
149
|
'mac
|
150
150
|
',(map car (hash-get body-forms 'comment))
|
@@ -160,7 +160,7 @@
|
|
160
160
|
'mac
|
161
161
|
'("define a new global macro")
|
162
162
|
'(name args . body)
|
163
|
-
'`(hash-set macs ',name (fn ,
|
163
|
+
'`(hash-set macs ',name (fn ,args ,@body))
|
164
164
|
'(nydp-core))
|
165
165
|
|
166
166
|
(dox-add-doc 'do
|
@@ -174,7 +174,7 @@
|
|
174
174
|
|
175
175
|
(def define-def-expr (name args body-forms)
|
176
176
|
; used internally by 'def
|
177
|
-
`(do (def-assign ,name (
|
177
|
+
`(do (def-assign ,name (fun ,args ,@(hash-get body-forms nil)))
|
178
178
|
(dox-add-doc ',name
|
179
179
|
'def
|
180
180
|
',(map car (hash-get body-forms 'comment))
|
@@ -85,8 +85,8 @@ scoping, assignment, anonymous functions and more...")
|
|
85
85
|
(pairs (cddr things)))))
|
86
86
|
|
87
87
|
(mac with (parms . body)
|
88
|
-
`((
|
89
|
-
|
88
|
+
`((fun ,(map car (pairs parms))
|
89
|
+
,@body)
|
90
90
|
,@(map cadr (pairs parms))))
|
91
91
|
|
92
92
|
(mac let (var val . body)
|
@@ -113,7 +113,7 @@ scoping, assignment, anonymous functions and more...")
|
|
113
113
|
; invocation)
|
114
114
|
(let ppairs (pairs params)
|
115
115
|
`(let ,name nil
|
116
|
-
(assign ,name (
|
116
|
+
(assign ,name (fun ,(map car ppairs) ,@body))
|
117
117
|
(,name ,@(map cadr ppairs)))))
|
118
118
|
|
119
119
|
(let uniq-counter 0
|
@@ -134,10 +134,14 @@ scoping, assignment, anonymous functions and more...")
|
|
134
134
|
(mac or args
|
135
135
|
; lazy-evaluates each argument, returns the first
|
136
136
|
; non-nil result, or nil if all evaluate to nil.
|
137
|
-
(
|
138
|
-
|
139
|
-
|
140
|
-
|
137
|
+
(if (cdr args)
|
138
|
+
(let arg (car args)
|
139
|
+
(if (isa 'symbol arg)
|
140
|
+
`(cond ,arg ,arg (or ,@(cdr args)))
|
141
|
+
(w/uniq ora
|
142
|
+
`(let ,ora ,arg
|
143
|
+
(cond ,ora ,ora (or ,@(cdr args)))))))
|
144
|
+
(car args)))
|
141
145
|
|
142
146
|
(mac pop (xs)
|
143
147
|
(w/uniq gp
|
@@ -255,3 +259,39 @@ scoping, assignment, anonymous functions and more...")
|
|
255
259
|
; stores ,val, executes ,@body, and returns ,val. Assumes 'body is going to do something
|
256
260
|
; destructive with 'val, but you want 'val before it gets changed. See also 'returnlet
|
257
261
|
(w/uniq retval `(returnlet ,retval ,val ,@body)))
|
262
|
+
|
263
|
+
(mac aif (expr . body)
|
264
|
+
; like if, except the value of each condition is locally bound to the variable 'it
|
265
|
+
; eg (aif (find thing) (show it))
|
266
|
+
; source: arc.arc
|
267
|
+
`(let it ,expr
|
268
|
+
(if it
|
269
|
+
,@(if (cddr body)
|
270
|
+
`(,(car body) (aif ,@(cdr body)))
|
271
|
+
body))))
|
272
|
+
|
273
|
+
(def destructure/with (var args n)
|
274
|
+
; provides the argument expression to 'with when
|
275
|
+
; destructuring arguments are present in a 'fun definition
|
276
|
+
(if (pair? args)
|
277
|
+
`(,(car args) (nth ,n ,var) ,@(destructure/with var (cdr args) (+ n 1)))
|
278
|
+
args
|
279
|
+
`(,args (lastcdr ,var))))
|
280
|
+
|
281
|
+
(def destructure/build (given-args new-args body)
|
282
|
+
; used internally by 'fun
|
283
|
+
(if (pair? given-args)
|
284
|
+
(if (sym? (car given-args))
|
285
|
+
(destructure/build (cdr given-args)
|
286
|
+
(cons (car given-args) new-args)
|
287
|
+
body)
|
288
|
+
(w/uniq destructure
|
289
|
+
(destructure/build (cdr given-args)
|
290
|
+
(cons destructure new-args)
|
291
|
+
`((with ,(destructure/with destructure (car given-args) 0) ,@body)))))
|
292
|
+
`(fn ,(rev new-args given-args) ,@body)))
|
293
|
+
|
294
|
+
(mac fun (args . body)
|
295
|
+
; build a 'fn form, changing 'args and 'body to
|
296
|
+
; properly handle any destructuring args if present
|
297
|
+
(destructure/build args nil body))
|
@@ -7,8 +7,6 @@
|
|
7
7
|
(iso (car x) (car y))
|
8
8
|
(iso (cdr x) (cdr y)))))
|
9
9
|
|
10
|
-
(def x1 (thing) thing)
|
11
|
-
(def sym? (arg) (isa 'symbol arg))
|
12
10
|
(def num? (arg) (isa 'number arg))
|
13
11
|
(def string? (arg) (isa 'string arg))
|
14
12
|
(mac just (arg) arg)
|
@@ -49,7 +47,7 @@
|
|
49
47
|
; 'things is a list, 'x is the name of a variable, and 'expr
|
50
48
|
; is evaluated and collected for each 'x in 'things
|
51
49
|
(chapter list-manipulation)
|
52
|
-
`(map (
|
50
|
+
`(map (fun (,x) ,expr) ,things))
|
53
51
|
|
54
52
|
(def atom? (thing)
|
55
53
|
; 't if 'thing is not a list or a hash
|
@@ -1,3 +1,5 @@
|
|
1
|
+
(chapter-start 'core-benchmarking "utils for benchmarking / measuring performance improvements")
|
2
|
+
|
1
3
|
;; (def bm-cond ()
|
2
4
|
;; (if (< 3 5) "less" "more"))
|
3
5
|
|
@@ -83,23 +85,6 @@
|
|
83
85
|
;; (def bm-len-fn ()
|
84
86
|
;; (len list))
|
85
87
|
|
86
|
-
;; (def bm-repeat (f n)
|
87
|
-
;; (for b 1 n (f)))
|
88
|
-
|
89
|
-
;; (def bm (desc f repeats iterations)
|
90
|
-
;; (p "\n================================================")
|
91
|
-
;; (p "Benchmark: ~desc - ~repeats runs of ~iterations iterations each")
|
92
|
-
;; (let times 0
|
93
|
-
;; (for reps 1 repeats
|
94
|
-
;; (let started (time)
|
95
|
-
;; (bm-repeat f iterations)
|
96
|
-
;; (let elapsed (- (time) started)
|
97
|
-
;; (assign times (+ elapsed times))
|
98
|
-
;; (p " took: ~elapsed ms, ~(/ elapsed iterations) ms per iteration"))))
|
99
|
-
;; (p "total ~(just times), average ~(/ times repeats) per run")
|
100
|
-
;; (p "================================================\n")
|
101
|
-
;; "~desc : total ~(just times), average ~(/ times repeats) per run"))
|
102
|
-
|
103
88
|
;; (assign a 1)
|
104
89
|
;; (assign b 1)
|
105
90
|
|
@@ -174,8 +159,32 @@
|
|
174
159
|
;; (= h.ca v1) (= h.cb v2) (= h.cc v3) (= h.ca v4) (= h.cb v5) (= h.cc v6)
|
175
160
|
;; (= h.da v1) (= h.db v2) (= h.dc v3) (= h.da v4) (= h.db v5) (= h.dc v6)))
|
176
161
|
|
162
|
+
(def bm-or-lex-lex-lex (a b c) (or a b c))
|
163
|
+
(def bm-faster-or ()
|
164
|
+
(bm-or-lex-lex-lex 1 2 3)
|
165
|
+
(bm-or-lex-lex-lex nil 2 3))
|
166
|
+
|
167
|
+
(def bm-repeat (f n)
|
168
|
+
; used in benchmarking
|
169
|
+
(for b 1 n (f)))
|
170
|
+
|
171
|
+
(def bm (desc f repeats iterations)
|
172
|
+
(p "\n================================================")
|
173
|
+
(p "Benchmark: ~desc - ~repeats runs of ~iterations iterations each")
|
174
|
+
(let times 0
|
175
|
+
(for reps 1 repeats
|
176
|
+
(let started (time)
|
177
|
+
(bm-repeat f iterations)
|
178
|
+
(let elapsed (- (time) started)
|
179
|
+
(assign times (+ elapsed times))
|
180
|
+
(p " took: ~elapsed ms, ~(/ elapsed iterations) ms per iteration"))))
|
181
|
+
(p "total ~(just times), average ~(/ times repeats) per run")
|
182
|
+
(p "================================================\n")
|
183
|
+
"~desc : total ~(just times), average ~(/ times repeats) per run"))
|
184
|
+
|
177
185
|
(def rbs (name)
|
178
186
|
(let summary nil
|
187
|
+
(push (bm "cond with OR " bm-faster-or 10 40000) summary)
|
179
188
|
;; (push (bm "cond with OR " bm-cond-9 10 40000) summary)
|
180
189
|
;; (push (bm "cond with OR " bm-cond-9 10 100000) summary)
|
181
190
|
;; (push (bm "cond with OR " bm-cond-lex-lit-lit 10 100000) summary)
|
@@ -41,7 +41,7 @@
|
|
41
41
|
; complete form for pretty-printing, and indent being the current
|
42
42
|
; indent level.
|
43
43
|
`(do (hash-set pp/special-forms ',name
|
44
|
-
(
|
44
|
+
(fun ,args ,@body))
|
45
45
|
(dox-add-doc ',name
|
46
46
|
'pp/def
|
47
47
|
(list "pretty-printer for forms starting with ~(quote ,name)")
|
@@ -77,3 +77,36 @@
|
|
77
77
|
; of parameters for 'f. Effectively, calls (apply f item)
|
78
78
|
; for each item in 'args
|
79
79
|
(map λa(apply f a) args))
|
80
|
+
|
81
|
+
(mac def/cycler (name things)
|
82
|
+
; create a function called 'name ; each invocation of the function will
|
83
|
+
; return the next value in 'things, cycling around to the start if no things are left
|
84
|
+
`(with (i -1 xs ',things list-len ,(len things))
|
85
|
+
(def ,name (j)
|
86
|
+
(comment ,(just "each call to ~name returns the next value from ~(inspect things)"))
|
87
|
+
(nth (= i (mod (+ 1 (or j i)) list-len))
|
88
|
+
xs))))
|
89
|
+
|
90
|
+
(def fill-bucket (items bucket size-f bucket-size maximum-size)
|
91
|
+
; returns a list (list a b c) where
|
92
|
+
; 'a is a subset of 'items
|
93
|
+
; 'b is the sum of sizes of items in 'a : (apply + (map size-f a))
|
94
|
+
; 'c is the subset of 'items not in 'a
|
95
|
+
; invariants:
|
96
|
+
; b < maximum-size
|
97
|
+
; 'a + 'c is equal to 'items
|
98
|
+
; arguments:
|
99
|
+
; 'items is the list of things of which you have too many
|
100
|
+
; 'bucket is either nil, or a list if you have an existing partially-filled bucket
|
101
|
+
; 'size-f is a function that can tell the size of each item in 'items
|
102
|
+
; 'bucket-size is the size of the existing bucket, or 0 if empty
|
103
|
+
; 'maximum-size is the maximum allowed size for the bucket
|
104
|
+
(let next-item (car items)
|
105
|
+
(let next-size (+ (size-f next-item) bucket-size)
|
106
|
+
(if (< next-size maximum-size)
|
107
|
+
(fill-bucket (cdr items)
|
108
|
+
(cons next-item bucket)
|
109
|
+
size-f
|
110
|
+
next-size
|
111
|
+
maximum-size)
|
112
|
+
(list (rev bucket) bucket-size items)))))
|
@@ -0,0 +1,20 @@
|
|
1
|
+
(examples-for aif
|
2
|
+
("binds 'it in dependent expression"
|
3
|
+
(aif (* 2 3)
|
4
|
+
(+ it 1))
|
5
|
+
7)
|
6
|
+
|
7
|
+
("binds 'it in subsequent dependent expressions"
|
8
|
+
(aif nil
|
9
|
+
(ignore it)
|
10
|
+
"hello"
|
11
|
+
"~it world")
|
12
|
+
"hello world")
|
13
|
+
|
14
|
+
("recurses as necessary"
|
15
|
+
(explain-mac 1 '(aif (a) (b) (c) (d) (e)))
|
16
|
+
(let it (a) (if it (b) (aif (c) (d) (e)))))
|
17
|
+
|
18
|
+
("avoids unnecessary expansion"
|
19
|
+
(explain-mac 1 '(aif (a) (b) (c)))
|
20
|
+
(let it (a) (if it (b) (c)))))
|
@@ -114,19 +114,20 @@
|
|
114
114
|
(cond a (cond b c))))
|
115
115
|
|
116
116
|
(examples-for or
|
117
|
-
("expands 'or"
|
117
|
+
("expands a tricky 'or"
|
118
118
|
(do (reset-uniq-counter)
|
119
|
-
(pre-compile '(or a b c)))
|
119
|
+
(pre-compile '(or (a) (b) (c))))
|
120
120
|
((fn (ora-1)
|
121
121
|
(cond ora-1
|
122
122
|
ora-1
|
123
123
|
((fn (ora-2)
|
124
124
|
(cond ora-2
|
125
125
|
ora-2
|
126
|
-
((
|
127
|
-
|
128
|
-
|
129
|
-
|
126
|
+
(c))) (b)))) (a)))
|
127
|
+
|
128
|
+
("expands a simple symbol-only 'or"
|
129
|
+
(pre-compile '(or a b c))
|
130
|
+
(cond a a (cond b b c))))
|
130
131
|
|
131
132
|
(examples-for w/uniq
|
132
133
|
("w/uniq provides unique variables for macro expansion"
|
@@ -0,0 +1,7 @@
|
|
1
|
+
(def/cycler cycler-testing-example (c1 c2 c3))
|
2
|
+
|
3
|
+
(examples-for cycler
|
4
|
+
("returns each item in the list, over and over"
|
5
|
+
(list (cycler-testing-example) (cycler-testing-example) (cycler-testing-example) (cycler-testing-example)
|
6
|
+
(cycler-testing-example) (cycler-testing-example) (cycler-testing-example) (cycler-testing-example))
|
7
|
+
(c1 c2 c3 c1 c2 c3 c1 c2)))
|
@@ -0,0 +1,64 @@
|
|
1
|
+
(examples-for destructure/with
|
2
|
+
("with just one arg"
|
3
|
+
(destructure/with 'xxx '(a) 0)
|
4
|
+
(a (nth 0 xxx)))
|
5
|
+
|
6
|
+
("with several args"
|
7
|
+
(destructure/with 'xxx '(a b (c d) e) 0)
|
8
|
+
(a (nth 0 xxx)
|
9
|
+
b (nth 1 xxx)
|
10
|
+
(c d) (nth 2 xxx)
|
11
|
+
e (nth 3 xxx)))
|
12
|
+
|
13
|
+
("with several complex args and a rest-arg"
|
14
|
+
(destructure/with 'xxx '(a (b c) (d (e f)) g . h) 0)
|
15
|
+
(a (nth 0 xxx)
|
16
|
+
(b c) (nth 1 xxx)
|
17
|
+
(d (e f)) (nth 2 xxx)
|
18
|
+
g (nth 3 xxx)
|
19
|
+
h (lastcdr xxx))))
|
20
|
+
|
21
|
+
(examples-for destructure/build
|
22
|
+
("with no args"
|
23
|
+
(destructure/build nil nil '(x))
|
24
|
+
(fn nil x))
|
25
|
+
|
26
|
+
("with one arg"
|
27
|
+
(destructure/build '(a) nil '(x))
|
28
|
+
(fn (a) x))
|
29
|
+
|
30
|
+
("with one rest-arg"
|
31
|
+
(destructure/build 'args nil '(x))
|
32
|
+
(fn args x))
|
33
|
+
|
34
|
+
("with one destructuring arg"
|
35
|
+
(do (reset-uniq-counter)
|
36
|
+
(destructure/build '((a b)) nil '(x)))
|
37
|
+
(fn (destructure-1) (with (a (nth 0 destructure-1) b (nth 1 destructure-1)) x)))
|
38
|
+
|
39
|
+
("with complex args"
|
40
|
+
(do (reset-uniq-counter)
|
41
|
+
(destructure/build '(a (b c) (d (e f)) g . h) nil '(x)))
|
42
|
+
(fn (a destructure-1 destructure-2 g . h)
|
43
|
+
(with (d (nth 0 destructure-2)
|
44
|
+
(e f) (nth 1 destructure-2))
|
45
|
+
(with (b (nth 0 destructure-1)
|
46
|
+
c (nth 1 destructure-1))
|
47
|
+
x)))))
|
48
|
+
|
49
|
+
(examples-for fun
|
50
|
+
("complete expansion, handles recursive destructures"
|
51
|
+
(do (reset-uniq-counter)
|
52
|
+
(pre-compile '(fun ((a (b c)) d . e) x)))
|
53
|
+
(fn (destructure-1 d . e)
|
54
|
+
((fn (a destructure-2)
|
55
|
+
((fn (b c) x)
|
56
|
+
(nth 0 destructure-2)
|
57
|
+
(nth 1 destructure-2))) (nth 0 destructure-1) (nth 1 destructure-1))))
|
58
|
+
|
59
|
+
("implicit in 'let and 'with"
|
60
|
+
(with ((a b) (list "h" "e")
|
61
|
+
(c (d e f)) (list "l" (list "l" "o" " ")))
|
62
|
+
(let (g (h (i j) k)) (list "w" (list "o" (list "r" "l") "d"))
|
63
|
+
(string-pieces a b c d e f g h i j k)))
|
64
|
+
"hello world"))
|
@@ -1,24 +1,24 @@
|
|
1
1
|
(examples-for explain-mac
|
2
2
|
("does nothing if n is zero"
|
3
|
-
(explain-mac 0 '(afn (a) (+ 2 a)))
|
4
|
-
(afn (a) (+ 2 a)))
|
3
|
+
(explain-mac 0 '(afn (a) (let b (+ 2 a) (* b b))))
|
4
|
+
(afn (a) (let b (+ 2 a) (* b b))))
|
5
5
|
|
6
|
-
("expands once for n = 1"
|
7
|
-
(explain-mac 1 '(afn (a) (+ 2 a)))
|
8
|
-
(rfn self (a) (+ 2 a)))
|
6
|
+
("expands once for n = 1; does not expand inside forms"
|
7
|
+
(explain-mac 1 '(afn (a) (let b (+ 2 a) (* b b))))
|
8
|
+
(rfn self (a) (let b (+ 2 a) (* b b))))
|
9
9
|
|
10
10
|
("expands twice for n = 2"
|
11
|
-
(explain-mac 2 '(afn (a) (+ 2 a)))
|
12
|
-
(let self nil (assign self (fn (a) (+ 2 a)))))
|
11
|
+
(explain-mac 2 '(afn (a) (let b (+ 2 a) (* b b))))
|
12
|
+
(let self nil (assign self (fn (a) (let b (+ 2 a) (* b b))))))
|
13
13
|
|
14
14
|
("expands thrice for n = 3"
|
15
|
-
(explain-mac 3 '(afn (a) (+ 2 a)))
|
16
|
-
(with (self nil) (assign self (fn (a) (+ 2 a)))))
|
15
|
+
(explain-mac 3 '(afn (a) (let b (+ 2 a) (* b b))))
|
16
|
+
(with (self nil) (assign self (fn (a) (let b (+ 2 a) (* b b))))))
|
17
17
|
|
18
18
|
("expands four times for n = 4"
|
19
|
-
(explain-mac 4 '(afn (a) (+ 2 a)))
|
20
|
-
((
|
19
|
+
(explain-mac 4 '(afn (a) (let b (+ 2 a) (* b b))))
|
20
|
+
((fun (self) (assign self (fn (a) (let b (+ 2 a) (* b b))))) nil))
|
21
21
|
|
22
22
|
("returns same expression for n > number of possible expansions"
|
23
|
-
(explain-mac 10 '(afn (a) (+ 2 a)))
|
24
|
-
((
|
23
|
+
(explain-mac 10 '(afn (a) (let b (+ 2 a) (* b b))))
|
24
|
+
((fun (self) (assign self (fn (a) (let b (+ 2 a) (* b b))))) nil)))
|
@@ -0,0 +1,20 @@
|
|
1
|
+
(examples-for fill-bucket
|
2
|
+
("fills a bucket with 12 characters"
|
3
|
+
(fill-bucket '("1" "2345" "67" "890" "1" "2345" "678")
|
4
|
+
nil
|
5
|
+
len
|
6
|
+
0
|
7
|
+
12)
|
8
|
+
(("1" "2345" "67" "890" "1")
|
9
|
+
11
|
10
|
+
("2345" "678")))
|
11
|
+
|
12
|
+
("fills a bucket up to 100"
|
13
|
+
(fill-bucket '(1 2 3 4 5 6 7 8 9 10)
|
14
|
+
nil
|
15
|
+
λx(* x x)
|
16
|
+
0
|
17
|
+
100)
|
18
|
+
((1 2 3 4 5 6)
|
19
|
+
91
|
20
|
+
(7 8 9 10))))
|
@@ -20,6 +20,14 @@
|
|
20
20
|
(rev '(a b c))
|
21
21
|
(c b a))
|
22
22
|
|
23
|
+
("'rev reverses a list, appending another list"
|
24
|
+
(rev '(a b c) '(x y z))
|
25
|
+
(c b a x y z))
|
26
|
+
|
27
|
+
("'rev reverses a list, appending an improper ending"
|
28
|
+
(rev '(a b c) 'surprise)
|
29
|
+
(c b a . surprise))
|
30
|
+
|
23
31
|
("'rev handles nil"
|
24
32
|
(rev nil)
|
25
33
|
nil)
|
data/lib/nydp/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nydp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Conan Dalton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-05-
|
11
|
+
date: 2017-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- lib/lisp/core-100-utils.nydp
|
107
107
|
- lib/lisp/tests/accum-examples.nydp
|
108
108
|
- lib/lisp/tests/add-hook-examples.nydp
|
109
|
+
- lib/lisp/tests/aif-examples.nydp
|
109
110
|
- lib/lisp/tests/all-examples.nydp
|
110
111
|
- lib/lisp/tests/any-examples.nydp
|
111
112
|
- lib/lisp/tests/auto-hash-examples.nydp
|
@@ -116,8 +117,10 @@ files:
|
|
116
117
|
- lib/lisp/tests/collect-tests.nydp
|
117
118
|
- lib/lisp/tests/cons-examples.nydp
|
118
119
|
- lib/lisp/tests/curry-tests.nydp
|
120
|
+
- lib/lisp/tests/cycler-examples.nydp
|
119
121
|
- lib/lisp/tests/date-examples.nydp
|
120
122
|
- lib/lisp/tests/def-examples.nydp
|
123
|
+
- lib/lisp/tests/destructuring-examples.nydp
|
121
124
|
- lib/lisp/tests/detect-examples.nydp
|
122
125
|
- lib/lisp/tests/dot-syntax-examples.nydp
|
123
126
|
- lib/lisp/tests/dox-tests.nydp
|
@@ -126,6 +129,7 @@ files:
|
|
126
129
|
- lib/lisp/tests/empty-examples.nydp
|
127
130
|
- lib/lisp/tests/error-tests.nydp
|
128
131
|
- lib/lisp/tests/explain-mac-examples.nydp
|
132
|
+
- lib/lisp/tests/fill-bucket-examples.nydp
|
129
133
|
- lib/lisp/tests/filter-forms-examples.nydp
|
130
134
|
- lib/lisp/tests/foundation-test.nydp
|
131
135
|
- lib/lisp/tests/group-by-examples.nydp
|