9 research outputs found

    Abstract Data Types without the Types. Dedicated to David Turner on the occasion of his 70'th birthday

    Get PDF
    The data abstraction mechanism of Miranda may be adapted to a dynamically typed programming language by applying ideas from gradual typing

    LiquidHaskell : Liquid Types for Haskell

    Get PDF
    Ακόμα και τα ασφαλή προγράμματα μπορούν να έχουν λάθη. Προγράμματα που έχουν μεταγλωτιστεί με βάση κάποιο ισχυρό σύστημα τύπων, όπως αυτό της Haskell, μπορούν να πετάξουν σφάλμα κατα τον χρόνο εκτέλεσης ή να δώσουν μη αναμενώμενη απάντηση. Τα refinement συστήματα τύπων αντιμετωπίζουν αυτήν την κατάσταση αφού επιτρέπουν την έκφραση σημασιολογικών προδιαφραφών των προγραμμάτων. Αναλύουμε την απόδειξη των προδιαγραφών σε αυτά τα συστήματα. Πολύ εκφραστικά συστήματα απαιτούν ελέγχους κατά τον χρόνο εκτέλεσης ή ρητές αποδείξεις από τον χρήστη, για την αποδειξη των προδιαγραφών, Λιγότερο εκφραστικά συστήματα τύπων επιτρέπουν την αυτόματη απόδειξη των προδιαγραφών, κατά τον χρόνο μεταγλώτισης. Παρουσιάζουμε τους liquidTypes ένα σύστημα τύπων που επιτρέπει την αυτόματη απόδειξη προδιαγραφών κατά τον χρόνο μεταγλώτισης. Επεκτείνουμε τους liquidTypes με abstract refinement, έναν μηχανισμό που αυξάνει την εκφραστικότητα του συστήματος, χωρίς να αυξάνει την πολυπλοκοτητά του. Υλοποιήσαμε την LiquidHaskell ένα σύστημα τύπων για Haskell που συνδιάζει liquidTypes με abstract refinement και το χρησιμοποιήσαμε για να αποδείξουμε ιδιώτητες πραγματικων βιβλιοθηκών της Haskell.Even well-typed programs can go wrong, by returning a wrong answer or throwing a run-time error. A popular response is to allow programmers use refinement type systems to express semantic specifications about programs. We study verification in such systems. On the one hand, expressive refinement type systems require run-time checks or explicit proofs to verify specifications. On the other, less expressive type systems allow static and automatic proofs of the specifications. Next, we present abstract refinement types, a means to enhance the expressiveness of a refinement type system without increasing its complexity. Then, we present LiquidHaskell that combines liquidTypes with abstraction over refinements to enhance expressiveness of LiquidTypes. LiquidHaskell is a quite expressive verification tool for Haskell programs that can be used to check termination, totality and general functional correctness. Finally, we evaluate LiquidHaskell in real world Haskell libraries

    Executable Refinement Types

    Full text link
    This dissertation introduces executable refinement types, which refine structural types by semi-decidable predicates, and establishes their metatheory and accompanying implementation techniques. These results are useful for undecidable type systems in general. Particular contributions include: (1) Type soundness and a logical relation for extensional equivalence for executable refinement types (though type checking is undecidable); (2) hybrid type checking for executable refinement types, which blends static and dynamic checks in a novel way, in some sense performing better statically than any decidable approximation; (3) a type reconstruction algorithm - reconstruction is decidable even though type checking is not, when suitably redefined to apply to undecidable type systems; (4) a novel use of existential types with dependent types to ensure that the language of logical formulae is closed under type checking (5) a prototype implementation, Sage, of executable refinement types such that all dynamic errors are communicated back to the compiler and are thenceforth static errors.Comment: Ph.D. dissertation. Accepted by the University of California, Santa Cruz, in March 2014. 278 pages (295 including frontmatter

    TOWARDS EFFICIENT GRADUAL TYPING VIA MONOTONIC REFERENCES AND COERCIONS

    Get PDF
    Thesis (Ph.D.) - Indiana University, Luddy School of Informatics, Computing, and Engineering/University Graduate School, 2020Integrating static and dynamic typing into a single programming language enables programmers to choose which discipline to use in each code region. Different approaches for this integration have been studied and put into use at large scale, e.g. TypeScript for JavaScript and adding the dynamic type to C#. Gradual typing is one approach to this integration that preserves type soundness by performing type-checking at run-time using casts. For higher order values such as functions and mutable references, a cast typically wraps the value in a proxy that performs type-checking when the value is used. This approach suffers from two problems: (1) chains of proxies can grow and consume unbounded space, and (2) statically typed code regions need to check whether values are proxied. Monotonic references solve both problems for mutable references by directly casting the heap cell instead of wrapping the reference in a proxy. In this dissertation, an integration is proposed of monotonic references with the coercion-based solution to the problem of chains of proxies for other values such as functions. Furthermore, the prior semantics for monotonic references involved storing and evaluating cast expressions (not yet values) in the heap and it is not obvious how to implement this behavior efficiently in a compiler and run-time system. This dissertation proposes novel dynamic semantics where only values are written to the heap, making the semantics straightforward to implement. The approach is implemented in Grift, a compiler for a gradually typed programming language, and a few key optimizations are proposed. Finally, the proposed performance evaluation methodology shows that the proposed approach eliminates all overheads associated with gradually typed references in statically typed code regions without introducing significant average-case overhead

    Manifest Contracts

    Get PDF
    Eiffel popularized design by contract, a software design philosophy where programmers specify the requirements and guarantees of functions via executable pre- and post-conditions written in code. Findler and Felleisen brought contracts to higher-order programming, inspiring the PLT Racket implementation of contracts. Existing approaches for runtime checking lack reasoning principles and stop short of their full potential---most Racket contracts check only simple types. Moreover, the standard algorithm for higher-order contract checking can lead to unbounded space consumption and can destroy tail recursion. In this dissertation, I develop so-called manifest contract systems which integrate more coherently in the type system, and relate them to Findler-and-Felleisen-style latent contracts. I extend a manifest system with type abstraction and relational parametricity, and also show how to integrate dynamic types and contracts in a space efficient way, i.e., in a way that doesn\u27t destroy tail recursion. I put manifest contracts on a firm type-theoretic footing, showing that they support extensions necessary for real programming. Developing these principles is the first step in designing and implementing higher-order languages with contracts and refinement types

    Design and evaluation of contracts for gradual typing

    Get PDF
    Gradual typing aims to improve the correctness of dynamically typed programs by incrementally adding type information. Sound gradual typing performs static type checking and inserts run-time checks when a type cannot be guaranteed statically. This form of gradual typing offers many features, but also requires that the programmer uses a language with a specialised gradual type system. A lightweight form of gradual typing uses contracts to enforce types at run-time, assigning blame when a type assertion fails. Contracts can be implemented as a library, without requiring a specialised gradual type system. Contracts provide a lower barrier of entry into sound gradual typing. This thesis investigates the design and evaluation of contracts for gradual typing, focusing on bridging the gap between JavaScript (dynamic) and TypeScript (static). There are two key outcomes regarding theory and practice. Contracts for higher-order intersection and union types can be designed in a uniform way, using blame to derive the semantics of contracts satisfaction. Contracts and gradual typing can be evaluated using the DefinitelyTyped repository, where JavaScript libraries are annotated with TypeScript definition files. Contract composition is the fundamental method for building complex type assertions. Intersection and union types are well suited for describing patterns common to dynamically typed programs. Our first contribution is to present a calculus of contracts for intersection and union types with blame assignment, giving a uniform treatment to both operators. A correct model of contracts must include a definition of contract satisfaction. Our second contribution is to show that contract satisfaction can be defined using blame: satisfying programs are those that do not elicit blame when monitored. We define a series of properties mandating how contract satisfaction should compose, ensuring that a contract for a type behaves as one would expect for that type. Building on our technical developments, our third contribution is a practical evaluation of gradual typing using the DefinitelyTyped repository. We show that contracts can be used to enforce conformance to a definition file, detecting errors in the specification. Our evaluation also reveals that technical concerns associated with implementing contracts using JavaScript proxies are a problem in practice

    Relationally-Parametric Polymorphic Contracts

    No full text
    The analogy between types and contracts raises the question of how many features of static type systems can be expressed as dynamic contracts. An important feature missing in prior work on contracts is parametricity, as represented by the polymorphic types in languages like Standard ML. We present a contract counterpart to parametricity. We explore multiple designs for such a system and present one that is simple and incurs minimal execution overhead. We show how to extend the notion of contract blame to our definition. We present a form of inference that can often save programmers from having to explicitly instantiate many parametric contracts. Finally, we present several examples that illustrate how this system mimics the feel and properties of parametric polymorphism in typed languages
    corecore