records alias with local vars

392 views
Skip to first unread message

Brian Craft

unread,
Aug 28, 2019, 7:08:32 PM8/28/19
to Clojure
In this example

(defrecord x [y])

(defn b [x] (.getBytes ^String x))


The compiler fails to resolve .getBytes. It emits reflection code, saying x is a class. It is resolved by deleting the defrecord, or renaming the parameter.

Is this expected, or documented? Are there other cases like this?

Sean Corfield

unread,
Aug 28, 2019, 9:35:32 PM8/28/19
to Clojure Mailing List
What version of Clojure/Script are you using? This works fine for me on Clojure 1.10.1.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/38933dc0-1b8e-452a-ae01-feec77739623%40googlegroups.com.


--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles Networks, LLC. -- https://worldsinglesnetworks.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Andy Fingerhut

unread,
Aug 28, 2019, 10:06:49 PM8/28/19
to clo...@googlegroups.com
I tried it on Clojure 1.10.1 and if I first did (set! *warn-on-reflection* true) the defn of b did give a reflection warning if you first did the defrecord, but not without the defrecord.

Andy

Shogo Ohta

unread,
Aug 29, 2019, 12:38:17 AM8/29/19
to Clojure
With the presence of the record definition, the macro expander seems to expand

(.getBytes ^String x)

into

(. ^Class (clojure.core/identity ^java.lang.String x) getBytes)

and which causes reflection call.
(BTW this "tricky" expansion is done to distinguish instance method calls on Class objects from static method calls if I understand correctly. cf. https://github.com/clojure/clojure/blob/653b8465845a78ef7543e0a250078eea2d56b659/src/jvm/clojure/lang/Compiler.java#L7035-L7039)

So, to resolve the issue, I think the macro expander should look at the local env first to check whether or not a local binding shadows the class-ish name.

Sean Corfield

unread,
Aug 29, 2019, 3:57:35 PM8/29/19
to clo...@googlegroups.com

Yup. Repro’d it now. Not sure why I didn’t get the reflection warning when I tried it yesterday. Weird.

 

Definitely looks like a bug.

 

I guess almost no one has ever run into this because it’s idiomatic (and almost universal, I expect) to use CamelCase for record names and kebab-case for arguments/locals so they would never normally conflict…?

 

Sean Corfield -- (904) 302-SEAN


An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Reply all
Reply to author
Forward
0 new messages