Papers by Susan Eisenbach
the modelling of mobile processes is not straightfor-DARWIN is a configuration language f o r dis... more the modelling of mobile processes is not straightfor-DARWIN is a configuration language f o r distributed and parallel programs, providing a hierarchical structure of components with dynamic binding. In order t o specify precisely the behaviour of DARWIN programs, we sketch a translation of the features of the language into the a-calculus, a formalism for modelling concurrent processes. The match between underlying models f o r DARWIN and ?r-calculus is good. Examples done in the calculus are clean abstractions of the same solutions in other concurrent languages.
arXiv (Cornell University), Sep 16, 2022
Robust modules guarantee to do only what they are supposed to do-even in the presence of untruste... more Robust modules guarantee to do only what they are supposed to do-even in the presence of untrusted, malicious clients, and considering not just the direct behaviour of individual methods, but also the emergent behaviour from calls to more than one method. Necessity is a language for specifying robustness, based on novel necessity operators capturing temporal implication, and a proof logic that derives explicit robustness specifications from functional specifications. Soundness and an exemplar proof are mechanised in Coq. CCS Concepts: • Software and its engineering → General programming languages.
Session details: Program analysis II
Lecture Notes in Computer Science, 2004
In Java the compiler guarantees that each local variable is initialised when we attempt to access... more In Java the compiler guarantees that each local variable is initialised when we attempt to access it at runtime. This prohibits access to uninitialised memory during execution and is a key ingredient for type safety. We have formalised the definite assignment analysis of the Java compiler in the theorem prover Isabelle/HOL and proved it correct.
Context-Aware Functional Programming
Context-awareness as defined in the setting of Ubiquitous Computing (3) is all about expressing t... more Context-awareness as defined in the setting of Ubiquitous Computing (3) is all about expressing the dependency of a specific com- putation upon some implicit piece of information. The manipulation and expression of such dependencies may thus be neatly encapsulated in a language where computations are first-class values. Perhaps surprisingly however, context-aware programming has not been explored in a func- tional setting, where first-class computations and higher-order functions are commonplace. In this paper we present an embedded domain-specific language (EDSL) for constructing context-aware applications in the func- tional programming language Haskell.

International Workshop on Software Specification and Design, Mar 22, 1996
Darwin is a language designed for configuring distributed systems. A system is modelled as a deco... more Darwin is a language designed for configuring distributed systems. A system is modelled as a decompositional hierarchy of components with interfaces. Connections are represented as bindings between interfaces. Darwin programs define component types. Configurations of a system are obtained by instantiating these types. Configurations have to comply with a number of constraints on the system structure. It is therefore intuitive to express these constraints in the domain of configurations rather than on the language level. To succeed in this endeavour we need to precisely express the relation between Darwin programs and configurations. We do this in terms of a firstorder logic theory of Darwin programs and configurations. Models of the theory provide a straightforward mapping from Darwin programs to configurations and vice versa. Most of the constraints on configurations as well as structural transformations can be specified by adding just a few axioms to the theory. Also the theory enables us to generate Darwin programs from configurations thus allowing for the inclusion of existing systems into new programs.
Our main paper presents SHAPES, a language extension which offers developers fine-grained control... more Our main paper presents SHAPES, a language extension which offers developers fine-grained control over the placement of data in memory, whilst retaining both memory safety and object abstraction via pooling and clustering. As part of the development of SHAPES, we wanted to investigate the usefulness of the concepts SHAPES brings to the table. To that extent, we implemented five such case studies. This publication provides the corresponding code and instructions on how to run these case studies and derive the results we provide.

