Hi,
Is there any way in Nim to solve this? Or is a bug?
proc test[T](x: T) =
echo x
proc test[T](x: openarray[T]) =
for i in x:
echo i
test([1, 2, 3])
It does not compile because the first "test" proc is called instead of the second.
Probably a better way but this works for me
proc test[T](x:varargs[T]) =
for i in x:
echo i
test(1)
test([1,2,3])
No, the compiler is correct. An array is convertible to an openarray, and convertible doesn't match as good as a simple generic match. For specialization use something like:
proc test[T, I](x: array[I, T]) =
for i in x:
echo i
Just specialize within one generic function:
proc test[T](x: T) =
when T is seq or T is array:
for i in x:
echo i
else:
echo x
test(1)
test([1, 2, 3])
test(@[4, 5, 6])
I wonder why this fails:
type
Iterable = concept c
for i in c: discard
proc test[T](x: T) =
echo x
proc test(x: Iterable) =
for i in x: echo i
test(1)
test([1, 2, 3])
Shouldn't Iterable be a better match?
I tried next two variants and they are working as expected:
#proc test[T](x: T) = # this signature doesn't work. Why?!
proc test[T:not(array|seq)](x: T) =
echo x
proc test_impl[T](x: openarray[T]) =
for i in x:
echo i
proc test[T:array|seq](x: T) =
test_impl x
test(1)
test([1, 2, 3])
test([1, 2, 3, 4])
test(@[1, 2, 3])
or:
proc test[T](x: T) =
echo x
proc test_impl[T](x: openarray[T]) =
for i in x:
echo i
proc test[T](x: seq[T]) =
test_impl x
proc test[R,T](x: array[R,T]) =
test_impl x
test(1)
test([1, 2, 3])
test([1, 2, 3, 4])
test(@[1, 2, 3])
Thank you.
Wouldn't be a good idea to expand internally a convertible type like openarray before matching? For example, expand test[T](x: openarray[T]) as test[T](x: (seq|array)[T])
And maybe create also a priority queue to try to match first with non-generic functions, and then try to match with generic functions in the order they were defined. For example, to avoid conflicts, defining in the last place the most generic functions like proc test[T](x: T)
What do you think?