Eleno
Eleno

Reputation: 3016

Sharing a type with a generic class?

How do you declare a variable to be the same type as a type parameter used to instantiate a generic class? The following code does not compile:

class
    TEST [G, H -> INTEGER]

feature

    f (i: INDEXABLE [G, H])
        local
            y: H
        do
            y := i.lower -- Type error here.
        end

end

The compiler says that the source of the assignment is not compatible with target.

Upvotes: 0

Views: 74

Answers (2)

obnosim
obnosim

Reputation: 151

Type anchoring can be used in those cases:

feature
    f (i: INDEXABLE [G, H])
        local
            y: like i.lower
        do
            y := i.lower
        end

Sometimes a generic type is not used as return type of any accessible feature on a class, so in those cases I like to declare a fake feature specifically to allow anchoring:

class SOME_CLASS [G]
feature
    generic_type_anchor: G
        do
            check
                for_anchoring_only: False
                -- This method should never actually be called, only used as an anchor in type declarations
            end
        end

This is particularly useful with complex inheritance trees or when descendant classes close the generics, in which case the correct type is not apparent from the declared type. Personally I tend to use type anchoring whenever values are semantically related as this helps expressing intent, simplifies refactoring (as there are fewer repetitions of types which by definition must match) and facilitates covariance.

Also as a side-note, expanded types (like INTEGER) cannot be used polymorphically (you need a reference for that; if class A is expanded and class B [expanded or reference] inherits A, you could not assign a value of type B to a variable of type A; inheritance from expanded types is implicitly non-conforming), and moreover the compiler disallows inheriting from basic expanded types (INTEGER, BOOLEAN, REAL_64, etc.), therefore the generic constraint in your example makes no sense because H could never be anything but INTEGER.

Upvotes: 1

Alexander Kogtenkov
Alexander Kogtenkov

Reputation: 5810

In the current implementation, INDEXABLE [G, H] inherits from TABLE [G, INTEGER]. As a result, lower is of type INTEGER, not H. And INTEGER does not conform to the formal generic type H of the class TEST. This explains the error.

To me, it looks like a mistake in the declaration of class INDEXABLE. It should inherit from TABLE [G, H] instead. Then, the example code would compile.

Upvotes: 1

Related Questions