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.

Slides:



Advertisements
Similar presentations
CMSC 330: Organization of Programming Languages Tuples, Types, Conditionals and Recursion or “How many different OCaml topics can we cover in a single.
Advertisements

Chapter 7 Introduction to Procedures. So far, all programs written in such way that all subtasks are integrated in one single large program. There is.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Introduction to Computing Science and Programming I
Tcl and Otcl Tutorial Part I Internet Computing KUT Youn-Hee Han.
Week 9: Methods 1.  We have written lots of code so far  It has all been inside of the main() method  What about a big program?  The main() method.
16-Jun-15 Recognizers. 2 Parsers and recognizers Given a grammar (say, in BNF) and a string, A recognizer will tell whether the string belongs to the.
1 Gentle Introduction to Programming Session 2: Functions.
28-Jun-15 Recognizers. 2 Parsers and recognizers Given a grammar (say, in BNF) and a string, A recognizer will tell whether the string belongs to the.
Methods. Why methods? A method gives a name to something that you want to do, so you don’t have to think about how to do it, you just do it The name should.
1 - buttons Click “Step Forward” to execute one line of the program. Click “Reset” to start over. “Play,” “Stop,” and “Step Back” are disabled in this.
Pattern matching. The if expression The else part of an if expression is optional if ( condition ) expression1 else expression2 If the condition evaluates.
Fall Week 3 CSCI-141 Scott C. Johnson.  Say we want to draw the following figure ◦ How would we go about doing this?
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.
Slides prepared by Rose Williams, Binghamton University ICS201 Lecture 19 : Recursion King Fahd University of Petroleum & Minerals College of Computer.
Loops: Handling Infinite Processes CS 21a: Introduction to Computing I First Semester,
COMPUTER PROGRAMMING. Functions What is a function? A function is a group of statements that is executed when it is called from some point of the program.
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.
Python uses boolean variables to evaluate conditions. The boolean values True and False are returned when an expression is compared or evaluated.
22-Nov-15 Recognizers. 2 Parsers and recognizers Given a grammar (say, in BNF) and a string, A recognizer will tell whether the string belongs to the.
February ,  2/16: Exam 1 Makeup Papers Available  2/20: Exam 2 Review Sheet Available in Lecture  2/27: Lab 2 due by 11:59:59pm  3/2:
CSE S. Tanimoto More-Concepts - 1 More Programming Language Concepts Currying Lazy Evaluation Polymorphism.
Monads. foo1 Method to print a string, then return its length: scala> def foo1(bar: String) = { | println(bar) | bar.size | } foo1: (bar: String)Int scala>
Functions. Motivation What is a function? A function is a self-contained unit of program code designed to accomplish a particular task. We already used.
CMSC 330: Organization of Programming Languages Operational Semantics a.k.a. “WTF is Project 4, Part 3?”
Lecture 08. Since all Java program activity occurs within a class, we have been using classes since the start of this lecture series. A class is a template.
FUNCTIONS. Midterm questions (1-10) review 1. Every line in a C program should end with a semicolon. 2. In C language lowercase letters are significant.
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
CSIS 113A Lecture 5 Functions. Introduction to Functions  Building Blocks of Programs  Other terminology in other languages:  Procedures, subprograms,
Haskell Chapter 5, Part II. Topics  Review/More Higher Order Functions  Lambda functions  Folds.
H ASKELL Session 2 Ronald L. Ramos Proglan DLS-CSB 2 nd Term SY
1 Recursion Recursive function: a function that calls itself (directly or indirectly). Recursion is often a good alternative to iteration (loops). Its.
Quiz 3 Topics Functions – using and writing. Lists: –operators used with lists. –keywords used with lists. –BIF’s used with lists. –list methods. Loops.
CSC 1010 Programming for All Lecture 5 Functions Some material based on material from Marty Stepp, Instructor, University of Washington.
Lets and Loops Tail Recursion.
Chapter 9: Value-Returning Functions
4. Java language basics: Function
Recursion.
Types CSCE 314 Spring 2016.
Recursion DRILL: Please take out your notes on Recursion
Lesson #6 Modular Programming and Functions.
COMP 170 – Introduction to Object Oriented Programming
Lesson #6 Modular Programming and Functions.
Haskell.
Functions.
Lesson #6 Modular Programming and Functions.
Call Stacks, Arguments and Returns
Important Concepts from Clojure
Control Structures (Structured Programming) for controlling the procedural aspects of programming CS1110 – Kaminski.
Important Concepts from Clojure
FP Foundations, Scheme In Text: Chapter 14.
CISC101 Reminders Assn 3 due tomorrow, 7pm.
Plus a few random things
C Programming Getting started Variables Basic C operators Conditionals
Plus a few random things
Lesson #6 Modular Programming and Functions.
Recursion Taken from notes by Dr. Neil Moore
Recursion, Higher-order-functions
Important Concepts from Clojure
February , 2009 CSE 113 B.
The structure of programming
Plus a few random things
Control Structures (Structured Programming) for controlling the procedural aspects of programming CS1110 – Kaminski.
Just Enough Java 17-May-19.
CISC101 Reminders Assignment 3 due today.
Plus a few random things
PROGRAMMING IN HASKELL
Plus a few random things
Plus a few random things
Presentation transcript:

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 does, in any recursive branch Example #1: def collatz(n: Int): Int = { if (n == 1) 1 else if (n % 2 == 0) collatz(n / 2) else collatz(3 * n + 1) } There is no recursion if n == 1 In each other case, the last operation is a recursive call A good compiler can replace tail recursion with a loop def collatz(n: Int): Int = { var nn = n while (nn != 1) { if (nn % 2 == 0) nn = nn / 2 else nn = 3 * nn + 1 } nn } This is desirable because loops don’t cause the stack to grow

