Lecture 17 Slides - On Functional Programming

1 of 28

Lecture 17

On Functional Programming

2 of 28

Logistics and Week Ahead

Today

  • Friday - Wrapping up Functional Programming
    • Saturday 11:59pm - late deadline for Ex5
    • Sunday 11:59pm - Ethics reflections for Module 6 - Impact

For some - Ethics Module 7 - Labor

  • Monday - Intro to Imperative Programming
  • Wednesday - More Imperatives (Pre-Recorded + MQ13) + Tutorial 7
  • Friday - Scope (MQ 14) (Ex 6 Due - Posted this Afternoon)

Announcements

  • Quiz 2 grades available by Wednesday at the latest (Median: ~85)
  • I'm a little behind on email; if you emailed me I will get back to you by Monday

3 of 28

The story up until now

  • Everything in your computer is data
    • Including programs
  • Data is divided into objects
  • Objects can be inside other objects
    • An album is made up of a title, artist, and genre
    • Colors inside bitmaps
  • Objects have types
    • Functions (procedures)
    • Numbers (1 or -3.5)
    • Strings (“this is a string”, “blue”)
    • Picture/image objects (ellipses, rectangles, etc.)
    • Albums, trees, lists, etc.

4 of 28

The story up until now

  • Computation is performed using expressions
    • Expressions have (or “return”) values (i.e. outputs)
    • Computation is performed by recursively replacing expressions with their values
  • A computation's only output is its return value
    • It's return value only depends on:
      • Its inputs
      • The expression's structure
      • The other definitions in the program
    • It doesn't depend on what was computed before unless it's directly nested/chained/connected to it (i.e. it doesn’t depend on the computer’s state)
  • Once we define a variable, it's been impossible to update it

5 of 28

Rules of computation in Racket

Look at the expression

  • If it’s a constant (i.e. a number or string), it’s its own value
  • If it’s a variable name (i.e. a word, hyphenated phrase, etc.), look its value up in the dictionary
  • Parentheses? (Check if it’s one of the special cases from the next slide)
  • Otherwise it’s a function call
    • (func-expression arg-expression1arg-expressionn)
    • Execute all the subexpressions�(func-expression and arg-expression1 through arg-expressionn)
    • Call the value of func-expression, passing it the values of arg-expression1 through arg-expressionn as inputs
    • Use its output as the value of the expression

6 of 28

Special cases: Rules of computation in Racket

If it starts with define

(define name value-expression)

  • Run value-expression
  • Assign its value to namein the dictionary

If it starts with λ or lambda:

(λ (name1namelast) result-expression)

  • Make a function
    • That names its inputs�name1namelast
    • And returns the value�of result-expression(presumably using those names)

If it starts with the the word local

(local [(define name1 value1) � …� (define namelast valuelast)]� result-expression)

  • Run the value expressions
  • Substitutes their values for their respective�names in result-expression
  • Runs the substituted result-expression
  • Returns its value

If it starts with if:

(if test consequent alternative)

  • Run test
  • If it returns true, run consequent and return its value
  • Otherwise run alternative and return its value

7 of 28

Special cases: Rules of computation in Racket

If it starts with define-struct

(define-struct typename (properties…))

  • Creates a new type of data called typename
  • Defines a constructor: make-typename
  • Defines accessors: typename-property-1
  • Defines predicate: typename?

If it starts with cond:

