• No results found

Foundations of Typing Slice

In document Decrypting Local Type Inference (Page 68-72)

With the TypeFocus abstraction we have shown a technique for navigating type derivation trees. In this section we describe the actual outcome of the TypeFocus-based analysis. Previous work on analyzing type errors and type system decisions has typically represented the results of its analysis through minimal program source locations, minimal sets of con- flicting type constraints or program modifications, as described in Chitil [2001], Stuckey and Sulzmann [2005], Haack and Wells [2004], and Chen and Erwig [2014b]. Our algorithm will instead find type derivation subtrees that introduce the target type for the first time. This way we can explain if the target type has been synthesized, inherited, or a mixture of both, and still choose the most suitable representation for expressing the result (e.g., source code modification, visual type derivation tree exploration or source code location). The result also includes the TypeFocus value associated with the type derivation subtree, or rather the type that it inferred. The TypeFocus, as in all the previous cases encapsulates the focus on the target type that is part of the inferred type.

The result of the algorithm may not necessarily be final, in a sense that further typing deci- sions from the returned type derivation subtree could potentially be irrelevant when explain- ing the source of the target type. At the same time, as we will show, the result contains all the necessary inputs for further analysis, i.e., the typing judgment and the TypeFocus.

The conscious choice has significant consequences for the end-users, as well as for the con- struction of the analysis of the typing decisions. The intermediate type derivation subtrees allow us to inform users about the intermediate typing decisions, and their corresponding program locations, that led to the inference of some target type, especially important for ex- plaining non-trivial dependencies that span over the different program locations.

Intermediate typing decisions returned by the algorithm can be grouped together based on how they affected the target type (such as, was the type partially or completely synthesized, inherited or a mixture of both?). Each of the groups has to be analyzed in a different way but the intermediate results allow us to define analysis components that are well-defined and isolated from the other reasons, keeping the core of the algorithm simple and the approach in general viable to language extensions.

Finally, because local type inference propagates type information locally between the adja- cent nodes, our approach to finding such adjacent intermediate typing decisions is on a par with the principles of Colored Local Type Inference ( and in contrast to global type inference techniques where it would be redundant).

3.4. Foundations of Typing Slice

3.4.1 Typing Slice

The result of a TypeFocus-based analysis is a final or an intermediate source of the target type. Both are represented through an abstraction named Typing Slice. Due to a range of typing decisions that may effectively infer the target type, we have to allow for different kinds of Typing Slices. To represent them we use a triple〈ν,(P, Γ wE : T ),Θ〉 consisting of:

• A slice kind,ν, identifying the kind of typing decision that led to the target type. We provide a classification of the slices later in the section.

• An error-free type inference judgment (or type derivation subtree), (P,Γ wE : T ). • A TypeFocus, Θ, representing the target type information in the inferred type of the

included inference judgment. The TypeFocus satisfies the well-formedness property with respect to the inferred type T , i.e., Θ,fv(T )WFT .

For presentation reasons, we use the ν3 notation for Typing Slice triples later in the work

(ν3::= 〈ν, (P, Γ wE : T ),Θ〉).

The kind of the typing slice ranges over four different categories, symbolically represented as: ν ::= νPT| νADAPT| νTVAR| νTSIG

all of which we will now discuss in turn. The Typing Slices belonging to the same category ex- hibit the same properties, in a sense that they can be further analyzed with the same category of well-defined techniques that will be subject of sections 3.6, 3.7 and 3.8, respectively.

3.4.2 Prototype Typing Slice

A Prototype Typing Slice (νPT) allows us to represent typing judgments where the target type is inferred in a type checking mode, meaning that it has been fully inherited from the con- text. In practice, this means that any premise or auxiliary typing decision that is part of the inference rule can be safely ignored. In the Prototype Typing Slice the included TypeFocus not only represents a well-formed type selection on the inferred type of the term, but also on the prototype that is part of the inference judgment.

To illustrate the objective of the Prototype Typing Slice we consider the analysis of the same type inference judgment that inferred the type of some term to be (I nt → Int) but with a different target type:

• ( I nt → Int) - we need to explain the source of the parameter type. • (I nt→ Int ) - we need to explain the source of the result type.

Chapter 3. Guided-analysis for type derivation trees

The difference means that the value of TypeFocus, sayΘfun, just reflects the fact that as part of the analysis of the type derivation tree we have reached the particular node with a different objective (or rather different target type to explain).

In the first caseΘfun = [φ

fun-param]:

(abst p)I nt→ ?,  wfun(x : I nt )x : I nt→ Int  Int → ? | I nt → Int

