Linking Types for Multi-Language Software: Have Your Cake and Eat It Too

Large software systems are and should be implemented with many different languages, each suited to the domain of the task at hand. High-level business logic may be written in Java or OCaml, resource-intensive components may be written in C or Rust, and high-assurance components may be written in Coq. In some development shops, domain-specific languages are used in various parts of systems to better separate the logic of particular problems from the plumbing of general-purpose programming. But how are programmers to reason about such multi-language systems? Currently, for a programmer to reason about a single source component within this multi-language system, it is not sufficient for her to consider how her component behaves in source-level contexts. Instead, she is required to understand the target contexts that her component will be run in after compilation - which requires not only understanding aspects of the compiler, but also how target components are linked together. These target contexts may have behavior inexpressible in the source, which can impact the notion of equivalence that justifies behavior-preserving modifications of code, whether programmer refactorings or compiler optimizations. But while programmers should not have to reason about arbitrary target contexts, sometimes multi-language linking is done exactly to gain access to features unavailable in the source. To enable programmers to reason about components that link with behavior inexpressible in their language, we advocate that language designers incorporate specifications for linking into the source language. Such specifications should allow a programmer to reason about inputs from other languages in a way that remains close to the semantics of her language. Linking types are a well-specified minimal extension of a source language that allow programmers to annotate where in their programs they can link with components that are not expressible in their unadulterated source language. This gives them fine-grained control over the contexts that they must reason about and the equivalences that arise.

[1]  Guy E. Blelloch,et al.  Cache and I/O efficent functional algorithms , 2013, POPL.

[2]  Matthias Felleisen,et al.  On the Expressive Power of Programming Languages , 1990, European Symposium on Programming.

[3]  Xavier Leroy,et al.  A Formally Verified Compiler Back-end , 2009, Journal of Automated Reasoning.

[4]  Chung-Kil Hur,et al.  A kripke logical relation between ML and assembly , 2011, POPL '11.

[5]  Marco Patrignani,et al.  Secure Compilation to Protected Module Architectures , 2015, TOPL.

[6]  Jeehoon Kang,et al.  Lightweight verification of separate compilation , 2016, POPL.

[7]  Riccardo Pucella,et al.  Stateful Contracts for Affine Types , 2010, ESOP.

[8]  Matthias Blume,et al.  An equivalence-preserving CPS translation via multi-language semantics , 2011, ICFP '11.

[9]  Luca Cardelli,et al.  Program fragments, linking, and modularization , 1997, POPL '97.

[10]  Dominique Devriese,et al.  Fully-abstract compilation by approximate back-translation , 2016, POPL.

[11]  Chung-Kil Hur,et al.  Realizability and Compositional Compiler Correctness for a Polymorphic Language , 2010 .

[12]  Santosh Nagarakatte,et al.  Formal verification of SSA-based optimizations for LLVM , 2013, PLDI.

[13]  Amal Ahmed,et al.  Noninterference for free , 2015, ICFP.

[14]  Amal Ahmed,et al.  Verifying an Open Compiler Using Multi-language Semantics , 2014, ESOP.

[15]  Marco Gaboardi,et al.  Relational cost analysis , 2017, POPL.

[16]  Chung-Kil Hur,et al.  Biorthogonality, step-indexing and compiler correctness , 2009, ICFP.

[17]  Andreas Lochbihler,et al.  Verifying a Compiler for Java Threads , 2010, ESOP.

[18]  Chung-Kil Hur,et al.  Pilsner: a compositionally verified compiler for a higher-order imperative language , 2015, ICFP.

[19]  Amal Ahmed,et al.  FunTAL: reasonably mixing a functional language with assembly , 2017, PLDI.

[20]  Matthias Blume,et al.  Typed closure conversion preserves observational equivalence , 2008, ICFP.

[21]  Daan Leijen,et al.  Koka: Programming with Row Polymorphic Effect Types , 2014, MSFP.

[22]  Amal Ahmed Verified Compilers for a Multi-Language World , 2015, SNAPL.

[23]  Max S. New,et al.  Fully abstract compilation via universal embedding , 2016, ICFP.

[24]  Andrew W. Appel,et al.  Compositional CompCert , 2015, POPL.

[25]  Yu Guo,et al.  Deep Specifications and Certified Abstraction Layers , 2015, POPL.

[26]  Suresh Jagannathan,et al.  Relaxed-memory concurrency and verified compilation , 2011, POPL '11.

[27]  Xavier Leroy,et al.  Formal certification of a compiler back-end or: programming a compiler with a proof assistant , 2006, POPL '06.

[28]  Ramana Kumar,et al.  CakeML: a verified implementation of ML , 2014, POPL.

[29]  Dawn Xiaodong Song,et al.  The Correctness-Security Gap in Compiler Optimization , 2015, 2015 IEEE Security and Privacy Workshops.

[30]  Martin Hofmann,et al.  Resource Aware ML , 2012, CAV.