Clojure

Class name clash between top-level functions and defn'ed ones

Details

  • Type: Defect Defect
  • Status: Open Open
  • Priority: Critical Critical
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: Release 1.7
  • Component/s: None
  • Labels:
  • Patch:
    Code
  • Approval:
    Vetted

Description

Named anonymous fn's are not guaranteed to have unique class names when AOT-compiled.

For example:

(defn g [])
(def xx (fn g []))

When AOT-compiled both functions will emit user$g.class, the latter overwriting the former.

Demonstration script: demo1.clj

Patch: 0001-Fix-CLJ-1330-make-top-level-named-functions-classnam.patch

Approach: Generate unique class names for named fn's the same way as for unnamed anonymous fn's.

See also: This patch also fixes the issue reported in CLJ-1227.

Activity

Nicola Mometto made changes -
Field Original Value New Value
Attachment 0001-CLJ-1330.patch [ 12713 ]
Nicola Mometto made changes -
Attachment 0001-CLJ-1330.patch [ 12713 ]
Nicola Mometto made changes -
Attachment 0001-Fix-CLJ-1330-make-top-level-named-functions-classnam.patch [ 12714 ]
Alex Miller made changes -
Patch Code [ 10001 ]
Approval Triaged [ 10120 ]
Labels aot compiler
Nicola Mometto made changes -
Attachment 0001-Fix-CLJ-1330-make-top-level-named-functions-classnam.patch [ 12714 ]
Nicola Mometto made changes -
Stuart Sierra made changes -
Description When aot compiling a named top-level function, this gets compiled to the same file name as defn'ed functions using the same name.

E.g.
{code}
(defn x [])
(fn x [])
{code}

Those two functions will both compile to user$x.class, the latter overwriting the former.
This is the root-cause of http://dev.clojure.org/jira/browse/CLJ-1227

A proposed solution is to compile top-level functions prefixing their name with a gensym, as gets done for anonymous functions.
Named anonymous {{fn}}'s are not guaranteed to have unique class names when AOT-compiled.

For example:

{code}
(defn g [])
(def xx (fn g []))
{code}

When AOT-compiled both functions will emit {{user$g.class}}, the latter overwriting the former.

*Demonstration script:* demo1.clj

*Patch:* 0001-Fix-CLJ-1330-make-top-level-named-functions-classnam.patch

*Approach:* Generate unique class names for named {{fn}}'s the same way as for unnamed anonymous {{fn}}'s.

*See also:* This patch also fixes the issue reported in CLJ-1227.
Attachment demo1.clj [ 12717 ]
Alex Miller made changes -
Comment [ There is consensus that this is a problem, however this is an area of the code with broad impacts as it deals with how classes are named. To that end, there is some work that needs to be done in understanding the impacts before we can consider it.

Some questions we would like to answer:

1) According to Rich, naming of (fn x []) function classes used to work in the manner of this patch - with generated names. Some code archaeology needs to be done on why that was changed and whether the change to the current behavior was addressing problems that we are likely to run into.

2) Are there issues with recursive functions? Are there impacts either in AOT or non-AOT use cases? Need some tests.

3) Are there issues with dynamic redefinition of functions? With the static naming scheme, redefinition causes a new class of the same name which can be picked up by reload of classes compiled to the old definition. With the dynamic naming scheme, redefinition will create a differently named class so old classes can never pick up a redefinition. Is this a problem? What are the impacts with and without AOT? Need some tests. ]
Rich Hickey made changes -
Fix Version/s Release 1.7 [ 10250 ]
Approval Triaged [ 10120 ] Vetted [ 10003 ]
Stuart Halloway made changes -
Approval Vetted [ 10003 ] Incomplete [ 10006 ]
Alex Miller made changes -
Approval Incomplete [ 10006 ] Vetted [ 10003 ]

People

Vote (7)
Watch (10)

Dates

  • Created:
    Updated: