Storing values of different types in a container, in arbitrary order, and handling them then appropriately to their types at run-time, necessarily means run-time dispatching (detemining type of each value in the container at run-time), that is, something you can program - there's no restrictions on run-time behaviour of your programs, made with Nim. At low level, your values have to have some type information stored along with them. To not do that manually (though you can), there are [object variants](https://nim-lang.org/docs/manual.html#types-object-variants) in Nim, exactly for this task, the same as in Pascal, or like "struct with union inside" in C terms; they use memory for the largest in size of branches, that is, use the same storage space for different, even different-sized, values. Yet, for objects, you can inherit them from one base type and use [methods](https://nim-lang.org/docs/manual.html#multi-methods) instead of procs - they distinguish types; this same way run-time dispatched interfaces work. These all don't use casts or any unsafe features.
The reason for mentioning casts was that in some cases they allow to manage without run-time overhead for this task.