23
1 Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson

Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

  • Upload
    others

  • View
    8

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

1

Introduction to Functional Programming in Racket

CS 270 Math Foundations of CSJeremy Johnson

Page 2: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

2

Objective• To introduce functional programming in racket

• Programs are functions and their semantics involve function application. Programs may also produce function by returning functions as values. In pure functional programming, this is it, there are no variables, side effects, nor loops. This simplifies semantics but does not reduce computational power.

• We will investigate the style of programming this implies, and how to model the semantics of such programs.

Page 3: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

3

Outline

1. Syntax and semantics2. Functional programming

1. Programs are functions – for every input there is a unique output (referential transparency)

2. No variables ⇒ no assignment and no loops3. Use recursion for control4. Functions are first class objects

1. Pass as arguments and return as values

5. Simple semantics [value semantics] (no side effects, referential transparency)

Page 4: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

A Pure Functional Language

x1 = y1,…,xn=yn ⇒ f(x1,…,xn) = f(y1,…,yn)

No side-effects, no assignments, no state, no loops

Use recursion instead of iteration Still Turing completeMakes reasoning about programs easier

4

Page 5: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

C++ Function with Side-Effects#include <iostream>

using namespace std;

int cc()

{

static int x = 0;

return ++x;

}

int main()

{

cout << "cc() = " << cc() << endl;

cout << "cc() = " << cc() << endl;

cout << "cc() = " << cc() << endl;

} 5

% g++ count.c

% ./a.out

cc() = 1cc() = 2cc() = 3

Page 6: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

6

Syntax

• Programs and data are lists – delimited by ( and ) or [ and ] and separated by space

• S expressions (E1 … En)• Special forms

