Skip to content

Commit 6b3a053

Browse files
authored
Support for optional metadata defmulti argument (#858)
Hi, could you please consider support for optional metadata argument in `defmulti`. It fixes #857. Added tests for the same. Thanks Co-authored-by: ikappaki <[email protected]>
1 parent b357e2b commit 6b3a053

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
* Added a compile-time warning for attempting to call a function with an unsupported number of arguments (#671)
1111

1212
### Changed
13-
* Cause exceptions arising from compilation issues during macroexpansion will no longer be nested for each level of macroexpansion (#852)
13+
* Cause exceptions arising from compilation issues during macroexpansion will no longer be nested for each level of macroexpansion (#852)
14+
* Support for optional metadata argument in `defmulti` (#857)
1415

1516
### Fixed
1617
* Fix a bug where `basilisp.lang.compiler.exception.CompilerException` would nearly always suppress line information in it's `data` map (#845)

src/basilisp/core.lpy

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5247,7 +5247,9 @@
52475247
;;;;;;;;;;;;;;;;;;
52485248

52495249
(defmacro defmulti
5250-
"Define a new multimethod with the given dispatch function.
5250+
"Define a new multimethod with the given ``name`` and a ``body`` consisting of an
5251+
optional docstring, optional metadata map, a dispatch function and options of key/value
5252+
pairs.
52515253

52525254
Multimethod dispatch functions should be defined with the same arity or arities as
52535255
the registered methods. The provided dispatch function will be called first on all
@@ -5286,12 +5288,18 @@
52865288
[name & body]
52875289
(let [doc (when (string? (first body))
52885290
(first body))
5289-
name (if doc
5290-
(vary-meta name assoc :doc doc)
5291-
name)
52925291
body (if doc
52935292
(rest body)
52945293
body)
5294+
mt (when (map? (first body))
5295+
(first body))
5296+
body (if mt
5297+
(rest body)
5298+
body)
5299+
name (vary-meta name merge mt)
5300+
name (if doc
5301+
(vary-meta name assoc :doc doc)
5302+
name)
52955303
dispatch-fn (first body)
52965304
opts (apply hash-map (rest body))]
52975305
`(def ~name (basilisp.lang.multifn/MultiFunction (quote ~name)

tests/basilisp/test_multifn.lpy

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,18 @@
9393
(testing "cannot establish conflicting preference"
9494
(is (thrown? basilisp.lang.runtime/RuntimeException)
9595
(prefer-method os-lineage :os/bsd :os/unix)))))
96+
97+
(defmulti args-test1 "test1" :x)
98+
(defmulti args-test2 {:test 2} :x)
99+
(defmulti args-test3 "test3" {:test 3} :x)
100+
(defmulti args-test4 "test4" {:doc "other"} :x)
101+
102+
(deftest multi-args-optional-test
103+
(let [mt1 (meta #'args-test1)
104+
mt2 (meta #'args-test2)
105+
mt3 (meta #'args-test3)
106+
mt4 (meta #'args-test4)]
107+
(is (= "test1" (:doc mt1)))
108+
(is (= 2 (:test mt2)))
109+
(is (= {:doc "test3" :test 3} (select-keys mt3 [:doc :test])))
110+
(is (= "test4" (:doc mt4)))))

0 commit comments

Comments
 (0)