Skip to content

Commit

Permalink
Merge pull request #41 from AbhinavOmprakash/Fix-38-
Browse files Browse the repository at this point in the history
fixes #38 where lambda functions sometimes return this>
  • Loading branch information
AbhinavOmprakash authored Jan 11, 2025
2 parents 872f5b1 + d408251 commit d742465
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 34 deletions.
34 changes: 22 additions & 12 deletions src/snitch/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -430,10 +430,23 @@
(cons (replay-function name params) body)))


(defn- prepost-map?
[forms]
;; returns true for something like this {:pre [#(even? %)]}
(and (map? (first forms))
(or (vector? (:pre (first forms)))
(vector? (:post (first forms))))
;; test for (rest form)
;; because the map shouldn't be treated
;; as a prep-post map IFF there is no body
;; since a fn can't exist without a body
(seq (rest forms))))


(defn define-in-variadic-forms
([name form]
(let [params (first form)
prepost-map? (when (map? (second form))
prepost-map? (when (prepost-map? (rest form))
(second form))
body (if (nil? prepost-map?)
(rest form)
Expand All @@ -442,8 +455,8 @@
body** (insert-replay-function name params body*)
params-def (define-args params*)]
(if (some? prepost-map?)
`(~params* ~@params-def
~prepost-map?
`(~params* ~prepost-map?
~@params-def
(~'let [result# (~'do ~@(define-let-bindings body**))]
(~'def ~(concat-symbols name '<) result#)
result#))
Expand All @@ -465,12 +478,12 @@
(defn replace-fn-with-*fn
"Replaces all occurences of `fn` with `*fn`"
[forms]
(let [result (prewalk (fn [form]
(if (fn-form? form)
`(*fn ~@(rest form))
(let [result (prewalk (fn [form]
(if (fn-form? form)
`(*fn ~@(rest form))

form))
forms)]
form))
forms)]
result))


Expand All @@ -492,10 +505,7 @@
[(first forms) (rest forms)]
[nil forms])
[prepost-map? forms] (if (and (some? params*)
(map? (first forms))
(or
(vector? (:pre (first forms)))
(vector? (:post (first forms)))))
(prepost-map? forms))
[(first forms) (rest forms)]
[nil forms])
[variadic-defs forms] (if (and (nil? params*)
Expand Down
67 changes: 45 additions & 22 deletions test/snitch/core_test.cljc
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
(ns snitch.core-test
#?(:clj
(:require
[snitch.test-utils :refer [contains-no-duplicate-inline-defs?]]
[clojure.test :refer [deftest is testing]]
[snitch.core :refer [concat-symbols define-args defn* define-let-bindings defmethod* *let *fn]])
[clojure.test :refer [deftest is testing]]
[snitch.core :refer [concat-symbols define-args defn* define-let-bindings defmethod* *let *fn]]
[snitch.test-utils :refer [contains-no-duplicate-inline-defs?]])
:cljs
(:require
[cljs.test :refer [deftest is testing run-tests]]))
[cljs.test :refer [deftest is testing run-tests]]))
#?(:cljs
(:require-macros
[snitch.core]
[snitch.test-utils :refer [contains-no-duplicate-inline-defs?]]
[snitch.core-test :refer [let-to-fn]])))
[snitch.core]
[snitch.core-test :refer [let-to-fn]]
[snitch.test-utils :refer [contains-no-duplicate-inline-defs?]])))


(deftest test-behaviour-of-defn*
Expand All @@ -31,8 +31,8 @@
expected-z 7
expected-m {:a/foo1-b1 1 :foo1-c2 2 :d 3}
expected-output [1 2 3 {:a/foo1-b1 1 :foo1-c2 2 :d 3} 5 6 7]]
;; b1, c2 etc are globally defined by the macro
;; defn*
;; b1, c2 etc are globally defined by the macro
;; defn*
(is (= expected-b foo1-b1))
(is (= expected-c foo1-c2))
(is (= expected-d foo1-dee3))
Expand Down Expand Up @@ -161,7 +161,35 @@
(is (= expected-foo6> foo6>)
"reconstructing a function with variadic args")))


(testing "prep-post map identification works correctly for variadic args"
;; This exists because define-in-variadic-forms
;; treated any map in the body as a prepost-map?
;; instead of checking whether there was a body or not
(let [_ (defn* foo7
([a] {:a a})
([b c] {:b b
:c c}))
_ (foo7 1)
_ (foo7 2 3)]
(is (= 1 a))
(is (= 2 b))
(is (= 3 c)))

;; if fn retruns a map with pre in it
;; don't consider it a prepost-map?
;; because a fn can't have a prep-post map with no body
(let [_ (defn* foo8 ([a]
{:pre [1 2 3]}))]
(is (= (foo8 1) {:pre [1 2 3]})))

(let [_ (defn* foo9 ([b]
{:pre [(even? b)]}
b))]
;; AssertionError is thrown when
;; prep-post maps are correctly recognised
;; because 1 is odd
(is (thrown? AssertionError (foo9 1)))
(is (= 2 (foo9 2)))))

;; FIXME commenting out the history feature because it doesn't work in cljs yet.
#_(testing "defn* stores history of the values.
Expand Down Expand Up @@ -250,6 +278,7 @@
(is (= {:d11 :foomethod} b11))
(is (= :foomethod d11))))


(deftest test-*let
(let [_ (*let [a 1
[b c] [2 3]]
Expand All @@ -263,6 +292,7 @@
:c))])]
(is (= some-thing 1))))


;; TODO: add more comprehensive tests
(deftest test-*fn
(let [_ ((*fn [a b]
Expand All @@ -279,7 +309,8 @@
(is (= x 1))
(is (= y 2)))
(let [_ ((*fn [a b]
((fn ([x] x)
((fn
([x] x)
([x y] [x y])) a b))
1 2)]
(is (= a 1))
Expand All @@ -288,9 +319,8 @@
(is (= y 2))))




(defmacro let-to-fn [bindings & body]
(defmacro let-to-fn
[bindings & body]
(->> (partition 2 bindings)
reverse
(reduce (fn [acc [binding-sym val]]
Expand All @@ -299,6 +329,7 @@
`((fn [~binding-sym] ~acc) ~val)))
body)))


(deftest custom-let-macros
(let [_ (defn* fn-with-custom-let-macro [x]
(let-to-fn [y x
Expand Down Expand Up @@ -333,16 +364,11 @@
y) 4)))))))



(comment
(macroexpand-1 '(let-to-fn [a 1 b 2]
(+ a b))))






(comment
(macroexpand-1 '(defn* foo [{:keys [a]}]
a))
Expand Down Expand Up @@ -380,6 +406,3 @@

(filter #(clojure.string/starts-with? (str %) "foo3") (keys (ns-publics 'snitch.core-test)))
(map #(ns-unmap 'snitch.core-test %) (keys (ns-publics 'snitch.core-test))))



0 comments on commit d742465

Please sign in to comment.