proc foo[T](x: float): T = T(x)
echo foo[int](1.0) #1 compiles
echo 1.0.foo[int]() #2 Error: cannot instantiate: 'T'
proc bar[T](x: float, _: typedesc[T]): T = T(x)
echo bar(1.0, int) #3 compiles
echo 1.0.bar(int) #4 compiles
proc baz[T](x: float, _: T): T = T(x)
echo baz(1.0, 1) #5 compiles
echo 1.0.baz(1) #6 compiles
proc qux(x: float, T: typedesc): T = T(x)
echo qux(1.0, int) #7 triggers ^ Error here: type expected
I'm using Nim Compiler 0.14.2.
echo 1.0.foo[int]()
means
echo ((1.0.foo)[int])()
That is, . has a higher precedence than [], so there's a foo(1.0) (unparameterized), and then indexing the result of that call (with int type as an index).
With #7 you pass a type as just an argument (something, that is passed at run-time), it can be used only within the body of the procedure, not for declaring its result. You used earlier the syntax to parameterize procedures with types (at compile-time), that is right. And in foo you did use such a parameter in the procedure's body, and that works.
Understood the #2 case.
With #7 you pass a type as just an argument (something, that is passed at run-time), it can be used only within the body of the procedure, not for declaring its result.
But why this compiles:
proc quz(x: float, T: typedesc): T = 1
echo quz(1.0, int) #8 compiles
You can disambiguate with a colon, analogous to Rust's turbofish:
echo 1.0.foo[:int]()