Commit | Line | Data |
---|---|---|
0544b52f NB |
1 | Once you have a working implementation, you may want to implement |
2 | parts of the process inside the MAL language itself. This has no other | |
3 | purpose than learning the MAL language. Once it exists, a built-in | |
4 | implementation will always be more efficient than a native | |
5 | implementation. Also, the functions described in MAL process are | |
6 | selected for educative purposes, so portability accross | |
7 | implementations does not matter much. | |
8 | ||
9 | You may easily check your answers by passing them directly to the | |
10 | interpreter. They will hide the built-in functions carrying the same | |
11 | names, and the usual tests (with REGRESS=1) will check them. The | |
12 | `runtest.py` script provide a convenient command-line parameter to | |
13 | pass a command like 'load-file' before running the testsuite. | |
14 | ||
15 | Some solutions are given in the `examples` directory. Feel free to | |
16 | submit new solutions, or new exercises. | |
17 | ||
1ca3ee3d NB |
18 | - Implement `nil?`, `true?`, `false?` and `sequential?` with other |
19 | built-in functions. | |
0544b52f NB |
20 | |
21 | - Implement `>`, `<=` and `>=` with `<`. | |
22 | ||
1ca3ee3d NB |
23 | - Implement `hash-map`, `list`, `prn` and `swap!` as non-recursive |
24 | functions. | |
25 | ||
26 | - Implement `count`, `nth`, `map`, `concat` and `conj` with the empty | |
27 | constructor `()`, `empty?`, `cons`, `first` and `rest`. | |
28 | ||
29 | Let `count` and `nth` benefit from tail call optimization. | |
0544b52f | 30 | |
1ca3ee3d | 31 | Try to replace explicit recursions with calls to `reduce` and `foldr`. |
0544b52f NB |
32 | |
33 | - Implement the `do` special as a non-recursive function. The special | |
34 | form will hide your implementation, so in order to test it, you will | |
35 | need to give it another name and adapt the test accordingly. | |
36 | ||
304930e7 NB |
37 | - Implement `let*` as a macro that uses `fn*` and recursion. |
38 | The same remark applies. | |
0544b52f | 39 | |
1ca3ee3d | 40 | - Implement `apply`. |
0544b52f NB |
41 | |
42 | - Implement maps using lists. | |
304930e7 NB |
43 | - Recall how maps must be evaluated. |
44 | - In the tests, you may want to replace `{...}` with `(hash-map ...)`. | |
45 | - An easy solution relies on lists alterning keys and values, so | |
46 | that the `hash-map` is only a list in reverse order so that the | |
47 | last definition takes precedence during searches. | |
48 | - As a more performant solution will use lists to construct trees, | |
49 | and ideally keep them balanced. You will find examples in most | |
50 | teaching material about functional languages. | |
51 | - Recall that `dissoc` is an optional feature. One you can implement | |
52 | dissoc is by assoc'ing a replacement value that is a magic delete | |
53 | keyword (e.g.: `__..DELETED..__`) which allows you to shadow | |
54 | values in the lower levels of the structure. The hash map | |
55 | functions have to detect that and do the right thing. e.g. `(keys | |
56 | ...)` might have to keep track of deleted values as it is scanning | |
57 | the tree and not add those keys when it finds them further down | |
58 | the tree. | |
0544b52f NB |
59 | |
60 | - Implement quoting within MAL. | |
61 | ||
62 | - Implement macros within MAL. |