9

Can I convert a tuple into a list of function arguments in Nim? In other languages this is known as "splat" or "apply".

For example:

proc foo(x: int, y: int) = echo("Yes you can!")

type:
  Point = tuple[x, y: int]

let p: Point = (1,1)

# How to call foo with arguments list p?
Imran
  • 12,950
  • 8
  • 64
  • 79

1 Answers1

10

I haven't seen this in the stdlib or any other lib, but you can certainly do it yourself with a macro:

import macros

macro apply(f, t: typed): typed =
  var args = newSeq[NimNode]()
  let ty = getTypeImpl(t)
  assert(ty.typeKind == ntyTuple)
  for child in ty:
    expectKind(child, nnkIdentDefs)
    args.add(newDotExpr(t, child[0]))
  result = newCall(f, args)

proc foo(x: int, y: int) = echo("Yes you can!")

type Point = tuple[x, y: int]

let p: Point = (1,1)

# How to call foo with arguments list p?
apply(foo, p) # or:
foo.apply(p)

Further testing would be required to make sure this works with nested tuples, objects etc. You also might want to store the parameter in a temporary variable to prevent side effects from calling it multiple times to get each tuple member.

def-
  • 5,275
  • 20
  • 18
  • 1
    Very nice! Lots of stuff I don't understand in there, though. Looks like I'll have to get up to speed on macros. – Imran Jan 24 '18 at 09:34
  • 1
    @Imran: Apart from reading the docs, one of the easiest ways to getting started with macros is to place some `echo`s on things like `result.repr`, `result.treeRepr` at the end of the macro and the same for the macro arguments `f` and `t`. – bluenote10 Jan 30 '18 at 20:21
  • It would be better if there were some concept restriction on the accepted types, like "is tuple". and there must be a way to replicate python's asterisk too – v.oddou Apr 02 '18 at 15:05