Functional Programming. Pure Functional Programming

Similar documents
Scheme in Scheme: The Metacircular Evaluator Eval and Apply

Functional Programming. Pure Functional Languages

Functional Programming. Pure Functional Languages

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

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

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?

A Brief Introduction to Scheme (II)

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

Functional Programming. Pure Functional Programming

CS 314 Principles of Programming Languages

Organization of Programming Languages CS3200/5200N. Lecture 11

Discussion 12 The MCE (solutions)

Syntactic Sugar: Using the Metacircular Evaluator to Implement the Language You Want

11/6/17. Functional programming. FP Foundations, Scheme (2) LISP Data Types. LISP Data Types. LISP Data Types. Scheme. LISP: John McCarthy 1958 MIT

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

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

Scheme Tutorial. Introduction. The Structure of Scheme Programs. Syntax

Below are example solutions for each of the questions. These are not the only possible answers, but they are the most common ones.

Introduction to Scheme

Project 2: Scheme Interpreter

CSc 520 Principles of Programming Languages

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

Vectors in Scheme. Data Structures in Scheme

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

Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

Turtles All The Way Down

Functional programming with Common Lisp

CS 360 Programming Languages Interpreters

Lisp Basic Example Test Questions

User-defined Functions. Conditional Expressions in Scheme

Documentation for LISP in BASIC

CS61A Midterm 2 Review (v1.1)

An Explicit-Continuation Metacircular Evaluator

An Introduction to Scheme

Fall Semester, The Metacircular Evaluator. Today we shift perspective from that of a user of computer langugaes to that of a designer of

Functional Languages. Hwansoo Han

Building a system for symbolic differentiation

LECTURE 16. Functional Programming

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

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Functional Programming

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

Building up a language SICP Variations on a Scheme. Meval. The Core Evaluator. Eval. Apply. 2. syntax procedures. 1.

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

FP Foundations, Scheme

CS 314 Principles of Programming Languages. Lecture 16

An introduction to Scheme

Principles of Programming Languages

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

6.001: Structure and Interpretation of Computer Programs

From Syntactic Sugar to the Syntactic Meth Lab:

Principles of Programming Languages 2017W, Functional Programming

Chapter 1. Fundamentals of Higher Order Programming

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

