I'd like to define a procedure which accepts combination of int/float types. I feel generics is the right tool for this job but need a feedback from Nim experts. Thank you.
The following code though:
proc myRem[T,T2](a: T ,b: T2): int =
result = int(a) - int(b) * int(float(a)/float(b))
let x = myRem(4.0,3)
echo x
I'm not certain what your question is. If you want to restrict T and T2 to only accept int or float types, then the easiest way is to declare it as follows:
proc myRem[T,T2: SomeNumber](a: T, b: T2): int =
result = int(a) - int(b) * int(float(a)/float(b))
SomeNumber is defined in lib/system.nim as SomeInteger|SomeReal, where SomeInteger is the type class of all integer types and SomeReal the type class of all float types.
Thanks for the reply and sorry for not being clear. No I didn't want to restrict types here, quite contrary, to make it the least strict as possible. Looking at the example again this morning I realized Nim actually does not expect argument types to be provided upfront.
This leads me though to the second question which I think leads to the root of my problem. Let's take a simple division with the mixed types - int/float. I don't understand why same expression gives me a compiler error when wrapped in a function.
proc myRem(a ,b): int =
result = int(a/b)
discard myRem(7,3.0)
test.nim(9, 18) Error: type mismatch: got (int, float)
but expected one of:
system./(x: int, y: int): float
system./(x: float32, y: float32): float32
system./(x: float, y: float): float
The standalone compiles fine.
discard int(7/3.0)
var f: float
f = 7
or this:
proc myRem(a ,b): int =
result = int(a/b)
discard myRem(float(7),3.0)
When you pass 7 to a generic proc, where the argument can be both int or float, int is chosen by the compiler. And there's no version of / that can take int and float at the same tiome.
In any way ``/`` for integers and floats do different things, so choose the appropriate one by casting its arguments (like ``a.int/b.int``). EDIT: Err, it's the same, as fadg44a3w4fe said, just lets to compile.