functions in scala

33
Functions In Scala Functions In Scala Satendra Kumar Software Consultant Knoldus Software LLP Satendra Kumar Software Consultant Knoldus Software LLP

Upload: knoldus-software-llp

Post on 15-Jul-2015

982 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Functions In Scala

Functions In ScalaFunctions In Scala

Satendra Kumar Software Consultant

Knoldus Software LLP

Satendra Kumar Software Consultant

Knoldus Software LLP

Page 2: Functions In Scala

Topics CoveredTopics CoveredFunction

Function Literal

Higher Order Function

Partial Function

Partial Applied Function

Nested Function

Closures

Function

Function Literal

Higher Order Function

Partial Function

Partial Applied Function

Nested Function

Closures

Page 3: Functions In Scala

FunctionFunction

A function is a type of procedure or routine. Which takes the input and return a value.

function define like:

def square(x: Int): Int = { x * x }

* Function always return a single value.

Page 4: Functions In Scala

Function Literal Function Literal

Function literal a function with no name in Scala source code, specified with function literal syntax.

For example: (x: Int, y: Int) => x + y

Anonymous function Another name for function literal.

Page 5: Functions In Scala

Function Literal Function Literal

Function literal a function with no name in Scala source code, specified with function literal syntax.

For example: (x: Int, y: Int) => x + y

Anonymous function Another name for function literal.

A function literal is compiled into a class that when instantiated at runtime is a function value. Thus the distinction between function literals and values is that function literals exist in the source code, whereas function values exist as objects at runtime. The distinction is much like that between classes (source code) and objects (runtime).

Page 6: Functions In Scala

Function Literal Function Literal

val fun2=(x: Int, y: Int) => x + y

val fun3 = (x: Int, y: Int, z: Int) => x + y + z

Page 7: Functions In Scala

Higher Order Function

def filter(p: (A) Boolean): List[A]⇒

def map[B](f: (A) ⇒ B): List[B]

def foreach(f: (A) Unit): Unit⇒

Higher-order functions are functions that can either take other functions as arguments or return them as results.

Higher order functions:

def collect[B](pf: PartialFunction[A, B]): List[B]

def calFun(operator: String): (Int, Int) => Int

Page 8: Functions In Scala

Higher Order Function

(1 to 100).filter { (number:Int) => number % 2 == 0 }

Page 9: Functions In Scala

Higher Order Function

(1 to 100).toList.filter { (number:Int) => number % 2 == 0 }

Or

(1 to 100).toList.filter { number => number % 2 == 0 }

Page 10: Functions In Scala

Higher Order Function

(1 to 100).toList.filter { (number:Int) => number % 2 == 0 }

Or

(1 to 100).toList.filter { number => number % 2 == 0 }

Or

(1 to 100).toList.filter { _ % 2 == 0 }

Page 11: Functions In Scala

Higher Order Function

def calFun(operator: String): (Int, Int) => Int = { (a: Int, b: Int) => operator match { case "+" => a + b case "-" => a - b case "*" => a * b case "/" => a / b } }

Page 12: Functions In Scala

Partial Function

A partial function is a function that is not defined for all possible arguments of the specified type.

In Scala :A partial function of type PartialFunction[A, B] is a unary function where the domain does not necessarily include all values of type A.

The function isDefinedAt allows to test dynamically if a value is in the domain of the function.

val isEven: PartialFunction[Int, String] = { case x if x % 2 == 0 => x + " is even" }

Page 13: Functions In Scala

Partial Function And Function

Partial Function: val isEven: PartialFunction[Int, String] = { case x if x % 2 == 0 => x + " is even" }

Function:def isEven(x: Int): String = { require(x % 2 == 0) x + " is even" }

Both are doing same thing so what is difference between Function and Partial Function ?

Page 14: Functions In Scala

Diff B/W Partial Function And FunctionThe main distinction between PartialFunction and Function is that the user of a PartialFunction may choose to do something different with input that is declared to be outside its domain.

For example:

val sample = 1 to 10 val isEven: PartialFunction[Int, String] = { case x if x % 2 == 0 => x + " is even" }

