Introduction to Functional Programming in Racket

Slides:



Advertisements
Similar presentations
1 Programming Languages (CS 550) Mini Language Interpreter Jeremy R. Johnson.
Advertisements

1 Scheme and Functional Programming Aaron Bloomfield CS 415 Fall 2005.
1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
1 Programming Languages and Paradigms Lisp Programming.
CSE 341 Lecture 16 More Scheme: lists; helpers; let/let*; higher-order functions; lambdas slides created by Marty Stepp
Lambda Calculus and Lisp PZ03J. Lambda Calculus The lambda calculus is a model for functional programming like Turing machines are models for imperative.
Chapter 3 Functional Programming. Outline Introduction to functional programming Scheme: an untyped functional programming language.
CS 355 – PROGRAMMING LANGUAGES Dr. X. Apply-to-all A functional form that takes a single function as a parameter and yields a list of values obtained.
1 Functional programming Languages And a brief introduction to Lisp and Scheme.
Functional programming: LISP Originally developed for symbolic computing Main motivation: include recursion (see McCarthy biographical excerpt on web site).
Chapter 15 Functional Programming Languages. Copyright © 2007 Addison-Wesley. All rights reserved. 1–2 Introduction Design of imperative languages is.
ISBN Chapter 15 Functional Programming Languages Mathematical Functions Fundamentals of Functional Programming Languages Introduction to.
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
CSC3315 (Spring 2009)1 CSC 3315 Programming Paradigms Scheme Language Hamid Harroud School of Science and Engineering, Akhawayn University
ISBN Chapter 15 Functional Programming Languages.
CS 330 Programming Languages 11 / 21 / 2006 Instructor: Michael Eckmann.
CS 326 Programming Languages, Concepts and Implementation Instructor: Mircea Nicolescu Lecture 8.
Functional Programming in Scheme and Lisp.
Introduction to ACL2 CS 680 Formal Methods for Computer Verification Jeremy Johnson Drexel University.
ISBN Chapter 15 Functional Programming Languages.
UMBC CMSC Common Lisp II. UMBC CMSC Input and Output Print is the most primitive output function > (print (list 'foo 'bar)) (FOO BAR) The.
1 Programming Languages (CS 550) Lecture 4 Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
1 Programming Languages (CS 550) Lecture 2 Summary Mini Language Interpreter Jeremy R. Johnson.
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
Computer Eng. Software Lab II , Semester 2, Who I am: Andrew Davison CoE, WiG Lab Office Functional Programming.
CS Class 04 Topics  Selection statement – IF  Expressions  More practice writing simple C++ programs Announcements  Read pages for next.
1 Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson.
1 Proving Properties of Recursive List Functions CS 270 Math Foundations of CS Jeremy Johnson.
Functional Programming in ACL2 Jeremy Johnson Kurt Schmidt Drexel University.
Functional Programming
CS314 – Section 5 Recitation 9
Operational Semantics of Scheme
Functional Programming
CS314 – Section 5 Recitation 10
Functional Programming Languages
CS 550 Programming Languages Jeremy Johnson
History of Computing – Lisp
CS 3304 Comparative Languages
User-Written Functions
CS 550 Programming Languages Jeremy Johnson
CS 326 Programming Languages, Concepts and Implementation
6.001 Jeopardy.
Basic Elements of C++.
CS 326 Programming Languages, Concepts and Implementation
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
CS 270 Math Foundations of CS Jeremy Johnson
COP4020 Programming Languages
Disjunctive Normal Form
Nondeterministic Evaluation
Basic Elements of C++ Chapter 2.
Proving Properties of Recursive List Functions
Mini Language Interpreter Programming Languages (CS 550)
PROGRAMMING IN HASKELL
The Metacircular Evaluator
FP Foundations, Scheme In Text: Chapter 14.
Functional Programming Languages
Announcements HW4 due today. There is no HW5. (It was merged into HW4.) HW6 (Scheme, Problem 1) out today, due October 23rd We’ll cover 100% of what you.
The Metacircular Evaluator (Continued)
CSCE 314: Programming Languages Dr. Dylan Shell
Streams, Delayed Evaluation and a Normal Order Interpreter
6.001 SICP Variations on a Scheme
Introduction to Functional Programming in Racket
CSE 3302 Programming Languages
Announcements Quiz 5 HW6 due October 23
Functional Programming: Lisp
6.001 SICP Interpretation Parts of an interpreter
Introduction to the Lab
Common Lisp II.
Presentation transcript:

Introduction to Functional Programming in Racket September 4, 1997 Introduction to Functional Programming in Racket CS 270 Math Foundations of CS Jeremy Johnson

Objective To introduce functional programming in racket September 4, 1997 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.

Outline Syntax and semantics Functional programming September 4, 1997 Outline Syntax and semantics Functional programming Programs are functions – for every input there is a unique output (referential transparency) No variables  no assignment and no loops Use recursion for iteration Functions are first class objects Pass as arguments and return as values Racket language and Dr. Racket IDE

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 complete Makes reasoning about programs easier

C++ Function with Side-Effects #include <iostream> using namespace std; int cc() { static int x = 0; return ++x; } int main() cout << "cc() = " << cc() << endl; % g++ count.c % ./a.out cc() = 1 cc() = 2 cc() = 3

