Clojure

Namespace is not loaded on defrecord class init

Details

  • Type: Enhancement Enhancement
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: Release 1.8
  • Component/s: None
  • Patch:
    Code and Test
  • Approval:
    Vetted

Description

As a user of Clojure interop from Java, I want defrecords (and deftypes?) to load their namespaces upon class initialization so that I can simply construct and use AOT'd record classes without manually requiring their namespaces first.

Calling the defrecord's constructor may or may not result in "Attempting to call unbound fn" exceptions, depending on what code has already been run.

This issue has been raised several times over the years, but I could not find an existing ticket for it:

Activity

Alex Miller made changes -
Field Original Value New Value
Approval Triaged [ 10120 ]
Labels defrecord
Issue Type Defect [ 1 ] Enhancement [ 4 ]
Rich Hickey made changes -
Approval Triaged [ 10120 ] Vetted [ 10003 ]
Rich Hickey made changes -
Fix Version/s Release 1.7 [ 10250 ]
Alex Miller made changes -
Fix Version/s Release 1.7 [ 10250 ]
Fix Version/s Release 1.8 [ 10254 ]
Nicola Mometto made changes -
Labels defrecord compiler defrecord deftype
Hide
Nicola Mometto added a comment -

The attached patch approaches this issue by adding a :load-ns options to deftype/defrecord which defaults to false.
When true, the type/record be compiled with a call to clojure.core/require to its originating namespace in its static initializer.

The patch has two known limitations:

  • clojure.core deftypes/defrecords cannot have :load-ns since we use clojure.core/require to load the namespaces so clojure.core needs to be loaded manually anyway
  • clojure.lang.Compiler/demunge is used to get the originating namespace from the deftype/defrecord class name, this means that namespaces like foo_bar are not supported since they get demunged into foo-bar. If this is something that needs to be addressed, it shouldn't be too hard to just pass the unmunged namespace name in the opts map.
Show
Nicola Mometto added a comment - The attached patch approaches this issue by adding a :load-ns options to deftype/defrecord which defaults to false. When true, the type/record be compiled with a call to clojure.core/require to its originating namespace in its static initializer. The patch has two known limitations:
  • clojure.core deftypes/defrecords cannot have :load-ns since we use clojure.core/require to load the namespaces so clojure.core needs to be loaded manually anyway
  • clojure.lang.Compiler/demunge is used to get the originating namespace from the deftype/defrecord class name, this means that namespaces like foo_bar are not supported since they get demunged into foo-bar. If this is something that needs to be addressed, it shouldn't be too hard to just pass the unmunged namespace name in the opts map.
Nicola Mometto made changes -
Patch Code and Test [ 10002 ]
Attachment 0001-CLJ-1208-load-own-namespace-in-deftype-defrecord-cla.patch [ 13778 ]
Nicola Mometto made changes -
Attachment 0001-CLJ-1208-load-own-namespace-in-deftype-defrecord-cla.patch [ 13778 ]
Nicola Mometto made changes -
Hide
Nicola Mometto added a comment -

Updated patch fixing a whitespace error and mentionint :load-ns in the docstrings of deftype/defrecord

Show
Nicola Mometto added a comment - Updated patch fixing a whitespace error and mentionint :load-ns in the docstrings of deftype/defrecord
Nicola Mometto made changes -
Hide
Nicola Mometto added a comment -

Updated patch so it applies on lastest HEAD

Show
Nicola Mometto added a comment - Updated patch so it applies on lastest HEAD
Nicola Mometto made changes -
Attachment 0001-CLJ-1208-load-own-namespace-in-deftype-defrecord-cla-v3.patch [ 13924 ]
Nicola Mometto made changes -
Attachment 0001-CLJ-1208-load-own-namespace-in-deftype-defrecord-cla-v3.patch [ 13924 ]
Nicola Mometto made changes -

People

Vote (5)
Watch (5)

Dates

  • Created:
    Updated: