Difference between revisions of "Default and explicit variance"

m (tag forgotten)
m (Improvments)
Line 91: Line 91:
 
* Contravariant redefinition of request result requires a 'variant' typing on first feature definition.
 
* Contravariant redefinition of request result requires a 'variant' typing on first feature definition.
  
A 'variant' typing requires a simple object test. Note that the type is not repeated in the object test.
+
A 'variant' typing requires a simple object test to use the entity with the expected type.
 +
 
 +
example 1: covariant redefinition of feature argument with 'variant' typing on redfined feature
 +
 
 +
Note that the type is not repeated in the object test.
 
In the interface of the current type the 'variant' is removed. Indeed it is not possible to call 'eat' on a COW instance with a paramter of type FOOD.
 
In the interface of the current type the 'variant' is removed. Indeed it is not possible to call 'eat' on a COW instance with a paramter of type FOOD.
  
example: covariant redefinition of feature argument with 'variant' typing on redfined feature
 
 
<e>
 
<e>
 
class
 
class
Line 104: Line 107:
 
faeture -- Eating
 
faeture -- Eating
 
eat (f: like last)
 
eat (f: like last)
 +
require
 +
True
 
do
 
do
 
last := f
 
last := f
 +
ensure
 +
True
 
end
 
end
 
end
 
end
Line 113: Line 120:
 
class
 
class
 
COW
 
COW
 +
 +
inherit
 +
ANIMAL
 
redefine
 
redefine
 
all  
 
all  
Line 122: Line 132:
 
faeture -- Eating
 
faeture -- Eating
 
eat (f: variant like last) -- or eat (f: variant FOOD)
 
eat (f: variant like last) -- or eat (f: variant FOOD)
 +
require else
 +
True
 +
-- 'f' type = type of the feature argument. Here: GRASS
 
do
 
do
 +
-- 'f' type = type of the first feature definition. Here: FOOD
 
if attached f as g then
 
if attached f as g then
 +
-- 'g' type = type of the feature argument. Here: GRASS
 
last := g
 
last := g
 
end
 
end
 +
ensure then
 +
True
 +
-- 'f' type = type of the first feature definition. Here: FOOD
 
end
 
end
  
Line 131: Line 149:
 
</e>
 
</e>
  
example: covariant redefinition of feature argument with 'variant' typing on first feature definition.
+
example 2: covariant redefinition of feature argument with 'variant' typing on first feature definition.
 
<e>
 
<e>
 
class
 
class
Line 152: Line 170:
 
class
 
class
 
COW
 
COW
 +
 +
inherit
 +
ANIMAL
 
redefine
 
redefine
 
last
 
last
Line 162: Line 183:
 
</e>
 
</e>
  
Contravariant redefinition of request result requires an object test on client side.
+
Contravariant redefinition of request result requires an object test on client side. If there is not an object test then the result is considered of type ANY (different for generic: see in the next section).
 
+
Then for agents it is possible to decalre requests 'operands' and 'empty_operands' as variant.
+
<e>
+
operands: variant detachable OPEN_ARGS
+
 
+
empty_operands: variant OPEN_ARGS
+
do create Result ensure ... end
+
</e>
+
 
+
'apply' and 'target' should be write again. For example:
+
<e>
+
apply
+
do
+
if attached operands as args then
+
call (args)
+
else
+
call (Void)
+
end
+
end
+
</e>
+
  
 
=== Generic conformance ===
 
=== Generic conformance ===

Revision as of 09:30, 9 May 2013

Research: This page describes research about Eiffel, not the actual language specification.

Introduction

This solution enables covariance and contravariance redefinition. The default behavior is detected automatically. When there is a cat-call risk the programmer must explicitly declare the variance.

Default variance

Feature redefinition

  • Covariant redefinition of request result is allowed
  • Contravariant redefinition of feature arguments is allowed

The first is a weaker precondition and the second is a stronger postconidtion. Only the second statment is a new semantic in Eiffel.

  • Contravariant redefinition of request result is allowed for non-conforming inheritance
  • Covariant redefinition of feature arguments is allowed for non-conforming inheritance

Generic conformance

Generic conformance is close from redefinition.

  • Generic used only on feature argument is contravariant.
  • Generic used only on request result is covariant.
  • Generic used both on feature argument and request result is novariant.

And then generic not used is covariant and contravariant.

The first checkpoint "Generic lists" is checked. As explain for Usage-site variance the generic 'OPEN_ARGS' from ROUTINE, PROCEDURE, FUNCTION, PREDICATE must be contravariant and the generics of TUPLE must be covariants.

However 'OPEN_ARGS' is novariant. Indeed the generic is used on request type and feature arguments.

The class must probably be redesigned. Indeed if contravariant is allowed then there may be a new contravariant cat-call on request result.

