Clojure Template Tail Recursion. Hello, Factorial! The factorial function is everybody’s introduction to recursion (defn factorial-1 [n] (if (zero? n)

Slides:



Advertisements
Similar presentations
Higher-Order Functions and Loops c. Kathi Fisler,
Advertisements

More about functions Plus a few random things. 2 Tail recursion A function is said to be tail recursive if the recursive call is the very last thing it.
Tail Recursion. Problems with Recursion Recursion is generally favored over iteration in Scheme and many other languages – It’s elegant, minimal, can.
1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
CSE 341 Lecture 16 More Scheme: lists; helpers; let/let*; higher-order functions; lambdas slides created by Marty Stepp
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Recursion. Recursion is a powerful technique for thinking about a process It can be used to simulate a loop, or for many other kinds of applications In.
Tail Recursion. Problems with Recursion Recursion is generally favored over iteration in Scheme and many other languages It’s elegant, minimal, can be.
Helper functions: when extra arguments are needed Consider this problem: we want a function index_items that takes a list L and gives a number to each.
Recursion Great fleas have little fleas upon their backs to bite 'em, And little fleas have lesser fleas, and so ad infinitum. And the great fleas themselves,
>(setf oldlist ) Constructing a list We know how to make a list in lisp; we simply write it: ‘4321( ) What if we want a new list with that list as a part?
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
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.
Tail Recursion. Problems with Recursion Recursion is generally favored over iteration in Scheme and many other languages – It’s elegant, minimal, can.
Conditionals and Recursion "To iterate is human, to recurse divine." - L. Peter Deutsch.
Clojure 3 Recursion, Higher-order-functions 27-Aug-15.
Solving N-Queens in Clojure
Clojure 2 Feb 7,
Feb 7, 2015 Thinking in Clojure. Jumping in We’ll quickly go through Clojure’s data types, some basic functions, and basic syntax Then we’ll get to the.
Function Design in LISP. Program Files n LISP programs are plain text –DOS extensions vary; use.lsp for this course n (load “filename.lsp”) n Can use.
Using the List Template CS 5010 Program Design Paradigms “Bootcamp” Lesson TexPoint fonts used in EMF. Read the TexPoint manual before you delete.
Using the List Template CS 5010 Program Design Paradigms “Bootcamp” Lesson 4.2 TexPoint fonts used in EMF. Read the TexPoint manual before you delete this.
Sometimes Structural Recursion Isn't Enough CS 5010 Program Design Paradigms “Bootcamp” Lesson 8.1 TexPoint fonts used in EMF. Read the TexPoint manual.
Solving Your Problem by Generalization CS 5010 Program Design Paradigms “Bootcamp” Lesson © Mitchell Wand, This work is licensed under.
Fall 2016 Images from Sebesta: Copyright © 2012 Addison-Wesley. All rights reserved.
Recursion Great fleas have little fleas upon their backs to bite 'em, And little fleas have lesser fleas, and so ad infinitum. And the great fleas themselves,
CS314 – Section 5 Recitation 9
Lets and Loops Tail Recursion.
List Algorithms Taken from notes by Dr. Neil Moore & Dr. Debby Keen
Tail Recursion.
CS 5010 Program Design Paradigms “Bootcamp” Lesson 5.2
More About Recursive Data Types
Class 11: Two-argument recursion
PPL Lazy Lists.
More Recursive Data Types
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Dan Grossman Spring 2017.
Halting Functions for Tree-Like Structures
Closures and Streams cs784(Prasad) L11Clos
Recursion, Tail Recursion
Recursion Great fleas have little fleas upon their backs to bite 'em, And little fleas have lesser fleas, and so ad infinitum. And the great fleas themselves,
6.001 SICP Data abstractions
Important Concepts from Clojure
Important Concepts from Clojure
List Algorithms Taken from notes by Dr. Neil Moore
The Metacircular Evaluator
Solving Your Problem by Generalization
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Dan Grossman Spring 2013.
Plus a few random things
The Metacircular Evaluator
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Dan Grossman Autumn 2018.
Recursion Great fleas have little fleas upon their backs to bite 'em, And little fleas have lesser fleas, and so ad infinitum. And the great fleas themselves,
Recursion Great fleas have little fleas upon their backs to bite 'em, And little fleas have lesser fleas, and so ad infinitum. And the great fleas themselves,
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Zach Tatlock Winter 2018.
Recursion, Higher-order-functions
Announcements Quiz 5 HW6 due October 23
Important Concepts from Clojure
Abstraction and Repetition
Clojure 2 22-Apr-19.
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Dan Grossman Spring 2016.
Plus a few random things
Developing Programs for Family Trees
Thinking in Clojure 8-Jun-19.
Plus a few random things
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Dan Grossman Spring 2019.
Plus a few random things
Brett Wortzman Summer 2019 Slides originally created by Dan Grossman
Plus a few random things
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Dan Grossman Autumn 2017.
Presentation transcript:

Clojure Template Tail Recursion

Hello, Factorial! The factorial function is everybody’s introduction to recursion (defn factorial-1 [n] (if (zero? n) 1 (* n (factorial-1 (dec n))))) (factorial-1 10) ;=> The problem with this function is that every recurrence increases the stack size Not a problem if the number of recurrences is small 2

Tail recursion, or tail call recursion A function is tail recursive if, for every recursive call in the function, the recursive call is the last thing done in the function In this situation, the compiler can replace the recursion with a simple loop, which does not add frames to the stack The programmer still does not have (or need!) loops In factorial-1, (* n (factorial-1 (dec n))) the multiplication keeps it from being tail recursive To make the factorial function tail recursive, we need to somehow bring the multiplication into the parameter list 3

Adding an accumulator (defn factorial-two-args [acc n] (if (zero? n) acc (recur (* acc n) (dec n)))) One way to think of this is as “pumping” information from the input parameter to the accumulator 4

Using factorial-two-args (factorial-helper 1 10) ;=> (factorial-helper 0 10) ;=> 0 (factorial-helper 10 1) ;=> 10 5

Use of a fa ҫ ade We can use a façade along with the “real” function (now called “factorial-helper” (defn factorial-2 [n] (factorial-helper 1 n)) (defn factorial-helper [acc n] (if (zero? n) acc (recur (* acc n) (dec n)))) This adds an unnecessary function to those available to the user 6

When tail recursion isn’t The function (defn factorial-? [acc n] (if (zero? n) acc (factorial-? (* acc n) (dec n)))) is tail recursive, but that doesn’t do you any good unless you tell the compiler to replace the recursion with a loop Use recur instead of factorial-? in the tail call 7

Polymorphic parameters Clojure functions can be defined with more than one parameter list (defn factorial-3 ([n] (factorial-3 1 n)) ([acc n] (if (zero? n) acc (recur (* acc n) (dec n)) ) ) ) 8

Defining a local helper function (defn factorial-4 [number] (let [factorial-helper (fn [acc n] (if (zero? n) acc (recur (* acc n) (dec n))))] (factorial-helper 1 number))) 9

let and loop In the previous example, we used (let [factorial-helper (fn [acc n] …]…) to define a helper function with local scope The general form is (let [ name1 value1, …, nameN valueN ] code ) and we use recur in the code to tell the compiler to turn this into a loop To simplify this, Clojure provides a loop construct: (loop [ name1 value1, …, nameN valueN ] code ) This is not a loop; it’s a request to the compiler to turn tail recursion into a loop! The name/value pairs are initial values of parameters The call to recur in the body supplies new values for the parameters 10

let and loop comparison (defn factorial-4 [number] (let [factorial-helper (fn [acc n] (if (zero? n) acc (recur (* acc n) (dec n))))] (factorial-helper 1 number))) (defn factorial-5 [number] (loop [acc 1, n number] (if (zero? n) acc (recur (* acc n) (dec n))))) 11

shallow-reverse (defn shallow-reverse-1 ([lst] (shallow-reverse () lst)) ([acc lst] (if (empty? lst) acc (recur (cons (first lst) acc) (rest lst)) ) ) ) (defn shallow-reverse-2 [lst] (loop [acc (), lst-2 lst] (if (empty? lst-2) acc (recur (cons (first lst-2) acc) (rest lst-2)) ) ) ) 12

find-first-index Problem: Find the index of the first thing in a sequence that satisfies a given predicate (defn find-first-index [pred a-seq] (loop [acc 0, b-seq a-seq] (cond (empty? b-seq) nil (pred (first b-seq)) acc :else (recur (inc acc) (rest b-seq)) ) ) ) 13

Find the average of a sequence (defn avg [a-seq] (loop [sum 0, n 0, b-seq a-seq] (if (empty? b-seq) (/ sum n) (recur (+ sum (first b-seq)) (inc n) (rest b-seq)) ) ) ) Notice that the loop takes 3 arguments 14

Summary: Tail recursion Tail recursion saves stack space, but the code is somewhat harder to read When the recursion is guaranteed to be “not too deep,” you can ignore tail recursion Tail recursion isn’t too hard, as long as you remember the “bucket” analogy 15 …and don’t fortet to use recur !

16 The End