clojure-dev

Issues: https://clojure.atlassian.net/browse/CLJ | Guide: https://insideclojure.org/2015/05/01/contributing-clojure/
2019-07-24T16:27:30.021700Z

I am probably missing something obvious here. I believe I understand why the fields hash hasheq meta extmap are reserved for defrecord -- because they are used internally in the implementation of every class created by defrecord. Why are these fields also reserved for deftype?

2019-07-24T16:31:26.022700Z

Perhaps because there were ideas that code for calculating hashes and/or adding metadata might be automatically generated for deftype objects, too?

alexmiller 2019-07-24T16:33:56.023200Z

b/c defrecords are implemented with deftype?

bronsa 2019-07-24T16:34:04.023500Z

the compiler doesn't know about defrecord vs deftype

bronsa 2019-07-24T16:34:14.023800Z

they're reserved in deftype*, which both use

2019-07-24T16:36:01.024300Z

So ignorant question, based on very partial information -- couldn't it be reserved only in defrecord, not deftype* ?

alexmiller 2019-07-24T16:36:12.024500Z

it could be

alexmiller 2019-07-24T16:36:26.024700Z

but it's not

2019-07-24T16:38:06.025600Z

And @bronsa if my reading of core_deftype.clj code is correct (it might not be), validate-fields is called from deftype directly, as well as defrecord, which is where the error message is given if you try to use one of those field names as a user of deftype/defrecord.

bronsa 2019-07-24T16:38:59.026400Z

yeah the exception is thrown from there, but in the Compiler those fields have special semantics

2019-07-24T16:39:05.026600Z

But perhaps the special handling of those fields in Compiler.java is what you are referring to?

bronsa 2019-07-24T16:39:11.026800Z

yes

2019-07-24T16:40:48.027600Z

Do you happen to know off the top of your head if those fields are present in all deftype-created objects? If so, do you know if they are simply dormant/unused for non-defrecords?

bronsa 2019-07-24T16:41:02.027900Z

they aren't present

bronsa 2019-07-24T16:41:16.028300Z

the compiler creates special constructors based on the presence of those fields (defrecord explicitely injects them)

bronsa 2019-07-24T16:41:57.029300Z

this behavior is actually quite convinient as it means that userspace code can use deftype* directly and implement types with __hash special treatment semantics for example

2019-07-24T16:42:08.029600Z

So this is a Compiler.java special handling of defrecord's, probably for efficiency?

bronsa 2019-07-24T16:42:23.030Z

hash and hasheq are about efficiency (and were later additions)

bronsa 2019-07-24T16:42:43.030500Z

meta and extmap are requirements for defrecord acting as an open map + IObj

bronsa 2019-07-24T16:43:10.031200Z

w/o that special handling you'd have to (defrecord Foo []) (Foo. {} {}) manually, for example

bronsa 2019-07-24T16:44:36.032700Z

if I'm not mistaken, creation of the extra constructors that hide away those fields is literally the only thing the compiler does special

2019-07-24T16:45:49.033800Z

Thx for the info. I only noticed this recently while creating a proposed patch for this ticket: https://clojure.atlassian.net/browse/CLJ-2528 From what you are saying it sounds like perhaps using deftype* there might be a better approach than my hacked-up patch, which keeps deftype for primitive vectors, and uses hashx and hasheqx to work around the name restriction of deftype.

bronsa 2019-07-24T16:46:48.034200Z

possibly, although I think hash and hasheq must go in tandem with meta and extmap

2019-07-24T16:47:02.034500Z

meaning, all or none?

bronsa 2019-07-24T16:47:04.034700Z

so that may be an issue, but I'm not sure that's the case

bronsa 2019-07-24T16:47:05.034900Z

yeah

bronsa 2019-07-24T16:47:23.035200Z

don't take my word for it on this, can't really remember right now

2019-07-24T16:48:14.036300Z

OK. I will add a comment on that ticket to at least raise the question of deftype* instead of deftype, in order to use the names hash and hasheq, but I won't quote you on the possible all-or-none restriction of those fields with deftype* 🙂

alexmiller 2019-07-24T16:50:07.036600Z

I don't think you should use deftype* there

alexmiller 2019-07-24T16:50:44.036800Z

just avoid the reserved names

alexmiller 2019-07-24T16:51:09.037100Z

why not just call them hash and hasheq?

2019-07-24T17:02:19.037800Z

hash and hasheq seem like perfectly good choices, too, and I can change the patch to use those.

2019-07-24T18:39:33.039200Z

It seems the JVM allows a class to have a method and field with the same name, referring to the hasheq field name suggestion above which would be the same name as the hasheq method that is implemented by the Vec class. It could be confusing, perhaps, for their names to be the same, though.

alexmiller 2019-07-24T18:44:39.039700Z

presumably it is private field

alexmiller 2019-07-24T18:49:04.040100Z

shouldnt be ambiguous anywhere

2019-07-24T19:45:03.040600Z

Confirmed that the fields are private, the methods public. Thx.