How do I instantiate a hashtable in Nim that maps strings to objects of any type? None of these seem to work:
import tables
var t = newTable[string, any]()
var t = newTable[string, ref]()
var t = newTable[string, auto]()
var t = newTable[string, object]()
In other words what's Nim equivalent of void*/Object/interface{}?
What you can use:
It seems like you want dynamic typing in a statically typed language.
The proper way for heterogeneous collection of objects currently is:
In the future you will also be able to use concepts and VTables.
type Any is the closest to what you want. It is also unsafe to use.
@mratsim Since I have already written my own custom vTable mechanism with nim macros and some emitted C++ code (in order to interop i.e. inherit with C++ base classes) ... I'm wondering what you meant by saying:
In the future you will also be able to use concepts and VTables.
Is there something planned to support vTables in nim ? are they meant to make it a language integrated feature to interop with C++ inheritance ?
Thanks
That was something that was in the manual as coming soon for about eight months before being removed:
https://github.com/nim-lang/Nim/commit/c671356d51488c96b4749a4d109b00d924e1f739
This should still be happening but after concepts, generics, statics are more consolidated. The goal is not to interop with C++ inheritance though, but you can already use importcpp for that.
..
VTable types
------------
Concepts allow Nim to define a great number of algorithms, using only
static polymorphism and without erasing any type information or sacrificing
any execution speed. But when polymorphic collections of objects are required,
the user must use one of the provided type erasure techniques - either common
base types or VTable types.
VTable types are represented as "fat pointers" storing a reference to an
object together with a reference to a table of procs implementing a set of
required operations (the so called vtable).
In contrast to other programming languages, the vtable in Nim is stored
externally to the object, allowing you to create multiple different vtable
views for the same object. Thus, the polymorphism in Nim is unbounded -
any type can implement an unlimited number of protocols or interfaces not
originally envisioned by the type's author.
Any concept type can be turned into a VTable type by using the ``vtref``
or the ``vtptr`` compiler magics. Under the hood, these magics generate
a converter type class, which converts the regular instances of the matching
types to the corresponding VTable type.
.. code-block:: nim
type
IntEnumerable = vtref Enumerable[int]
MyObject = object
enumerables: seq[IntEnumerable]
streams: seq[OutputStream.vtref]
proc addEnumerable(o: var MyObject, e: IntEnumerable) =
o.enumerables.add e
proc addStream(o: var MyObject, e: OutputStream.vtref) =
o.streams.add e
The procs that will be included in the vtable are derived from the concept
body and include all proc calls for which all param types were specified as
concrete types. All such calls should include exactly one param of the type
matched against the concept (not necessarily in the first position), which
will be considered the value bound to the vtable.
Overloads will be created for all captured procs, accepting the vtable type
in the position of the captured underlying object.
Under these rules, it's possible to obtain a vtable type for a concept with
unbound type parameters or one instantiated with metatypes (type classes),
but it will include a smaller number of captured procs. A completely empty
vtable will be reported as an error.
The ``vtref`` magic produces types which can be bound to ``ref`` types and
the ``vtptr`` magic produced types bound to ``ptr`` types.