In these classes there is only two requests using the generic as type:

operands: detachable OPEN_ARGS
 
empty_operands: OPEN_ARGS
	do create Result ensure ... end

The second request is not used internally and may be problematic for creation: How create a tuple of not self-initialized and attached types? The first is used in these features : 'target', 'is_equal', 'set_operands', 'copy', 'apply'

'is_equal', 'set_operands' and 'copy' rely on data model. 'apply' and 'target' are more sensitive. Indeed the problem is when there is an opened target.

'apply' could be restricted for no opened arguments.

apply
	require
		no_opened_operands: open_count = 0
	do
		call (Void)
	end

'target' could be modfied:

target: ANY
	require
		is_target_closed
	do
		-- ...
	end

Or maybe it is better to separate opened target and closed target in two abstractions.

The redisgn of agent classes is an opportunity to solve agent problems (see Minor-ECMA-problems, Agents in SCOOP).

Another solution will be mentioned later.

Note: The generic 'RESULT_TYPE' of FUNCTION class is used only on request result. Then it is a covariant generic. It is an expected point.

Sub-conclusion

The default semantic use no new keyword. We can critisize the lack of explicity for generic conformance. But the variance for generic is little used.


Explicit variance (Variant typing)

What is the advantages of covariance compared to a novariant typing?

  • explicit and adaptative interface
  • One routine

Feature redefinition

These rules concern the conforming inheritance.

  • Covariant redefinition of feature argument requires a 'variant' typing on redfined feature or first feature definition.
  • Contravariant redefinition of request result requires a 'variant' typing on first feature definition.

A 'variant' typing requires a simple object test to use the entity with the expected type.

example 1: covariant redefinition of feature argument with 'variant' typing on redfined feature

Note that the type is not repeated in the object test. In the interface of the current type the 'variant' is removed. Indeed it is not possible to call 'eat' on a COW instance with a paramter of type FOOD.

class
	ANIMAL
 
feature -- Access
	last: FOOD
 
faeture -- Eating
	eat (f: like last)
		require
			True
		do
			last := f
		ensure
			True
		end
end
class
	COW
 
inherit
	ANIMAL
		redefine
			all 
		end
 
feature -- Access
	last: GRASS
 
faeture -- Eating
	eat (f: variant like last) -- or eat (f: variant FOOD)
		require else
			True
			-- 'f' type = type of the feature argument. Here: GRASS
		do
			-- 'f' type = type of the first feature definition. Here: FOOD
			if attached f as g then
				-- 'g' type = type of the feature argument. Here: GRASS
				last := g
			end
		ensure then
			True
			-- 'f' type = type of the first feature definition. Here: FOOD
		end
 
end

example 2: covariant redefinition of feature argument with 'variant' typing on first feature definition.

class
	ANIMAL
 
feature -- Access
	last: FOOD
 
faeture -- Eating
	eat (f: variant like last)
		do
			if attached f as safe then
				last := safe
			end
		end
end
class
	COW
 
inherit
	ANIMAL
		redefine
			last
		end
 
feature -- Access
	last: GRASS
 
end

Contravariant redefinition of request result requires an object test on client side. If there is not an object test then the result is considered of type ANY (different for generic: see in the next section).

Generic conformance

The variant typing can be used to change the default variance of generic type.

  • Generic used only on feature argument or request result with variant typing is contravariant.
  • Generic used only on request result or creation procedure (not included in constraint) or feature argument with variant typing is covariant.

Sub-conclusion

This proposition reused an existing keyword and is very close from the Detachable types proposition but without the detachable constraint and extended on the generics. The contravariant redefinition of request result can be remoted for simplicty.

Other

Export status restrictions

Since the ECMA Eiffel Standard forbids the export restriction with conforming inheritance, it is not a problem. However the semantic can be changed for enable this restriction on conforming inheritance.

Restrict exportation should not cuase a cat-call. The mechanism could be used just to change the class interface.

deferred class
	ANIMAL
feature
	is_vegetarian: BOOLEAN
		deferred end
end
class
	COW
inherit
	ANIMAL
		export {NONE}
			is_vegetarian
		end
feature {NONE}
	is_vegetarian: BOOLEAN = True
end
local
	an_animal: ANIMAL; a_cow: COW
	b: BOOLEAN
do
	create a_cow
	b := a_cow.is_vegetarian -- invalid call
 
	an_animal := a_cow
	b := an_animal .is_vegetarian -- valid call
end

The class interface is easier.

Conclusion

The proposition use no new keyword and solve the cat-call problem. It passes all Catcall checkpoints.

The default generic conformance give a natural safe and flexible static typing. The variant typing enables to create adaptive interfaces keeping a safe static typing.