Interesting proc overloads with parameter constraints in Nim
Overloading on constants¶
Let's say you have a function that returns a seq
of N bytes, such as this one.
wzxhzdk:0
It's a useful function, and all is well. But what if you want to give the result of urandom(32)
to a function that takes an array of 32 bytes? Converting a seq
to an array of fixed size is surprisingly complicated and dirty (but I may be missing something).
Long story short, you can use static[T]
to provide an alternative generic function that returns arrays of fixed size.
wzxhzdk:1
But if you want to keep the 2 versions of the function under the same name, you'll run into a problem: some of the calls, like urandom(32)
, can work with both versions, so the compiler will complain about ambiguity!
But we can work around this with parameter constraints! An argument (static[Natural]){lit}
would allow only integer literals. {`const`}
may be more appropriate here, though.
(This example also shows how to factor out a common part of two functions into a template, and how to read exactly N bytes from a file)
wzxhzdk:2
This code is part of my library nim-random: urandom.nim.
Overloading on var
¶
Similarly, you may want to have two versions of a function: one that takes a normal argument, and the other one that works more optimally by taking a var
argument (yes, I'm aware that Nim can do the right thing and pass arguments by a hidden pointer, but there are real use cases for using var
directly even if you don't modify the argument, such as when you need to take its address, or when you wrap a C function as var
instead of ptr
)
Just providing two overloads (one var
, one non-var
) doesn't work because of ambiguity (this is something that may be improved in future versions of Nim).
UPDATE: This seems to be supported in Nim now.
We need to use parameter constraints again. {lvalue}
will do the trick.
An example of this is in my library nim-csfml: csfml_graphics_gen.nim.
wzxhzdk:3
Here I wrap a ptr FloatRect
as var
but also provide a non-var
version of this, which just copies the given argument and passes it to the var
version.
Comments powered by Disqus