Functions in Scala allow dividing programs into smaller, manageable pieces that perform specific tasks. Some key features of functions in Scala include local functions defined inside other functions, first-class functions that can be passed as arguments, partially applied functions, closures that close over variables from outer scopes, and repeated/variable length parameters indicated with an asterisk. Tail recursion makes recursive functions more efficient by ensuring the recursive call is the last operation.
In this document
Powered by AI
Introduction to functions in Scala and agenda components including function types and characteristics.
A function groups statements for specific tasks, improving program organization.
Functions exist independently while methods belong to classes; methods require instances.
Syntax for defining and calling functions in Scala, including an example of an addition function.
Local functions are defined within other functions to encapsulate logic like calculating factorial.
Functions can be treated as values, allowing assignments and manipulations, with simple examples.
Use of higher-order functions like foreach and filters to work with collections.
Functions can be partially applied, where not all parameters are provided, simplifying function calls.
Closures capture variables from their surrounding context, showcasing bound and free variables.
Last parameters in functions can be repeated, illustrated with an example of counting input size.
Explains tail recursion properties and how to rewrite functions to optimize recursive calls.
Discusses memory efficiency in tail recursion by eliminating the need for storing intermediate values.
AGENDA ● What is Functions. ● Local Functions. ● First Class Function ● Placeholders ● Partially Applied Functions ● Closures ● Repeated Parameters ● Tail Recursion
3.
What is Function ➢ A function is a group of statements that together perform a task. ➢ When program gets larger, you need some way to divide them into smaller more manageable pieces. ➢ How you divide is up to you, but logically each function perform a specific task.
4.
Difference Between FunctionsAnd Methods Functions Methods ➢ Functions have independent ➢ Methods do not have existence means they can be independent existence defined outside of the class. they are always defined with in class. ➢ Methods are called using ➢ Functions are called instance or object. independently.
5.
Functions Declaration AndDefinition def functionName ([list of parameters]) : [return type] def functionName ([list of parameters]) : [return type] = { function body return [expr] } def addInt( a:Int, b:Int ) = { var sum = 0 sum = a + b sum }
6.
Calling Functions Following isthe standard way to call a method: object Test { def main(args: Array[String]) { println( "Returned Value : " + addInt(5,7) ) } def addInt( a:Int, b:Int ) : a+b }
7.
Local Functions Scala allowsyou to define functions inside a function are called local functions. def factorial(i: Int): Int = { def fact(i: Int, factor: Int): Int = { if (i <= 1) factor else fact(i - 1, i * factor) } fact(i, 1) } }
8.
First Class Functions Scalasupports first-class functions,which means you can express functions in function literal syntax, ie. , (x: Int) => x + 1, A function literal is compiled into a class that when instantiated at run- time is a function value. For eg : var increase = (x: Int) => x + 1 increase(10)
9.
Functions Applied OnFunctions foreach: It takes a function as an argument and invokes that function on each of its elements. For eg: val someNumbers = List(-11, -10, -5, 0, 5, 10) SomeNumbers foreach((x: Int) => println(x))
10.
Filters: Scala provides a number of ways to leave out redundant information. This method selects those elements of a collection that pass a test the user supplies. For eg: someNumbers.filter(x => x > 0) someNumbers.filter(_> 0) To make a function literal even more concise, you can use underscores as placeholders for one or more parameters, so long as each parameter appears only one time within the function literal.
11.
Partially Applied Functions Replacethe entire list of parameter. For example, rather than writing println(_), you could write println _. val someNumbers = List(-11, -10, -5, 0, 5, 10) someNumbers.foreach(println _) A partially applied function is an expression in which you don’t supply all of the arguments needed by the function. Instead, you supply some, or none, of the needed arguments.
12.
Closures A closureis a function whose return value depends on the value of one or more variables declared outside this function. For eg: val multiplier = (i:Int) => i * 10 ➢ A statement with no free variable is called close term. val multiplier = (i:Int) => i * factor ➢ A statement with free variable is called open term. factor is a free variable i is a bound variable The function value (the object) that’s created at runtime from this function literal is called a closure.
13.
REPEATED PARAMETERS Scala allowsyou to indicate that the last parameter to a function may be Repeated. This allows clients to pass variable length argument lists to the Function. For eg: def Size(is: Int*) = is.length println(Size(2,3,4,5,6,67)) To denote a repeated parameter, place an asterisk after the type of the parameter.
14.
Tail Recursion In orderfor a recursive call to be tail recursive, the call back to the function must be the last action performed in the function. def factorial(number:Int) : Int = { if (number == 1) return 1 number * factorial (number - 1) } println(factorial(5)) This is not a tail recursive Function, because the total returned from the recursive call is being multiplied by number, the recursive call is NOT the last action performed in the function.
15.
To take thisexample and make it tail recursive, we must make sure that last action performed in the function is the recursive call. def factorial(fact: Int, number: Int) : Int = { if(number == 1) return fact factorial(number * fact, number - 1) } print(factorial(1,5))
16.
Why Tail Recursion? Inthe recursion example, notice how the result of each call must be remembered, to do this each recursive call requires an entry on the stack until all recursive calls have been made. This makes the recursive call more expensive in terms of memory. While in the tail recursive example, there are no intermediate values that need to be stored on the stack, the intermediate value is always passed back as a parameter.