Advances in Programming Languages

Similar documents
RustBelt: Securing the Foundations of the Rust Programming Language

CMSC 330: Organization of Programming Languages. Ownership, References, and Lifetimes in Rust

CMSC 330: Organization of Programming Languages

Rust for C++ Programmers

Aaron Turon! Mozilla Research

Index. object lifetimes, and ownership, use after change by an alias errors, use after drop errors, BTreeMap, 309

Region-based Memory Management. Advanced Operating Systems Lecture 10

CS558 Programming Languages

CS558 Programming Languages

The Concept of Ownership in Rust and Swift

Nicholas Matsakis! Mozilla Research

Guaranteeing memory safety in Rust

CS527 Software Security

CSE 307: Principles of Programming Languages

Rust for high level applications. Lise Henry

Rust. A safe, concurrent, practical language. Graydon Hoare October 2012

CS558 Programming Languages

CS 430 Spring Mike Lam, Professor. Data Types and Type Checking

$ cat ~/.profile GIT_AUTHOR_NAME=Florian Gilcher TWITTER_HANDLE=argorak GITHUB_HANDLE=skade BLOG=skade.

Introduction to Rust. CC-BY Mozilla. Jonathan Pallant

Rust: system programming with guarantees

CPSC 3740 Programming Languages University of Lethbridge. Data Types

Rust intro. (for Java Developers) JFokus #jfokus 1. 1

Advances in Programming Languages: Regions

Why you should take a look at

It turns out that races can be eliminated without sacrificing much in terms of performance or expressive power.

Programming Languages (PL)

Structure of Programming Languages Lecture 10

Heap, Variables, References, and Garbage. CS152. Chris Pollett. Oct. 13, 2008.

The Case for Building a Kernel

The Case for N-Body Simulations in Rust

Advances in Programming Languages

Lecture Notes on Memory Layout

Region-Based Memory Management in Cyclone

CS-XXX: Graduate Programming Languages. Lecture 9 Simply Typed Lambda Calculus. Dan Grossman 2012

Applied Unified Ownership. Capabilities for Sharing Across Threads

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

Hoare logic. A proof system for separation logic. Introduction. Separation logic

Short Notes of CS201

CS201 - Introduction to Programming Glossary By

Programming Languages Third Edition. Chapter 7 Basic Semantics

Advances in Programming Languages

Inheritance: Develop solutions by abstracting real-world object and their interaction into code to develop software solutions. Layering: Organization

In Java we have the keyword null, which is the value of an uninitialized reference type

Memory Management and Efficient Graph Processing in Rust

Advances in Programming Languages

Next Gen Networking Infrastructure With Rust

Rely-Guarantee References for Refinement Types over Aliased Mutable Data

CS 330 Lecture 18. Symbol table. C scope rules. Declarations. Chapter 5 Louden Outline

1. true / false By a compiler we mean a program that translates to code that will run natively on some machine.

CMSC 330: Organization of Programming Languages. Memory Management and Garbage Collection

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

Chapter 5. Names, Bindings, and Scopes

Rust Advanced Topics

CSCI-1200 Data Structures Spring 2017 Lecture 27 Garbage Collection & Smart Pointers

CCured. One-Slide Summary. Lecture Outline. Type-Safe Retrofitting of C Programs

Memory Management. Advanced Operating Systems (M) Lecture 3

Advances in Programming Languages

Program Verification (6EC version only)

COMP 181. Agenda. Midterm topics. Today: type checking. Purpose of types. Type errors. Type checking

Operational Semantics. One-Slide Summary. Lecture Outline

QUIZ. What is wrong with this code that uses default arguments?

CS-527 Software Security

'Safe' programming languages

G Programming Languages - Fall 2012

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

Concurrent & Distributed Systems Supervision Exercises

Next Gen Networking Infrastructure With Rust

CS6202: Advanced Topics in Programming Languages and Systems Lecture 0 : Overview

n Closed book n You are allowed 5 cheat pages n Practice problems available in Course Materials n Check grades in Rainbow grades

