Here's a simple concept and a function that makes use of the concept methods, which doesn't compile:
type Eq* = concept x, y
eq(x, y) is bool
ne(x, y) is bool
func is_symmetric*(x, y: Eq): bool =
eq(x, y) == eq(y, x)
func eq*(x, y: int): bool = x == y
func ne*(x, y: int): bool = x != y
assert int is Eq
assert eq(3, 3)
assert is_symmetric(3, 4)
Changing the order to this does allow it to compile:
type Eq* = concept x, y
eq(x, y) is bool
ne(x, y) is bool
func eq*(x, y: int): bool = x == y
func ne*(x, y: int): bool = x != y
func is_symmetric*(x, y: Eq): bool =
eq(x, y) == eq(y, x)
assert int is Eq
assert eq(3, 3)
assert is_symmetric(3, 4)
I think this prevents me from placing the eq/ne implementations for various types into separate files that import the file defining the concept? Do all types that implement the concept have to be in the same file as the concept, defined before any generic functions that use the concept methods in a type independent way?
Firstly -- thanks for planning and implementing the new concepts approach, much appreciated.
Concept derivation is central to modelling the algebraic structures I'm working with and I don't think the new concepts have any kind of derivation? (Please correct me if I'm wrong).
The emmy Nim library is probably going to have the same issues moving to new concepts.
This should compile:
ype Eq* = concept x, y
eq(x, y) is bool
ne(x, y) is bool
func eq*(x, y: int): bool
func is_symmetric*(x, y: Eq): bool =
eq(x, y) == eq(y, x)
func eq*(x, y: int): bool = x == y
func ne*(x, y: int): bool = x != y
assert int is Eq
assert eq(3, 3)
assert is_symmetric(3, 4)
If a function is not defined yet, it needs to be given as a (forward) declaration. Same thing as in good old C.
Thanks for that technique.
I think I'll still have the same issue of not being able to separate that example into two files: one with the concept and the is_symmetric function and a second file with the concept implementations? Something like:
In eq.nim:
type Eq* = concept x, y
eq(x, y) is bool
ne(x, y) is bool
func eq*(x, y: int): bool
func is_symmetric*(x, y: Eq): bool =
eq(x, y) == eq(y, x)
And in eq_implementers.nim:
func eq*(x, y: int): bool = x == y
func ne*(x, y: int): bool = x != y
# Ditto for float, etc.
assert int is Eq
assert eq(3, 3)
assert is_symmetric(3, 4)
try our new concept implementation
What is the "new concept"? I didn't heard about it, can I have a link please.
Well it compiles after some rearrangements
#module eqc.nim
import eq_impl
type Eq* = concept x, y
eq(x, y) is bool
ne(x, y) is bool
func is_symmetric*(x, y: Eq): bool =
eq(x, y) == eq(y, x)
#module eq_impl.nim
func eq*(x, y: int): bool = x == y
func ne*(x, y: int): bool = x != y
import eqc
assert int is Eq
assert eq(3, 3)
assert is_symmetric(3, 4)
explanations: