All: TCO let* and quasiquote.
[jackhill/mal.git] / tests / stepA_more.mal
1 ;;
2 ;; Testing try*/catch*
3
4 (try* (abc 1 2) (catch* exc (prn "exc is:" exc))))
5 ; "exc is:" "'abc' not found"
6 ;=>nil
7
8 ;;;TODO: fix so long lines don't trigger ANSI escape codes ;;;(try*
9 ;;;(try* (throw {"data" "foo"}) (catch* exc (do (prn "exc is:" exc) 7))) ;;;;
10 ;;;; "exc is:" {"data" "foo"} ;;;;=>7
11 ;;;;=>7
12
13 (try* (throw {"data" "foo"}) (catch* exc (do (prn "err:" exc) 7)))
14 ; "err:" {"data" "foo"}
15 ;=>7
16
17 (try* (throw "my exception") (catch* exc (do (prn "exc:" exc) 7)))
18 ; "exc:" "my exception"
19 ;=>7
20
21
22 ;;
23 ;; Testing builtin functions
24
25 (symbol? 'abc)
26 ;=>true
27 (symbol? "abc")
28 ;=>false
29
30 (nil? nil)
31 ;=>true
32 (nil? true)
33 ;=>false
34
35 (true? true)
36 ;=>true
37 (true? false)
38 ;=>false
39 (true? true?)
40 ;=>false
41
42 (false? false)
43 ;=>true
44 (false? true)
45 ;=>false
46
47 ;; Testing apply function
48 (apply + (list 2 3))
49 ;=>5
50 (apply + 4 (list 5))
51 ;=>9
52 (apply prn (list 1 2 "3" (list)))
53 ; 1 2 "3" ()
54 ;=>nil
55
56
57 ;; Testing map function
58 (def! nums (list 1 2 3))
59 (def! double (fn* (a) (* 2 a)))
60 (double 3)
61 ;=>6
62 (map double nums)
63 ;=>(2 4 6)
64
65 ;;
66 ;; Testing read-str and eval
67 (read-string "(1 2 (3 4) nil)")
68 ;=>(1 2 (3 4) nil)
69
70 (read-string "7 ;; comment")
71 ;=>7
72
73 ;;; Differing output, but make sure no fatal error
74 (read-string ";; comment")
75
76
77 (eval (read-string "(+ 4 5)"))
78 ;=>9
79
80 ;;
81 ;; Testing readline
82 (readline "mal-user> ")
83 "hello"
84 ;=>"\"hello\""
85
86 ;;
87 ;; -------- Optional Functionality --------
88
89 ;; Testing sequential? function
90
91 (sequential? (list 1 2 3))
92 ;=>true
93 (sequential? [15])
94 ;=>true
95 (sequential? sequential?)
96 ;=>false
97 (sequential? nil)
98 ;=>false
99 (sequential? "abc")
100 ;=>false
101
102 ;; Testing vector functions
103
104 (vector? [10 11])
105 ;=>true
106 (vector? '(12 13))
107 ;=>false
108 (vector 3 4 5)
109 ;=>[3 4 5]
110
111 ;; Testing conj function
112 (conj (list) 1)
113 ;=>(1)
114 (conj (list 1) 2)
115 ;=>(2 1)
116 (conj (list 2 3) 4)
117 ;=>(4 2 3)
118 (conj (list 2 3) 4 5 6)
119 ;=>(6 5 4 2 3)
120 (conj (list 1) (list 2 3))
121 ;=>((2 3) 1)
122
123 (conj [] 1)
124 ;=>[1]
125 (conj [1] 2)
126 ;=>[1 2]
127 (conj [2 3] 4)
128 ;=>[2 3 4]
129 (conj [2 3] 4 5 6)
130 ;=>[2 3 4 5 6]
131 (conj [1] [2 3])
132 ;=>[1 [2 3]]
133
134 (map? [])
135 ;=>false
136
137 ;;
138 ;; Testing hash-maps
139 (hash-map "a" 1)
140 ;=>{"a" 1}
141
142 {"a" 1}
143 ;=>{"a" 1}
144
145 (assoc {} "a" 1)
146 ;=>{"a" 1}
147
148 (def! hm1 (hash-map))
149 ;=>{}
150
151 (map? hm1)
152 ;=>true
153 (map? 1)
154 ;=>false
155 (map? "abc")
156 ;=>false
157
158 (get nil "a")
159 ;=>nil
160
161 (get hm1 "a")
162 ;=>nil
163
164 (contains? hm1 "a")
165 ;=>false
166
167 (def! hm2 (assoc hm1 "a" 1))
168 ;=>{"a" 1}
169
170 (get hm1 "a")
171 ;=>nil
172
173 (contains? hm1 "a")
174 ;=>false
175
176 (get hm2 "a")
177 ;=>1
178
179 (contains? hm2 "a")
180 ;=>true
181
182 (keys hm2)
183 ;=>("a")
184
185 (vals hm2)
186 ;=>(1)
187
188 (count (keys (assoc hm2 "b" 2 "c" 3)))
189 ;=>3
190
191 (def! hm3 (assoc hm2 "b" 2))
192 (count (keys hm3))
193 ;=>2
194 (count (vals hm3))
195 ;=>2
196
197 (dissoc hm3 "a")
198 ;=>{"b" 2}
199
200 (dissoc hm3 "a" "b")
201 ;=>{}
202
203 (dissoc hm3 "a" "b" "c")
204 ;=>{}
205
206 (count (keys hm3))
207 ;=>2
208
209
210 ;;
211 ;; Testing metadata
212 (meta [1 2 3])
213 ;=>nil
214
215 (meta (fn* (a) a))
216 ;=>nil
217
218 (with-meta [1 2 3] {"a" 1})
219 ;=>[1 2 3]
220
221 (meta (with-meta [1 2 3] {"a" 1}))
222 ;=>{"a" 1}
223
224 (meta (with-meta [1 2 3] "abc"))
225 ;=>"abc"
226
227 (meta (with-meta (list 1 2 3) {"a" 1}))
228 ;=>{"a" 1}
229
230 (meta (with-meta {"abc" 123} {"a" 1}))
231 ;=>{"a" 1}
232
233 ;;; Not actually supported by Clojure
234 ;;;(meta (with-meta (atom 7) {"a" 1}))
235 ;;;;=>{"a" 1}
236
237 (def! l-wm (with-meta [4 5 6] {"b" 2}))
238 ;=>[4 5 6]
239 (meta l-wm)
240 ;=>{"b" 2}
241
242 (meta (with-meta l-wm {"new_meta" 123}))
243 ;=>{"new_meta" 123}
244 (meta l-wm)
245 ;=>{"b" 2}
246
247 ;; Testing metadata on functions
248 (def! f-wm (with-meta (fn* [a] (+ 1 a)) {"abc" 1}))
249 (meta f-wm)
250 ;=>{"abc" 1}
251
252 (meta (with-meta f-wm {"new_meta" 123}))
253 ;=>{"new_meta" 123}
254 (meta f-wm)
255 ;=>{"abc" 1}
256
257
258 (def! f-wm2 ^{"abc" 1} (fn* [a] (+ 1 a)))
259 (meta f-wm2)
260 ;=>{"abc" 1}
261
262 ;; Testing metadata on builtin functions
263 (meta +)
264 ;=>nil
265 (def! f-wm3 ^{"def" 2} +)
266 (meta f-wm3)
267 ;=>{"def" 2}
268 (meta +)
269 ;=>nil
270
271 ;;
272 ;; Make sure closures and metadata co-exist
273 (def! gen-plusX (fn* (x) (with-meta (fn* (b) (+ x b)) {"meta" 1})))
274 (def! plus7 (gen-plusX 7))
275 (def! plus8 (gen-plusX 8))
276 (plus7 8)
277 ;=>15
278 (meta plus7)
279 ;=>{"meta" 1}
280 (meta plus8)
281 ;=>{"meta" 1}
282 (meta (with-meta plus7 {"meta" 2}))
283 ;=>{"meta" 2}
284 (meta plus8)
285 ;=>{"meta" 1}
286
287
288 ;;
289 ;; Testing atoms
290
291 (def! inc3 (fn* (a) (+ 3 a)))
292
293 (def! a (atom 2))
294 ;=>(atom 2)
295
296 ;;;(type a)
297 ;;;;=>"atom"
298
299 (deref a)
300 ;=>2
301
302 @a
303 ;=>2
304
305 (reset! a 3)
306 ;=>3
307
308 @a
309 ;=>3
310
311 (swap! a inc3)
312 ;=>6
313
314 @a
315 ;=>6
316
317 (swap! a (fn* (a) a))
318 ;=>6
319
320 (swap! a (fn* (a) (* 2 a)))
321 ;=>12
322
323 (swap! a (fn* (a b) (* a b)) 10)
324 ;=>120
325
326 (swap! a + 3)
327 ;=>123
328
329 ;; Testing swap!/closure interaction
330 (def! inc-it (fn* (a) (+ 1 a)))
331 (def! atm (atom 7))
332 (def! f (fn* [] (swap! atm inc-it)))
333 (f)
334 ;=>8
335 (f)
336 ;=>9
337