1: /////////////// 2: // 1. Basics // 3: /////////////// 4: 5: // Functions. i32 is the type for 32-bit signed integers 6: fn add2(x: i32, y: i32) ->

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

Key-value store with eventual consistency without trusting individual nodes

Introduction to Prof. Clarkson Fall Today s music: Prelude from Final Fantasy VII by Nobuo Uematsu (remastered by Sean Schafianski)

CMSC 330: Organization of Programming Languages

CMSC 330: Organization of Programming Languages

Summary: Open Questions:

September 10,

Compiler Construction

G Programming Languages Spring 2010 Lecture 6. Robert Grimm, New York University

Effective Performance Measurement and Analysis of Multithreaded Applications

CS321 Languages and Compiler Design I Winter 2012 Lecture 13

Acknowledgements These slides are based on Kathryn McKinley s slides on garbage collection as well as E Christopher Lewis s slides

G Programming Languages - Fall 2012

CSCI-GA Scripting Languages

Class Information ANNOUCEMENTS

Chapter 8 :: Composite Types

Compiler Construction

CMSC 330: Organization of Programming Languages

Typed Assembly Language for Implementing OS Kernels in SMP/Multi-Core Environments with Interrupts

Ironclad C++ A Library-Augmented Type-Safe Subset of C++

CSE 341, Spring 2011, Final Examination 9 June Please do not turn the page until everyone is ready.

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

CMSC 330: Organization of Programming Languages

Lecture 15a Persistent Memory & Shared Pointers

Simply-Typed Lambda Calculus

TYPES, VALUES AND DECLARATIONS

CSCI-1200 Data Structures Spring 2018 Lecture 25 Garbage Collection & Smart Pointers

Hoare logic. WHILE p, a language with pointers. Introduction. Syntax of WHILE p. Lecture 5: Introduction to separation logic

Informatics 1: Data & Analysis

Transcription:

Advances in Programming Languages Lecture 18: Concurrency and More in Rust Ian Stark School of Informatics The University of Edinburgh Friday 24 November 2016 Semester 1 Week 10 https://blog.inf.ed.ac.uk/apl16

PL News (Maybe): Schiaparelli Landing + 23 November 2016 The European Space Agency have reported initial analysis of extensive telemetry data transmitted during the descent of the ExoMars Schiaparelli lander. It appears that Inertial Measurement Unit reached its maximum output measurement for a full second, longer than would be expected. When merged into the navigation system, the erroneous information generated an estimated altitude that was negative that is, below ground level...... In reality, the vehicle was still at an altitude of around 3.7km

Topic: Programming for Memory Safety The final block of lectures cover features used in the Rust programming language. Introduction: Zero-Cost Abstractions (and their cost) Control of Memory: Ownership Concurrency and more This section of the course is entirely new Rust itself is not that old and I apologise for any consequent lack of polish.

The Rust Programming Language The Rust language is intended as a tool for safe systems programming. Three key objectives contribute to this. Zero-cost abstractions Memory safety Safe concurrency Basic References https://www.rust-lang.org https://blog.rust-lang.org The systems programming motivation resonates with that for imperative C/C++. The safe part draws extensively on techniques developed for functional Haskell and OCaml. Sometimes these align more closely than you might expect, often by overlap between two aims: Precise control for the programmer; Precise information for the compiler.

Previous Homework Watch This Peter O Hearn: Reasoning with Big Code https://is.gd/reasoning_big_code Talk at the Alan Turing Institute about how Facebook is using automatic verification at scale to check code and give feedback to programmers.

Guest Speaker! Probabilistic Programming: What is it and how to improve it? Maria Gorinova University of Edinburgh 3.10pm Tuesday 29 November 2016