3 Factorial Here’s everybody’s first recursive function: def factorial(n: Long): Long = { if (n == 0 || n == 1) 1 else n * factorial(n - 1) } This is not tail recursive, because there is a multiplication that is performed after the recursive call Can the factorial function be rewritten to be tail recursive? Yes it can, and the technique for doing so can be applied to a lot of other functions, so it’s worth learning I’ll leave this as an exercise, since if you figure it out yourself you are much more likely to remember how to do it Here are three hints, which you can uncover one at at time if you get stuck (the text is white; select it and change the color) 1.Use two functions; the second one should do all the recursive work 2.The second function should have two parameters 3.One of the parameters should be 1

4 Currying Here’s a function to find the hypotenuse of a right triangle: def hyp(a: Double, b: Double) = sqrt(a * a + b * b) Suppose you were to call it this way: val h = hyp(5.0, 12.0) You can think of this as the compiler substituting a value for each variable Suppose we substitute 5.0 for a first: sqrt(a * a + b * b) becomes sqrt(5.0 * b * b) And afterwards substitute 12.0 for b : sqrt(5.0 * b * b) becomes sqrt(5.0 * * 12.0) which is then calculated (giving 13.0 ) Now suppose we stop after step 1 What we have after step 1 is a partially applied function Currying is a way to make partially applied functions

5 Currying in Scala Instead of giving our hyp function one parameter list, we can give it two parameter lists: scala> def hyp(a: Double)(b: Double) = sqrt(a * a + b * b) hyp: (a: Double)(b: Double)Double Now when we call it, we have to give it two argument lists, not just one list with two arguments: scala> hyp(5)(12) res2: Double = 13.0 We can stop with just the first list (but we need to use an underscore to tell Scala we know we left something out) scala> val h5 = hyp(5) _ h5: (Double) => Double = scala> h5(12) res3: Double = 13.0 With more parameters, we can break up the parameter list any way we like def foo(a: Int)(b: Int, c: String)(d: Double) = {...}

6 Another way to curry Here’s a function written in the usual way: scala> def avg(a: Double, b: Double) = (a + b) /2.0 avg: (a: Double,b: Double)Double Here we’re calling it in the usual way: scala> avg(5, 12) res6: Double = 8.5 Here we’re calling it with the first argument specified ( 5 ) but the second argument unspecified ( _ ) scala> val a5 = avg(5, _: Double) a5: (Double) => Double = Notice that we had to specify the type of the omitted parameter Also pay careful attention to the type of the result Now let’s call our new, curried function: scala> a5(12) res7: Double = 8.5

7 Call-by-name parameters When using a function as a argument, the function parameter is used only when requested: Example: def foo(f: Int => Int) { println("In foo with " + f(10)) } foo(factorial) // prints "In foo with " Other types of parameters are first evaluated, then their values are passed into the function: Example: def foo(n: Long) { println(n} } foo(factorial(10)) What is passed into the function is the number By using => as the first part of the type in a function definition, the function will treat a parameter as a function Example: def foo(f: => Int) { println("In foo with " + f(10)) } foo(factorial) // prints "In foo with " This is an example of call-by-name

8 Lazy evaluation Lazy evaluation is a technique whereby a computation is not actually performed until and unless the result is needed lazy val xxx = someLongAndExpensiveComputation... if (we decide that we need xxx) { use xxx // The computation is done here } Ranges in Scala are lazy scala> println((1 to Int.MaxValue) take 3) Range(1, 2, 3) The Stream class supports lazy evaluation, and therefore allows “infinite” data structures (example from Programming Scala by Wampler & Payne) scala> lazy val fib: Stream[Int] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(p => p._1 + p._2))) fib: Stream[Int] = cons is like :: scala> fib.take(10).print 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, empty

9 Building control structures When calling a curried function, you can replace the last set of parentheses with braces scala> hyp(5) { 12 } res27: Double = 13.0 You can only put expressions inside parentheses, but you can put multiple “statements” inside braces This, plus currying, plus lazy evaluation, allows you to build your own control structures scala> def repeat(n: Int)(body: => Unit) { | for (i Unit)Unit scala> repeat(3) { | println("Hello") | } Hello Hello Hello

XML XML is built into Scala as a data type—not just as something supported by some package scala> val name = "Dave" name: java.lang.String = Dave scala> val x = Hello, {name}! x: scala.xml.Elem = Hello, Dave! 10

DSL Scala has superb support for Domain Specific Languages A parser combinator is a function that takes only other functions as parameters and returns only functions BNF is essentially built into Scala as a combinator library Example: Arithmetic expressions (adapted from Odersky, pp ) BNF: ::= { “+” | “-” } ::= { “*” | “/” } ::= | “(” “)” Scala ( ~ is used to indicate one thing follows another in sequence): import scala.util.parsing.combinator._ class Arith extends JavaTokenParsers { def expr: Parser[Any] = term ~ rep("+" ~ term | "-" ~ term) def term: Parser[Any] = factor ~ rep("*" ~ factor | "/" ~ factor) def factor: Parser[Any] = floatingPointNumber | "(" ~ expr ~ ")" } 11

The End 12