I noticed bind no longer works in generic procs. I came up with a macro that can be used as a pragma workaround.
macro genProcWithBind*(a : untyped) : untyped =
let templateSym = genSym(nskTemplate)
let body = a[6].copy()
let newProc = a.copy()
newProc[6] = quote do:
`templateSym`()
result = newStmtList()
result.add quote do:
template `templateSym`() : untyped =
`body`
result.add newProc
You use it like this.
when false:
#now works with bind
proc sort*[T](a : T) {.genProcWithBind.} =
bind privateSort
privateSort(a)
#turns into this
template genSymed() : untyped =
bind privateSort
privateSort(a)
proc sort*[T](a : T) =
genSymed()
Should work with mixin too. I though it might be useful; maybe even add it to the system or macros module with a better name then I came up with.
Here's a better example of what I'm talking about.
Imagine you have two files foreignFile.nim and myFile.nim.
foreignFile.nim
template p[T:int|float](a : T) =
echo "Number:" & $a
template p(a : string) =
echo "String:" & a
proc printVar*[T:int|float|string](a : T) =
p(a)
All the templates printVar should call are already defined but p isn't bound so it can potentially use new templates/procs/etc defined in the future.
myFile.nim
import foreignFile
var x = 0
template p(a : int) =
x += a
echo x
p(7)
printVar(5)
printVar(5.0)
printVar("5.0")
In this example you've inadvertently overwritten p from myFile when aProc is passed an int. It will echo 12 instead of Number:5. You only wanted to call your new p definition directly. In this case the generic printVar proc should probably be three seperate printVar definitions instead of
proc printVar*[T:int|float|string](a : T)
Your example doesn't work on my compiler.
proc p(a : int) =
echo a
proc printVar*[T:int|float|string](a : T) =
bind p
p(a)
printVar(5)
nim
gives Error: invalid expression: bind p
Oddly enough if you don't call the printVar at all it doesn't give you an error.
Nim Compiler Version 0.20.2 [Windows: amd64] Compiled at 2019-07-17 Copyright (c) 2006-2019 by Andreas Rumpf
compiled with nim c test.nim
I've actually had this problem for a few versions but I assumed you already knew about it before.
Nim Compiler Version 0.17.0 (2017-05-18) [Windows: amd64] Copyright (c) 2006-2017 by Andreas Rumpf
also gives me the same error.
I would be interested to see if anyone else has encountered this error.
proc p(a : int) =
echo a
proc printVar*[T:int|float|string](a : T) =
bind p
p(a)
printVar(5)
Run this little bit of code and if it spits back
Error: invalid expression: bind p
then we have the same bug.