1

Say I just want a template to "generate" a type, from a generic argument, and use the template's invocation in places where a type is expected:

template p[T] = T
var a: p[int]()

(3, 14) Error: expression 'T' is of type 'type int' and has to be discarded

lol, really ?
I hope I'm just being a newbie and there is indeed a way (hopefully uncontrived) to do that.

Note that it's the same output, with a non generic attempt:

template p(t: typedesc) = t
var a: p(int)

EDIT: reading this insightful answer, I realized the system might feel more patted on the back if we specified the templates's return type; adding : untyped before = t got the previous snippets to build. any explanation ?

v.oddou
  • 6,476
  • 3
  • 32
  • 63

2 Answers2

3
template p[T] = T
var a: p[int]()

This is the same as:

template p[T]: void = T
var a: p[int]()

You're telling the compiler that your template returns nothing, this is why it complains.

So you need to specify the return type...

template p[T]: typedesc = T
var a: p[int]()

Then it works fine. This behaviour extends to procedures and methods in Nim, not specifying a return type means that there is no return value.

dom96
  • 1,012
  • 1
  • 9
  • 22
2

Compile-time functions mapping from types to types in Nim are usually implemented with typedesc parameters. Compared to generic params, this has the additional benefit of allowing to provide multiple overloads handling different types in different ways:

type
  Foo = object

# handler all integer types:
template myTypeMapping(T: typedesc[SomeInteger]): typedesc = string 

# specific handling of the Foo type:
template myTypeMapping(T: typedesc[Foo]): typedesc = seq[string]

# all sequence types are not re-mapped:
template myTypeMapping(T: typedesc[seq]): typedesc = T

Please note that you always need to specify that your template has a typedesc return type.

zah
  • 5,314
  • 1
  • 34
  • 31
  • generic parameters have the convenience of being deduced. we lose this with typedesc parameters ? – v.oddou Apr 01 '18 at 12:59
  • 2
    well, they can be deduced only when the template has other params. When the type itself is a required param, then my suggestion is to always use `typedesc`. – zah Apr 02 '18 at 15:50