nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.49k stars 1.46k forks source link

Type class confusion #15716

Closed zevv closed 3 years ago

zevv commented 3 years ago

I'm not even sure what a proper title for this would be, sorry.

I am not sure if this is a bug or if I understand the manual wrong. The following fails to compile:

type IntOrFloat = int | float

proc foo(a: IntOrFloat, b: IntOrFloat) =
  discard

foo(3.int, 3.int)      # ok
foo(3.float, 3.float)  # also ok

foo(3.float, 3.int)    # type mismatch!
foo(3.int, 3.float)    # type mismatch!

The error being:

Error: type mismatch: got <float, int>
but expected one of: 
proc foo(a: IntOrFloat; b: IntOrFloat)
  first type mismatch at position: 2
  required type for b: IntOrFloat
  but expression 'int(3)' is of type: int

However, if I change the proc signature to his, things are just fine:

proc foo[A, B: IntOrFloat](a: A, b: B) =
  discard

Also works:

proc foo(a: int | float, b: int | float) =
  discard
jrfondren commented 3 years ago

@zevv what conclusion did you come to about this?

zevv commented 3 years ago

That I was not smart enough to properly read the manual.

https://nim-lang.github.io/Nim/manual.html#generics-type-classes

"Whilst the syntax of type classes appears to resemble that of ADTs/algebraic data types in ML-like languages, it should be understood that type classes are static constraints to be enforced at type instantiations. Type classes are not really types in themselves, but are instead a system of providing generic "checks" that ultimately resolve to some singular type. Type classes do not allow for runtime type dynamism, unlike object variants or methods"