I don't think there is kwargs in Nim. It may be possible to implement similar things with macros. You can also just do
import std/tables
proc foo(a: int, b: string, kwds: seq[(string, string)] = @[]) =
let kwdTable = kwds.toTable
echo kwds, kwdTable
foo(1, "bar")
foo(2, "baz", @{"kwarg1": "value1"})
Nim is a static typed language and functions must have certain parameters known at compile time. (btw, in Nim it is relatively hard to do dynamic types, compared to modern C++ std::any, Go interface{} and Rust std::Any, Nim doesn't have such things widely used or in standard lib)
Disclaimer: I am not very familiar with Nim, so maybe I am wrong.
I use JsonNode for my dynamic type, it works great for a kwargs standin. I usually name it options, but for sake of consistency I named it kwargs here. I use it all over an in-production tool at work, with permission to share:
import std/json
import std/strformat
proc get_json_value*[T: bool | float | int | string | JsonNode](node: JsonNode,
keys: seq[string],
default: T): T =
var current_node = node
for key in keys:
if key in current_node:
current_node = current_node[key]
else:
return default
when T is bool:
if current_node.kind == JBool:
return current_node.get_bool
when T is float:
if current_node.kind == JFloat or current_node.kind == JInt:
return current_node.get_float
when T is int:
if current_node.kind == JInt:
return current_node.get_int
when T is string:
if current_node.kind == JString:
return current_node.get_str
when T is JsonNode:
if current_node.kind in [JObject, JArray]:
return current_node
return default
proc get_json_value*[T: bool | float | int | string | JsonNode](node: JsonNode,
key: string,
default: T): T =
node.get_json_value(@[key], default)
proc foo(a: int, b: string, kwargs: JsonNode = %*{}) =
echo &"Calling foo() with {kwargs=}"
let kwarg1 = kwargs.get_json_value("kwarg1", "default")
echo &"{kwarg1=}"
foo(1, "bar")
foo(2, "baz", %*{"kwarg1": "something else"})
Output:
Calling foo() with kwargs={}
kwarg1=default
Calling foo() with kwargs={"kwarg1":"something else"}
kwarg1=something else
nim has varargs
https://nim-lang.org/docs/tut1.html#advanced-types-varargs
proc myWriteln(f: File, a: varargs[string]) =
for s in items(a):
write(f, s)
write(f, "\n")
myWriteln(stdout, "abc", "def", "xyz")
# is transformed by the compiler to:
myWriteln(stdout, ["abc", "def", "xyz"])
You may use a tuple to pass arguments of uncertain various type.
proc f(a: string, b: int, kwargs: tuple) =
for k, v in kwargs.fieldPairs():
echo (k, v)
f("", 0, (c: 1, d: "2", e: '3'))