European Conference on Object-Oriented Programming, 2020
The vast gap between CPU and RAM speed means that on modern architectures, developers need to car... more The vast gap between CPU and RAM speed means that on modern architectures, developers need to carefully consider data placement in memory to exploit spatial and temporal cache locality and use CPU caches effectively. To that extent, developers have devised various strategies regarding data placement; for objects that should be close in memory, a contiguous pool of objects is allocated and then new instances are constructed inside it; an array of objects is clustered into multiple arrays, each holding the values of a specific field of the objects 1. Such data placements, however, have to be performed manually, hence readability, maintainability, memory safety, and key OO concepts such as encapsulation and object identity need to be sacrificed and the business logic needs to be modified accordingly. We propose a language extension, SHAPES, which aims to offer developers high-level fine-grained control over data placement, whilst retaining memory safety and the look-and-feel of OO. SHAPES extends an OO language with the concepts of pools and layouts: Developers declare pools that contain objects of a specific type and specify the pool's layout. A layout specifies how objects in a pool are laid out in memory. That is, it dictates how the values of the fields of the pool's objects are grouped together into clusters. Objects stored in pools behave identically to ordinary, standalone objects; the type system allows the code to be oblivious to the layout being used. This means that the business logic is completely decoupled from any placement concerns and the developer need not deviate from the spirit of OO to better utilise the cache. In this paper, we present the features of SHAPES, as well as the design rationale behind each feature. We then showcase the merit of SHAPES through a sequence of case studies; we claim that, compared to the manual pooling and clustering of objects, we can observe improvement in readability and maintainability, and comparable (i.e., on par or better) performance. We also present SHAPES h , an OO calculus which models the SHAPES ideas, we formalise the type system, and prove soundness. The SHAPES h type system uses ideas from Ownership Types [1] and Java Generics [2]: In SHAPES h , pools are part of the types; SHAPES h class and type definitions are enriched with pool parameters. Moreover, class pool parameters are enriched with bounds, which
A Chorded Compiler for Java
A Chorded Compiler for Java Fourth Year MEng Project Report ... We design and implement a compile... more A Chorded Compiler for Java Fourth Year MEng Project Report ... We design and implement a compiler which adds Polyphonic C ♯ like extensions (called chords) to Java. Our compiler uses Antlr, the parser-generator, and Velocity, the Apache project's template engine for Java. ...

51, Mar 31, 2009
Haskell makes it very easy to build and use Domain Specific Languages (DSLs). However, it is freq... more Haskell makes it very easy to build and use Domain Specific Languages (DSLs). However, it is frequently the case that a DSL has invariants that can not be easily enforced statically, resulting in runtime checks. This is a great pity given Haskell's rich and powerful type system and leads to all the usual problems of dynamic checking. We believe that Domain Specific Languages are becoming more popular: the internet itself is a good example of many DSLs (HTML, CSS, JavaScript, Flash, etc), and more seem to be being added every day; most graphics cards already accept programs written in the DSL OpenGL Shading Language (GLSL); and the predicted growth of heterogeneous CPUs (for example IBM's Cell CPU) will demand many different DSLs for the various programming models and instruction sets that become available. We present a technique that allows invariants of any given DSL to be lifted into the Haskell type system. This removes the need for runtime checks of the DSL and prevents programs that violate the invariants of the DSL from ever being compiled or executed. As a result we avoid the pitfalls of dynamic checking and return the user of the DSL to the safety and tranquillity of the strongly statically typed Haskell world.
Lecture Notes in Computer Science, 1994
Computer language paradigms offer linguistic abstractions and proof theories for expressing progr... more Computer language paradigms offer linguistic abstractions and proof theories for expressing program implementations. Similarly, system architectures offer the hardware abstractions and quantitative theories applicable to the execution of compiled programs. Although the two entities are usually treated independently, object-oriented technology can be used to obtain a unifying framework. Specifically, inheritance can be used to model both programming languages as extensions to the assembly language executed by the target architecture, and system architectures as the root class of those paradigms. We describe how these principles can be used to model, structure and implement real multiparadigm systems in a portable and extendable way.

