The Problem of Structural Type Tests in a Gradual-Typed Language

The Problem of Structural Type Tests in a Gradual-Typed Language

FOOL 2014 The Problem of Structural Type Tests in a Gradual-Typed Language John Tang Boyland University of Wisconsin-Milwaukee [email protected] Abstract ing tested, then a type test’s result may switch from positive The Grace programming language includes structural type to negative (or vice versa). If a program can use the result of tests and gradual typing. We demonstrate that this combina- the type test in a conditional branch, then the addition of a tion results in a mismatch. In particular, structural type tests type annotation can change its (non-error) behavior. (but not structural type assertions) can cause programs to If, on the other hand, type tests only lead to possible run- give different results after typing annotations are added. We time errors, and if type tests are implemented to err on the review the current uses of type tests in Grace programs and side of lenience in the case of missing type information, then propose potential ways forward, all of which have their own the addition of a type annotation can only make a previously drawbacks. running program fail with a type error. It cannot change its non-error behavior. 1. Introduction I discuss this situation in the case of Grace, extend- ing TinyGrace [4] (a statically-typed minimal dialect of Grace [2, 3] is a new language specifically tailored to teach- Grace) with gradual features, keeping in mind the current ing Computer Science. It has a simple syntax and a powerful (dynamically-typed) implementation, minigrace. Section 2 yet minimal type system. For power and simplicity, it uses starts by presenting a definition of TinyGrace, modified to a structural type system. In order to make the system usable be more amenable to gradual typing. Then Section 3 dis- for rapid prototyping and scripting, Grace supports gradual cusses minigrace and considers an example of a type test in typing. the example corpus of Grace programs distributed with min- Gradual typing [6] bridges dynamically and statically igrace. Section 4 discusses how to define a gradually-typed typed code by adding type assertions at the boundary be- version of Grace, thus attempting to connect minigrace and tween them. Even more important than implementation ef- TinyGrace. It gives a simple artificial program that demon- ficiency, static typing gives the ability to find errors sooner strates the problems with type tests. It also discusses the in the development process, either at compile-time, or dy- possibility of doing away with type tests altogether. namically, when execution enters a subsystem with particu- lar explicit expectations. Furthermore, many gradually typed 2. Syntax and Semantics systems use types as contracts in which one can track blame, locating the code that breaks a contract [9]. Figure 1 gives the syntax of TinyGrace, copied with mi- In this paper, I argue that the combination of the three nor variation from Jones and Noble [4] with an additional features (structural types, type tests and gradual types) leads highlighted form for the “Dynamic” (or “Unknown”) type. to a serious problem. One cannot provide continuity between Jones and Noble further define a well-formedness relation on dynamically typed and statically typed programs, because types that ensures that all recursive references are in scope adding a (valid) type annotation can change a program’s and signatures have unique method names. In this paper, we behavior. assume these restrictions are fulfilled. The problem I describe turns on how type tests are per- In examples as a shorthand and for clarity, I will use formed. In a nutshell, if more precise type information en- named type definitions and named objects in place of the ables the type test to more precisely determine the type be- recursive types and anonymous objects in Figure 1. Figure 2 gives typing rules for TinyGrace, modified from Jones and Noble, by making the type system algorithmic (and dropping an explicit T-SUB rule) and in T-REQ, explic- itly substituting the recursive type into the parameter types (τ1) and the result type (τ2). For the current purposes, the type rule for matches, T- CASE, is the most relevant: the expression being matched [Copyright notice will appear here once ’preprint’ option is removed.] over must be one of the types being matched (to make sure FOOL 2014: Portland OR, October 20, 2014 1 2014/10/11 S-ASSUM 0 M ::= method S { e } method X ≤ X 2 Σ O ::= object { M } object creation Σ ` X ≤ X0 C ::= case { x : τ -> e } branch S ::= m(x:τ) -> τ signature S-LIT Σ;X ≤ X0 ` S ≤ S0 Σ ` rec X.type{S,S } ≤ rec X0.type{S0} e ::= expression: 0 O object S-UNION x variable use S-UNIONL S-UNIONR Σ ` τ1 ≤ τ e.m(e) method call Σ ` τ ≤ τ1 Σ ` τ ≤ τ2 Σ ` τ2 ≤ τ match (e) C type test Σ ` τ ≤ τ1|τ2 Σ ` τ ≤ τ1|τ2 Σ ` τ1|τ2 ≤ τ τ ::= type: S-INTER Σ ` τ ≤ τ X S object type S-INTERL S-INTERR 1 rec .type { } Σ ` τ ≤ τ Σ ` τ ≤ τ Σ ` τ ≤ τ X recursive reference 1 2 2 τ | τ union type Σ ` τ1&τ2 ≤ τ Σ ` τ1&τ2 ≤ τ Σ ` τ ≤ τ1&τ2 τ & τ intersection type S-SIG ? dynamic type 0 0 Σ ` τ1 ≤ τ1 Σ ` τ2 ≤ τ2 Π ::= · j Π, X type context 0 0 0 Σ ` m(x:τ1)->τ2 ≤ m(x :τ )->τ Σ ::= · j Σ, τ <: τ subtype context 1 2 Γ ::= · j Γ, x : τ variable context Figure 3. Subtyping in TinyGrace: Σ ` τ ≤ τ. Figure 1. TinyGrace syntax with an addition. one of the branches match), and in the body of the case, one can assume that the match variable has the chosen type. The resulting type is the union of all the body types. The subtyping relation τ ≤ τ is defined in Fig. 3. It differs significantly from that of Jones and Noble only in the (stricter) way recursive types are handled. Here we use the T-VAR “Amber” rule for simplicity, but since recursive types aren’t (x : τ) 2 Γ the focus of this work, the difference is irrelevant. Following Γ ` x : τ Jones and Noble, in S-LIT, the signatures are assumed to be freely reorderable so that we can assume that all the T-OBJ matching methods are in the same order at the front of the τ = rec X.type{m(x:τ )->τ } 1 2 type. For now, since TinyGrace doesn’t use the dynamic type Γ; self : τ; x : τ ; ` e : τ 1 2 ?, we define no subtyping rules for ?. Γ ` object{method m(x:τ1) -> τ2 { e }} : τ Jones and Noble concede the subtyping of intersection types is not complete because a signature with a single T-REQ method whose return type is an intersection type is not Γ ` e : X S m x τ τ 2 S s rec .type{ } ( : 1)-> 2 a supertype of the intersection of two object types with Γ ` ep : τp τp ≤ τ1[X 7! rec X.type{S}] signatures with the same method having the individual return Γ ` es.m(ep) : τ2[X 7! rec X.type{S}] types. The same argument applies mutatis mutandi to union types, although Jones and Noble do not mention this fact. T-CASE Figure 4 repeats evaluation rules from Jones and Noble, Γ ` e : τ τ ≤ or(τ1)Γ; x : τ1 ` e2 : τ2 with the addition of “type assertions” on actual parameters in Γ ` match(e) case x:τ1 -> e2 : or(τ2) R-REQ to match the semantics implemented by minigrace.1 The type assertion O 2 τ consists of getting the type of or(τ1 : : : τn) = τ1|...|τn the object and then testing the resulting type with subtyping. The static type system of TinyGrace ensures that the type Figure 2. (Algorithmic) Type System for TinyGrace. 1 It would also make sense to add type assertions on the method return, but as this would require more machinery (an explicit cast syntax) and because minigrace currently doesn’t check return values, I do not do so in this paper. FOOL 2014: Portland OR, October 20, 2014 2 2014/10/11 R-RECV 0 L ⊇ fmg L ≤ τ1 e1 −! e1 0 L ≤ rec X.type{m(τ1)->τ2} L ≤ τ1|τ2 e1.m(e2) −! e1.m(e2) L ≤ τ2 L ≤ τ1 L ≤ τ2 R-PRM 0 e2 −! e2 L ≤ τ1|τ2 L ≤ τ1&τ2 0 e1.m(O,e2,e3) −! e1.m(O,e ,e3) 2 R-INST’ fmg ≤ τ R-REQ object{method m(:::)->:::{e}} 2 τ (method m(x:τ1) -> τ2 {e}) 2 M O 2 τ1 object{M}.m(O) −! e[self 7! object{M}; x 7! O] Figure 6. Evaluation of Type Assertions for minigrace. R-MATCH e −! e0 match (e) C −! match (e0) C Being dynamically-typed, minigrace does not use a static type system (no equivalent of Fig. 2), but (in my feather- R-CASE weight conception of minigrace), it shares the evaluation re- O 2 τ lation given in Fig. 4, with one difference seen in Fig. 6. match (O) case {x:τ->e}C −! e[x 7! O] Assertions are implemented by simply checking whether the set of labels in the object covers those required by the type.3 R-MISS An important property of this system is that the evaluation of O2 = τ type assertions do not depend on type annotations on meth- match (O) case {x:τ->e}C −! match (O) case C ods of the object being tested or on methods of the type being test against. As a result, one property enjoyed by minigrace is that Figure 4.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    7 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us