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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab2e8ff02992658d66f96d3744cf872ece5e0c6c
4
- data.tar.gz: ca9cb9b175abd201e722d7f6a60a334d164bb442
3
+ metadata.gz: 8ca4e399a839f5396035c2e8fe863c35e6c5acc4
4
+ data.tar.gz: 0e1ae8034c02c3d2401b97082d949bb29345ea5b
5
5
  SHA512:
6
- metadata.gz: 31f1534694189aaec724cf8f49c1de8a98c07c50d2a94fef0737d331f8f11b054d860c64fed579365f4715cb8c6b8f3dce8de896e243ebf577aa8dc826e72d03
7
- data.tar.gz: e93101eeae01cbed4c07a051de5ff7bba66b9962e92636c349c934cb7f788e6c322b3c00a64c348bdbe027c64ae67e80e67b5eac44148d851d8e37f34669e966
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" and(everything)]
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. Basic error handling
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
- #### 7 Intercept comments
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
- #### 8 Prefix lists
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
- #### 9 Self-documenting
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
- #### 10 Pretty-Printing
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
- #### 11 DSLs
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 :
@@ -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 'fn args)
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-accum (things acc)
24
- (cond things
25
- (rev-accum (cdr things)
26
- (cons (car things)
27
- acc))
28
- acc))
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 (fn ,args ,@(hash-get body-forms nil)))
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 ,ooargs ,@body))
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 (fn ,args ,@(hash-get body-forms nil)))
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))
@@ -33,7 +33,7 @@
33
33
  'def
34
34
  '("returns 'things in reverse order")
35
35
  '(things)
36
- '(rev-accum things nil)
36
+ '(if (pair? things) (rev (cdr things) (cons (car things) last-cdr)) last-cdr)
37
37
  '(list-manipulation))
38
38
 
39
39
  (dox-add-doc 'hash-cons
@@ -85,8 +85,8 @@ scoping, assignment, anonymous functions and more...")
85
85
  (pairs (cddr things)))))
86
86
 
87
87
  (mac with (parms . body)
88
- `((fn ,(map car (pairs parms))
89
- ,@body)
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 (fn ,(map car ppairs) ,@body))
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
- (cond args
138
- (w/uniq ora
139
- `(let ,ora ,(car args)
140
- (cond ,ora ,ora (or ,@(cdr args)))))))
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 (fn (,x) ,expr) ,things))
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
- (fn ,args ,@body))
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
- ((fn (ora-3)
127
- (cond ora-3
128
- ora-3
129
- nil)) c))) b))) a)))
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
- ((fn (self) (assign self (fn (a) (+ 2 a)))) nil))
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
- ((fn (self) (assign self (fn (a) (+ 2 a)))) nil)))
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)
@@ -1,3 +1,3 @@
1
1
  module Nydp
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3.0"
3
3
  end
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.2.6
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-16 00:00:00.000000000 Z
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