// the method collect can use isDefinedAt to select which members to collect val evenNumbers = sample collect isEven

val isOdd: PartialFunction[Int, String] = { case x if x % 2 == 1 => x + " is odd" }

// the method orElse allows chaining another partial function to handle // input outside the declared domain val numbers = sample map (isEven orElse isOdd)

Page 15: Functions In Scala

match

def checkNumber(a: Int):String = a match { case x if x % 2 == 0 => x + " is even" case x if x % 2 == 1 => x + " is odd" case _ => "Neither even nor odd" }

match is method or keyword ?

Page 16: Functions In Scala

match

def checkNumber(a: Int):String = a match { case x if x % 2 == 0 => x + " is even" case x if x % 2 == 1 => x + " is odd" case _ => "Neither even nor odd" }

match is method or keyword ?

Answer => Keyword

Page 17: Functions In Scala

match

def checkNumber(a: Int):String = a match { case x if x % 2 == 0 => x + " is even" case x if x % 2 == 1 => x + " is odd" case _ => "Neither even nor odd" }

match is method or keyword ?

Answer => Keyword

Why keyword ?

Page 18: Functions In Scala

Why match is keyword ?

From: David Pollak <dpp <at> athena.com>

Subject: match question

Newsgroups: gmane.comp.lang.scala.debate

Date: 2008-01-21 20:30:29 GMT (6 years, 49 weeks, 5 days, 3 hours and 8 minutes ago)

Folks,Why is 'match' a language level construct rather than a method on Any?Wouldn't "def match[XX](func: PartialFunction[this.type, XX]): XX = ..."result in syntactically identical code?Thanks,David

Page 19: Functions In Scala

Why match is keyword ?From: martin odersky <martin.odersky <at> epfl.ch>

Subject: Re: match question

Newsgroups: gmane.comp.lang.scala.debate

Date: 2008-01-21 21:25:02 GMT (6 years, 49 weeks, 5 days, 2 hours and 27 minutes ago)

On Jan 21, 2008 9:35 PM, Erik Engbrecht <erik.engbrecht <at> gmail.com> wrote:> I always wondered that...>> Good question.>> On 1/21/08, David Pollak <dpp <at> athena.com> wrote:> > Folks,> >> > Why is 'match' a language level construct rather than a method on Any?> >> > Wouldn't "def match[XX](func: PartialFunction[ this.type, XX]): XX = ..."> > result in syntactically identical code?> >It used to be that way in Scala 1. I am no longer sure why we changed.syntax highlighting? error reporting? not sure. I don't think itmatters much either way, though.Cheers -- Martin

Page 20: Functions In Scala

Partial Applied Function

When you invoke a function, If you send only a few arguments, then you get back a partially applied function. This gives you the convenience of binding some arguments and leaving the rest to be filled in later.

Example: uncurried version

scala> def sum(a:Int,b:Int,c:Int,d:Int):Int=a+b+c+dsum: (a: Int, b: Int, c: Int, d: Int)Int

scala> val partialAppliedFun=sum(1,2,_:Int,_:Int)partialAppliedFun: (Int, Int) => Int = <function2>

scala> partialAppliedFun(3,4)res46: Int = 10

Example: curried version

scala> def sum(a:Int,b:Int)(c:Int)(d:Int):Int=a+b+c+dsum: (a: Int, b: Int)(c: Int)(d: Int)Int

scala> val partialAppliedFun=sum(1,2) _partialAppliedFun: Int => (Int => Int) = <function1>

scala> partialAppliedFun(3)(4)res47: Int = 10

Page 21: Functions In Scala

Uncurried Function Vs Curried Function

By Martin Odersky

Currying is mostly used if the second parameter section is a function or a by name parameter. This has two advantages.

First, the function argument can then look like a code block enclosed in braces.

E.g.

using(new File(name)) { f => ...}

This reads better than the uncurried alternative:

using(new File(name), f => { ...})

Page 22: Functions In Scala

Uncurried Function Vs Curried Function

Second, and more importantly, type inference can usually figure out the function's parameter type, so it does not have to be given at the call site.

For instance, if I define a max function over lists like this:

def max[T](xs: List[T])(compare: (T, T) => Boolean)