Optional: Review and Exam Preparation! The final lecture will be an exam review, principally for single-semester visiting students. Everyone welcome, though. I hope to do another in Semester 2 you arrange it, I ll be there. Past Papers http://blog.inf.ed.ac.uk/apl16/exam#past 2007 2008 2008 2009 2009 2010 2010 2011 2014 2015 Look at the past papers. Pick out a question or lecture topic and nominate it for the review lecture mailing me or posting on Piazza.

Review Traits Any struct or enum in Rust can have methods attached with impl, or implement a suite of several methods to match a trait, with ad-hoc polymorphism. Trait inheritance gives subtyping, and trait bounds refine generics for parameterised structures and polymorphic functions. All is resolved and monomorphised statically at compile time, giving strict checking of sophisticated types with no runtime overhead.

Review Ownership Rust tracks ownership of values using move semantics for the handover of values in assignment, function call and return. Move semantics lets the compiler statically check the lifetime of structured values, both on the stack and in Boxes on the heap. This guarantees memory safety without runtime overhead. Borrowing references makes it possible to live with move semantics. Borrowing mutable references, with multiple-read single-writer, makes for C-like pointer manipulation and precise control of memory.

Object Deconstruction Rust picks apart many of the features that go together to make objects and classes in most other languages. Collecting values with struct Alternate variants with enum Method implementation with impl Ad-hoc polymorphism with method call syntax Interfaces and subtyping with trait Heap allocation with Box Explicit mutability with let mut Call-by-reference with & and &mut With all these we can build our own objects. As well as all kinds of other things.

Object Deconstruction Rust picks apart many of the features that go together to make objects and classes in most other languages. Collecting values with struct Alternate variants with enum Method implementation with impl Ad-hoc polymorphism with method call syntax Interfaces and subtyping with trait Heap allocation with Box Explicit mutability with let mut Call-by-reference with & and &mut With all these we can build our own objects. As well as all kinds of other things.

What Do We Win? The key guarantee in Rust is memory safety. No null pointers. No dangling pointers. No reading unitialised memory. No reading memory after deallocation. No aliasing bugs. No memory leaks. No manual deallocation. All without reference counting, tag words, garbage collection, or other space or time overheads. Everything statically checked and assured by the compiler. Provided you can convince the borrow checker

Trait Objects We even now have enough to manage dynamic dispatch and runtime method selection, instead of the default static dispatch and compile-time monomorphisation. trait HasDimensions { fn height(&self) > i32; fn width(&self) > i32; } fn generic_footprint<t: HasDimensions>(item: T) > i32 { item.height() item.width() } fn dynamic_footprint(item: &HasDimensions) > i32 { item.height() item.width() }

Trait Objects Here item: &HasDimensions is a trait object whose type is not resolved statically, but carries around a method table at runtime for dynamic dispatch. trait HasDimensions { fn height(&self) > i32; fn width(&self) > i32; } fn generic_footprint<t: HasDimensions>(item: T) > i32 { item.height() item.width() } fn dynamic_footprint(item: &HasDimensions) > i32 { item.height() item.width() }

Trait Objects There is an equivalent construction on the heap with trait object Box<&HasDimensions>, which can contain any value implementing the HasDimensions trait. trait HasDimensions { fn height(&self) > i32; fn width(&self) > i32; } fn generic_footprint<t: HasDimensions>(item: T) > i32 { item.height() item.width() } fn dynamic_footprint(item: &HasDimensions) > i32 { item.height() item.width() }