• Self evaluating: numbers, Booleans, strings, …• (quote expr)• (if test-expr then-expr else-expr)• (cond ([P1 E1] … [Pt Et]))• (lambda (p1 … pn) E1 … Et)• (define name E)• (let ([b1 v1] … [bt vt] E)

Page 7: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

7

Semantics

• To evaluate (E1 E2 ... En), recursively evaluate E1, E2,...,En - E1 should evaluate to a function -and then apply the function value of E1 to the arguments given by the values of E2,...,En.

• In the base case, there are self evaluating expressions (e.g. numbers and symbols). In addition, various special forms such as quote and if must be handled separately.

Page 8: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

8

Read-Eval-Print-Loop (REPL)

• Dr. Racket IDE

Page 9: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

Example Evaluation> 2 => 2

> (/ 4 6) => 23

> + => #<procedure:+>> (+ 2 (* 3 4)) => (+ 2 12) => 14> (max 1 2 3) => 3> (1 2 3) => error> (list 1 2 3) => ‘(1 2 3)> (list 1 (2 3) 4) => error> (list 1 (list 2 3) 4) => ‘(1 (2 3) 4)

Page 10: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

Booleans and Predicates

• Boolean constants: #t and #f > (= 2 3) => #f> (or (= 2 3) (not (= 2 3))) => #t> (and #t #t #t) => #t

• Predicates are Boolean functions• Convention is name?> (equal? 2 3) => #f> (eq? 2 3) => #f> (number? 2) => #t> (boolean? (and #t #f)) => #t

Page 11: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

Conditional

• (if test-expr then-expr else-expr)• Evaluate test-expr if not #f evaluate and

return then-expr else evaluate and return else-expr

> (if (< 2 3) 0 1) => 0> (if (< 3 2) 0 1) => 1> (if (= 3 (+ 2 1)) 0 1) => 0> (if (or (= 2 3) (= 3 3))

(+2 3) (+ 3 3)) => 5

Page 12: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

Conditional

• (cond [test-expr1 then-body1][test-exprn then-bodyn][else then-body])

• Evaluate test-expr1 if #f then goto next case otherwise return then-body1. The else case always returns then-body

> (cond [(= 2 3) 2][(= 3 4) 3][else 4]) => 4

Page 13: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

List Processing Functions

> (null? ‘()) => #t> (null? ‘(1 2 3)) => #f> (car ‘(1 2 3)) => 1> (cdr ‘(1 2 3)) => ‘(2 3)> (cons 1 ‘()) => ‘(1)> (cons 1 ‘(2 3)) => ‘(1 2 3)> (cons 1 (cons 2 (cons 3 '()))) => ‘(1 2 3)> (cons (cons 1 ‘()) ‘(2 3)) => ‘((1) 2 3)

Page 14: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

Lambda Expressions

• (lambda (parameters) body)• Evaluates to a function • When applied the actual arguments are

substituted for the formal parameters into the body which is then evaluated and returned

> (lambda (x) (* x x)) => #<procedure>> ((lambda (x) (* x x)) 2) => 4> (define sqr (lambda (x) (* x x)))> (define (sqr x) (* x x))> (sqr 2) => 4

Page 15: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

Recursion

• In a functional language there are no side effects, hence no assignment and no loops.

• All control must be done through recursion> (define (fact n)

(if (= n 0) 1 (* n (fact (- n 1)))))> (fact 3) => 6> (define (ones n)

(if (= n 0) '() (cons 1 (ones (- n 1)))))> (ones 3) => ‘(1 1 1)

Page 16: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

Tail Recursion

• A tail recursive function is a function where the recursive call is the last operation. Such procedures can easily be converted to loops.

> (define (sum n)(if (zero? n) 0 (+ n (sum (- n 1))))))

> (define (sumt n sofar)> (if (zero? n) sofar

(sumt (- n 1) (+ n sofar)))))

Page 17: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

Tail Recursion

• An equivalent loop can be constructed, which updates the arguments each iteration of the loop.

for (;;){

if (n == 0)

return sofar;

else {

t1 = n - 1;

t2 = sofar + n;

n = t1;

sofar = t2; } }

Page 18: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

18

Higher Order Functions

sort:

> (sort '(4 3 2 1) <) => (1 2 3 4)> (sort '("one" "two" "three" "four") string<?) => '("four" "one" "three" "two")

map: > (map sqr '(1 2 3 4)) => ‘(1 4 9 16)

Page 19: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

19

Higher Order Functionsfilter: > (filter odd? '(1 2 3 4 5)) => ‘(1 3 5)> (filter even? ‘(1 2 3 4 5)) => ‘(2 4)

fold: > (foldr cons '() '(1 2 3 4)) => ‘(1 2 3 4)> (foldr list '() '(1 2 3 4)) => '(1 (2 (3 (4 ()))))> (foldr + 0 '(1 2 3 4)) => 10> (foldl cons ‘() ‘(1 2 3 4)) => ‘(4 3 2 1)> (foldl list '() '(1 2 3 4)) => '(4 (3 (2 (1 ()))))> (foldl * 1 ‘(1 2 3 4)) => 24

Page 20: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

20

Functions that Return Functions• Make-adder> (define (make-adder x) (lambda (y) (+ x y)))> (define add1 (make-adder 1))> (add1 3) => 4

> (define (make-multiplier x) (lambda (y) (* x y)))> (define double (make-multiplier 2))> (double 3) => 6

Page 21: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

21

Function Composition> (define (compose f g) (lambda (x) (f (g x))))

> (define add2 (compose add1 add1))> (add2 3) => 5

> (define getsecond (compose car cdr))> (getsecond ‘(1 2 3 4 5)) => 2

Page 22: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

22

Currying

> (define (curry f a) (lambda (b) (f a b)))

> (define add1 (curry + 1))> (add1 3) => 4

> (define double (curry * 2))> (doulble 3) => 6

Page 23: Introduction to Functional Programming in Racketjjohnson/2015-16/spring/CS270/...Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson 2 Objective

23

Tower of Hanoi

> (define (move from to)(list (string-append from to)))

> (define (hanoi n from to using)(if (= n 1)

(move from to)(append (hanoi (- n 1) from using to)

(move from to)(hanoi (- n 1) using to from))))

> (hanoi 3 "a" "b" "c")'("ab" "ac" "bc" "ab" "ca" "cb" "ab")