-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error "invalid declaration order" when mixing generic and specific methods #5325
Comments
A first suspect: Maybe the problem lies somewhere in |
I have found a work-around by mixing the type and method definitions: # First: generic types _only_ (specialized types must wait)
type
Iterator[T] = ref object of RootObj
CachedIterator[T] = ref object of Iterator[T]
s: seq[T]
# ... with generic methods
method collect*[T](i: Iterator[T]): seq[T] {.base.} =
quit "to override"
method collect*[T](i: CachedIterator[T]): seq[T] =
result = i.s
# And only now: specialized types and their methods
type
FileRowIterator = ref object of Iterator[string]
RangeIterator = ref object of Iterator[int]
method collect*(i: FileRowIterator): seq[string] =
result = @["1", "2", "3"]
method collect*(i: RangeIterator): seq[int] =
result = @[1, 2, 3]
proc newCachedIterator[T](s: seq[T]): Iterator[T] =
result = CachedIterator[T](s: s)
proc newFileRowIterator(): Iterator[string] =
result = FileRowIterator()
proc newRangeIterator(): Iterator[int] =
result = RangeIterator()
let it1 = newCachedIterator[int](@[1, 2, 3])
echo it1.collect()
let it2 = newFileRowIterator()
echo it2.collect()
let it3 = newRangeIterator()
echo it3.collect() |
Same issue/error messsage for me, had to exchange the order of two base methods to make the compiler happy. type
Gate[TT] = ref object {.inheritable.}
# Base operator or layer
# Inherit from it and add a forward and backward method.
Node[TT] = ref NodeObj[TT]
NodeObj {.acyclic.} [TT] = object
# Store an operator/layer + its parent
gate: Gate[TT]
parents: array[2, Node[TT]]
Context*[TT] = ref object
## Tape / Wengert list. Contains the list of applied operations or layers
nodes: seq[Node[TT]]
Variable*[TT] = object
## Wrapper for values
tape: Context[TT]
value: TT # TT should be a Tensor[T] or CudaTensor[T] or a scalar
method forward*[TT](self: Gate[TT], a, b: Variable[TT]): Variable[TT] {.base.} =
raise newException(ValueError, "forward method is not implemented")
## Exchanging the order of forward and backward works ##############
method backward*[TT](self: Gate[TT], gradient: TT): array[2,TT] {.base.} =
raise newException(ValueError, "backward method is not implemented")
proc newContext*(TT: typedesc): Context[TT] {.noSideEffect.} =
## Initialize a context (Tape / Wengert list)
new result
result.nodes = newSeq[Node[TT]]()
#############################################################
type AddGate {.final.} [TT] = ref object of Gate[TT]
arity: int
a_shape: seq[int]
b_shape: seq[int]
method forward*[TT](self: AddGate[TT], a, b: Variable[TT]): Variable[TT] =
return Variable[TT](tape: a.tape, value: a.value + b.value)
method backward*[TT](self: AddGate[TT], gradient: TT): array[2,TT] =
result[0] = 1.TT
result[1] = 1.TT
var ctx = newContext float32 |
No compile time error anymore but doesn't give the right output and the compiler gives a warning |
Consider a type hierarchy, where the base type is generic, but certain subtypes are not generic by nature, like in this example:
There are multiple issues with this:
invalid declaration order; cannot attach 'collect' to method defined here:
<pointing to first (base) definition>.use {.base.} for base methods; baseless methods are deprecated [UseBase]
which is probably not what is intended here, because it is a method of a subtype.The text was updated successfully, but these errors were encountered: