Is there any way to have a default type for an initializer for generics?
I would like to allow users to call it without specifying type information to get a default type. It seems obvious this is not directly supported, but is there a way to achieve this behavior?
type Foo[T] = object
x: T
proc initFoo[T](): Foo[T] =
result
# works
#[
proc initFoo(): Foo[string] =
result
# error "would lead to ambiguous calls"
]#
let a = initFoo[int]() # works
#[
let b = initFoo() # error: cannot instantiate T
]#
It's a bit hacky but using the Type.init() convention it's possible:
import std/typetraits
type Foo[T] = object
val: T
proc init*[T: Foo](_: typedesc[T]): auto =
when Foo is T:
Foo[int]()
else:
T()
assert Foo.init() is Foo[int]
assert Foo[string].init() is Foo[string]
What is a default type?
How could a compiler infer what type does the user want and if he hasn't just forgotten to specify it?
I don't think it's possible, thankfully.
Not bad!!!
Now I to ponder whether I should actually do this... my init has some args.
It seems that, when you say:
proc init*[T: Foo](_: typedesc[T]): auto
T is inferred based on _ (the first argument).
When the first arg is Foo[string] (which is of the type typedesc[Foo[string]]), T is inferred as Foo[string]. As Foo (without generic arg) is not Foo[string], but its superset, "Foo is T" will be evaluated to false.
However if it is Foo (which has the type typedesc[Foo] ), then T is inferred as Foo (with no generic arg) and thus "Foo is T" is true.
This is also the first time I see this trick.
To elaborate Foo without generic parameters is a typeclass that accepts all Foo instantiations, as such Foo is Foo when passed the and Foo isnot Foo[string] when passed a generic instantiation.
Now I to ponder whether I should actually do this... my init has some args.
I personally only use the init and new convention for my types and they do take arguments. I do wish though that the compiler would analyze generic constraints if they are all concrete types, just instantiate the procedure in place to allow static analysis to kick in.