diff options
| author | Andrey Orst <andreyorst@gmail.com> | 2020-10-31 14:27:46 +0300 |
|---|---|---|
| committer | Andrey Orst <andreyorst@gmail.com> | 2020-10-31 14:27:46 +0300 |
| commit | 596089aece8383bd374621babff1a14f99413dba (patch) | |
| tree | 44d26accf16f92fe69d42b2c4e72e944cbc9c9f7 /macros/core.fnl | |
| parent | eeb77bd0c1e251e0c84ff55f178bb4f2beb78f24 (diff) | |
feature(macros): implement simple multimethods
Diffstat (limited to 'macros/core.fnl')
| -rw-r--r-- | macros/core.fnl | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/macros/core.fnl b/macros/core.fnl index be0c1bb..d107ad6 100644 --- a/macros/core.fnl +++ b/macros/core.fnl @@ -138,4 +138,33 @@ :else (error "expected table as first argument")) to#)))) +(fn first [tbl] + (. tbl 1)) + +(fn rest [tbl] + [(unpack tbl 2)]) + +(fn string? [x] + (= (type x) :string)) + +(fn* core.defmulti + [name & opts] + (let [docstring (if (string? (first opts)) (first opts)) + opts (if docstring (rest opts) opts) + dispatch-fn (first opts)] + `(local ,name + (let [multimethods# {}] + (setmetatable {} {:__call + (fn [_# ...] + ,docstring + ((or (. multimethods# (,dispatch-fn ...)) + (. multimethods# :default)) ...)) + :multimethods multimethods#}))))) + +(fn* core.defmethod + [multifn dispatch-val & fn-tail] + `(tset (. (getmetatable ,multifn) :multimethods) + ,dispatch-val + (fn ,(unpack fn-tail)))) + core |