mirror of
https://github.com/kanaka/mal.git
synced 2024-08-16 17:20:23 +03:00
exercises: fix apply reimplementation, add Joel's hints for maps
This commit is contained in:
parent
0544b52f1a
commit
304930e749
@ -35,14 +35,28 @@ submit new solutions, or new exercises.
|
||||
form will hide your implementation, so in order to test it, you will
|
||||
need to give it another name and adapt the test accordingly.
|
||||
|
||||
- Implement `let*` as a macro that uses `fn*` and recursionn. The same
|
||||
remark applies.
|
||||
- Implement `let*` as a macro that uses `fn*` and recursion.
|
||||
The same remark applies.
|
||||
|
||||
- Implement `apply` as a macro.
|
||||
|
||||
- Implement maps using lists.
|
||||
FIXME: Is dissoc use anywhere? It makes this implememtation and the
|
||||
process more complex.
|
||||
- Recall how maps must be evaluated.
|
||||
- In the tests, you may want to replace `{...}` with `(hash-map ...)`.
|
||||
- An easy solution relies on lists alterning keys and values, so
|
||||
that the `hash-map` is only a list in reverse order so that the
|
||||
last definition takes precedence during searches.
|
||||
- As a more performant solution will use lists to construct trees,
|
||||
and ideally keep them balanced. You will find examples in most
|
||||
teaching material about functional languages.
|
||||
- Recall that `dissoc` is an optional feature. One you can implement
|
||||
dissoc is by assoc'ing a replacement value that is a magic delete
|
||||
keyword (e.g.: `__..DELETED..__`) which allows you to shadow
|
||||
values in the lower levels of the structure. The hash map
|
||||
functions have to detect that and do the right thing. e.g. `(keys
|
||||
...)` might have to keep track of deleted values as it is scanning
|
||||
the tree and not add those keys when it finds them further down
|
||||
the tree.
|
||||
|
||||
- Implement quoting within MAL.
|
||||
|
||||
|
@ -37,12 +37,15 @@
|
||||
more (rest (rest binds))]
|
||||
`((fn* [~key] (let2 ~more ~form)) ~val)))))
|
||||
|
||||
(defmacro! apply
|
||||
(fn* [& xs]
|
||||
(;; Rewrite (f a b [c d]) to (f a b c d).
|
||||
(def! rec
|
||||
(fn* [lst]
|
||||
(if (= 1 (count lst))
|
||||
(first lst) ; last argument must be a sequence
|
||||
(cons (first lst) (rec (rest lst))))))
|
||||
xs)))
|
||||
(def! apply
|
||||
(let* [
|
||||
;; (a b [c d]) -> (a b c d)
|
||||
flat_end (fn* [xs]
|
||||
(if (= 1 (count xs))
|
||||
(first xs) ; [c d] above
|
||||
(cons (first xs) (flat_end (rest xs)))))
|
||||
;; x -> 'x to protect the already-evaluated arguments.
|
||||
quote_elt (fn* [x] `(quote ~x))
|
||||
]
|
||||
(fn* [& xs]
|
||||
(eval (map quote_elt (flat_end xs))))))
|
||||
|
Loading…
Reference in New Issue
Block a user