I can call it like this:max(List(1, -3, 43, 0)) ((x, y) => x < y)

or even shorter:max(List(1, -3, 43, 0)) (_ < _)

If I defined max as an uncurried function, this would not work, I'd have to call it like this:

max(List(1, -3, 43, 0), (x: Int, y: Int) => x < y)

If the last parameter is not a function or by-name parameter, I would not advise currying. Scala's _ notatation is amost as lightweight, more flexible, and IMO clearer.

Page 23: Functions In Scala

Nested Function

A nested function is a function defined inside another function.

Purpose:

Nested functions are used as helper functions or as recursive functions inside another function. This has the structural benefit of organizing the code, avoids polluting the scope, and also allows functions to share state easily.

As nested function can access local variables of the enclosing function, sharing of state is possible without passing parameters to the nested function or use a global variable, simplifying code.

Also called Local function.

Page 24: Functions In Scala

Nested Function

def processFile(filename: String, width: Int) {

def processLine(filename: String, width: Int, line: String) { if (line.length > width) println(filename + ": " + line) } val source = Source.fromFile(filename) for (line <- source.getLines()) { processLine(filename, width, line) }

}

Page 25: Functions In Scala

Nested Function

def processFile(filename: String, width: Int) {

def processLine(filename: String, width: Int, line: String) { if (line.length > width) println(filename + ": " + line) } val source = Source.fromFile(filename) for (line <- source.getLines()) { processLine(filename, width, line) }

}

possible improvement ?

Page 26: Functions In Scala

Nested Function

def processFile(filename: String, width: Int) {

def processLine(line: String) { if (line.length > width) println(filename + ": " + line) }

val source = Source.fromFile(filename) for (line <- source.getLines()) processLine(line)

}

Page 27: Functions In Scala

Closures

scala> var more = 1more: Int = 1

scala> val addMore = (x: Int) => x + moreaddMore: Int => Int = <function1>

scala> addMore(10)res6: Int = 11

The function value (the object) that’s created at runtime from this function literal is called a closure.

The name arises from the act of “closing” the function literal by “capturing” the bindings of its free variables.A function literal with no free variables, such as (x: Int) => x + 1 , is called a closed term,where a term is a bit of source code.Thus a function value created at run-time from this function literal is not a closure in the strictest sense, because (x: Int) => x + 1 is already closed as written.

Closures mean that you can save some data inside a function that's only accessible to a specific returning function, i.e the returning function keeps its execution environment.

Page 28: Functions In Scala

Closures

scala> var more = 1more: Int = 1

scala> val addMore = (x: Int) => x + moreaddMore: Int => Int = <function1>

scala> addMore(10)res6: Int = 11

scala> more=10more: Int = 10

scala> addMore(10) What is output ?

Page 29: Functions In Scala

Closures

scala> var more = 1more: Int = 1

scala> val addMore = (x: Int) => x + moreaddMore: Int => Int = <function1>

scala> addMore(10)res6: Int = 11

scala> more=10more: Int = 10

scala> addMore(10)res7: Int = 20

Page 30: Functions In Scala

Closures

scala> def makeIncreaser(more: Int) = (x: Int) => x + moremakeIncreaser: (more: Int)Int => Int

scala> val inc1 = makeIncreaser(1)inc1: Int => Int = <function1>

scala> val inc9999 = makeIncreaser(9999)inc9999: Int => Int = <function1>

scala> inc1(10) output ?

scala> inc9999(10) output ?

Page 31: Functions In Scala

Closures

scala> def makeIncreaser(more: Int) = (x: Int) => x + moremakeIncreaser: (more: Int)Int => Int

scala> val inc1 = makeIncreaser(1)inc1: Int => Int = <function1>

scala> val inc9999 = makeIncreaser(9999)inc9999: Int => Int = <function1>

scala> inc1(10)res8: Int = 11

scala> inc9999(10)res9: Int = 10009

Reason : the variable instance used is the one that was active at the time the closure was created.

Page 32: Functions In Scala

Question And Option[Answer]Question And Option[Answer]

Page 33: Functions In Scala

ThanksThanks