I am a little confused by the
includes? method as to why it does not have a type check at its parameter (
def includes?(obj) : Bool as opposed to
def includes?(obj : T) : Bool)
For example, code like this which will always return
false is able to compile:
Is there any reason for this?
includes? checking existence by using overloadable operator
== which works beyond a single type.
I had a feeling that would be the case. But tbh, I created a bug in my code due to this, which is what made me realize there was no type-checking happening on this method.
But what I don’t understand is, rather than making the type so generic, wouldn’t it be good if a dev–who wanted to overload the
== operator to extend to other types–could just define their own overloads
def includes?(t1 : Type1)
def includes?(t2 : Type2)
This wouldn’t really work with generic collections.
A restriction to
T would be possible, though. Here has been a similar proposal for
Hash#: Enforce hash key types at compile time by jgaskins · Pull Request #8893 · crystal-lang/crystal · GitHub
This is essentially an instance of the conflict between convenience of use and type safety.
I’d rather chose type safety, but we’re not there currently.
Perhaps it would be possible to consider having two flavours of such collection methods with varying strictness.
Thank you for the explanation, @straight-shoota !
I admire the flexibility that it gives to compare different types. It is even prevalent in Java if I’m not mistaken. Possibly a common feature in OOP languages in general. However, since I rely heavily on types and rules enforced by them during compilation, I probably won’t be needing this feature (even in the future) . Perhaps, it might be a good idea to have two flavours indeed
For now I’ll polyfill my code:
def includes_t?(obj : T)