Skip to content

Static vs Dynamic Types #197

@apblack

Description

@apblack

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"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions