To understand recursion, one must first understand recursion.

Slides:



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

Lists in Lisp and Scheme a. Lists are Lisp’s fundamental data structures, but there are others – Arrays, characters, strings, etc. – Common Lisp has moved.
1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
Lisp II. How EQUAL could be defined (defun equal (x y) ; this is how equal could be defined (cond ((numberp x) (= x y)) ((atom x) (eq x y)) ((atom y)
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.
Lisp II. How EQUAL could be defined (defun equal (x y) ; this is how equal could be defined (cond ((numberp x) (= x y)) ((atom x) (eq x y)) ((atom y)
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.
1-1 An Introduction to Scheme March Introduction A mid-1970s dialect of LISP, designed to be a cleaner, more modern, and simpler version than.
מבוא מורחב - שיעור 10 1 Symbols Manipulating lists and trees of symbols: symbolic differentiation Lecture 10.
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.
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
SchemeCOP Introduction to Scheme. SchemeCOP Scheme Meta-language for coding interpreters –“ clean ” semantics Scheme = LISP + ALGOL –simple.
Recursion. Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example: A list.
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.
SICP Interpretation Parts of an interpreter Arithmetic calculator Names Conditionals and if Storing procedures in the environment Environment as.
COP4020 Programming Languages Functional Programming Prof. Xin Yuan.
Introduction to Scheme. Lisp and Scheme Lisp: List processor language –Full recursion –Conditional expression –Extensibility –Interactive Scheme: one.
18-October-2002cse Symbols © 2002 University of Washington1 Symbols CSE 413, Autumn 2002 Programming Languages
מבוא מורחב 1 Lecture #9. מבוא מורחב 2 Symbol: a primitive type constructors: (quote alpha) ==> quote is a special form. One argument: a name. selectors.
Ceg860 (Prasad)LADT1 Specification and Implementation of Abstract Data Types Algebraic Techniques.
CS535 Programming Languages Chapter - 10 Functional Programming With Lists.
You can access the members of a list with the functions car (or first) and cdr (or rest): (setf list '(a b c)) (car list) ⇒ a (first list) ⇒ a (cdr list)
Functional Programming: Lisp MacLennan Chapter 10.
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
SICP Interpretation part 2 Store operators in the environment Environment as explicit parameter Defining new procedures.
Artificial Intelligence and Lisp Lecture 6 LiU Course TDDC65 Autumn Semester,
Abstract Syntax cs7100 (Prasad) L7AST.
CS314 – Section 5 Recitation 10
Functional Programming Languages
Additional Scheme examples
Functional Programming Languages
Section 15.4, 15.6 plus other materials
CS 550 Programming Languages Jeremy Johnson
Example of formula (defun roots (a b c) (list
Introduction to Scheme
CSC 533: Programming Languages Spring 2017
Scheme : variant of LISP
Chapter 15 – Functional Programming Languages
Lists in Lisp and Scheme
CSC 533: Programming Languages Spring 2015
CSC 533: Programming Languages Spring 2016
Closures and Streams cs784(Prasad) L11Clos
CS 270 Math Foundations of CS Jeremy Johnson
CSC 533: Organization of Programming Languages Spring 2008
COP4020 Programming Languages
Original material by Eric Grimson
The Metacircular Evaluator
FP Foundations, Scheme In Text: Chapter 14.
Functional Programming Languages
The Metacircular Evaluator
Lecture #8 מבוא מורחב.
CS 36 – Chapter 11 Functional programming Features Practice
Modern Programming Languages Lecture 20 Fakhar Lodhi
The Metacircular Evaluator (Continued)
Lecture #9 מבוא מורחב.
Abstract Syntax cs7100 (Prasad) L7AST.
topics mutable data structures
Announcements Quiz 5 HW6 due October 23
Lecture #7 מבוא מורחב.
List and list operations (continue).
Abstraction and Repetition
Functional Programming: Lisp
6.001 SICP Interpretation Parts of an interpreter
Lecture # , , , , מבוא מורחב.
CSC 533: Organization of Programming Languages Spring 2007
Lecture 25: The Metacircular Evaluator Eval Apply
Presentation transcript:

To understand recursion, one must first understand recursion. RECURSIVE STRUCTURE: Sub-problem must resemble the original problem Tree -> subtrees; List -> sublists; Expressions -> subexpressions (transformations: traversals, evaluation, code generation, …) E.g., f : EXPR -> int CORRECT DECOMPOSITION: (f ‘(+ e1 e2)) -> (+ (f ‘e1) (f ‘e2)) WRONG FORMULATION: -> (f ‘(e1 e2)) Requires f to handle expressions, plus unnessary inputs such as lists of expressions, empty list, etc. Creates unnecessary work with complicated logic ---------------------------------------------------------------------------------------------------------- While explaining program code, focus is on problem solving and not on data structure creation, low-level manipulation, and destruction. => DECLARATIVE PROGRAMMING cs3180(Prasad) L14Recur+Clojure

Specifying Incremental Work D1 1 -> f(1) ... n -> f(n) Dn n+1 -> f(n+1) cs3180(Prasad) L14Recur

Divide and Conquer Problem decomposition Subproblem1 Subproblem2 primitive recursion Subsolution1 Subsolution2 composition Solution cs3180(Prasad) L14Recur

Cartesian Product > (cart2 '(1 2) '(a b)) ( (1 a) (1 b) (2 a) (2 b) ) > (cart2 '(0 1 2) '(a b)) ( (0 a) (0 b) (1 a) (1 b) (2 a) (2 b) ) > (couple ' 1 '(b c)) ( (1 b) (1 c) ) > (couple ' 1 '(a b c)) ( (1 a) (1 b) (1 c) ) cs3180(Prasad) L14Recur

Divide and Conquer (cart2 '(a b) '(1)) car/cdr (couple ' a '(1)) (cart2 '(b) '(1)) “primitive” recursion ((a 1)) ((b 1)) append ((a 1) (b 1)) cs3180(Prasad) L14Recur

Different Problems; Same pattern cs3180(Prasad) L14Recur

Scheme Definition (define (cart2 x y) (if (null? x) '() (append (couple (car x) y) (cart2 (cdr x) y) ) (define (couple a y) (if (null? y) '() (cons (list a (car y)) (couple a (cdr y)) cs3180(Prasad) L14Recur

Alternate Syntax : lambda (define cart2 (lambda (x y) (if (null? x) '() (append (couple (car x) y) (cart2 (cdr x) y) ) (define couple (lambda (a y) (if (null? y) '() (cons (list a (car y)) (couple a (cdr y)) cs3180(Prasad) L14Recur

Clojure Syntax (defn couple [a y] (if (empty? y) '() (cons (list a (first y)) (couple a (rest y)) ) ) ) (defn cart2 [x y] (if (empty? x) '() (concat (couple (first x) y) (cart2 (rest x) y) (couple ' (1) '(a ("abc") c)) (((1) a) ((1) ("abc")) ((1) c)) (cart2 ' (1 2 3) '(a b c)) ((1 a) (1 b) (1 c) (2 a) (2 b) (2 c) (3 a) (3 b) (3 c)) cs3180(Prasad) L14Recur

Powerset > (powerset '(2)) ( ( ) (2) ) > (powerset '(1 2) ) ( ( ) (2) ) > (powerset '(1 2) ) ( (1) (1 2) () (2) ) > (powerset '(0 1 2)) ( (0 1) (0 1 2) (0) (0 2) (1) (1 2) () (2) ) Subsets of {0,1,2} with 0 are equinumerous with subsets of {0,1,2} without 0. cs3180(Prasad) L14Recur

(define (powerset s) (if (null? s) '(()) (append (ins (car s) (powerset (cdr s)) ) )) (define (ins a ss) (if (null? ss) '() (cons (cons a (car ss)) (ins a (cdr ss)) > (powerset '(0 1 2)) ((0 1 2) (0 1) (0 2) (0) (1 2) (1) (2) ()) (define (powerset s) (if (null? s) (list ()) (let ( (aux (powerset (cdr s))) ) (append (ins (car s) aux) aux ) )) cs3180(Prasad) L14Recur

Alternate Syntax : let (define (powerset s) (if (null? s) '(()) (let ( (aux (powerset (cdr s))) ) (append (ins (car s) aux) aux ) )) (define (ins a ss) (if (null? ss) '() (cons (cons a (car ss)) (ins a (cdr ss)) > (powerset '(0 1 2)) ((0 1 2) (0 1) (0 2) (0) (1 2) (1) (2) ()) (define (powerset s) (if (null? s) (list ()) (let ( (aux (powerset (cdr s))) ) (append (ins (car s) aux) aux ) )) cs3180(Prasad) L14Recur

Clojure Syntax (defn ins [a ss] (if (empty? ss) '() (cons (cons a (first ss)) (ins a (rest ss)) ) )) (defn powerset [s] (if (empty? s) '(()) (let [aux (powerset (rest s))] (concat (ins (first s) aux) aux > (powerset '(0 1 2)) ((0 1 2) (0 1) (0 2) (0) (1 2) (1) (2) ()) cs3180(Prasad) L14Recur

Related problems; Different Patterns cs3180(Prasad) L14Recur

Remove-First-TopLevel (define (rm-fst-top sym lis) (if (null? lis) '() (if (eq? sym (car lis)) (cdr lis) (cons (car lis) (rm-fst-top sym (cdr lis)) ) > (rm-fst-top 'a '(b (b a) a b a)) = (b (b a) b a) Linear recursion cs3180(Prasad) L14Recur

Alternate Syntax : if => cond (define (rm-fst-top sym lis) (cond ( (null? lis) '()) ( (eq? sym (car lis)) (cdr lis) ) ( else (cons (car lis) (rm-fst-top sym (cdr lis)) ) > (rm-fst-top 'a '(b (b a) a b a)) = (b (b a) b a) Linear recursion cs3180(Prasad) L14Recur

Remove-All-TopLevel Linear recursion (define (rm-all-top sym lis) (cond ( (null? lis) '()) ( (eq? sym (car lis)) (rm-all-top sym (cdr lis) ) ) ( else (cons (car lis) (rm-all-top sym (cdr lis))) ) > (rm-all-top 'a '(b (b a) a b a)) = (b (b a) b) > (rm-all-top ' (b a) '(b (b a) a b a)) = (b (b a) a b a) Linear recursion cs3180(Prasad) L14Recur

Remove-All-Expression-TopLevel (define (rm-all-top exp lis) (cond ( (null? lis) '()) ( (equal? exp (car lis)) (rm-all-top exp (cdr lis) ) ) ( else (cons (car lis) (rm-all-top exp (cdr lis)))) ) > (rm-all-top ' (b a) '(b (b a) a b a)) = (b a b a) Linear recursion cs3180(Prasad) L14Recur

Remove-All > (rm-all ' a '(b (b a) a b a)) = (b (b) b) (define (rm-all sym ll) (cond ( (null? ll) '()) ( (symbol? (car ll)) (if (eq? sym (car ll)) ( rm-all sym (cdr ll) ) ( cons (car ll) (rm-all sym (cdr ll)) ) ) ) (else (cons (rm-all sym (car ll)) (rm-all sym (cdr ll)) > (rm-all ' a '(b (b a) a b a)) = (b (b) b) Double recursion cs3180(Prasad) L14Recur

rm-all : Structural recursion Empty list (Basis case) (rm-all 'a '()) First – Atom (Recursive case) (rm-all 'a '(a b c a)) (rm-all 'a '(b b c a)) First - Nested list (Recursive case) (rm-all 'a '((a b c) d (a))) (rm-all 'a '(b (a b c) d (a))) cs3180(Prasad) L14Recur

Insertion sort (Note: creates a sorted copy) (define (insert n lon) (cond ((null? lon) (list n)) ((> n (car lon)) (cons (car lon) (insert n (cdr lon)))) (else (cons n lon)) ) (define (ins-sort lon) (if (null? lon) '() (insert (car lon) (ins-sort (cdr lon))) Precondition: second arg to insert ordered. Postcondition: insert returns an ordered list. cs3180(Prasad) L14Recur

Clojure Syntax (defn insert [n lon] (cond (empty? lon) (list n) (> n (first lon)) (cons (first lon) (insert n (rest lon))) :true (cons n lon)) ) (defn ins-sort [lon] (if (empty? lon) '() (insert (first lon) (ins-sort (rest lon))) Precondition: second arg to insert ordered. Postcondition: insert returns an ordered list. > (ins-sort '(2 3 5 4 1 0)) (0 1 2 3 4 5) cs3180(Prasad) L14Recur

Subset (uses OR and AND instead of IF) (define (subset? ss s) (or (null? ss) (and (member (car ss) s) (subset? (cdr ss) s) ) ) ) 1=> (subset? '(a b c) '(A p 1 C 2 B q r)) #t 2=> (subset? '(a b c) '(p)) #f cs3180(Prasad) L14Recur

Anonymous functions and list membership test in Clojure > ( (fn [x y] (+ x y)) 25 30) 55 > ( #(+ %1 %2) 25 30) > (some #(= 5 %) '(5 30)) true > (some #(= 5 %) '(15 30)) nil ```’’’’’ cs3180(Prasad) L14Recur

Subset in Clojure (cf. case sensitive Scheme) (defn subset? [ss s] (or (empty? ss) (and (some #(= (first ss) %) s) (subset? (rest ss) s) ) ) ) > (subset? '() '(A p 1 C 2 B q r)) true > (subset? '(a b c) '(A p 1 C 2 B q r)) nil > (subset? '(a b c) '(p a c b)) > (defn in? "true if seq contains elm" [seq elm] (some #(= elm %) seq)) #'sandbox20469/in? > (in? '( 1 2 3) 1) true > (in? '( 1 2 3) 4) nil cs3180(Prasad) L14Recur

Expression evaluation : A simple syntax directed translation expr -> x | y | z expr -> (+ expr expr) expr -> (if expr expr expr) Write a recursive definition for a function ops that counts the number of “+”s. cs3180(Prasad) L14Recur

; e is assumed to be a symbol or a list (cond ((symbol? e) 0) (define (ops e) ; e is assumed to be a symbol or a list (cond ((symbol? e) 0) ((eq? (car e) '+) (+ 1 (ops (cadr e)) (ops (caddr e))) ) ((eq? (car e) 'if) (+ (ops (cadr e)) (ops (caddr e)) (ops (cadddr e)))) (else (display 'ILLEGAL)) ) (ops 'x) (ops ' (+ y z)) (ops ' (if x (+ y z) (+ x z))) cs3180(Prasad) L14Recur

(defn third [x] (second (rest x))) (defn ops [e] ; Clojure code "e is assumed to be a symbol or a list" (cond (symbol? e) 0 (= (first e) '+) (+ 1 (ops (second e)) (ops (third e)) ) (= (first e) 'if) (+ (ops (second e)) (ops (third e)) (ops (last e))) true 'ILLEGAL )) (defn third [x] (second (rest x))) (defn fourth [x] (third (rest x))) (ops 'x) (ops ' (+ y z)) (ops ' (if x (+ y z) (+ x z))) cs3180(Prasad) L14Recur

; e is assumed to be a symbol or a list (if (member e '(x y z)) 0 (Alternative Scheme syntax with member and case-construct (not equivalent)) (define (ops e) ; e is assumed to be a symbol or a list (if (member e '(x y z)) 0 (if (symbol? e) (display 'ILLEGAL) (case (car e) ((+) (+ 1 (ops (cadr e)) (ops (caddr e))) ) ((if) (+ (ops (cadr e)) (ops (caddr e)) (ops (cadddr e))) ) (else (display 'ILLEGAL))) ) )) (ops 'x) (ops ' (+ y z)) (ops ' (if x (+ y z) (+ x z))) cs3180(Prasad) L14Recur

(ops 'x) 0 (ops '(+ y z)) 1 (ops '(if x (+ y z) (+ x z))) 2 Examples (ops 'x) 0 (ops '(+ y z)) 1 (ops '(if x (+ y z) (+ x z))) 2 cs3180(Prasad) L14Recur

(Alternative syntax in Clojure (not equivalent or robust)) (defn ops [e] ;e is assumed to legal (if (some #(= e %) '(x y z)) 0 (if (symbol? e) (println 'ILLEGAL) (case (first e) (+) (+ 1 (ops (second e)) (ops (last e))) (if) (+ (ops (second e)) (ops (third e)) (println 'ILLEGAL))) ) ) > (ops '(a)) ILLEGAL > (ops '(if x (+ y z) a)) java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number Thrown if ILLEGAL symbol returned > (println 'ILLEGAL) nil > > (ops '(if x nil  a)) java.lang.NullPointerException >   > (ops '(case x nil a)) cs3180(Prasad) L14Recur