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! 

Reply via email to