This post is related to issues addressed in https://github.com/nim-lang/RFCs/issues/380 and it attempts to solve them. I'll quote some statements from there (copyrights not mentioned)
A remarkable observation:
Instead of attaching syms to types, I think we should attach scopes (the declaration scope) to syms, so that symbols available at declaration will always be available at instantiation.
This is a description of a sym as a scope predicate, or, said otherwise, it has a scope predicate. Predicates are available in Nim already, they are called concepts. Scope concepts update the scope, they have an effect. This can be expressed within different ways. I choose the star "*" symbol (a pragma could do the same) The example is taken from the RFC as well and it looks like this:
# Module objs.nim
import hashes
type
Obj* = object
x*, y*: int
z*: string # to be ignored for equality
proc `==`*(a, b: Obj): bool =
a.x == b.x and a.y == b.y
proc hash*(a: Obj): Hash =
$!(hash(a.x) &! hash(a.y))
# Module bindtable.nim
import tables,hashes
export tables # potentially redundant
type
BTable[T,V] = concept
type U* = Table[T,V]
Self : U
proc `==`*(a, b: T): bool
proc hash*(a: T): Hash
#an example for a proc with the eigentype U
#proc getval*(t: U, k: int) : int
# main.nim
from objs import Obj
import bindtable
var t: BTable[Obj, int]
t[Obj(x: 3, y: 4, z: "debug")] = 34
echo t[Obj(x: 3, y: 4, z: "ignored")]
We already have the necessary parametrization in Nim's generics, we're getting generic constraints via concept,
O.k. How do we obtain concept wide intrinsic type parameters then or did I miss a detail?
How do we obtain concept wide intrinsic type parameters then or did I miss a detail?
I don't understand the question, the concept can demand a ==/hash operation to exist. The problem is what does it mean "demand to exist"? Currently it means it exists in the instantiation scope, but this an unnatural, error-prone design when the rest of the world attaches these operations to the type.
don't understand the question
true...
already can the concept demand a ==/hash operation to exist.
This was not the question. What I did with the example above: I linked a type with Self that is not directly attached to Self.
Do you spot it now ?
type
ExU = concept
type U
proc aproc*(a: Self,v: U)
proc cproc*(v: U) : int # attached proc that does not belong to Self!
The Link goes like this: Self -> U -> cproc
You can't do that with your proposal in RFC 380 and therefore, your specificatin is not complete. What you are doing there: You attempt to build a naive (static) virtual table for a type . At the same time, it is a simplified concept plus a prototypic implementation.
I did essentially the same with a {.prototype.} pragma in https://forum.nim-lang.org/t/7925 . It tells the compiler to build a static vtable. It makes the things explicit for a specific type. Other types can be attached too. However, they are not granular enough. Concepts are the more general approach.
Do you spot it now?
I think so, yes.
The limitations are obvious.
Coherence is a feature.