Hi,
I was looking at approaches to something resembling variadic templates in C++.
Procs accepting tuples seem very powerful but maybe not super friendly for a
third party to use in some cases where seemingly insignificant syntax
differences can cause errors: <https://play.nim-lang.org/#ix=2SnY>
But this is otherwise awesome so I figured why not try and put an abstraction
in front of them?
In my case this is useful because it lets me easily populate what is
essentially a multi-typed generic data store of components for an entity
component system (of course what the world really needs is yet another ECS,
right? :D). I have a generic builder which works fine (if slightly java-y) but
wanted something a bit more terse.
I found you can simplify the interface by putting a special template in front
of it that looks like this:
echoTypes(values: varargs[untyped]) =
echoTypesImpl((values))
Run
The magic happens because adding that extra pair of parens causes the compiler
to interpret the varargs as a tuple assuming it contains two or more elements.
If it only contains one it interprets it as that single value (not a tuple). It
seems the compiler sees the varargs as a kind of comma separated list in the
template context. I discovered this almost totally by accident:
<https://play.nim-lang.org/#ix=2SnK>
Example generates an error containing: `but expression 'MyType()' is of type:
MyType "expression: myProc(MyType(), MyType())"`
Here's a full, working example:
import typetraits
type
A = object
B = object
proc echoTypesImpl[T](value: T) =
echo "the type is: ", value.type # maybe this is more like
myContainer[T].put(key, value) or something to that effect.
proc echoTypesImpl(values: tuple) =
for x in values.fields: echoTypesImpl(x)
template echoTypes(values: varargs[untyped]) =
echoTypesImpl((values))
echoTypes(A(), B(), B(), A())
Run
<https://play.nim-lang.org/#ix=2Snw>
My question is: is this a good idea? Is the way template varargs are handled
stable such that this won't break in the future? Is there some edge case where
this won't work properly? Or is using macros simply a better approach for this?
I ask partly because the nim manual suggests that untyped varargs in templates
aren't that useful, but this seems useful and I've not seen this approach
documented anywhere. Thanks!