September 4, 1997 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)

September 4, 1997 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.

Read-Eval-Print-Loop (REPL) September 4, 1997 Read-Eval-Print-Loop (REPL) Dr. Racket IDE (racket-lang.org) Definition Window Click Run to load and run definitions Students should download DrRacket from racket-lang.org. There are lots of resources for learning Racket and DrRacket available at this website. After installing DrRacket, students can access extensive documentation. Interaction Window Enter expressions at the prompt (REPL)

Example Evaluation 2 => 2 (/ 4 6) => 2 3 (/ 4 6) => 2 3 + => #<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)

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 Each type has a predicate to recognize elements of that type. E.G. number? Note that there are different types of numbers, such as integer, rational, and floating point with their corresponding predicates integer?, Rational? and flonum?. The predicate equal? Checks for equality of arbitrary Racket objects, whereas the predicate eq? checks for equality of symbols.

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

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

List Processing Functions (null? ‘()) => #t (null? ‘(1 2 3)) => #f (car ‘(1 2 3)) => 1 ;same as (first ‘(1 2 3)) (cdr ‘(1 2 3)) => ‘(2 3) ;same as (rest ‘(1 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)

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)) ;shorthand for above (sqr 2) => 4

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) Recursive functions, like fact, are closely related to definitions of what is being computed. Recursive programming, when you get used to it, is much closer to declarative programming, which states what is to be computed rather than how it is computed.

Trace Recursion (define (fact n) (if (= n 0) 1 (* n (fact (- n 1))))) (fact 3) = (* 3 (fact 2)) = (* 3 (* 2 (fact 1))) (* 3 (* 2 (* 1 (fact 0)))) (* 3 (* 2 (* 1 1))) = 6 When n=0 [base case] no recursion When n>0 [recursive case] recursion occurs

Recursion (define (fact n) (if (= n 0) 1 (* n (fact (- n 1))))) Similar to mathematical definition – define what to compute 𝑛!= 1 𝑤ℎ𝑒𝑛 𝑛=0 𝑛∙ 𝑛−1 !𝑤ℎ𝑒𝑛 𝑛>0 Declarative programming states what to compute rather than how to compute it

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 (fact n) (if (= n 0) 1 (* n (fact (- n 1))))) (define (factt n sofar) (if (= n 0) sofar (factt (- n 1) (* n sofar))))) (fact n) = (factt n 1) Students may have “learned” that recursion is slow. The point of mentioning tail recursion is that in many cases it is possible to automatically convert recursion to loops. Racket does this for tail recursive functions. The point is that when it is natural students should not fear using recursion. Note that the function sum is not tail recursive since + is called after the recursive call; however, by passing an extra argument which keeps track of the sum so far, it is possible to convert sum to a tail recursive function.

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; } }

Testing Test cases give examples of what a function should compute if implemented properly. They can be used for debugging. (fact 3) = 6 (fact 2) = 2 (fact 1) = 1 (fact 0) = 1

Unit Testing in Racket (require rackunit) (require rackunit/text-ui) (define-test-suite fact-suite (check-equal? (fact 0) 1) (check-equal? (fact 1) 1) (check-equal? (fact 2) 2) (check-equal? (fact 3) 6) ) (run-tests fact-suite 'verbose) 4 success(es) 0 failure(s) 0 error(s) 4 test(s) run 0

Higher Order Functions September 4, 1997 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) Higher order functions, are functions that have arguments that are functions and/or return functions as results. Sort and map are examples of higher order functions. Note that by passing a comparison function to sort, it is possible to use the same function to sort different types of objects. The function map applies a given function to the elements of a list to return a new list obtained by applying the function to each of the elements of the original list. This is a useful operation that can be combined with other higher order functions such as fold (next slide) to accomplish many different tasks. The function fold is also called reduce and the paradigm of programming with map and reduce is very powerful and is the motivation behind Apache Hadoop.

Higher Order Functions September 4, 1997 Higher Order Functions filter: (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 Filter applies a given function, which must be a predicate, to the elements of a list and returns a new list of the elements that satisfy the predicate. The foldl functions apply a given function to the first element of a list and the recursive fold of the rest of the elements of a list. Foldr is similar, but works in the opposite direction.

Functions that Return Functions September 4, 1997 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 The function make-adder returns a function that addes the given argument x to its input. Recall that a lambda expression evaluates to a function. Thus (lambda (y) (+ x y)) is the function that adds x to the input y.

Function Composition (define (compose f g) (lambda (x) (f (g x)))) September 4, 1997 Function Composition (define (compose f g) (lambda (x) (f (g x)))) (define add2 (compose add1 add1)) (add2 3) => 5 (define getsecond (compose first rest)) (getsecond ‘(1 2 3 4 5)) => 2 Function composition is an important example of a higher order function that takes two functions as input and returns a new function which is the composition of the two input functions.

Currying (define (curry f a) (lambda (b) (f a b))) September 4, 1997 Currying (define (curry f a) (lambda (b) (f a b))) (define add1 (curry + 1)) (add1 3) => 4 (define double (curry * 2)) (doulble 3) => 6 Currying is another important example involving higher order functions. The function curry takes a function f of two inputs and a value a and returns a function of one argument obtained by fixing one of the inputs to f to the value a. This process is called currying.