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?
Perhaps because there were ideas that code for calculating hashes and/or adding metadata might be automatically generated for deftype objects, too?
b/c defrecords are implemented with deftype?
the compiler doesn't know about defrecord vs deftype
they're reserved in deftype*
, which both use
So ignorant question, based on very partial information -- couldn't it be reserved only in defrecord, not deftype* ?
it could be
but it's not
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.
yeah the exception is thrown from there, but in the Compiler those fields have special semantics
But perhaps the special handling of those fields in Compiler.java is what you are referring to?
yes
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?
they aren't present
the compiler creates special constructors based on the presence of those fields (defrecord explicitely injects them)
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
So this is a Compiler.java special handling of defrecord's, probably for efficiency?
hash and hasheq are about efficiency (and were later additions)
meta and extmap are requirements for defrecord acting as an open map + IObj
w/o that special handling you'd have to (defrecord Foo [])
(Foo. {} {})
manually, for example
if I'm not mistaken, creation of the extra constructors that hide away those fields is literally the only thing the compiler does special
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.
possibly, although I think hash and hasheq must go in tandem with meta and extmap
meaning, all or none?
so that may be an issue, but I'm not sure that's the case
yeah
don't take my word for it on this, can't really remember right now
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* 🙂
I don't think you should use deftype* there
just avoid the reserved names
why not just call them hash and hasheq?
hash and hasheq seem like perfectly good choices, too, and I can change the patch to use those.
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.
presumably it is private field
shouldnt be ambiguous anywhere
Confirmed that the fields are private, the methods public. Thx.