Levity Polymorphism Richard A

Total Page:16

File Type:pdf, Size:1020Kb

Levity Polymorphism Richard A Bryn Mawr College Scholarship, Research, and Creative Work at Bryn Mawr College Computer Science Faculty Research and Computer Science Scholarship 2017 Levity Polymorphism Richard A. Eisenberg Bryn Mawr College, [email protected] Simon Peyton Jones Microsoft Research, Cambridge, [email protected] Let us know how access to this document benefits ouy . Follow this and additional works at: http://repository.brynmawr.edu/compsci_pubs Part of the Programming Languages and Compilers Commons Custom Citation R.A. Eisenberg and S. Peyton Jones 2017. "Levity Polymorphism." Proceeding PLDI 2017 Proceedings of the 38th ACM SIGPLAN Conference on Programming Language Design and Implementation: 525-539. This paper is posted at Scholarship, Research, and Creative Work at Bryn Mawr College. http://repository.brynmawr.edu/compsci_pubs/69 For more information, please contact [email protected]. Levity Polymorphism Richard A. Eisenberg Simon Peyton Jones Bryn Mawr College, Bryn Mawr, PA, USA Microsoft Research, Cambridge, UK [email protected] [email protected] Abstract solves the problem, but it is terribly slow (Section 2.1). Thus Parametric polymorphism is one of the linchpins of modern motivated, most polymorphic languages also support some typed programming, but it comes with a real performance form of unboxed values that are represented not by a pointer penalty. We describe this penalty; offer a principled way to but by the value itself. For example, the Glasgow Haskell reason about it (kinds as calling conventions); and propose Compiler (GHC), a state of the art optimizing compiler for levity polymorphism. This new form of polymorphism allows Haskell, has supported unboxed values for decades. abstractions over calling conventions; we detail and verify But unboxed values come at the price of convenience restrictions that are necessary in order to compile levity- and re-use (Section 3). In this paper we describe an elegant polymorphic functions. Levity polymorphism has created new approach to reconciling high performance code with new opportunities in Haskell, including the ability to general- pervasive polymorphism. Our contributions are these: ize nearly half of the type classes in GHC’s standard library. • We present (Section 4) a principled way to reason about CCS Concepts • Software and its engineering ! Poly- compiling polymorphic functions and datatypes. Types morphism; Compilers; Functional languages are categorized into kinds, where each kind describes the Keywords unboxed types, compilation, polymorphism memory layout of its types. Thus the kind determines the calling convention of functions over its types. 1. The Cost of Polymorphism • Having a principled way to describe memory layout and Consider the following Haskell function: calling convention, we go one step further and embrace levity polymorphism, allowing functions to be abstracted bTwice :: 8 a: Bool ! a ! (a ! a) ! a over choices of memory layout provided that they never bTwice b x f = case b of True ! f (f x) move or store data with an abstract representation (Section False ! x 5). We believe we are the first to describe and implement The function is polymorphic1 in a; that is, the same function levity polymorphism. works regardless of the type of x, provided f and x are • It is tricky to be sure precisely when levity polymorphism compatible. When we say “the same function” we usually is permissible. We give a formal proof that our rules mean “the same compiled code for bTwice works for any guarantee that levity-polymorphic functions can indeed be type of argument x”. But the type of x influences the calling compiled into concrete code (Section 6). Along the way, convention, and hence the executable code for bTwice! For we were surprised to be unable to find any prior literature example, if x were a list, it would be passed in a register proving that the widespread technique of compiling via A- pointing into the heap; if it were a double-precision float, it normal form [7] is semantics-preserving. A key part of that would be passed in a special floating-point register; and so proof (unrelated to levity polymorphism) is challenging, on. Thus, sharing code conflicts with polymorphism. and we leave it as an open problem (Section 6.4). A simple and widely-used solution is this: represent every • With levity polymorphism in hand, new possibilities open value uniformly, as a pointer to a heap-allocated object. That up—including the ability to write an informative kind 1 We use the term polymorphism to refer to parametric polymorphism only. for (!) and to overload operations over both boxed and unboxed types. We explore these in Section 7. We are not the first to use kinds in this way (see Section 9), but we take the idea much further than any other compiler we know, with happy consequences. Levity polymorphism does not make code go faster; rather, it makes highly-performant code more convenient to write and more re-usable. Levity [Copyright notice will appear here once ’preprint’ option is removed.] polymorphism is implemented in GHC 8.0.1. 1 2017/4/14 2. Background: Performance through Boxed Unboxed Int Unboxed Types Lifted Bool We begin by describing the performance challenges that our Int paper tackles. We use the language Haskell2 and the compiler Unlifted ByteArray # # Char GHC as a concrete setting for this discussion, but many of # our observations apply equally to other languages supporting polymorphism. We discuss other languages and compilers in Figure 1. Boxity and levity, with examples Section 9. them. Given these unboxed values, the boxed versions can be 2.1 Unboxed Values defined in Haskell itself; GHC does not treat them specially. Consider this loop, which computes the sum of the integers For example: 1 :: n: data Int = I# Int# sumTo :: Int ! Int ! Int plusInt :: Int ! Int ! Int sumTo acc 0 = acc plusInt (I i )(I i ) = I (i + i ) sumTo acc n = sumTo (acc + n)(n − 1) # 1 # 2 # 1 # 2 Here Int is an ordinary algebraic data type, with one data GHC represents values of type Int as a pointer to a two-word constructor I , that has one field of type Int . The function heap-allocated cell; the first word is a descriptor, while the # # plusInt simply pattern matches on its arguments, fetches their second has the actual value of the Int. If sumTo used this contents (i and i , both of type Int ), adds them using (+ ), representation throughout, it would be unbearably slow. Each 1 2 # # and boxes the result with I . iteration would evaluate its second argument,3 follow the # pointer to get the value, and test it against zero; in the non- 2.2 Boxed vs. Unboxed and Lifted vs. Unlifted zero case it would allocate thunks for (acc + n) and (n − 1), and then iterate. In contrast, a C compiler would use a three- In general, a boxed value is represented by a pointer into the machine-instruction loop, with no memory traffic whatsoever. heap, while an unboxed value is represented by the value The performance difference is enormous. For this loop, on a itself. It follows that an unboxed value cannot be a thunk; typical machine 10,000,000 iterations executes in less than arguments of unboxed type can only be passed by value. 0.01s when using unboxed Ints, but takes more 2s when using Haskell also requires consideration of levity—that is, the boxed integers. choice between lifted and unlifted. A lifted type is one that is For performance-critical code, GHC therefore allows lazy. It is considered lifted because it has one extra element the programmer to write code over explicitly-unboxed val- beyond the usual ones, representing a non-terminating com- ues [20]. For example, GHC provides a built-in data type putation. For example, Haskell’s Bool type is lifted, meaning that three Bools are possible: True, False, and ?. An unlifted Int# of unboxed integers [20], represented not by a pointer but by the integer itself. Now we can rewrite sumTo like this4 type, on the other hand, is strict. The element ? does not exist in an unlifted type. sumTo# :: Int# ! Int# ! Int# Because Haskell represents lazy computation as a heap- sumTo# acc 0# = acc allocated thunk, all lifted types must also be boxed. However, sumTo# acc n = sumTo# (acc +# n)(n −# 1#) it is possible to have boxed, unlifted types. Figure 1 summa- We had to use different arithmetic operations and literals, but rizes the relationship between boxity and levity, providing apart from that the source code looks just the same. But the examples of the three possible points in the space. compiled code is very different; we get essentially the same code as if we had written it in C. 2.3 Unboxed Tuples GHC’s strictness analyzer and other optimizations can of- Along with the unboxed primitive types (such as Int# and ten transform sumTo into sumTo#. But it cannot guarantee Double#), Haskell has support for unboxed tuples. A normal, to do so, so performance-conscious programmers often pro- boxed tuple—of type, say, (Int; Bool)—is represented by a gram with unboxed values directly. As well as Int#, GHC heap-allocated vector of pointers to the elements of the tuple. provides a range of other unboxed types, such as Char#, and Accordingly, all elements of a boxed tuple must also be boxed. Double#, together with primitive operations that operate on Boxed tuples are also lazy, although this aspect of the design is a free choice. 2 GHC extends Haskell in many ways to better support high-performance Originally conceived to support returning multiple values code, so when we say “Haskell” we will always mean “GHC Haskell”. from a function, an unboxed tuple is merely Haskell syntax 3 Haskell is a lazy language, so the second argument might not be evaluated.
Recommended publications
  • Structured Recursion for Non-Uniform Data-Types
    Structured recursion for non-uniform data-types by Paul Alexander Blampied, B.Sc. Thesis submitted to the University of Nottingham for the degree of Doctor of Philosophy, March 2000 Contents Acknowledgements .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 1 Chapter 1. Introduction .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 2 1.1. Non-uniform data-types .. .. .. .. .. .. .. .. .. .. .. .. 3 1.2. Program calculation .. .. .. .. .. .. .. .. .. .. .. .. .. 10 1.3. Maps and folds in Squiggol .. .. .. .. .. .. .. .. .. .. .. 11 1.4. Related work .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 14 1.5. Purpose and contributions of this thesis .. .. .. .. .. .. .. 15 Chapter 2. Categorical data-types .. .. .. .. .. .. .. .. .. .. .. .. 18 2.1. Notation .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 19 2.2. Data-types as initial algebras .. .. .. .. .. .. .. .. .. .. 21 2.3. Parameterized data-types .. .. .. .. .. .. .. .. .. .. .. 29 2.4. Calculation properties of catamorphisms .. .. .. .. .. .. .. 33 2.5. Existence of initial algebras .. .. .. .. .. .. .. .. .. .. .. 37 2.6. Algebraic data-types in functional programming .. .. .. .. 57 2.7. Chapter summary .. .. .. .. .. .. .. .. .. .. .. .. .. 61 Chapter 3. Folding in functor categories .. .. .. .. .. .. .. .. .. .. 62 3.1. Natural transformations and functor categories .. .. .. .. .. 63 3.2. Initial algebras in functor categories .. .. .. .. .. .. .. .. 68 3.3. Examples and non-examples .. .. .. .. .. .. .. .. .. .. 77 3.4. Existence of initial algebras in functor categories .. .. .. .. 82 3.5.
    [Show full text]
  • Safe, Flexible Aliasing with Deferred Borrows Chris Fallin Mozilla1, Mountain View, CA, USA [email protected]
    Safe, Flexible Aliasing with Deferred Borrows Chris Fallin Mozilla1, Mountain View, CA, USA [email protected] Abstract In recent years, programming-language support for static memory safety has developed significantly. In particular, borrowing and ownership systems, such as the one pioneered by the Rust language, require the programmer to abide by certain aliasing restrictions but in return guarantee that no unsafe aliasing can ever occur. This allows parallel code to be written, or existing code to be parallelized, safely and easily, and the aliasing restrictions also statically prevent a whole class of bugs such as iterator invalidation. Borrowing is easy to reason about because it matches the intuitive ownership-passing conventions often used in systems languages. Unfortunately, a borrowing-based system can sometimes be too restrictive. Because borrows enforce aliasing rules for their entire lifetimes, they cannot be used to implement some common patterns that pointers would allow. Programs often use pseudo-pointers, such as indices into an array of nodes or objects, instead, which can be error-prone: the program is still memory-safe by construction, but it is not logically memory-safe, because an object access may reach the wrong object. In this work, we propose deferred borrows, which provide the type-safety benefits of borrows without the constraints on usage patterns that they otherwise impose. Deferred borrows work by encapsulating enough state at creation time to perform the actual borrow later, while statically guaranteeing that the eventual borrow will reach the same object it would have otherwise. The static guarantee is made with a path-dependent type tying the deferred borrow to the container (struct, vector, etc.) of the borrowed object.
    [Show full text]
  • The Rust Programming Language
    The Rust Programming Language The Rust Programming Language The Rust Project Developpers The Rust Programming Language, © The Rust Project Developpers. Contents I Introduction 7 1 The Rust Programming Language 9 II Getting Started 11 1 Getting Started 13 2 Installing Rust 15 3 Hello, world! 17 4 Hello, Cargo! 21 5 Closing Thoughts 25 III Tutorial: Guessing Games 27 1 Guessing Game 29 2 Set up 31 3 Processing a Guess 33 4 Generating a secret number 37 5 Comparing guesses 41 6 Looping 45 7 Complete! 49 IV Syntax and Semantics 51 1 Syntax and Semantics 53 V Effective Rust 159 1 Effective Rust 161 VI Appendix 243 1 Glossary 245 2 Syntax Index 247 3 Bibliography 253 6 Part I Introduction Chapter 1 The Rust Programming Language Welcome! This book will teach you about the Rust Programming Language. Rust is a systems programming language focused on three goals: safety, speed, and concurrency. It maintains these goals without having a garbage collector, making it a useful language for a number of use cases other languages aren’t good at: embedding in other languages, programs with specific space and time requirements, and writing low-level code, like device drivers and operating systems. It improves on current languages targeting this space by having a number of compile-time safety checks that produce no runtime overhead, while eliminating all data races. Rust also aims to achieve ‘zero-cost abstractions’ even though some of these abstractions feel like those of a high-level language. Even then, Rust still allows precise control like a low-level language would.
    [Show full text]
  • Practical Type Inference for Polymorphic Recursion: an Implementation in Haskell
    Practical Type Inference for Polymorphic Recursion: an Implementation in Haskell Cristiano Vasconcellos1 , Luc´ılia Figueiredo2 , Carlos Camarao˜ 3 1Departamento de Informatica,´ Pontif´ıcia Universidade Catolica´ do Parana,´ Curitiba, PR. 2Departamento de Computac¸ao,˜ Universidade Federal de Ouro Preto, Ouro Preto, MG. 3Departamento de Cienciaˆ da Computac¸ao,˜ Universidade Federal de Minas Gerais, Belo Horizonte, MG. [email protected],[email protected],[email protected] Abstract. This paper describes a practical type inference algorithm for typing polymorphic and possibly mutually recursive definitions, using Haskell to pro- vide a high-level implementation of the algorithm. Keywords: Programming Languages, Type Inference, Polymorphic Recursion 1. Introduction In general, polymorphic recursion occurs in functions defined over nested (also called non-uniform or non-regular) data types, i.e. data types whose definitions include a re- cursive component that is not identical to the type being defined. Several examples of such data types and interesting functions that operate on them have been presented [Connelly and Morris, 1995, Okasaki, 1997, Okasaki, 1998, Bird and Meertens, 1998]. Languages with support for parametric polymorphism [Milner, 1978, Damas and Milner, 1982], such as Haskell [Jones et al., 1998, Thompson, 1999] and SML [Milner et al., 1989], use one of the following two approaches for the treatment of recursive definitions. The first approach imposes a restriction on recursive definitions, either consider- ing recursive definitions to be monomorphic (as in e.g. SML), or allowing polymorphic recursion only when the programmer explicitly annotates the polymorphic types (as in e.g. Haskell). In this approach, the language processor front-end separates the definitions occurring in a program into non-mutually recursive binding groups, by examining the pro- gram’s call graph, and performs a topological sort of these binding groups for determining an order in which to type the definitions.
    [Show full text]
  • Quantified Types in an Imperative Language
    Quantified Types in an Imperative Language DAN GROSSMAN University of Washington We describe universal types, existential types, and type constructors in Cyclone, a strongly-typed C-like language. We show how the language naturally supports first-class polymorphism and polymorphic recursion while requiring an acceptable amount of explicit type information. More importantly, we consider the soundness of type variables in the presence of C-style mutation and the address-of operator. For polymorphic references, we describe a solution more natural for the C level than the ML-style “value restriction.” For existential types, we discover and subsequently avoid a subtle unsoundness issue resulting from the address-of operator. We develop a formal abstract machine and type-safety proof that captures the essence of type variables at the C level. Categories and Subject Descriptors: D.3.3 [Programming Languages]: Language Constructs and Features—abstract data types, polymorphism; F.3.3 [Logics and Meanings of Programs]: Studies of Program Constructs—type structure; F.3.2 [Logics and Meanings of Programs]: Se- mantics of Programming Languages—operational semantics; D.3.1 [Programming Languages]: Formal Definitions and Theory General Terms: Languages, Theory, Verification Additional Key Words and Phrases: Cyclone, existential types, polymorphism, type variables 1. INTRODUCTION Strongly typed programming languages prevent certain programming errors and provide a way for users to enforce abstractions (e.g., at interface boundaries). In- evitably, strong typing prohibits some correct programs, but an expressive type system reduces the limitations. In particular, universal (i.e., polymorphic) types let code operate uniformly over many types of data, and data-hiding constructs (such as closures and objects) let users give the same type to data with some com- ponents of different types.
    [Show full text]
  • Region-Based Memory Management in Cyclone ∗
    Region-Based Memory Management in Cyclone ∗ Dan Grossman Greg Morrisett Trevor Jim† Michael Hicks Yanling Wang James Cheney † Computer Science Department AT&T Labs Research Cornell University 180 Park Avenue Ithaca, NY 14853 Florham Park, NJ 07932 {danieljg,jgm,mhicks,wangyl,jcheney}@cs.cornell.edu [email protected] ABSTRACT control over data representation (e.g., field layout) and re- Cyclone is a type-safe programming language derived from source management (e.g., memory management). The de C. The primary design goal of Cyclone is to let program- facto language for coding such systems is C. However, in mers control data representation and memory management providing low-level control, C admits a wide class of danger- without sacrificing type-safety. In this paper, we focus on ous — and extremely common — safety violations, such as the region-based memory management of Cyclone and its incorrect type casts, buffer overruns, dangling-pointer deref- static typing discipline. The design incorporates several ad- erences, and space leaks. As a result, building large systems vancements, including support for region subtyping and a in C, especially ones including third-party extensions, is per- coherent integration with stack allocation and a garbage col- ilous. Higher-level, type-safe languages avoid these draw- lector. To support separate compilation, Cyclone requires backs, but in so doing, they often fail to give programmers programmers to write some explicit region annotations, but the control needed in low-level systems. Moreover, porting a combination of default annotations, local type inference, or extending legacy code is often prohibitively expensive. and a novel treatment of region effects reduces this burden.
    [Show full text]
  • Region Inference for an Object-Oriented Language
    Region Inference for an Object-Oriented Language £ £ ¤¡ £ ¥ Wei-Ngan Chin ¢¡ , Florin Craciun , Shengchao Qin , and Martin Rinard Computer Science Programme, Singapore-MIT Alliance £ Department of Computer Science, National University of Singapore ¥ Laboratory for Computer Science, Massachusetts Institute of Technology ¦ chinwn,craciunm,qinsc § @comp.nus.edu.sg, [email protected] ABSTRACT time tests for danglings can be omitted. Region-based memory management offers several important ad- There are two main approaches to prevent unsafe accesses. One vantages over garbage-collected heap, including real-time perfor- approach[12] uses a type-and-effect system to analyse regions that mance, better data locality and efficient use of limited memory. The might be accessed, so that those regions that are not being accessed concept of regions was first introduced for a call-by-value func- can be deallocated earlier, even if there are dangling references tional language by Tofte and Talpin, and has since been advocated to these regions. Another approach[8] prevents all potential dan- for imperative and object-oriented languages. Scope memory, a gling references (from older to younger regions) by ensuring that lexical variant of regions, is now a core feature in a recent proposal each object always point-to other objects in regions with equal or longer lifetimes. The former approach (no-dangling-access) may on Real-Time Specification for Java (RTSJ)[4]. 1 Recent works in region-based programming for Java have fo- yield more precise lifetimes , but the latter approach (no-dangling) cused on region-checking which requires manual effort in choos- is required by RTSJ and for co-existence with garbage collection.
    [Show full text]
  • Scala Implicits Are Everywhere a Large-Scale Study of the Use of Scala Implicits in the Wild
    Scala Implicits Are Everywhere A Large-Scale Study of the Use of Scala Implicits in the Wild FILIP KŘIKAVA, Czech Technical University in Prague, CZ HEATHER MILLER, Carnegie Mellon University, USA JAN VITEK, Czech Technical University in Prague and Northeastern University, USA The Scala programming language offers two distinctive language features implicit parameters and implicit conversions, often referred together as implicits. Announced without fanfare in 2004, implicits have quickly grown to become a widely and pervasively used feature of the language. They provide a way to reduce the boilerplate code in Scala programs. They are also used to implement certain language features without having to modify the compiler. We report on a large-scale study of the use of implicits in the wild. For this, we analyzed 7,280 Scala projects hosted on GitHub, spanning over 8.1M call sites involving implicits and 370.7K 163 implicit declarations across 18.7M lines of Scala code. CCS Concepts: • Software and its engineering → Language features; General programming languages. Additional Key Words and Phrases: Implicit parameters, implicit conversions, corpora analysis, Scala ACM Reference Format: Filip Křikava, Heather Miller, and Jan Vitek. 2019. Scala Implicits Are Everywhere: A Large-Scale Study of the Use of Scala Implicits in the Wild. Proc. ACM Program. Lang. 3, OOPSLA, Article 163 (October 2019), 28 pages. https://doi.org/10.1145/3360589 1 INTRODUCTION “...experienced users claim that code bases are train wrecks because of overzealous use of implicits.” –M. Odersky, 2017 “...can impair readability or introduce surprising behavior, because of a subtle chain of inference.” –A. Turon, 2017 “Any sufficiently advanced technology is indistinguishable from magic.” –A.C.
    [Show full text]
  • A Polymorphic Aspect-Oriented Functional Programming Language
    Aspectml: A polymorphic aspect-oriented functional programming language DANIEL S. DANTAS and DAVID WALKER Princeton University fddantas,[email protected] and GEOFFREY WASHBURN and STEPHANIE WEIRICH University of Pennsylvania fgeoffw,[email protected] This paper defines Aspectml, a typed functional, aspect-oriented programming language. The main contribution of Aspectml is the seamless integration of polymorphism, run-time type analysis and aspect-oriented programming language features. In particular, Aspectml allows programmers to define type-safe polymorphic advice using pointcuts constructed from a collection of polymorphic join points. Aspectml also comes equipped with a type inference algorithm that conservatively extends Hindley-Milner type inference. To support first-class polymorphic point-cut designators, a crucial feature for developing aspect-oriented profiling or logging libraries, the algorithm blends the conventional Hindley-Milner type inference algorithm with a simple form of local type inference. We give our language operational meaning via a type-directed translation into an expressive type-safe intermediate language. Many complexities of the source language are eliminated in this translation, leading to a modular specification of its semantics. One of the novelties of the intermediate language is the definition of polymorphic labels for marking control-flow points. When a set of labels is assembled as a pointcut, the type of each label is an instance of the type of the pointcut. Categories and Subject Descriptors:
    [Show full text]
  • Practical Type Inference for Polymorphic Recursion: an Implementation in Haskell
    Journal of Universal Computer Science, vol. 9, no. 8 (2003), 873-890 submitted: 24/2/03, accepted: 30/5/03, appeared: 28/8/03 J.UCS Practical Type Inference for Polymorphic Recursion: an Implementation in Haskell Cristiano Vasconcellos (Pontif´ıcia Universidade Cat´olica do Paran´a, Brazil [email protected]) Luc´ılia Figueiredo (Universidade Federal de Ouro Preto, Brazil [email protected]) Carlos Camar˜ao (Universidade Federal de Minas Gerais, Brazil [email protected]) Abstract This paper describes a practical type inference algorithm for typing poly- morphic and possibly mutually recursive definitions, using Haskell to provide a high- level implementation of the algorithm. Key Words: Programming Languages, Type Inference, Polymorphic Recursion Category: D.3, D.3.3 1 Introduction In general, polymorphic recursion occurs in functions defined over nested (also called non-uniform or non-regular) data types, i.e. data types whose definitions include a recursive component that is not identical to the type being defined. Sev- eral examples of such data types and interesting functions that operate on them have been presented [Connelly and Morris, 1995, Okasaki, 1997, Okasaki, 1998, Bird and Meertens, 1998]. Languages such as Haskell [Jones et al., 1998, Thompson, 1999] and SML [Milner et al., 1989], with support for parametric polymorphism [Milner, 1978, Damas and Milner, 1982], use one of the following two approaches for the treat- ment of recursive definitions. The first approach imposes a restriction on recursive definitions, either con- sidering recursive definitions to be monomorphic (as for example in SML), or allowing polymorphic recursion only when the programmer explicitly annotates the polymorphic types (as for example in Haskell).
    [Show full text]
  • X10 Language Specification
    X10 Language Specification Version 2.5 Vijay Saraswat, Bard Bloom, Igor Peshansky, Olivier Tardieu, and David Grove Please send comments to [email protected] December 3, 2014 This report provides a description of the programming language X10. X10 is a class- based object-oriented programming language designed for high-performance, high- productivity computing on high-end computers supporting ≈ 105 hardware threads and ≈ 1015 operations per second. X10 is based on state-of-the-art object-oriented programming languages and deviates from them only as necessary to support its design goals. The language is intended to have a simple and clear semantics and be readily accessible to mainstream OO pro- grammers. It is intended to support a wide variety of concurrent programming idioms. The X10 design team consists of David Cunningham, David Grove, Ben Herta, Vijay Saraswat, Avraham Shinnar, Mikio Takeuchi, Olivier Tardieu. Past members include Shivali Agarwal, Bowen Alpern, David Bacon, Raj Barik, Ganesh Bikshandi, Bob Blainey, Bard Bloom, Philippe Charles, Perry Cheng, Christopher Donawa, Julian Dolby, Kemal Ebcioglu,˘ Stephen Fink, Robert Fuhrer, Patrick Gallop, Christian Grothoff, Hiroshi Horii, Kiyokuni Kawachiya, Allan Kielstra, Sreedhar Ko- dali, Sriram Krishnamoorthy, Yan Li, Bruce Lucas, Yuki Makino, Nathaniel Nystrom, Igor Peshansky, Vivek Sarkar, Armando Solar-Lezama, S. Alexander Spoon, Toshio Suganuma, Sayantan Sur, Toyotaro Suzumura, Christoph von Praun, Leena Unnikrish- nan, Pradeep Varma, Krishna Nandivada Venkata, Jan Vitek, Hai Chuan Wang, Tong Wen, Salikh Zakirov, and Yoav Zibin. For extended discussions and support we would like to thank: Gheorghe Almasi, Robert Blackmore, Rob O’Callahan, Calin Cascaval, Norman Cohen, Elmootaz El- nozahy, John Field, Kevin Gildea, Chulho Kim, Orren Krieger, Doug Lea, John Mc- Calpin, Paul McKenney, Josh Milthorpe, Andrew Myers, Filip Pizlo, Ram Rajamony, R.
    [Show full text]
  • Unification of Compile-Time and Runtime Metaprogramming in Scala
    Unification of Compile-Time and Runtime Metaprogramming in Scala THÈSE NO 7159 (2017) PRÉSENTÉE LE 6 MARS 2017 À LA FACULTÉ INFORMATIQUE ET COMMUNICATIONS LABORATOIRE DE MÉTHODES DE PROGRAMMATION 1 PROGRAMME DOCTORAL EN INFORMATIQUE ET COMMUNICATIONS ÉCOLE POLYTECHNIQUE FÉDÉRALE DE LAUSANNE POUR L'OBTENTION DU GRADE DE DOCTEUR ÈS SCIENCES PAR Eugene BURMAKO acceptée sur proposition du jury: Prof. J. R. Larus, président du jury Prof. M. Odersky, directeur de thèse Dr D. Syme, rapporteur Prof. S. Tobin-Hochstadt, rapporteur Prof. V. Kuncak, rapporteur Suisse 2017 To future travels. Acknowledgements I would like to heartily thank my advisor Martin Odersky for believing in my vision and trusting me with the autonomy to explore its avenues. It was astonishing to see my work shipped as part of a programming language used by hundreds of thousands of developers, and it would not have been possible without Martin’s encouragement and support. It is my pleasure to thank the members of my thesis jury, Viktor Kunčak, James Larus, Don Syme and Sam Tobin-Hochstadt for their time and insightful comments. I am grateful to my colleagues at EPFL and students whom I supervised during my PhD studies. We hacked many fun things and shared many good times together. My special thanks goes to Denys Shabalin whose relentless passion for excellence shaped our numerous joint projects. A lot of the ideas described in this dissertation were born from discussions and collaborations with Denys. I am continuously humbled by the privilege of being part of the Scala community. During my time at EPFL, I had the chance to work together with Scala enthusiasts all over the world, and that was an amazing experience.
    [Show full text]