Blockchain-based platforms such as Ethereum support the execution of versatile decentralised appl... more Blockchain-based platforms such as Ethereum support the execution of versatile decentralised applications, known as smart contracts. These typically hold and transfer digital currency (e.g., Ether) to other parties on the platform. Smart contracts have, however, been subject to numerous attacks due to the unintentional introduction of bugs. In total, over a billion dollars worth of Ether has been stolen. As smart contracts cannot be updated after deployment, it is imperative to ensure their correctness during development. Current program analysers cannot accurately find all vulnerabilities in smart contracts, as the main programming language used to write smart contracts allows many unsafe patterns. For this reason, program analysers are often not part of the development cycle. We propose Flint, a new statically-typed programming language specifically designed for writing robust smart contracts. Flint's features enforce the writing of safe and predictable code. To help programmers reason about access control of functions, we introduce caller capabilities. To prevent vulnerabilities relating to the unintentional loss of currency, Flint Asset types provide safe atomic operations, ensuring the state of contracts is always consistent. Writes to state are restricted, and simplify reasoning about smart contracts. I would like to thank: • Professor Susan Eisenbach and Professor Sophia Drossopoulou, for introducing me to Ethereum, for their amazing continuous support, and for the invaluable insight they have shared with me on designing a programming language and on writing academic papers, • the Department of Computing, for funding my trip to the 2nd International Conference on the Art, Science, and Engineering of Programming, • Paul Liétar, for the great discussions about linear type systems, which led to the development of Flint's Asset types, • Malina, Saurav, Daniel, and Amin, for being exceptional friends, • and of course, my parents, who have always given me the opportunity to pursue my dreams. 2.1. Ethereum, a Smart Contracts Platform Record Account types Description balance All The number of Wei owned by the account. storageRoot Smart contracts Keccak-256 hash of Merkle Patricia's tree root used to encode the contract's internal storage. codeHash Smart contracts Keccak-256 hash of the account's bytecode. Figure 2.1: Ethereum Account States (Omitting Certain Fields) 2.1.1 Currency and Gas The Ethereum platform provides its own currency, Ether, which can be used to reflect the value of goods and services. There are a variety of denominations of Ether, the smallest one being a Wei. 1 Wei is 10 −18 Ether. When referring to Ether in Ethereum transactions, the Wei denomination is used. Users also use Ether to purchase gas, required to pay for computational costs when executing transactions (see subsection 2.1.5). The amount of gas required to execute a function depends on its computational cost. 2.1.2 Cryptography and Addresses The Keccak-256 [28] cryptographic hashing algorithm is used throughout the Ethereum platform. Keccak-256 was a proposed implementation of the Secure Hash Algorithm 3 [29] (SHA-3), but was not the final implementation of SHA-3 (FIPS-202), which differs slightly. Users and smart contracts are identified by their Ethereum address, which is a 160-bit integer. Addresses are usually represented in hexadecimal format. 2.1.3 Accounts and Account States Information about accounts is stored by every miner in the Ethereum network. There are two types of accounts on Ethereum: Externally owned accounts (EOAs). These are controlled by private keys. Creating an EOA involves generating a private key (a 256-bit integer) and computing the corresponding address by using a combination of the Elliptic Curve Digital Signature Algorithm [30] (ECSDA) and Keccak-256. Users create EOAs to send Ether to other users and call contract functions, by creating transactions (described in 2.1.5).

Functional specifications describe what program components can do: the sufficient conditions to i... more Functional specifications describe what program components can do: the sufficient conditions to invoke components' operations. They allow us to reason about the use of components in a closed world setting, where components interact with known client code, and where the client code must establish the appropriate preconditions before calling into a component. Sufficient conditions are not enough to reason about the use of components in an open world setting, where components interact with external code, possibly of unknown provenance, and where components may evolve over time. In this open world setting, we must also consider the necessary conditions, i.e. what are the conditions without which an effect will not happen. In this paper we propose the Chainmail specification language for writing holistic specifications that focus on necessary conditions (as well as sufficient conditions). We give a formal semantics for Chainmail, and discuss several examples. The core of Chainmail has been mechanised in the Coq proof assistant.

