80 research outputs found
First Class Call Stacks: Exploring Head Reduction
Weak-head normalization is inconsistent with functional extensionality in the
call-by-name -calculus. We explore this problem from a new angle via
the conflict between extensionality and effects. Leveraging ideas from work on
the -calculus with control, we derive and justify alternative
operational semantics and a sequence of abstract machines for performing head
reduction. Head reduction avoids the problems with weak-head reduction and
extensionality, while our operational semantics and associated abstract
machines show us how to retain weak-head reduction's ease of implementation.Comment: In Proceedings WoC 2015, arXiv:1606.0583
Control Reduction Theories: the Benefit of Structural Substitution
L'article contient une annexe historique par Matthias Felleisen sur la génèse des opérateurs de contrôle à l'université d'Indiana à la fin des années 80.International audienceThe historical design of the call-by-value theory of control relies on the reification of evaluation contexts as regular functions and on the use of ordinary term application for jumping to a continuation. To the contrary, the lambda-C-tp control calculus, developed by the authors, distinguishes between jumps and terms. This alternative calculus, which derives from Parigot's lambda-mu-calculus, works by direct "structural substitution" of evaluation contexts. We review and revisit the legacy theories of control and argue that lambda-C-tp provides an observationally equivalent but smoother theory. In an additional note contributed by Matthias Felleisen, we review the story of the birth of control calculi during the mid to late eighties at Indiana University
Beyond Polarity: Towards a Multi-Discipline Intermediate Language with Sharing
The study of polarity in computation has revealed that an "ideal" programming language combines both call-by-value and call-by-name evaluation; the two calling conventions are each ideal for half the types in a programming language. But this binary choice leaves out call-by-need which is used in practice to implement lazy-by-default languages like Haskell. We show how the notion of polarity can be extended beyond the value/name dichotomy to include call-by-need by only adding a mechanism for sharing and the extra polarity shifts to connect them, which is enough to compile a Haskell-like functional language with user-defined types
Compiling With Classical Connectives
The study of polarity in computation has revealed that an "ideal" programming
language combines both call-by-value and call-by-name evaluation; the two
calling conventions are each ideal for half the types in a programming
language. But this binary choice leaves out call-by-need which is used in
practice to implement lazy-by-default languages like Haskell. We show how the
notion of polarity can be extended beyond the value/name dichotomy to include
call-by-need by adding a mechanism for sharing which is enough to compile a
Haskell-like functional language with user-defined types. The key to capturing
sharing in this mixed-evaluation setting is to generalize the usual notion of
polarity "shifts:" rather than just two shifts (between positive and negative)
we have a family of four dual shifts.
We expand on this idea of logical duality -- "and" is dual to "or;" proof is
dual to refutation -- for the purpose of compiling a variety of types. Based on
a general notion of data and codata, we show how classical connectives can be
used to encode a wide range of built-in and user-defined types. In contrast
with an intuitionistic logic corresponding to pure functional programming,
these classical connectives bring more of the pleasant symmetries of classical
logic to the computationally-relevant, constructive setting. In particular, an
involutive pair of negations bridges the gulf between the wide-spread notions
of parametric polymorphism and abstract data types in programming languages. To
complete the study of duality in compilation, we also consider the dual to
call-by-need evaluation, which shares the computation within the control flow
of a program instead of computation within the information flow
A Type-Theoretic Foundation of Delimited Continuations
International audienceThere is a correspondence between classical logic and programming language calculi with first-class continuations. With the addition of control delimiters, the continuations become composable and the calculi become more expressive. We present a fine-grained analysis of control delimiters and formalise that their addition corresponds to the addition of a single dynamically-scoped variable modelling the special top-level continuation. From a type perspective, the dynamically-scoped variable requires effect annotations. In the presence of control, the dynamically-scoped variable can be interpreted in a purely functional way by applying a store-passing style. At the type level, the effect annotations are mapped within standard classical logic extended with the dual of implication, namely subtraction. A continuation-passing-style transformation of lambda-calculus with control and subtraction is defined. Combining the translations provides a decomposition of standard CPS transformations for delimited continuations. Incidentally, we also give a direct normalisation proof of the simply-typed lambda-calculus with control and subtraction
Lambda Calculus with Explicit Recursion
AbstractThis paper is concerned with the study ofλ-calculus with explicit recursion, namely of cyclicλ-graphs. The starting point is to treat aλ-graph as a system of recursion equations involvingλ-terms and to manipulate such systems in an unrestricted manner, using equational logic, just as is possible for first-order term rewriting. Surprisingly, now the confluence property breaks down in an essential way. Confluence can be restored by introducing a restraining mechanism on the substitution operation. This leads to a family ofλ-graph calculi, which can be seen as an extension of the family ofλσ-calculi (λ-calculi with explicit substitution). While theλσ-calculi treat the let-construct as a first-class citizen, our calculi support the letrec, a feature that is essential to reason about time and space behavior of functional languages and also about compilation and optimizations of program
Equational term graph rewriting
We present an equational framework for term graph rewriting with cycles. The usual notion of homomorphism is phrased in terms of the notion of bisimulation, which is well-known in process algebra and concurrency theory. Specifically, a homomorphism is a functional bisimulation. We prove that the bisimilarity class of a term graph, partially ordered by functional bisimulation, is a complete lattice. It is shown how Equational Logic induces a notion of copying and substitution on term graphs, or systems of recursion equations, and also suggests the introduction of hidden or nameless nodes in a term graph. Hidden nodes can be used only once. The general framework of term graphs with copying is compared with the more restricted copying facilities embodied in the -rule, and translations are given between term graphs and -expressions. Using these, a proo
Compiling With Classical Connectives
The study of polarity in computation has revealed that an "ideal" programming
language combines both call-by-value and call-by-name evaluation; the two
calling conventions are each ideal for half the types in a programming
language. But this binary choice leaves out call-by-need which is used in
practice to implement lazy-by-default languages like Haskell. We show how the
notion of polarity can be extended beyond the value/name dichotomy to include
call-by-need by adding a mechanism for sharing which is enough to compile a
Haskell-like functional language with user-defined types. The key to capturing
sharing in this mixed-evaluation setting is to generalize the usual notion of
polarity "shifts:" rather than just two shifts (between positive and negative)
we have a family of four dual shifts.
We expand on this idea of logical duality---"and" is dual to "or;" proof is
dual to refutation---for the purpose of compiling a variety of types. Based on
a general notion of data and codata, we show how classical connectives can be
used to encode a wide range of built-in and user-defined types. In contrast
with an intuitionistic logic corresponding to pure functional programming,
these classical connectives bring more of the pleasant symmetries of classical
logic to the computationally-relevant, constructive setting. In particular, an
involutive pair of negations bridges the gulf between the wide-spread notions
of parametric polymorphism and abstract data types in programming languages. To
complete the study of duality in compilation, we also consider the dual to
call-by-need evaluation, which shares the computation within the control flow
of a program instead of computation within the information flow
- …