Hello world. Here is the first line of my generic proc:
proc myProc[T1, T2](param1: T1, param2: T2) =
Is there a way to say that one of the two params must be a string ? Or am I forced to create two complementary procs with exactly the same body ?this is pretty unusual, but you can do something like this:
proc myProc[T1, T2](param1: T1, param2: T2) =
when param1 isnot string and param2 isnot string:
{.fatal: "atleast one of the parameter must be a string".}
This will ensure that at least one is a string, but I'm not sure how reliable it is.
type
CondStr[T] = concept x
(x is string) or (T is string)
proc myProc[T](param1: T, param2: CondStr[T]) =
echo $T
#myproc(0, 0) # fails
myproc("", 0)
myproc(0, "")
myproc("", "")
Maybe in a near future, a more precise generics syntax will be provided.
I think this is an acceptable limitation, there is no other language that supports what you propose either and it seems like it would make the proc declaration complex.
@jcosborn solution is actually quite elegant, otherwise use private "implementation proc or template".
template myProcImpl(param1, param2: typed) =
discard "your implementation
proc myProc[T](param1: T, param2: string) =
myProcImpl(param1, param2)
proc myProc*[T](param1: string, param2: T) =
myProcImpl(param1, param2)
proc myProc*[T](param1: string, param2: T) =
myProcImpl(param1, param2)
@jcosborn code uses concept which are detailed here: https://nim-lang.org/docs/manual_experimental.html#concepts
This allows to represent arbitrary requirements as an abstract type.
The concept definition here
type
CondStr[T] = concept x
(x is string) or (T is string)
Does:
Then his code
proc myProc[T](param1: T, param2: CondStr[T]) =
echo $T
If param 1 is a string, then param2 will be a CondStr[T]
If param1 is not a string, then param2 satisfies CondStr[T] only if it's actually a string.