I can't figure out why the following overloaded procs work:

import sequtils proc newSeq2d*[int](x, y: int): seq[int] = result = newSeq[int]((x * y) + 1) result[0] = x proc newSeq2d*[uint8](x, y: int): seq[uint8] = result = newSeq[uint8]((x * y) + 3) result[0] = (x and 0xff0000).uint8 result[1] = (x and 0x00ff00).uint8 result[2] = (x and 0x0000ff).uint8

but switching the parameters to Natural type:

proc newSeq2d*[int](x, y: Natural): seq[int] =and

proc newSeq2d*[uint8](x, y: Natural): seq[uint8] =

gives

Error: redefinition of 'newSeq2d'.

Does anyone have any ideas?

import sequtils proc newSeq2d*[T: int](x, y: Natural): seq[T] = result = newSeq[int]((x * y) + 1) result[0] = x proc newSeq2d*[T: uint8](x, y: Natural): seq[T] = result = newSeq[uint8]((x * y) + 3) result[0] = (x and 0xff0000).uint8 result[1] = (x and 0x00ff00).uint8 result[2] = (x and 0x0000ff).uint8 let x = newSeq2d[int](10, 10)I don't know why this happens, but it may be a clue. I didn't know that what you are doing (using the generics syntax without a type parameter) was even valid.

Yeah, even keeping the return signature the same, and just adding the [T: int] and [T: uint8] to newSeq2d fixes the compilers complaint, and works fine with the rest of what I was doing, so thanks for that!

But yeah, I don't get why that would fix it, heh.

It's because when you write `[int]`, `int` is actually the name of a type parameter, it's not the built-in `int` type. It's just like you had written an unbound type parameter `[T]`.

To prove this to yourself, try running:

import typetraits proc foo[int]() = echo $type(int) foo[string]()

It will print `string` since `[int]` gets bound to `string`.

So without type constraint such as `[T: int]`, both of your procs have the same type signature, hence the compile failure.

That makes sense, and explains why using T: int / T: uint8 is correct, but there is still something wierd going on because if I use int for the parameters it compiles fine, it is only if I use Natural that it fails,.

Also, the int and uint8 must be more than simple symbols, because if I use a different symbol, and try to call one of the procs, it can't differentiate between the two, and won't compile:

import sequtils proc newSeq2d*[a](x, y: int): seq[int] = result = newSeq[a]((x * y) + 1) result[0] = x proc newSeq2d*[a](x, y: int): seq[uint8] = result = newSeq[a]((x * y) + 4) result[0] = (x and 0xff000000).uint8 result[1] = (x and 0x00ff0000).uint8 result[2] = (x and 0x0000ff00).uint8 result[3] = (x and 0x000000ff).uint8 var a: newSeq2d[int](2,3)Edit: Actually this does make sense, since the return type will actually be an int or uint8 now. But on the other hand, shouldn't the differing return type allow for the procs to be distinguished?

If I do use int/uint8 as I did, the uint8 proc is called regardless of the type I am using, so in that sense the uint8/int are acting as simple symbols, and not allowing type differentiation:

import sequtils proc newSeq2d*[int](x, y: int): seq[int] = echo "int!" result = newSeq[int]((x * y) + 1) result[0] = x proc newSeq2d*[uint8](x, y: int): seq[uint8] = echo "uint8!" result = newSeq[uint8]((x * y) + 4) result[0] = (x and 0xff000000).uint8 result[1] = (x and 0x00ff0000).uint8 result[2] = (x and 0x0000ff00).uint8 result[3] = (x and 0x000000ff).uint8 var a: seq[uint8] a = newSeq2d[uint8](2,3) var b: seq[int] b = newSeq2d[int](2,3)

So clearly the T: is necessary for what I want, but somehow the compiler is being fooled into thinking the signatures are different, even though they aren't really.

@boia01:

It's because when you write [int], int is actually the name of a type parameter, it's not the built-in int type.

Hah! Good catch. This possibility never occurred to me because I never realized Nim allows you to use type names as normal identifiers.

let int: int = 123 echo intThat is strange...

@nucky9:

somehow the compiler is being fooled into thinking the signatures are different, even though they aren't really.

They actually are different. It's easier to see if you fix the confusing naming.

proc newSeq2d*[T](x, y: T): seq[T] proc newSeq2d*[T](x, y: int): seq[T]

Now, with `Natural`, this is what you get:

proc newSeq2d*[T](x, y: Natural): seq[T] proc newSeq2d*[T](x, y: Natural): seq[T]