Concurrency Rust offers concurrent programming through its standard thread library. use std::thread; fn print_hello_world () { println!("hello, World!") } fn main(){ let h = thread::spawn(print_hello_world); let _ = h.join(); println!("that went well"); // Pass function to be executed // Wait for completion, discard result // Announce success }

Concurrency Rust threads can be spawned from arbitrary lambdas and closures, not just bare functions, and map directly to OS threads. Features such as thread pools, lightweight tasks, futures, promises, work stealing, data parallelism, are all under development: http://areweconcurrentyet.com/ Rust Win Ownership and move semantics mean each item of data is owned by just one thread at a time. Threads can still share access to data by borrowing references. It s also possible for threads to borrow write access to shared store, using mutable references. The multiple-reader single-writer constraint on borrowing mutable references means that: Concurrent Rust programs never contain data races

Communication Rust provides channels for communication between threads. The channel() function creates a new channel to carry T values and returns a pair (Sender<T>, Receiver<T>). Communication Traits Marker traits help manage shared resources, and are automatically inferred by the compiler. Send identifies types that can be safely transferred between threads. Sync marks types whose references can be safely shared between threads. Sender<T> implements both Clone and Send: the capability to send on a channel can be duplicated and passed around threads. Receiver<T> implements Send but not Clone: only one thread at a time can listen on a channel, although that ability can be transferred. With these Rust statically guarantees multiple-producer single-consumer channel behaviour.

So Much Winning Rust offers: Safe shared memory No dereferencing errors No aliasing bugs No memory leaks No manual deallocation Safe concurrency Shared memory access No data races Value-passing channels No channel input races To do this uses just: strict static typing, default immutability, deconstructed objects, traits, trait bounds, ownership, reference borrowing, lifetime polymorphism, markers traits, a separate unsafe language,...

Rust: Friends Don t Let Friends Skip Leg Day +

Maybe Not So Simple: Reference Counting Even with Box, &T and &mut T it can be hard to build and manipulate complex linked datastructures. That s why Rust provides the following, too. Rc<T> is a reference counted pointer: a runtime counter tracks how many instances of the reference still exist. It can help when there s no certainty which reference will be the last one to be used. Cycles of these will not be deallocated and may leak memory. Rc<T> is not safe to share between threads. Weak<T> is a weak pointer variant of Rc<T>: it will not on its own cause a value to be retained, but if the value is still there it can be accessed. Arc<T> is a version of Rc<T> that can be used across multiple threads, as it has an atomic reference count.

Maybe Not So Simple: Interior Mutability Strict separation between mutable and immutable can be limiting; especially as struct fields cannot be individually mutable. So Rust has some more datatypes to help. Cell<T> provides interior mutability: the contents can be changed with get and set methods, but it s not regarded by the compiler as a mutable reference. Type T must have copy semantics. There is no runtime cost, but Cell<T> can give aliasing errors and invalidate datastructure assumptions and invariants. RefCell<T> provides interior mutability for arbitrary T. Access control is enforced with explicit borrow and borrow_mut functions that use runtime counters and may fail. Mutex<T> provides threadsafe interior mutability: access requires explicit request for a lock. There s no explicit release, as Rust drops this when the lock goes out of scope. RwLock<T> provides threadsafe interior mutability for multiple readers or a single writer, again requiring explicit lock requests.

Maybe Not So Simple: Unsafe + There s also the Unsafe Rust language, in which many of these previous structs are written. That provides raw pointers const T and mut T which can alias, be null, and generally fail to provide the guarantees of Safe Rust. Managing the interface between safe and unsafe is tricky too, as each can only rely on certain things from the other. To find out more, you want this: The Rustonomicon The Dark Arts of Advanced and Unsafe Rust Programming https://doc.rust-lang.org/nomicon

Summary Safe Shared Memory Static checking of ownership and lifetimes, via default immutability and move semantics. Borrowing to allow multiple-reader single-writer behaviour. Guarantees no pointer errors or aliasing bugs, no runtime overhead. Safe Concurrency Ownership tracking guarantees data-race freedom. Safe shared memory, as well as channel-based communication. Splitting Sender<T> from Receiver<T> and using marker traits ensures multiple-producer single-consumer message handling. But at what cost? Complexity, multiplication of concerns, fighting the borrow checker, and skipping leg day?

Guest Speaker! Probabilistic Programming: What is it and how to improve it? Maria Gorinova University of Edinburgh 3.10pm Tuesday 29 November 2016

Guest Lecture: Near, Now! Domain Specific Languages The Xtext Framework Avaloq Guest Lecture Software Design and Modelling Teviot Lecture Theatre 4.10pm Friday 25 November 2016