CS 360 Programming Languages Day 14 Closure Idioms

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

Programming Languages. Thunks, Laziness, Streams, Memoization. Adapted from Dan Grossman s PL class, U. of Washington

regsim.scm ~/umb/cs450/ch5.base/ 1 11/11/13

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

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

CSE341: Programming Languages Winter 2018 Unit 5 Summary Zach Tatlock, University of Washington

Computer Science 21b (Spring Term, 2015) Structure and Interpretation of Computer Programs. Lexical addressing

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

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

CS 360 Programming Languages Interpreters

CS 314 Principles of Programming Languages

Racket. CSE341: Programming Languages Lecture 14 Introduction to Racket. Getting started. Racket vs. Scheme. Example.

CSE341: Programming Languages Lecture 15 Macros. Zach Tatlock Winter 2018

What is a macro. CSE341: Programming Languages Lecture 15 Macros. Example uses. Using Racket Macros. Zach Tatlock Winter 2018

A brief tour of history

MORE SCHEME. 1 What Would Scheme Print? COMPUTER SCIENCE MENTORS 61A. October 30 to November 3, Solution: Solutions begin on the following page.

CS 314 Principles of Programming Languages

Functional Programming. Pure Functional Languages

CS 415 Midterm Exam Spring 2002

Functional Programming. Pure Functional Languages

Functional Programming

Mutation. COS 326 David Walker Princeton University

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

CSE 341: Programming Languages

Putting the fun in functional programming

Project 2: Scheme Interpreter

How to Design Programs

Subclassing for ADTs Implementation

Equivalent Notations. Higher-Order Functions. (define (f x y) ( body )) = (define f (lambda (x y) ) ) Anonymous Functions.

Racket: Macros. Advanced Functional Programming. Jean-Noël Monette. November 2013

CS61A Notes Week 9: Muta4on (solu4ons) Revenge of the Box- and- pointers

Separate Compilation Model

Robot Programming with Lisp

Box-and-arrow Diagrams

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

Deferred operations. Continuations Structure and Interpretation of Computer Programs. Tail recursion in action.

cs61amt2_4 CS 61A Midterm #2 ver March 2, 1998 Exam version: A Your name login: cs61a- Discussion section number TA's name

Discussion 4. Data Abstraction and Sequences


User-defined Functions. Conditional Expressions in Scheme

Write a procedure powerset which takes as its only argument a set S and returns the powerset of S.

Sample Final Exam Questions

CS450: Structure of Higher Level Languages Spring 2018 Assignment 7 Due: Wednesday, April 18, 2018

Functional Programming. Pure Functional Programming

CS 314 Principles of Programming Languages. Lecture 16

Introduction to Functional Programming in Racket. CS 550 Programming Languages Jeremy Johnson

Vectors in Scheme. Data Structures in Scheme

Turtles All The Way Down

CS 314 Principles of Programming Languages

Racket: Modules, Contracts, Languages

STREAMS 10. Basics of Streams. Practice with Streams COMPUTER SCIENCE 61AS. 1. What is a stream? 2. How does memoization work?

CSE341 Spring 2016, Final Examination June 6, 2016

CMSC 331 Final Exam Section 0201 December 18, 2000

CS 61A Midterm #2 ver March 2, 1998 Exam version: A. Your name. login: cs61a- Discussion section number. TA's name

Parsing Scheme (+ (* 2 3) 1) * 1

Typed Scheme: Scheme with Static Types

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

Late Binding; OOP as a Racket Pattern

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

Programming Languages. Streams Wrapup, Memoization, Type Systems, and Some Monty Python

Berkeley Scheme s OOP


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

Typed Racket: Racket with Static Types

Notes on Higher Order Programming in Scheme. by Alexander Stepanov

CSE 341 Section Handout #6 Cheat Sheet

The Typed Racket Guide

An Introduction to Scheme

Every language has its own scoping rules. For example, what is the scope of variable j in this Java program?

Comp 311: Sample Midterm Examination

Introduction to Functional Programming

PROFESSOR: Well, now that we've given you some power to make independent local state and to model objects,

A Brief Introduction to Scheme (II)

Oriented Programming Terminology. Using classes and instances to design a system. Example Instance Diagram

(scheme-1) has lambda but NOT define

Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

Scheme: Expressions & Procedures

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

Garbage Collection Basics

CIS4/681 { Articial Intelligence 2 > (insert-sort '( )) ( ) 2 More Complicated Recursion So far everything we have dened requires

Principles of Programming Languages Topic: Scope and Memory Professor Louis Steinberg Fall 2004

Why do we need an interpreter? SICP Interpretation part 1. Role of each part of the interpreter. 1. Arithmetic calculator.

Tail Recursion and Accumulators

CS61A, Fall/1999 Midterm #1 Professor Brian Harvey

John McCarthy IBM 704

SCHEME 10 COMPUTER SCIENCE 61A. July 26, Warm Up: Conditional Expressions. 1. What does Scheme print? scm> (if (or #t (/ 1 0)) 1 (/ 1 0))

Streams, Delayed Evaluation and a Normal Order Interpreter. CS 550 Programming Languages Jeremy Johnson

Lisp. Versions of LISP

More Scheme CS 331. Quiz. 4. What is the length of the list (()()()())? Which element does (car (cdr (x y z))) extract from the list?

;;; Determines if e is a primitive by looking it up in the primitive environment. ;;; Define indentation and output routines for the output for

PROBLEM SOLVING 11. July 24, 2012

Announcements. The current topic: Scheme. Review: BST functions. Review: Representing trees in Scheme. Reminder: Lab 2 is due on Monday at 10:30 am.

An Explicit-Continuation Metacircular Evaluator

CSE341 Autumn 2017, Final Examination December 12, 2017

Ways to implement a language

Functional Programming Lecture 1: Introduction

6.037 Lecture 4. Interpretation. What is an interpreter? Why do we need an interpreter? Stages of an interpreter. Role of each part of the interpreter

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

CSE 12 Week Eight, Lecture One

Transcription:

CS 360 Programming Languages Day 14 Closure Idioms

Why lexical scope rocks Last time: currying Today: implementing callbacks and object-oriented programming.

Review: mutable state Racket's variables are mutable. The name of any function which mutates something contains a "!" Mutate a variable with set! (set! variable new-value) Only works after the variable has been placed into an environment with define, let, or as an argument to a function. set! does not return a value.

Review: mutable state (define times-called 0) (define (function) (set! times-called (+ 1 times-called)) times-called) Notice that functions that have side-effects or use mutation are the only functions that need to have bodies with more than one expression in them. Wouldn't it be nice to not have the times-called variable cluttering up the global frame?

Lexical scope to the rescue! (define (function) (let ((times-called 0)) (set! times-called (+ 1 times-called)) times-called)) Why does this not work? The let is executed when the function is called. We want it to be executed when the function is defined. (define function (let ((times-called 0)) (lambda () (set! times-called (+ 1 times-called)) times-called)))

Example use: callbacks A common idiom: Library takes functions to apply later, when an event occurs: When a key is pressed, mouse moves, data arrives. When the program enters or leaves some state (e.g., a turn in a game begins or ends). Most callback libraries use a higher-order function to setup a callback.

Example Racket GUI with callback 1 ; Make a frame by instantiating the frame% class (define frame (new frame% (label "Example"))) ; Make a button in the frame (define btn (new button% (parent frame) (label "Click Me") (callback (lambda (button event) (send btn set-label "Hello!"))))) ; Show the frame by calling its show method (send frame show #t)

Example Racket GUI with callback 2 ; Make a frame by instantiating the frame% class (define frame (new frame% (label "Example"))) ; Make a button in the frame (define btn (new button% (parent frame) (label "Click Me") (callback (lambda (button event) (send btn set-label (number->string (function)))))) ; Show the frame by calling its show method (send frame show #t)

Example Racket GUI with callback 3 ; Make a frame by instantiating the frame% class (define frame (new frame% (label "Example"))) ; Make a button in the frame (define btn (new button% (parent frame) (label "Click Me") (callback (let ((count-clicks 0)) (lambda (button event) (set! count-clicks (+ 1 count-clicks)) (send btn set-label (number->string count-clicks)))))) ; Show the frame by calling its show method (send frame show #t)

Implementing an ADT As our last pattern, closures can implement psuedo-classes in an object-oriented style. "Pseudo" because you don't have things like polymorphism, public/private variables, etc. Good illustration of the power of closures. The actual code is advanced/clever/tricky, but has no new features. Combines lexical scope, closures, and higher-level functions. Client use is not so tricky.

(define (new-stack) (let ((the-stack '())) (define (dispatch method-name) (cond ((eq? method-name 'empty?) empty?) ((eq? method-name 'push) push) ((eq? method-name 'pop) pop) (#t (error "Bad method name")))) (define (empty?) (null? the-stack)) (define (push item) (set! the-stack (cons item the-stack))) (define (pop) (if (null? the-stack) (error "Can't pop an empty stack") dispatch)) (let ((top-item (car the-stack))) (set! the-stack (cdr the-stack)) top-item))) ; this last line is the return value ; of the let statement at the top.

New stuff! A little more about set! and mutation. Delayed evaluation.

Set! Yes, Racket really has assignment statements But used only-when-really-appropriate! For the x in the current environment, subsequent lookups of x get the result of evaluating expression e Any code using this x will be affected Like C++/Python s x = e (set! x e) Once you have side-effects, sequences are useful: (begin e1 e2 en)

Example Example uses set! at top-level; mutating local variables is similar (define b 3) (define f (lambda (x) (* 2 (+ x b)))) (define c (+ b 4)) (set! b 5) (define z (f 4)) (define w c) Not much new here: Environment for closure determined when function is defined, but body is evaluated when function is called

Top-level Mutating top-level definitions is particularly problematic What if any code could do set! on anything? How could we defend against this? A general principle: If something you need not to change might change, make a local copy of it. Example: (define b 3) (define f (let ((b b)) (lambda (x) (* 2 (+ x b))))) Could use a different name for local copy but do not need to. Called defensive copying --- used often in languages like C++ and Java.

cons cells are immutable What if you wanted to mutate the contents of a cons cell? In Racket you can t (major change from Scheme) This is good List-aliasing irrelevant Implementation can make a fast list? since listness is determined when cons cell is created This does not mutate the contents: (define x (cons 14 '())) (define y x) (set! x (cons 42 '())) (define fourteen (car y)) Like C++: x = Cons(42,null), not x.car = 42

mcons cells are mutable Since mutable pairs are sometimes useful (will use them later in class), Racket provides them too: mcons mcar mcdr mpair? set-mcar! set-mcdr! Run-time error to use mcar on a cons cell or car on a mcons cell