(cond [test1 result1]

[ … ]

[else resultlast])

  • Runs tests in order, first one to pass (#true) return corresponding result

If it starts with require:

(require some-library)

  • Loads function definitions for later use from some-library

If it starts with check-expect:

(check-expect thing-1 thing-2)

  • Compares two things and "passes" if the two things are equivalent.

8 of 28

Simple Execution Examples

2

"Friday"

#true

9 of 28

Simple Execution Examples

(define a "FRIDAY!")

a

map

10 of 28

What are these?

(λ (x)

(+ x 2))

(define pizza "connor")

11 of 28

Compound Examples

(define pizza "connor")

(cond [(string=? pizza "pizza") #false ]

[(string=? pizza "pineapple") #true ]

[(= pizza 5) "wait" ]

[else "uh oh"])

((λ (x)

(+ x 2))

5)

12 of 28

(define (map-helper func in out)

(if (empty? in)

out

(loop func

(rest in)

(cons (func (first in))

out))))

(define (map lst)

(map-helper - lst '())

map

13 of 28

Pernicious Examples

(foldl or #false '(#false #true #false #false))

14 of 28

; my-filter/iter-helper : (any -> bool) (listof any) (listof any) -> (listof any)

; helper function for my-filter/iter

(define (my-filter/iter-helper pred l accum)

(cond [(empty? l) accum]

[(pred (first l)) (my-filter/iter-helper pred

(rest l)

accum)]

[else (my-filter/iter-helper pred

(rest l)

accum)]))

; my-filter/iter : (any -> bool) (listof any) -> (listof any)

; Works identically to filter, but uses iterative recursion

(define (my-filter/iter pred lst)

(reverse (my-filter/iter-helper pred lst '())))

(my-filter/iter even? '(1 2 3 4))

15 of 28

; my-filter/iter-helper : (any -> bool) (listof any) (listof any) -> (listof any)

; helper function for my-filter/iter

(define (my-filter/iter-helper pred l accum)

(cond [(empty? l) accum]

[(pred (first l)) (my-filter/iter-helper pred

(rest l)

accum)]

[else (my-filter/iter-helper pred

(rest l)

accum)]))

16 of 28

; my-filter/iter-helper : (any -> bool) (listof any) (listof any) -> (listof any)

; helper function for my-filter/iter

(define (my-filter/iter-helper pred l accum)

(cond [(empty? l) accum]

[(pred (first l)) (my-filter/iter-helper pred

(rest l)

(cons (first l) accum))]

[else (my-filter/iter-helper pred

(rest l)

accum)]))

17 of 28

; my-iterated-overlay/iter : (num -> img) num -> img

; Works the same was as iterated-overlay using iterative recursion.

(define (my-iterated-overlay/iter gen num)

(local [(define (helper mygen n acc)

(local [(define recursive-step n)]

(cond [(= n 0) acc]

[else (helper mygen

recursive-step

(overlay (mygen recursive-step)

acc))])))]

(helper gen num empty-image)))

(my-iterated-overlay/iter (lambda (x) (square (* x 50) "outline" "red")) 5)

18 of 28

; my-iterated-overlay/iter : (num -> img) num -> img

; Works the same was as iterated-overlay using iterative recursion.

(define (my-iterated-overlay/iter gen num)

(local [(define (helper mygen n acc)

(local [(define recursive-step (- n 1))]

(cond [(= n 0) acc]

[else (helper mygen

recursive-step

(overlay (mygen recursive-step)

acc))])))]

(helper gen num empty-image)))

(my-iterated-overlay/iter (lambda (x) (square (* x 50) "outline" "red")) 5)

19 of 28

;; A binary-tree is one of:

;; - A string (a name), e.g. "Connor"

;; - A (make-branch string[s] binary-tree binary-tree)

(define-struct branch (name left right))

;; Valid Trees given this definition!

“Connor”

(make-branch “Rex” “Buzz” “Stinky Pete”)

;; Invalid Trees given this definition!

(make-branch “Rex” #false #false)

(make-branch “Rex”)

20 of 28

Why though?

21 of 28

Functional vs Imperative Programming

  • Functional programming is programming without effects and sequencing
    • The only effects (output) of an expression is its return value
    • Value of a function call is determined entirely by the inputs to a function which might include nested function calls
    • Result doesn't depend on order of execution of subexpressions; the substitution model perfectly emulates execution.
  • Imperative programming
    • Expressions can have many different effects: return value, changing variables, deleting files, etc.
    • Those side effects can influence the behavior of other expressions (even if they seem unrelated).
    • Computation is achieved by sequencing changes
    • Forces us to think about execution as changes and causality

22 of 28

A Little Game Design

Believe it or not, we have all the tools necessary to implement a real game!

And that's what we're going to do in Exercise 6!

23 of 28

Basics of Game Design: Model View Controller

A way of abstracting game design into three interconnected parts:

Model

  • Takes care of representing and updating game data objects

View

  • Renders the contents of the model

Controller

  • Takes inputs from the user

24 of 28

25 of 28

Let's focus on the DATA behind the game

What sorts of data do we need to represent the game?

What objects exist?

What properties do they have?

How might we make these in Racket?

26 of 28

Let's focus on the REPRESENTATION of the game

How is each object represented visually?

How might we make these in Racket?

27 of 28

Let's focus on the LOGIC of the game

How does the game work?

How are objects manipulated?

How might we write this in Racket?

28 of 28

Basics of Game Design: Model View Controller

A way of abstracting game design into three interconnected parts:

Model

  • Takes care of representing and updating game data objects

View

  • Renders the contents of the model

Controller

  • Takes inputs from the user