The type after the| symbol (not part of the official type inference judgment) shows the com- puted result of the operation that adapts the type of the term to the provided prototype. In the presented inference judgment, the target type has been fully inherited from the proto- type - the application ofΘfunto the prototype,Θfun(I nt→ ?) =inlI nt , and the application ofΘfunto the inferred type,Θfun(I nt→ Int)=inlI nt , yield the same parameter type of the function type.

In the second caseΘfun = [φ

fun-res]:

(abst p)I nt→ ?, wfun(x : I nt )x : I nt→ Int  Int → ? | Int → I nt

In the presented inference judgment, the target type has not been fully inherited from the prototype - the application ofΘfunto the prototype,Θfun(I nt→ ?) =inl?, yields a constant wildcard type, meaning that no information regarding the particular fragment of the inferred type has been enforced from the outside context at this node of the derivation.

In consequence, the first target type will be explained using the Prototype Typing Slice, while the second one must not. The practical implications of such statement are that in the former case we can completely ignore the analysis of the premises of the type inference rule(abst p),

while for the latter example this is not the case.

The relation between the application of the same type selection of the target type to the in- ferred type and to the prototype is formally defined in Lemma 3.4. The statement establishes that the application of TypeFocus to the prototype is safe, provided that it is safe with respect to the inferred type of the term. This in turn implies that such TypeFocus will extract the same part of the prototype that inferred the target type.

Lemma 3.4 Well-formedness of TypeFocus with respect to the prototype. If (P,Γ wE : T ) and (Θ,a WFT ) forfv(T )⊆ a, then (Θ,a WFP ).

Proof.

Proof by induction on the structure of the TypeFocus instances. A full proof is provided in Appendix D.1.

3.4. Foundations of Typing Slice

3.4.3 Type Variable Typing Slice

Type inference rules for function applications,(app)and(appt p)determine optimal instan-

tiation for all type variables that are present in the polymorphic function type. Type infer- ence rules specify that the instantiation comes either from the collected and solved type con- straints, or from the explicit type arguments, as illustrated in our informal introduction to TypeFocus.

We use the Type Variable Typing Slice (νTVAR) to identify a type inference judgment where the instantiation of the type variable is the source of the target type.

3.4.4 Adaptation Typing Slice

An Adaptation Typing Slice (νADAPT) stands for a typing decision that infers the target type as part of the result of the adaptation. We recall that the  operation adapts the type of a term to a prototype, which may lead to type synthesis when their shapes are structurally different. For example, let TypeFocus [φfun-res,φfun-param] represent the target type in some inference judgment (the type after the| symbol represents the inferred type):

(abst p) A→? →?,  we : A→ ⊥  A →? →? | A →  → ⊥

In the example term e was assigned type A→ ⊥. Such type is a subtype of the inferred one but does not match the shape of the required prototype. Reporting the Adaptation Typing Slice indicates that the selected part of the inferred type has been synthesized during the adaptation, as highlighted in the involved components of types: A→ ⊥  A → ? → ? | A →

 → ⊥.

Therefore, in comparison to the Prototype Typing Slice, returning the Adaptation Typing Slice indicates the two elements that explain the source of the target type: the part of the inherited prototype and the synthesized type of the term.

3.4.5 Type Signature Typing Slice

The Type Signature Typing Slice (νTSIG) represents typing decisions that have fully synthesized the type of the target type from the term. Therefore, for our core language, the source of the target type, which is represented by the Type Signature Typing Slice, stands for one of the following:

• An explicit type annotation for the parameter of the abstraction. • A variable, whose type is synthesized from the environment.

Chapter 3. Guided-analysis for type derivation trees

• An abstraction term. • A record term.

For example, we consider the typing judgment where the last type inference rule used is(var) and the target type is represented through a TypeFocus [φfun-param]:

(var) ?, (,x : Int → Int) wx : I nt→ Int  ? | I nt → Int

The highlighted part of the inferred type of the term represents the information about the target type.

Reporting the Type Signature Typing Slice identifies the part of the type of a variable x, com- ing from the environment ((,x : Int → Int)), as the source of the target type. Such Typing Slice can be inferred because none of the previous kinds of the Typing Slice (involving proto- type or the type variables) applied for the given scenario.

An abstraction term becomes the source of the target type if the target type is a function type, and the inferred type of the abstraction has been synthesized from the term. Similarly, a record term can become the source of the target type if the target type is a record type, and the inferred type of the record has been synthesized from the term.

As we will indicate in Section 3.8, the Type Signature Typing Slices are final, in a sense that they do not require further analysis of the associated type derivation trees and can directly be associated with program locations.

In document Decrypting Local Type Inference (Page 68-72)