Even Haskell programs can occasionally go wrong. Programs calling head on an empty list, and inco... more Even Haskell programs can occasionally go wrong. Programs calling head on an empty list, and incomplete patterns in function definitions can cause program crashes, reporting little more than the precise location where error was ultimately called. Being told that one application of the head function in your program went wrong, without knowing which use of head went wrong can be infuriating. We present our work on adding the ability to get stack traces out of GHC, for example that our crashing head was used during the evaluation of foo, which was called during the evaluation of bar , during the evaluation of main. We provide a transformation that converts GHC Core programs into ones that pass a stack around, and a stack library that ensures bounded heap usage despite the highly recursive nature of Haskell. We call our extension to GHC StackTrace. Categories and Subject Descriptors D.3.2 [Programming Languages]: Language Classifications-Haskell short description of paper 1 2009/5/14 1 Several of the example functions used have primes (') suffixed on. Because of a currently unresolved bootstrapping issue, it is challenging to recompile all the standard libraries with our transform turned on, so we have just rewritten a few standard prelude functions and rebuilt them (with the exception of error , which is discussed later). short description of paper 2 2009/5/14

SIMD (Single Instruction, Multiple Data) instruction sets are ubiquitous on modern hardware, but ... more SIMD (Single Instruction, Multiple Data) instruction sets are ubiquitous on modern hardware, but rarely used in software projects. A major reason for this is that efficient SIMD code requires data to be laid out in memory in an unconventional manner, forcing developers to explicitly refactor their code and data structures in order to make use of SIMD. In previous work, we proposed SHAPES, an abstract layout specification for enabling memory optimisations for managed, object-oriented languages. In this paper, we explain how, by extending SHAPES with well-known constructs from the literature, which are not specific to SIMD, we can extend SHAPES to compile programs to use SIMD instructions. The resulting language (sketch) seems able to exploit SIMD capabilities without sacrificing ease of development. 2018/6/26 26 __m128 pz = _mm_loadu_ps(&arr->pz[i]); 27 28 __m128 x2 = _mm_add_ps(x, x); 29 __m128 y2 = _mm_add_ps(y, y); 30 __m128 z2 = _mm_add_ps(z, z); 31 __m128 xx2 = _mm_mul_ps(x, x2); 32 __m128 yy2 = _mm_mul_ps(y, y2); 33 __m128 zz2 = _mm_mul_ps(z, z2); 34 35 __m128 xy2 = _mm_mul_ps(x, y2); 36 __m128 wz2 = _mm_mul_ps(w, z2); 37 __m128 xz2 = _mm_mul_ps(x, z2); 38 __m128 wy2 = _mm_mul_ps(w, y2); 39 __m128 yz2 = _mm_mul_ps(y, z2); 40 __m128 wx2 = _mm_mul_ps(w, x2); 41 42 __m128 a11 = _mm_sub_ps(_mm_sub_ps(ONES, yy2), zz2); 43 __m128 a12 = _mm_add_ps(xy2, wz2); 44 __m128 a13 = _mm_sub_ps(xz2, wy2); 45 __m128 a21 = _mm_sub_ps(xy2, wz2); 46 __m128 a22 = _mm_sub_ps(_mm_sub_ps(ONES, xx2), zz2);
Proceedings of the ACM on programming languages, Jul 26, 2019
Type family applications in Haskell must be fully saturated. This means that all type-level funct... more Type family applications in Haskell must be fully saturated. This means that all type-level functions have to be first-order, leading to code that is both messy and longwinded. In this paper we detail an extension to GHC that removes this restriction. We augment Haskell's existing type arrow, →, with an unmatchable arrow, ↠, that supports partial application of type families without compromising soundness. A soundness proof is provided. We show how the techniques described can lead to substantial code-size reduction (circa 80%) in the type-level logic of commonly-used type-level libraries whilst simultaneously improving code quality and readability. CCS Concepts: • Software and its engineering → Functional languages; Polymorphism; Data types and structures; Reusability.
Proceedings of the ACM on Programming Languages
Robust modules guarantee to do only what they are supposed to do – even in the presence of untrus... more Robust modules guarantee to do only what they are supposed to do – even in the presence of untrusted malicious clients, and considering not just the direct behaviour of individual methods, but also the emergent behaviour from calls to more than one method. Necessity is a language for specifying robustness, based on novel necessity operators capturing temporal implication, and a proof logic that derives explicit robustness specifications from functional specifications. Soundness and an exemplar proof are mechanised in Coq.
Zenodo (CERN European Organization for Nuclear Research), Sep 17, 2022
Robust modules guarantee to do only what they are supposed to do-even in the presence of untruste... more Robust modules guarantee to do only what they are supposed to do-even in the presence of untrusted, malicious clients, and considering not just the direct behaviour of individual methods, but also the emergent behaviour from calls to more than one method. Necessity is a language for specifying robustness, based on novel necessity operators capturing temporal implication, and a proof logic that derives explicit robustness specifications from functional specifications. Soundness and an exemplar proof are mechanised in Coq. CCS Concepts: • Software and its engineering → General programming languages.

If a library designer takes full advantage of HaskellÆs rich type system and type-level programmi... more If a library designer takes full advantage of HaskellÆs rich type system and type-level programming capabilities, then the resulting library will frequently inflict huge and unhelpful error messages on the library user. These error messages are typically in terms of the library and do not refer to the call-site of the library by the library user, nor provide any guidance to the user as to how to fix the error. The increasing appetite for programmable type-level computation makes this a critical issue, as the advantages and capabilities of type-level computation are nullified if useful error messages cannot be returned to the user. We present a novel technique that neatly side-steps the default error messages and allows the library programmer to control the generation of error messages that are statically returned to the user. Thus with this technique, there is no longer any drawback to using the full power of HaskellÆs type system.
Uploads
Papers by Susan Eisenbach