CMSC 330: Organization of Programming Languages

Similar documents
CMSC 330: Organization of Programming Languages. Rust Basics

CMSC 330: Organization of Programming Languages

CMSC 330: Organization of Programming Languages

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

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

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

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

CMSC 330: Organization of Programming Languages. OCaml Higher Order Functions

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions

CMSC 330: Organization of Programming Languages. Strings, Slices, Vectors, HashMaps in Rust

Rust for C++ Programmers

CMSC330 Spring 2016 Midterm #1 9:30am/12:30pm/3:30pm

Introduction to OCaml

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

Nicholas Matsakis! Mozilla Research

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

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

Rust Advanced Topics

Next Gen Networking Infrastructure With Rust

CMSC 330, Fall 2013, Practice Problems 3

CMSC330 Spring 2016 Midterm #1 9:30am/12:30pm/3:30pm Solution

CMSC 330, Fall 2018 Midterm 1

Rust: system programming with guarantees

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

CS Lecture 6: Map and Fold. Prof. Clarkson Spring Today s music: Selections from the soundtrack to 2001: A Space Odyssey

CMSC 330, Fall 2013, Practice Problem 3 Solutions

CMSC 330, Fall 2018 Midterm 1

Introduction to Rust 2 / 101

Programming In Rust. Jim Blandy, / Portland, (Slides are as presented; followup discussion,

CSCI-GA Scripting Languages

CompSci 220. Programming Methodology 12: Functional Data Structures

CSE341, Spring 2013, Final Examination June 13, 2013

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

CMSC 330: Organization of Programming Languages

Functions. Nate Foster Spring 2018

Advances in Programming Languages

Introduction to Rust. CC-BY Mozilla. Jonathan Pallant

Dialects of ML. CMSC 330: Organization of Programming Languages. Dialects of ML (cont.) Features of ML. Functional Languages. Features of ML (cont.

Next Gen Networking Infrastructure With Rust

CS Lecture 6: Map and Fold. Prof. Clarkson Fall Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Type Soundness. Type soundness is a theorem of the form If e : τ, then running e never produces an error

PyCon Otto 6-9 April 2017 Florence. Rusty Python. Rust, a new language for our programmer tool belt. Matteo

Background. CMSC 330: Organization of Programming Languages. Useful Information on OCaml language. Dialects of ML. ML (Meta Language) Standard ML

Recap: Functions as first-class values

CMSC 330: Organization of Programming Languages. Operational Semantics

INF121: Functional Algorithmic and Programming

CSci 4223 Lecture 12 March 4, 2013 Topics: Lexical scope, dynamic scope, closures

CSE 341: Programming Languages

Guaranteeing memory safety in Rust

Tokio: How we hit 88mph. Alex Crichton

CMSC 430 Introduction to Compilers. Fall Everything (else) you always wanted to know about OCaml (but were afraid to ask)

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Aaron Turon! Mozilla Research

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

CSE 130, Fall 2006: Final Examination

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

CMSC 330: Organization of Programming Languages. Functional Programming with OCaml

CSE 341 Section 5. Winter 2018

Chapter 11 :: Functional Languages

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

MY PYTHON IS RUSTING. A PYTHON AND RUST LOVE STORY Ronacher

Idiomatic Rust. Writing concise and elegant Rust code

Introduction to Concepts in Functional Programming. CS16: Introduction to Data Structures & Algorithms Spring 2017

Common Programming. Variables and Mutability

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

Metaprogramming assignment 3

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

Fall Lecture 3 September 4. Stephen Brookes

Rust for high level applications. Lise Henry

CSCI 2041: Functions, Mutation, and Arrays

Polymorphism and Type Inference

Functors signature Order = sig functor name type elem (structname:signature) = structure definition; val le : elem*elem -> bool end; elem

CMSC 330: Organization of Programming Languages

Anonymous Functions CMSC 330: Organization of Programming Languages

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

CPL 2016, week 10. Clojure functional core. Oleg Batrashev. April 11, Institute of Computer Science, Tartu, Estonia

CMSC 330: Organization of Programming Languages. Closures (Implementing Higher Order Functions)

CMSC 330: Organization of Programming Languages. Lets, Tuples, Records

CMSC330 Fall 2015 Midterm #1 12:30pm/2:00pm/5:00pm

CMSC 330 Exam #2 Fall 2008

Programming Languages. Function-Closure Idioms. Adapted from Dan Grossman's PL class, U. of Washington

Option Values, Arrays, Sequences, and Lazy Evaluation

Type Checking. Outline. General properties of type systems. Types in programming languages. Notation for type rules.

CSE341: Programming Languages Lecture 7 First-Class Functions. Dan Grossman Winter 2013

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

Programming Languages

Outline. General properties of type systems. Types in programming languages. Notation for type rules. Common type rules. Logical rules of inference

CMSC330 Fall 2016 Midterm #1 2:00pm/3:30pm

Region-based Memory Management. Advanced Operating Systems Lecture 10

Lecture 8: Summary of Haskell course + Type Level Programming

Key components of a lang. Deconstructing OCaml. In OCaml. Units of computation. In Java/Python. In OCaml. Units of computation.

Exercises on ML. Programming Languages. Chanseok Oh

Harvard School of Engineering and Applied Sciences Computer Science 152

CMSC 330: Organization of Programming Languages. Closures (Implementing Higher Order Functions)

Notes from a Short Introductory Lecture on Scala (Based on Programming in Scala, 2nd Ed.)

CS Lecture 7: The dynamic environment. Prof. Clarkson Spring Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack

CIS 341 Final Examination 4 May 2017

Implementing Recursion

Transcription:

CMSC 330: Organization of Programming Languages Closures and Iterators In Rust CMSC330 Spring 2018 Copyright 2018 Michael Hicks, the University of Maryland. Some material based on https://doc.rustlang.org/book/second-edition/index.html

Closures Syntax x1[:t1]?,, xn[:tn]? [-> u]? e Type annotations are optional will be inferred if absent Evaluation A closure is a value Type checking has type (t1,,tn) -> u when e : u under assumptions x1 : t1,, xn : tn Not curried 2

Using Closures/Functions Locally Rust has local functions, and closures fn moveit(l:bool,x:i32) -> i32 { let left = x x 1; fn right(x:i32) -> i32 { x+1 }; if l { left(x) } else { right(x) } } OCaml local functions/closures let moveit l x = let left = fun x -> x 1 in let right = fun x -> x + 1 in if l then left x else right x Closure (may have an environment) Local function (no environment) 3

Limits of Type Inference Rust infers non-polymorphic types let id = x x; let x = id(1); //infers x:i32 let y = id("hi"); //fails: &str i32 OCaml infers polymorphic types let f = fun x -> x in (* a -> a *) let x = id 1 in let y = id "hi" in (* OK *) We ll see polymorphically typed closures shortly 4

Passing Closures as Arguments Each closure has a distinct type Even if two closures have the same signature, their types are considered different Such types are called generative types To specify the type of a closure (for a function parameter, say), use generics with trait bounds Fn t (will describe later) FnMut t FnOnce t Functions (defined with fn f ) implement the above trait bounds too 5

Using the Fn Trait Trait bound on T to specify type of f fn app_int<t>(f:t,x:i32) -> i32 where T:Fn(i32) -> i32 { f(x) } fn main() { println!( {},app_int(( x x-1),1)); } But cannot write fn app_int(f:(i32) -> i32,x:i32) -> i32 { f(x) } Can also use function trait bounds in struct, enum, etc. definitions 6

Using the Fn Trait Polymorphically fn app<t,u,w>(f:t,x:u) -> W where T:Fn(U) -> W { f(x) } fn main() { println!("{}",app(( x x-1),1));//i32 let s = String::from("hi "); println!("{}",app( x x+"there",s));//string } 7

Capturing Free Variables fn main() { let x = 4; let equal_to_x = z z == x; let y = 4; assert!(equal_to_x(y)) } // true Closure env captures x Note: fails if equal_to_x defined as a local function Local functions do not have an environment Complication: What if x is owned? Capturing it could move it or borrow (mut or immut) Use various FnX traits to specify what to do 8

Distinguishing Fn Trait Bounds FnOnce t (where t is a func type) Consumes the variables it captures from its enclosing scope (i.e., moves or copies them) Thus can only be called once The call consumes ownership FnMut t Borrows captured variables mutably Fn t Borrows captured variables immutably, or copies equal_to_x copied x due to its Copy trait In general, try this first, and follow the compiler s advice if it doesn t work 9

Example use of FnOnce let x = String::from("hi"); let add_x = z x+z; //captures x; is FnOnce println!("x = {}",x); //fails let s = add_x(" there");//consumes closure let t = add_x(" joe");//fails, add_x consumed 10

Iteration using the Iterator Trait Recall an earlier example: let a = vec![10, 20, 30, 40, 50]; for e in a.iter() { println!("the value is: {}", e); } The iter() method returns an iterator, i.e., a value with the Iterator trait trait Iterator { type Item; //this is an associated type fn next(&mut self) -> Option<Self::Item>; //default method impls } 11

Unpacking the for syntax Each call to next advances the iterator So it has to be mut let a = vec![10, 20]; let mut iter = a.iter(); assert_eq!(iter.next(), Some(&10)); assert_eq!(iter.next(), Some(&20)); assert_eq!(iter.next(), None); calls to next produce immutable references to the values in a else may call into_iter or iter_mut on a to get different sorts of references 12

Iterator Adaptors We can make one iterator from another An iterator is consumed as it used; it is lazy This is a pattern for higher order programming i.map(f) produces an iterator returning f(e) for each of i s elements e i.filter(f) produces iterator for i s elements e such that f(e) == true i.collect() converts an iterator into a vector i.fold(a,f) is like OCaml s fold_right fold_right f a v where v is the list corresponding to i zip, sum, 13

Examples let a = vec![10,20]; let i = a.iter(); let j = i.map( x x+1).collect(); //[11,21] let k = a.iter().fold(0, a,x x-a); //10 for e in a.iter().filter( &&x x == 10) { println!("{}",e); } //prints 10 14

Quiz 1: Output of the following code fn main(){ let a = [0, 1, 2, 3, 4, 5]; let mut iter2 = a.iter().map( x 2 * x); iter2.next(); let t2 = iter2.next(); println!("{:?}", t2) } A. Some(0) B. Some(1) C. Some(2) D. Some(4) 15

Quiz 1: Output of the following code fn main(){ let a = [0, 1, 2, 3, 4, 5]; let mut iter2 = a.iter().map( x 2 * x); iter2.next(); let t2 = iter2.next(); println!("{:?}", t2) } A. Some(0) B. Some(1) C. Some(2) D. Some(4) 16

Notes You can make your own iterators too Implement the Iterator trait Several examples in the Rust Book Iterators perform extremely well Better that for loops with explicit indexes! This is because Rust aggressively optimizes the code it generates, e.g., by unrolling the iteration loop So feel free to program using map, fold, zip, etc. 17