For example, I have an old code like this
initTable[K,V](rightSize(capacity))
Since rightSize is deprecated in 1.4.0, I modify the code to the following
when (1,0) <= (NimMajor, NimMinor) and (NimMajor, NimMinor) < (1,4):
initTable[K,V](rightSize(capacity))
else:
initTable[K,V](capacity)
However, compiler is still saying Warning: Deprecated since 1.4.0; rightSize is deprecated on the second line.
This code is part of a library and I want the code still being able to run on before Nim 1.4 without warning. Users are not happy with warning =)
I am aware that initTable[K,V]() can be used in this case, but this is not general solution to support multi-version of Nim.
I use choosenim 1.4.0 on linux.
To reproduce
git clone https://github.com/jackhftang/lrucache.nim.git -b remove_rightsize
nimble test
Thanks, I've pin pointed the issue and opened #15650 to track it.
Currently there is no walkaround for this issue so you'll have to wait until the issue is fixed.
This works..(Note - rightSize has been around since Nim-0.10.2, but checking its actual declaration is cleanest):
import tables
template iniTab(capacity=2): untyped {.dirty.} =
when declared(tables.rightSize)and(NimMajor,NimMinor)<(1,4):
initTable[int,int](rightSize(capacity))
else:
initTable[int,int](capacity)
var j = iniTab(4)
..but you cannot put generic parameters on the template and pass them through on the template iniTab. So, it does not quite work for lrucache's use case.template rightSize(cap): untyped {.dirty.}=
when declared(tables.rightSize)and(NimMajor,NimMinor)<(1,4):
tables.rightSize(cap)
else:
cap
proc newLruCache*[K,T](capacity: int): LruCache[K,T] =
## Create a new Least-Recently-Used (LRU) cache that store the last `capacity`-accessed items.
LruCache[K,T](
capacity: capacity,
list: initDoublyLinkedList[Node[K,T]](),
table: initTable[K, DoublyLinkedNode[Node[K,T]]]( rightSize(capacity) )
)
ummm.. turn out that this cannot solving the problem completely... tried a number of variants
template rightSize(cap): untyped {.dirty.} =
# not work in 1.2.6 as declare(table.rightSize) is false
when declared(tables.rightSize) and (NimMajor,NimMinor) < (1,4):
tables.rightSize(cap)
else:
cap
template rightSize(cap): untyped {.dirty.} =
# not work in 1.2.6: undeclared identifier: 'tables'
when (NimMajor,NimMinor) < (1,4):
tables.rightSize(cap)
else:
cap
template correctSize(cap): untyped {.dirty.} =
# still showing warning in 1.4.0
when (NimMajor,NimMinor) < (1,4):
rightSize(cap)
else:
cap
template correctSize(cap): untyped {.dirty.} =
# still showing warning in 1.4.0
when declared(tables.rightSize) and (NimMajor,NimMinor) < (1,4):
tables.rightSize(cap)
else:
cap
If "tables" isn't a defined as an identifier, you have more problems than just the deprecation 😂
Works for me on 0.16.0, 0.20.0, 1.0.0, 1.0.10, 1.2.0, 1.2.4,1.2.6, 1.2.8, 1.4.0, and 1.5.1
Did you import from another file? I tested on three machines with the following settings, all showing undeclared identifier: 'tables'.
Here the codes, two files or clone git clone https://github.com/jackhftang/lrucache.nim.git -b minimal_rightsize_test
# lrucache.nim
import lists
import tables
type
# no need to use ref, since DoublyLinkedNode is already a ref
Node[K,T] = object
key: K
val: T
LruCache*[K, T] = ref object
capacity: int
list: DoublyLinkedList[Node[K,T]]
table: Table[K, DoublyLinkedNode[Node[K,T]]]
template rightSize(cap): untyped {.dirty.} =
when (NimMajor,NimMinor)<(1,4):
tables.rightSize(cap)
else:
cap
proc newLruCache*[K,T](capacity: int): LruCache[K,T] =
## Create a new Least-Recently-Used (LRU) cache that store the last `capacity`-accessed items.
LruCache[K,T](
capacity: capacity,
list: initDoublyLinkedList[Node[K,T]](),
table: initTable[K, DoublyLinkedNode[Node[K,T]]]( rightSize(capacity) )
)
# test.nim
import lrucache
let c = newLruCache[int,int](10)
run with nim c -r test.nim
I do not know why tables is not defined, also I cannot see what wrong I did in the code. Let me know If you still cannot reproduce it. I don't think my nim setup has anything special.
tested on
Well, your issue is really simple - you forgot to bind rightSize in the template :) Don't forget that templates are simple code substitution, with this template it works:
template rightSize(cap): untyped {.dirty.} =
when (NimMajor,NimMinor)<(1,4):
bind rightSize
tables.rightSize(cap)
else:
cap
you were right @jackhftang, i wasn't importing the lib. I got that isPowerOfTwo AssertionError from declared(tables.rightSize) being false within user.nim, that is frustrating.
found two solutions:
use a proc:
#lrucache.nim
import tables, lists
type
Node[K, T] = object
key: K
val: T
LruCache[K, T] = object
capacity: int
list: DoublyLinkedList[Node[K, T]]
table: Table[K, DoublyLinkedNode[Node[K, T]]]
proc rightSize(cap: int): int =
when declared(tables.rightSize) and (NimMajor, NimMinor) < (1, 4):
tables.rightSize(cap)
else:
cap
proc newLruCache*[K, T](capacity: int): LruCache[K, T] =
LruCache[K, T](
capacity: capacity,
list: initDoublyLinkedList[Node[K, T]](),
table: initTable[K, DoublyLinkedNode[Node[K, T]]](rightSize(capacity))
)
#test.nim
import lrucache
let z = newLruCache[int,string](5)
echo z.repr
or, export tables from lrucache.nim:
#lrucache.nim
import tables,lists
when declared(tables.rightSize) and (NimMajor,NimMinor) < (1,4):
export tables.rightSize
type
Node[K, T] = object
key: K
val: T
LruCache[K, T] = object
capacity: int
list: DoublyLinkedList[Node[K, T]]
table: Table[K, DoublyLinkedNode[Node[K, T]]]
template rightSize(cap): untyped {.dirty.} =
when declared(lru.rightSize) and (NimMajor, NimMinor) < (1, 4):
lru.rightSize(cap)
else:
cap
proc newLruCache*[K, T](capacity: int): LruCache[K, T] =
LruCache[K, T](
capacity: capacity,
list: initDoublyLinkedList[Node[K, T]](),
table: initTable[K, DoublyLinkedNode[Node[K, T]]](rightSize(capacity))
)