-
Notifications
You must be signed in to change notification settings - Fork 1
Description
This issue is a placeholder for the issue that the spec itself admits. Let me quote the section on Type Annotations, which concludes with "This treatment is types not entirely satisfactory, and is subject to review and change." I believe that this makes it an issue.
Type Annotations
When parameters, fields, and method results are annotated with types,
the programmer can be confident that objects bound to those parameters and
fields,
and returned from those methods, do indeed have the specified types, insofar
as Grace has the required type information. The checks necessary to implement
this guarantee may be performed statically or dynamically.
Static Type Checking
When implementing the static type check, types specified as Unknown will always
conform. So, if a variable is annotated with type
interface {
add(Number) → Collection⟦Number⟧
removeLast → Number
}
an object with type
interface {
add(Unknown) → Collection⟦Unknown⟧
removeLast → Unknown
size → Number
}
will pass the type test. Of course, the presence of Unknown in the type
of the object means that a subsequent type error may still occur.
For example, the code of the add(_) method
might actually depend on being given a String argument,
or the collection returned from add(_) might contain Booleans.
Static type checking is implemented by dialects; various static typing dialects
may impose varied restrictions on Grace.
Dynamic Type Checking
Currently, the dynamic interpretation of types is shallow, that is,
it considers only the methods present in an interface,
and not the types of the arguments or the results of those methods.
This is because, in the absence of type annotations, Grace has no information
about the argument types or the return type of a method.
This means that if programmers annotate a declaration
var x:Number
they can be sure that any object assigned to x has a method +(_), but are not
assured that this +(_) method will expect an argument that is also a Number,
nor that the result will be a Number, even though these details are part of
the Number interface.
Similarly, when the operators <:, :> and == between types are evaluated
dynamically, argument and result types are ignored, even if they are present in the
type definitions.
This treatment is types not entirely satisfactory, and is subject to review and change.
Examples
assert (B <: A) description "B does not conform to A"
assert (B <: interface { foo(_) } ) description "B has no foo(_) method"
assert (B <: interface {foo(_:C) → D} ) description "B has no foo(_) method"
assert (B == (A | C)) description "B is neither an A or a C"