32 research outputs found

    Decrypting Local Type Inference

    Get PDF
    Statically typed languages verify programs at compile-time. As a result many programming mistakes are detected at an early stage of development. A programmer does not have to specify types for every single term manually, however. Many programming languages can reconstruct a termâs type using type inference algorithms. While helpful, programmers often find it hard to comprehend the choice of typing decisions that led to the derived type for a term. A particularly serious consequence is that the reporting of type errors yields cryptic messages and misleading program locations. In this thesis we propose a novel approach to explaining type checking decisions by exploring fragments of type derivation trees. Our approach applies to programming languages that use local type inference: typing decisions are made locally and the type information is only propagated between the adjacent AST nodes. We design an algorithm that backtracks through the nodes of type derivation trees in order to discover the typing decisions that introduce the types for the first time during the type inference process. Our algorithm has two properties: - it is type-driven, meaning that we only visit the nodes and their respective typing decisions if they participated in the inference of a type. - it is autonomous, meaning that it does not require any user-input in its operation. These properties allow us to identify the complete and precise set of locations defining the source of a type; previous work mostly focussed on heuristics or used approximations for locating the cause of an error. Our algorithm is not tied to a particular implementation of a type checker: our type derivation trees can be reconstructed from a pre-existing type checker without modifying its internal logic or affecting its regular compilation times. It therefore readily applies to existing programs: we can not only provide improved feedback for them, we also expose limitations of local type inference algorithms and their implementations, without artificially limiting the language features. We implement our type debugging algorithm on top of Scalaâs type checker. Our analysis applies to a range of erroneous scenarios. It provides better error locations than the standard type error reporter of the Scala compiler. This type debugging analysis is just a starting point from which many interesting and useful applications around type debugging can be built: - we implement an interactive type debugger that guides the users through the decisions of local type inference for erroneous and error-free programs alike. - with precise and minimal source code locations we can also offer surgical-level code modifications that fix for example the limitations of local type inference. - we open the door for programmatically defined, application-specific error feedback or corrections. To the best of our knowledge this thesis is the first to address the problem of type errors for programming languages that use local type inference. Current trends suggest that this scheme is gaining in popularity with mainstream languages other than Scala

    Boxy Types: Inference for Higher-Rank Types and Impredicativity

    Get PDF
    Languages with rich type systems are beginning to employ a blend of type inference and type checking, so that the type inference engine is guided by programmer-supplied type annotations. In this paper we show, for the first time, how to combine the virtues of two well-established ideas: unification-based inference, and bidirectional propagation of type annotations. The result is a type system that conservatively extends Hindley-Milner, and yet supports both higher-rank types and impredicativity

    Kind Inference for the FreeST Programming Language

    Full text link
    We present a kind inference algorithm for the FREEST programming language. The input to the algorithm is FREEST source code with (possibly part of) kind annotations replaced by kind variables. The algorithm infers concrete kinds for all kind variables. We ran the algorithm on the FREEST test suite by first replacing kind annotation on all type variables by fresh kind variables, and concluded that the algorithm correctly infers all kinds. Non surprisingly, we found out that programmers do not choose the most general kind in 20% of the cases.Comment: In Proceedings PLACES 2023, arXiv:2304.0543

    SĂ©paration des couleurs dans un lambda-calcul bichrome

    Get PDF
    National audienceDans cet article nous introduisons un λ-calcul bichrome pour expliciter une partie de l'évaluation d'un terme en précisant la localité du calcul1. L'intérêt est alors de pouvoir définir une transformation, par β-expansion, qui regroupe les expressions de même couleur. Les propriétés de correction, de terminaison et de confluence de cette transformation sont démontrées 'a l'aide de l'assistant de preuves Coq. Cette transformation est indépendante de la sémantique de communication et de synchronisation de l'application. On s'intéresse alors aux applications utilisant deux unités de calcul comme les couples client-serveur de la programmation Web. Nous abordons le passage à un λ-calcul à plus de deux couleurs et montrons les difficultés que cela engendre

    Simplicitly: Foundations and Applications of Implicit Function Types

    Get PDF
    Understanding a program entails understanding its context; dependencies, configurations and even implementations are all forms of contexts. Modern programming languages and theorem provers offer an array of constructs to define contexts, implicitly. Scala offers implicit parameters which are used pervasively, but which cannot be abstracted over. This paper describes a generalization of implicit parameters to implicit function types, a powerful way to abstract over the context in which some piece of code is run. We provide a formalization based on bidirectional type-checking that closely follows the semantics implemented by the Scala compiler. To demonstrate their range of abstraction capabilities, we present several applications that make use of implicit function types. We show how to encode the builder pattern, tagless interpreters, reader and free monads and we assess the performance of the monadic structures presented

    Additional Material for "Unifying Data Representation Transformations"

    Get PDF
    This report shows an attempt to formalize the data representation transformation mechanism in the ``Unifying Data Representation Transformations'' paper. Since the mechanism described in the paper is targeted at the Scala programming language and the specification is written against System Fsub with local colored type inference formally reasoning about the calculus is a major undertaking. Instead, in this report we start from the simply typed lambda calculus with subtyping, natural numbers and unit. We add rewriting and adapt the calculus to propagate expected type information in a mechanism inspired from local colored type inference. Finally we show how the representation transformation mechanism (the convert phase) rewrites terms. We show that, given a series of assumptions about the inject phase, type-checking a term against the updated rules produces a correct and operationally equivalent term, with a minimum number of runtime coercions introduced for the annotations given. We finish the report by giving a series of examples which show how the code is transformed

    Improving Human-Compiler Interaction Through Customizable Type Feedback

    Get PDF
    Type errors reported by compilers can sometimes be cryptic, or difficult to understand. In this paper, we propose a type debugging framework that exposes a high-level representation of the typechecking decision-making process that users normally do not have access to in state-of-the-art compilers. This representation makes it easier for non-experts to analyze complex type errors. Our system is implemented by instrumenting the existing Scala typechecker, but without modifying it. We also provide generic search algorithms that can be used as basic building blocks to build a number of systems, from visual type debugging tools to customized error reporting for normal Scala users as well as to users of domain-specific languages. Using our framework, it is possible to overcome well-known limitations of local type inference by providing precise type error messages to mainline Scala users or Scala DSL users alike. In addition, the framework provides better user feedback for non-trivial type errors from existing Scala libraries and DSLs
    corecore