Atlassian uses cookies to improve your browsing experience, perform analytics and research, and conduct advertising. Accept all cookies to indicate that you agree to our use of cookies on your device. Atlassian cookies and tracking notice, (opens new window)
deftype generates new types when evaluation is expected to be suppressed
Key details
Description
There does not seem to be a consistent way to prevent deftype from emitting a new type. This was discovered in ClojureCLR when trying to write a defonce-style macro wrapper for deftype, but it affects ClojureJVM as well. It seems to emit types on analysis, which defies Clojure's evaluation semantics.
The following REPL session highlights expected and unexpected behavior, namely that when false is unable to prevent deftype from emitting a new type into memory. comment seems to work, however.
nREPL server started on port 52921 on host 127.0.0.1 - nrepl://127.0.0.1:52921
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_60-b27
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> (deftype TypeTest [a b])
user.TypeTest
user=> (->> user.TypeTest .getDeclaredFields (map #(.getName %)))
("a" "b")
user=> (deftype TypeTest [a b c])
user.TypeTest
user=> (->> user.TypeTest .getDeclaredFields (map #(.getName %)))
("a" "b" "c") ;; <= expected redefinition
user=> (when false (deftype TypeTest [a]))
nil
user=> (->> user.TypeTest .getDeclaredFields (map #(.getName %)))
("a") ;; <= when false fails to prevent redefinition
user=> (comment (deftype TypeTest [a b c]))
nil
user=> (->> user.TypeTest .getDeclaredFields (map #(.getName %)))
("a") ;; <= comment manages to prevent redefinition
user=>
There does not seem to be a consistent way to prevent
deftypefrom emitting a new type. This was discovered in ClojureCLR when trying to write adefonce-style macro wrapper fordeftype, but it affects ClojureJVM as well. It seems to emit types on analysis, which defies Clojure's evaluation semantics.The following REPL session highlights expected and unexpected behavior, namely that
when falseis unable to preventdeftypefrom emitting a new type into memory.commentseems to work, however.nREPL server started on port 52921 on host 127.0.0.1 - nrepl://127.0.0.1:52921 REPL-y 0.3.7, nREPL 0.2.12 Clojure 1.8.0 Java HotSpot(TM) 64-Bit Server VM 1.8.0_60-b27 Docs: (doc function-name-here) (find-doc "part-of-name-here") Source: (source function-name-here) Javadoc: (javadoc java-object-or-class-here) Exit: Control+D or (exit) or (quit) Results: Stored in vars *1, *2, *3, an exception in *e user=> (deftype TypeTest [a b]) user.TypeTest user=> (->> user.TypeTest .getDeclaredFields (map #(.getName %))) ("a" "b") user=> (deftype TypeTest [a b c]) user.TypeTest user=> (->> user.TypeTest .getDeclaredFields (map #(.getName %))) ("a" "b" "c") ;; <= expected redefinition user=> (when false (deftype TypeTest [a])) nil user=> (->> user.TypeTest .getDeclaredFields (map #(.getName %))) ("a") ;; <= when false fails to prevent redefinition user=> (comment (deftype TypeTest [a b c])) nil user=> (->> user.TypeTest .getDeclaredFields (map #(.getName %))) ("a") ;; <= comment manages to prevent redefinition user=>