6.001, Spring Semester, 1998, Final Exam Solutions Your Name: 2 Part c: The procedure eval-until: (define (eval-until exp env) (let ((return (eval-seq

Notes on Higher Order Programming in Scheme. by Alexander Stepanov

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

4/19/2018. Chapter 11 :: Functional Languages

Lexical vs. Dynamic Scope

Comp 311: Sample Midterm Examination

Fundamentals of Artificial Intelligence COMP221: Functional Programming in Scheme (and LISP)

CPS 506 Comparative Programming Languages. Programming Language Paradigm

Chapter 15. Functional Programming Languages

Functional Programming Languages (FPL)

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

CS 275 Name Final Exam Solutions December 16, 2016

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

CS61A Discussion Notes: Week 11: The Metacircular Evaluator By Greg Krimer, with slight modifications by Phoebus Chen (using notes from Todd Segal)

Chapter 15. Functional Programming Languages

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

CSC 533: Programming Languages. Spring 2015

Overview. CS301 Session 3. Problem set 1. Thinking recursively

Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

Functional Programming. Big Picture. Design of Programming Languages

Evaluating Scheme Expressions

Scheme Quick Reference

Using Symbols in Expressions (1) evaluate sub-expressions... Number. ( ) machine code to add

Lambda Calculus LC-1

Programming Languages

Lambda Calculus. Gunnar Gotshalks LC-1

CSCC24 Functional Programming Scheme Part 2

(scheme-1) has lambda but NOT define

(Func&onal (Programming (in (Scheme)))) Jianguo Lu

TAIL RECURSION, SCOPE, AND PROJECT 4 11

Principles of Programming Languages COMP251: Functional Programming in Scheme (and LISP)

Lecture08: Scope and Lexical Address

A Small Interpreted Language

Scheme Quick Reference

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

SOFTWARE ARCHITECTURE 6. LISP

Building a system for symbolic differentiation

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))

Lecture #24: Programming Languages and Programs

Programming Languages

INF4820: Algorithms for Artificial Intelligence and Natural Language Processing. Common Lisp Fundamentals

4.2 Variations on a Scheme -- Lazy Evaluation

CS 342 Lecture 8 Data Abstraction By: Hridesh Rajan

COP4020 Programming Assignment 1 - Spring 2011

Homework 3 COSE212, Fall 2018

Introduction to Functional Programming

Transcription:

Functional Programming Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends only on the values of its sub-expressions (if any). Evaluation does not produce side effects. The value of an expression cannot change over time. No notion of state. Computation may generate new values, but not change existing ones.

Simplicity Advantages No explicit manipulation of memory. Values are independent of underlying machine with assignments and storage allocation. Garbage collection. Power Recursion Functions as first class values Can be value of expression, passed as argument, placed in data structures. Need not be named. Scheme (A Dialog of LISP) Primarily an interpreted language. Interacting with the interpreter Supply an expression to be evaluated Bind a name to a value (could be a function) > 3.14159 ; a number evaluates to itself 3.14159 > (define pi 3.14159) ; bind name to value pi > pi 3.14159

Expressions Prefix notation (op operand1 operand2 operand3 ) > (* 5 7) ; 35 > (+ 4 (* 5 7)) ; 39 General Expression Evaluation (E 1 E 2 E 3 E K ) Each E i is evaluated (in unspecified order) E 1 must evaluate to a function which is applied to the values of E 2 E K Innermost (call-by-value) evaluation Expressions (2) Uniform syntax is useful for manipulating programs as data. Some special forms are evaluated differently.

Function Definitions Lambda expressions (a special form) evaluate to anonymous functions: (lambda (formal-parameters) expression) > (define square (lambda (x) (* x x))) ; square > (square 5) ; 25 > ( (lambda (x) (* x x)) 5) ; 25 Quoting Quote (a special form) prevents evaluation of its operand: > (define pi 3.14159) ; pi > pi ; 3.14159 > (quote pi) ; pi > pi ; pi > (define f *) ; f > (f 2 3) ; 6 > (define f *) ; f > (f 2 3) ; Error * not a procedure

Lists A list is a sequence of zero or more values (symbols, numbers, booleans, functions, other lists). A list is written by enclosing its elements in parentheses. Some expressions are lists. > (length () ) ; 0 > (length (a b c) ) ; 3 > (length ((a b c)) ) ; 1 > (length ((a b) c) ) ; 2 > (length a) ; 2 > (length (+ 2 3) ) ; 3 List length

(null? X) (car x) (cdr x) Operations on Lists ; true if x is the empty list, else false ; First element in the list x ; List of all elements of x except the first (cons a x) ; List whose car is a and whose cdr is x (append x y) ; The concatenation of lists x and y (list e 1 e 2 e k ) ; List of values of e 1 e k Operators do not change lists: > (define l (b c d)) ; l > (cons a l) ; (a b c d) > l ; (b c d) Operations on Lists (2) > (null? a) ; #f > (null? (a)) ; #f > (null? ()) ; #t > (car (a b c)) ; a > (car ((a b) c)) ; (a b) > (cdr (a b c)) ; (b c) > (cdr ((a b) c)) ; (c) > (cons a (b c)) ; (a b c) > (cons (a b) (c d)) ; ((a b) c d) > (append (a b) (c d)) ; (a b c d) > (list a (+ 3 4) b) ; (a 7 b)

Examples: factorial, length (define factorial (lambda (n) (if (equal? n 0) 1 (* n (factorial (- n 1)))))) (define length (lambda (x) (if (empty? x) 0 (+ 1 (length (cdr x)))))) Example: flatten (define flatten (lambda (x) (cond ((null? x) x) ((list? (car x)) (append (flatten (car x)) (flatten (cdr x)))) (else (cons (car x) (flatten (cdr x))))))) > (flatten '(a (b (c) d) e) ) ; (a b c d e)

Let special form Scoping (let ((x 1 e 1 ) (x 2 e 2 ) (x k e k )) f 1 f 2 f n ) 1. Each e i is evaluated (in parallel) 2. Each f j is evaluated with x i denoting the value of e i 3. The result is the value of f n Let* special form (sequential let) (let* ((x 1 e 1 ) (x 2 e 2 ) (x k e k )) f 1 f 2 f n ) Bindings to x i s take place sequentially. That is, e i+1 is evaluated with the binding of x i to e i already in effect. Scope Examples > (+ (square 3) (square 3)) ; 18 > (let ((sq3 (square 3))) (+ sq3 sq3)) ; 18 > (define x 0) ; x > (let ((x 2) (y x)) y) ; 0 > (let* ((x 2) (y x)) y) ; 2

Lexical Scoping > (define g (lambda (f) (let ((x 5)) (f) ))) > (let ((x 0)) ; 1 (g (lambda () (+ 1 x)) )) C int f(int i) { int x = 0; } Naming vs. Assignment if (i > 10) x = 1; else x = 2; return x; Scheme (define f (lambda (i) (let ((x 0)) ; arbitrary code ; x))) ; What does f return?

Naming vs. Assignment (2) Scheme (define f (lambda (i) (let ((x 0)) (if (> i 10) (let ((x 1)) x) (let ((x 2)) x)) x))) ; What does f return? C int f(int i) { int x = 0; if (i > 10) { int x = 1; } else { int x = 2; } } return x; Efficiency: Cons vs. Append > (define x1 ()) > (define x2 (cons c x1)) > (define x3 (cons b x2)) > (define x4 (cons a x3)) x4 Cons cells > x1 ; () > x2 ; (c) > x3 ; (b c) > x4 ; (a b c) x3 x2 x1 a b c

Conditionals Booleans #t #f Predicates number? symbol? list? equal? etc. If special form (if P E 1 E 2 ) Cond special form (cond (P 1 E 1 ) (P 2 E 2 ) (P k E k ) (else E k+1 )) Efficiency: Cons vs. Append (2) > (define x1 (a)) > (define x2 Cons cells (append x1 (b))) > (define x3 (append x2 (c))) x1 a > x1 ; (a) x2 > x2 ; (a b) > x3 ; (a b c) x3 a a b b c

Efficiency: Tail Recursion When a recursive function returns the result of its recursive call, there is no need to maintain a stack of activation records. (define last (lambda (x) (cond ((null? X) ()) ((null? (cdr x)) (car x)) (else (last (cdr x)))))) Efficiency: Tail Recursion (2) (define length (lambda (x) (if (null? X) 0 (+ 1 (length (cdr x))))) (define length (lambda (x) (length-help x 0))) (define length-help (lambda (x n) (if (null? x) n (length-help (cdr x) (+ 1 n)))))

Applications: Insertion Sort (define insert ;; insert a number, n, into a sorted list, x. (lambda (n x) (cond ((null? x) (list n)) ((< n (car x)) (cons n x)) (else (cons (car x) (insert n (cdr x))))))) (define insertion-sort (lambda (x) (cond ((null? x) x) (else (insert (car x) (insertion-sort (cdr x))))))) Applications: Merge Sort ; Merge two sorted lists (define merge (lambda (x y) (cond ((null? x) y) ((null? y) x) ((< (car x) (car y)) (cons (car x) (merge (cdr x) y))) (else (cons (car y) (merge x (cdr y)))))))

Applications: Merge Sort (2) (define split (lambda (x) (split-help x '()))) (define split-help (lambda (x y) (if (<= (length x) (length y)) (list x y) (split-help (cdr x) (cons (car x) y))))) (define split (lambda (x) (let ((help (lambda (h x y) (if (<= (length x) (length y)) (list x y) (h h (cdr x) (cons (car x) y)))))) (help help x '())))) Applications: Merge Sort (3) ; Mergesort a list (define mergesort (lambda (x) (if (< (length x) 2) x (let* ((halfs (split x)) (r1 (mergesort (car halfs))) (r2 (mergesort (cadr halfs)))) (merge r1 r2)))))

List of key/value pairs Association Lists (assoc exp x) ; Find the first pair in x whose ; key has the same value as exp > (define alist ((a 1) (b 2) (c 3) (b 4))) ; alist > (assoc b alist) ; (b 2) Higher Order Functions: Map Let l 1, l 2, l k be lists of equal length, n. Let a i,j be the j th element of l i. Then: (map f l 1 l 2 l k ) = ((f a 1,1 a 2,1 a k,1 ) (f a 1,2 a 2,2 a k,2 ) (f a 1,n a 2,n a k,n )) > (map + (1 2 3) (4 5 6)) ; (5 7 9) > (map cons (a b c) (() (c d) (e))) ; ((a) (b c d) (c e)) > (map + (1 2 3) (4 5 6) (7 8 9)) ; (12 15 18) > (map list (a b c)) ; ((a) (b) (c))

Higher Order Functions (2) How to write a tail recursive version of length without adding helper functions to top level name space? (define length (lambda (x) (let ((helper (lambda (x n) (if (null? x) n (helper (cdr x) (+ 1 n)))))) (helper x 0)))) But this doesn t work. Scheme does not allow you to use a symbol before it is bound in a let, so we can t make the recursive call. Higher Order Functions (3) Add an additional parameter to the helper function for the function to call. Pass the helper function to itself (after it is defined), so that it can make the recursive call. Each time a recursive call is made, the helper function is passed along so the recursion can continue. (define length (lambda (x) (let ((helper (lambda (help x n) (if (null? X) n (help help (cdr x) (+ 1 n)))))) (helper helper x 0))))

Example: Searching A directed acyclic graph in Scheme (define g ((a (b c d)) (b ()) (c (e)) (d (f g)) (e ()) (f (h i j)) (g ()) (h ()) (i ()) (j ()))) A B C D E F G H I J (define successors (lambda (node graph) (cadr (assoc node graph)))) Searching (2) (define path-extensions (lambda (path graph) ;; find all one node extensions of the path (map (lambda (node) (cons node path)) (successors (car path) graph)))) (define expand (lambda (graph goal paths) (if (null? paths) '() (let ((first-path (car paths)) (remaining-paths (cdr paths))) (if (equal? goal (car first-path)) first-path (expand graph goal (append (path-extensions first-path graph) remaining-paths))))))) (define search (lambda (graph start goal) (reverse (expand graph goal (list (list start))))))

(search g a i) (expand g i ((a)) ) Example: Expression Evaluator Consider the following grammar for expressions with scheme-like semantics: E ::= (num val) (var symbol) (plus E E) (times E E) (let (params) E) params ::= (symbol E) (symbol E) params

Expression Evaluator (2) (define lookup (lambda (x env) (cadr (assoc x env)))) (define bind (lambda (params env) (append (map (lambda (y) (list (car y) (eval (cadr y) env))) params) env))) Expression Evaluator (3) (define eval (lambda (exp env) (cond ((equal? (car exp) 'num) (cadr exp)) ((equal? (car exp) 'var) (lookup (cadr exp) env)) ((equal? (car exp) 'plus) (+ (eval (cadr exp) env) (eval (caddr exp) env))) ((equal? (car exp) 'let) (eval (caddr exp) (bind (cadr exp) env))))))

Expression Evaluator (4) > (eval '(let ((x (num 2)) (y (num 3))) ; 5 (plus (var x) (var y))) '()) > (eval '(let ((x (num 1))) (plus (let ((x (num 2)) (y (num 3))) (plus (var x) (var y))) (var x))) '()) ; 6