nydp 0.2.6 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|