Fork me on GitHub
#clojure-dev
<
2019-07-24
>
andy.fingerhut16:07:30

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?

andy.fingerhut16:07:26

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

alexmiller16:07:56

b/c defrecords are implemented with deftype?

bronsa16:07:04

the compiler doesn't know about defrecord vs deftype

bronsa16:07:14

they're reserved in deftype*, which both use

andy.fingerhut16:07:01

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

alexmiller16:07:26

but it's not

andy.fingerhut16:07:06

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.

bronsa16:07:59

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

andy.fingerhut16:07:05

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

andy.fingerhut16:07:48

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?

bronsa16:07:02

they aren't present

bronsa16:07:16

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

bronsa16:07:57

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

andy.fingerhut16:07:08

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

bronsa16:07:23

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

bronsa16:07:43

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

bronsa16:07:10

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

bronsa16:07:36

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

andy.fingerhut16:07:49

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.

bronsa16:07:48

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

andy.fingerhut16:07:02

meaning, all or none?

bronsa16:07:04

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

bronsa16:07:23

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

andy.fingerhut16:07:14

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* 🙂

alexmiller16:07:07

I don't think you should use deftype* there

alexmiller16:07:44

just avoid the reserved names

alexmiller16:07:09

why not just call them hash and hasheq?

andy.fingerhut17:07:19

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

andy.fingerhut18:07:33

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.

alexmiller18:07:39

presumably it is private field

alexmiller18:07:04

shouldnt be ambiguous anywhere

andy.fingerhut19:07:03

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