deftype generates new types when evaluation is expected to be suppressed

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.

Environment

macOs 10.12.6

Activity

Show:
Kevin Downey
November 13, 2017, 7:26 PM

not on analysis, on compilation.

deftype has a compilation time effect. similarly def has a compilation time effect.

so

will result in the var for a being interned, but it won't have a root value.

the reason wrapping in (comment ...) stops whatever from happening is compilation happens after macroexpansions, and the comment macro replaces whatever form with nil.

I am not sure this would be considered a bug. The only way to avoid this would be to have deftype generate types at runtime instead of at compile time, but I am pretty sure the types are generated at compile time to 1. avoid generating a new type every time the compiled expression is run 2. to make class generation fairly predictable so clojure can be used in environments with unusual classloader restrictions.

Kevin Downey
November 13, 2017, 7:29 PM
Alex Miller
November 13, 2017, 11:23 PM

As Kevin commented, this is the intended behavior.

Ramsey Nasser
November 14, 2017, 4:41 PM

Noted. compile-if is what we need. Apologies for the noise.

Completed

Assignee

Unassigned

Reporter

Ramsey Nasser

Labels

Approval

None

Patch

None

Affects versions

Priority

Minor