Computer Science 312 Making choices Tail Recursion

Slides:



Advertisements
Similar presentations
Programming Languages and Paradigms
Advertisements

Programming Languages and Paradigms The C Programming Language.
Types of Recursive Methods
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Lecture 3: Topics If-then-else Operator precedence While loops Static methods Recursion.
Selection Statements choice of one among several blocks of code Java supports 3 kinds of selection statements: if statement – selects one block or leaves.
Computer Science 210 Computer Organization Introduction to C.
CSCI 1100/1202 January 16, Why do we need variables? To store intermediate results in a long computation. To store a value that is used more than.
1 Chapter 9 Scope, Lifetime, and More on Functions.
PrasadCS7761 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language.
Operators, Functions and Modules1 Pattern Matching & Recursion.
Haskell. 2 GHC and HUGS Haskell 98 is the current version of Haskell GHC (Glasgow Haskell Compiler, version 7.4.1) is the version of Haskell I am using.
0 REVIEW OF HASKELL A lightening tour in 45 minutes.
0 PROGRAMMING IN HASKELL Chapter 7 - Defining Functions, List Comprehensions.
Computer Science Department Data Structure & Algorithms Lecture 8 Recursion.
Computer Science 101 Introduction to Programming.
CPS120: Introduction to Computer Science
Expressions and Statements. Expressions Literals and identifiers are expressions More complex expressions are built from simple expressions by the application.
ITIP © Ron Poet Lecture 12 1 Finding Out About Objects.
Overview of the Haskell 98 Programming Language
Practical Erlang Programming Basic Erlang. © Erlang Training and Consulting Ltd2Basic Erlang Practical Erlang Programming.
CSC115 Introduction to Computer Programming Zhen Jiang Dept. of Computer Science West Chester University West Chester, PA 19383
School of Computer Science & Information Technology G6DICP - Lecture 4 Variables, data types & decision making.
0 PROGRAMMING IN HASKELL Chapter 4 - Defining Functions.
Haskell. GHC and HUGS Haskell 98 is the current version of Haskell GHC (Glasgow Haskell Compiler, version 7.4.1) is the version of Haskell I am using.
Defining Classes Modules and ADTs CSCE 314 Spring 2016.
An introduction to functional programming using Haskell CENG242 –Recitation 1.
Lecture 16: Advanced Topic: Functional Programming CS5363 Compiler and Programming Languages.
CS314 – Section 5 Recitation 9
Basic concepts of C++ Presented by Prof. Satyajit De
Conditional Expressions
The Machine Model Memory
Types CSCE 314 Spring 2016.
Computer Science 210 Computer Organization
dr Robert Kowalczyk WMiI UŁ
Making Choices with if Statements
Control Structures Combine individual statements into a single logical unit with one entry point and one exit point. Used to regulate the flow of execution.
A lightening tour in 45 minutes
C++, OBJECT ORIENTED PROGRAMMING
Haskell.
CSC115 Introduction to Computer Programming
Advanced Programming Behnam Hatami Fall 2017.
Computer Science 210 Computer Organization
Recursion "To understand recursion, one must first understand recursion." -Stephen Hawking.
Advanced Programming in Java
Haskell Strings and Tuples
Computer Science 312 Haskell Lists 1.
Chapter 6: Functions Starting Out with C++ Early Objects Ninth Edition
CMPE 152: Compiler Design October 2 Class Meeting
Haskell Dealing with impurity 30-Nov-18.
Variables Numbers can be stored and retrieved while a program is running if they are given a home. The way that integers and decimal numbers are stored.
Recursion.
Basic Syntax and Semantics
Type & Typeclass Syntax in function
PROGRAMMING IN HASKELL
CSCE 314: Programming Languages Dr. Dylan Shell
Haskell Types, Classes, and Functions, Currying, and Polymorphism
Fundamentals of Functional Programming
Chapter 17 Recursion.
Haskell Dealing with impurity 8-Apr-19.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
CS210- Lecture 3 Jun 6, 2005 Announcements
Haskell Dealing with impurity 29-May-19.
Laziness and Its Consequences
PROGRAMMING IN HASKELL
Haskell Dealing with impurity 28-Jun-19.
Controlling Program Flow
Corresponds with Chapter 5
Presentation transcript:

Computer Science 312 Making choices Tail Recursion Local contexts with where clauses Dealing with Errors Modules, Imports, Exports 1

Making Choices in Haskell Use a set of function clauses, where pattern matching selects the option (factorial, fibonacci, etc.) factorial :: Integer -> Integer factorial 1 = 1 factorial n = n * factorial (n – 1) fibonacci:: Integer -> Integer fibonacci 1 = 1 fibonnaci 2 = 1 fibonacci n = fibonacci (n – 1) + fibonacci (n – 2)

Making Choices in Haskell Simple function clauses will not work in the cases of functions like max, min, and sum, where the option depends on an explicit condition Prelude> max 3 4 4 Prelude> sum 1 4 10

Use a Function Guard Indentation is significant! <function name> <parameters> | <Boolean expression-1> = <expression-1> … | <Boolean expression-n> = <expression-n> | otherwise = <default expression> myMax :: Ord a => a -> a -> Bool myMax x y | x > y = x | otherwise = y sum :: Integer -> Integer -> Integer sum lower upper | lower == upper = lower | otherwise = lower + sum (lower + 1) upper Indentation is significant!

Or Use an if-else Expression <function name> <parameters> = if <Boolean expression-1> then <expression-1> … else if <Boolean expression-n> then <expression-n> else <default expression> myMax :: Ord a => a -> a -> Bool myMax x y = if x > y then x else y Syntactic sugar for function guards

Which Form to Prefer? factorial :: Integer -> Integer factorial n = n * factorial (n – 1) factorial :: Integer -> Integer factorial n | n == 1 = 1 | otherwise = n * factorial (n – 1) factorial :: Integer -> Integer factorial n = if n == 1 then 1 else n * factorial (n – 1)

The case Expression interpretCommand :: Char -> String interpretCommand letter = case toUpper letter of 'N' -> newFile 'O' -> openFile 'S' -> saveFile 'Q' -> quitProgram _ -> handleError Like a switch statement in C or Java, but returns a value The _ symbol is a wildcard that matches any pattern

How Costly Is Recursion? factorial :: Integer -> Integer factorial 1 = 1 factorial n = n * factorial (n – 1) fib:: Integer -> Integer fib 1 = 1 fib 2 = 1 fib n = fib (n – 1) + fib (n – 2) Factorial is O(n) in running time and memory Fibonacci is O(kn) in running time and O(logn) in memory The growth of memory is due to cells for each function call pushed onto the runtime stack

Tail Recursion factorial :: Integer -> Integer factorial 1 = 1 factorial n = n * factorial (n – 1) tailFactorial :: Integer -> Integer -> Integer tailFactorial 1 result = result tailFactorial n result = tailFactorial (n – 1) (n * result) In tail recursion, there is no work remaining to be done after a recursive call The compiler can translate this to a loop with a single record for state variables on the stack

Tracing the Two Versions factorial 3 -> 3 * factorial 2 -> 2 * factorial 1 -> <- 1 <- 2 <- 6 tailFactorial 3 1 -> tailFactorial 2 3 -> tailFactorial 1 6 -> <- 6

Maintain the Interface with a Helper factorial :: Integer -> Integer factorial n = tailFactorial n 1 tailFactorial :: Integer -> Integer -> Integer tailFactorial 1 result = result tailFactorial n result = tailFactorial (n – 1) (result * n)

Nest the Helper in a where Clause factorial :: Integer -> Integer factorial n = tailFactorial n 1 where tailFactorial :: Integer -> Integer -> Integer tailFactorial 1 result = result tailFactorial n result = tailFactorial (n – 1) (result * n) If a function is just a helper for another function, you can define it locally within a where clause The scope of the where is determined by indentation

Nest Function in a where Clause factorial :: Integer -> Integer factorial n = tailFactorial n 1 where tailFactorial :: Integer -> Integer -> Integer tailFactorial 1 result = result tailFactorial n result = tailFactorial (n – 1) (result * n) fib :: Integer -> Integer fib n = tailFib 1 0 n where tailFib:: Integer -> Integer -> Integer -> Integer tailFib a b 1 = a tailFib a b n = tailFib (a + b) a (n – 1) Both functions are now linear in running time and constant in memory usage

Dealing with Errors factorial :: Integer -> Integer factorial 0 = 1 factorial n | n < 0 = error "Argument n must be >= 0" | otherwise = n * factorial (n – 1) The error function halts the program with an error message

Modules Prelude – the standard module, always available Data – organizes many data types under submodules Data.Char – character and text processing functions Data.Array – array processing functions Module names are capitalized

Full Imports Like from math import * Prelude> import Data.Char Prelude Data.Char> isLetter('K') True Prelude Data.Char> isLower('K') False Prelude Data.Char> digitToInt('9') 9 Prelude Data.Char> ord('9') 57 Prelude Data.Char> chr(57) '9' Like from math import *

Partial Imports Like from math import sqrt, etc. Prelude> import Data.Char (isLetter, isLower, digitToInt, ord) Prelude Data.Char> isLetter('K') True Prelude Data.Char> isLower('K') False Prelude Data.Char> digitToInt('9') 9 Prelude Data.Char> ord('9') 57 Prelude Data.Char> chr(57) '9' Like from math import sqrt, etc. Avoids name conflicts with other functions

Qualified Imports – The Full Slate Prelude> import qualified Data.Char Prelude Data.Char> Data.Char.isLetter('K') True Prelude Data.Char> Data.Char.isLower('K') False Prelude Data.Char> Data.Char.digitToInt('9') 9 Prelude Data.Char> Data.Char.ord('9') 57 Prelude Data.Char> Data.Char.chr(57) '9' Like import math Avoids name conflicts with these and other functions

Qualified Imports – A Subset Prelude> import qualified Data.Char (isLetter, isLower, digitToInt, ord) Prelude Data.Char> Data.Char.isLetter('K') True Prelude Data.Char> Data.Char.isLower('K') False Prelude Data.Char> Data.Char.digitToInt('9') 9 Prelude Data.Char> Data.Char.ord('9') 57 Prelude Data.Char> Data.Char.chr(57) '9' Avoids name conflicts with just these functions, And the others are not imported at all

Unrestricted Exports {- File: NewMath.hs Author: Ken Lambert Purpose: provides some simple math functions -} module NewMath where factorial :: Integer -> Integer factorial n = tailFactorial n 1 tailFactorial :: Integer -> Integer -> Integer tailFactorial 1 result = result tailFactorial n result = tailFactorial (n – 1) (result * n) Both factorial and tailFactorial are visible to importers

Restricted Exports {- File: NewMath.hs Author: Ken Lambert Purpose: provides some simple math functions -} module NewMath (factorial) where factorial :: Integer -> Integer factorial n = tailFactorial n 1 tailFactorial :: Integer -> Integer -> Integer tailFactorial 1 result = result tailFactorial n result = tailFactorial (n – 1) (result * n) Now the helper function tailFactorial is hidden from importers

For next time Introduction to lists, strings and tuples Homework assignment #1 is available on Sakai!