Built-in Control Structures


     Ayush Kumar Mishra
    Sr. Software Consultant
            Knoldus
●
    Scala has only a handful of built-in control structures :
    if, while, for, try, match, and function calls .
●
    The reason Scala has so few is that it has included
    function literals .
●
    A function literal is defined like so:
    scala> val add = (a:Int, b:Int) => a + b
    add: (Int, Int) => Int = <function2>

    scala> add(1,2)
    res1: Int = 3
●
    Almost all of Scala's control structure result in some
     value .

●
    Scala’s built-in control structures act much like their
     imperative equivalents.

●
    But because they tend to result in a value, they
     support a functional style, too.
If Expression
Scala’s if works just like in many other languages.
In Imperative style:
var filename = "default.txt"
if (!args.isEmpty)
filename = args(0)
In Functional Style :
1)val filename =
if (!args.isEmpty) args(0)
else "default.txt"
2)println(if (!args.isEmpty) args(0) else "default.txt")
while and do.. while
●
    Scala’s while and do.. while loop behaves as in other
     languages.
●
    The while and do-while constructs are called “loops,”
     not expressions .
●
    Because the while loop results in no value, it is often
    left out of pure functional languages.
●
     Sometimes an imperative solution can be more
     readable using While Loop . :( But Not
     Recommended .
In Imperative style:
 def gcdLoop(x: Long, y: Long): Long = {
 var a = x
 var b = y
 while (a != 0) {
 val temp = a
 a=b%a
 b = temp}
 b}
– In Functional Style
 def gcd(x: Long, y: Long): Long =
 if (y == 0) x else gcd(y, x % y)
Exception handling with try expressions

  ●
      In Scala exceptions are not checked so effectively all
        exceptions are runtime exceptions.
  ●
      Instead of returning a value in the normal way, a method
        can terminate by throwing an exception.
      Throwing exceptions

  ●
      You create an exception object and then you throw it with
       the throw keyword:
      throw new IllegalArgumentException
●
    An exception throw has type Nothing.
●
    Type Nothing is at the very bottom of Scala’s class
      hierarchy; it is a sub-type of every other type.
●
    In Scala Library , it is defined as :
    def error(message: String): Nothing =
    throw new RuntimeException(message)


    def divide(x: Int, y: Int): Int =
    if (y != 0) x / y
    else error("can't divide by zero")
Catching exceptions


●
    Scala allows you to try/catch any exception in a single block
    and then perform pattern matching against it using case blocks as shown
    below:

    try {
    val f = new FileReader("input.txt")
    // Use and close file
    } catch {
    case ex: FileNotFoundException => // Handle missing file
    case ex: IOException => // Handle other I/O error
    }
The finally clause


●
    The finally clause can contain code that you need to be executed,
    no matter if an exception is thrown or not.
    val file = new FileReader("input.txt")
    try {
    // Use the file
    } finally {
    file.close()
    // Be sure to close the file
    }
Yielding a value


●
    As with most other Scala control structures, try-catch-finally results in
    a value .

    def urlFor(path: String) =
    try {
    new URL(path)
    } catch {
    case e: MalformedURLException =>
    new URL("http://www.scala-lang.org")
    }
Match expressions


●   Scala’s match expression lets you select from a number of
     alternatives, just like switch statements in other languages.


    val firstArg = if (args.length > 0) args(0) else ""
    firstArg match {
    case "salt" => println("pepper")
    case "chips" => println("salsa")
    case "eggs" => println("bacon")
    case _ => println("huh?")
    }
–
Living without break and continue
●
     The simplest approach is to replace every continue by an if and every
     break by a boolean variable.
    int i = 0;
    // This is Java
    boolean foundIt = false;
    while (i < args.length) {
    if (args[i].startsWith("-")) {i = i + 1;
    continue;}
    if (args[i].endsWith(".scala")) {foundIt = true;
    break;
    }i = i + 1;}
In Scala :                        In Functional Style :
var i = 0
                                  def searchFrom(i: Int): Int =
var foundIt = false
                                  if (i >= args.length) -1
while (i < args.length && !
  foundIt) {                      else if (args(i).startsWith("-"))
if (!args(i).startsWith("-")) {      searchFrom(i + 1)
if (args(i).endsWith(".scala"))
                                  else if
foundIt = true                       (args(i).endsWith(".scala")) i
}
                                  else searchFrom(i + 1)
i=i+1
}                                 val i = searchFrom(0)
Still Want to use Break ? :(
    ●
        In Scala’s standard library. Class Breaks in package
          scala.util.control offers a break method .

            breakable {
                 while (true) {
                        println("hiii ")
                        if (in.readLine() == "") break
                 }
            }
        –
For expressions


●   It can result in an interesting value, a collection whose
    type is determined by the for expression’s <- clauses.

●   for ( seq ) yield expr
    seq is a sequence of generators, definitions, and filters .
    Ex: for {
                 p <- persons // a generator
                 n = p.name // a definition
                 if (n startsWith "To") // a filter
          }
Filtering:-
        filter: an if clause inside the for’s parentheses.
        val filesHere = (new java.io.File(".")).listFiles
        for (file <- filesHere if file.getName.endsWith(".scala") )
        println(file)
Producing a new collection:-
        Prefix the body of the for expression by the keyword yield.
        for clauses yield body
to find the titles of all books whose author’s last name is “Gosling”:
        scala> for (b <- books; a <- b.authors
        if a startsWith "Gosling")
        yield b.title
        res4: List[String] = List(The Java Language Specification)
Translation of for expressions
    Every for expression can be expressed in terms of the three higher-order
     functions
●   Map
●   FlatMap
●   withFilter.
    Translating for expressions with one generator
    for (x <- expr1 ) yield expr2   is translated to
    expr1 .map(x => expr2 )


    Translating for expressions starting with a generator and a filter
    for (x <- expr1 if expr2 ) yield expr3 is translated to:
    for (x <- expr1 withFilter (x => expr2 )) yield expr3
    finally
    expr1 withFilter (x => expr2 ) map (x => expr3 )




–
Translating for expressions starting with two generators


    for (x <- expr1 ; y <- expr2 ; seq) yield expr3
    is translated to
    expr1 .flatMap(x => for (y <- expr2 ; seq) yield expr3 )
    Ex:-
    for (b1 <- books; b2 <- books if b1 != b2;
           a1 <- b1.authors; a2 <- b2.authors if a1 == a2)
                  yield a1
    This query translates to the following map/flatMap/filter combination:
    books flatMap (b1 =>
           books withFilter (b2 => b1 != b2) flatMap (b2 =>
                  b1.authors flatMap (a1 =>
                  b2.authors withFilter (a2 => a1 == a2) map (a2 =>
                  a1))))
•
Thank You

Knolx Session : Built-In Control Structures in Scala

  • 1.
    Built-in Control Structures Ayush Kumar Mishra Sr. Software Consultant Knoldus
  • 2.
    Scala has only a handful of built-in control structures : if, while, for, try, match, and function calls . ● The reason Scala has so few is that it has included function literals . ● A function literal is defined like so: scala> val add = (a:Int, b:Int) => a + b add: (Int, Int) => Int = <function2> scala> add(1,2) res1: Int = 3
  • 3.
    Almost all of Scala's control structure result in some value . ● Scala’s built-in control structures act much like their imperative equivalents. ● But because they tend to result in a value, they support a functional style, too.
  • 4.
    If Expression Scala’s ifworks just like in many other languages. In Imperative style: var filename = "default.txt" if (!args.isEmpty) filename = args(0) In Functional Style : 1)val filename = if (!args.isEmpty) args(0) else "default.txt" 2)println(if (!args.isEmpty) args(0) else "default.txt")
  • 5.
    while and do..while ● Scala’s while and do.. while loop behaves as in other languages. ● The while and do-while constructs are called “loops,” not expressions . ● Because the while loop results in no value, it is often left out of pure functional languages. ● Sometimes an imperative solution can be more readable using While Loop . :( But Not Recommended .
  • 6.
    In Imperative style: def gcdLoop(x: Long, y: Long): Long = { var a = x var b = y while (a != 0) { val temp = a a=b%a b = temp} b} – In Functional Style def gcd(x: Long, y: Long): Long = if (y == 0) x else gcd(y, x % y)
  • 7.
    Exception handling withtry expressions ● In Scala exceptions are not checked so effectively all exceptions are runtime exceptions. ● Instead of returning a value in the normal way, a method can terminate by throwing an exception. Throwing exceptions ● You create an exception object and then you throw it with the throw keyword: throw new IllegalArgumentException
  • 8.
    An exception throw has type Nothing. ● Type Nothing is at the very bottom of Scala’s class hierarchy; it is a sub-type of every other type. ● In Scala Library , it is defined as : def error(message: String): Nothing = throw new RuntimeException(message) def divide(x: Int, y: Int): Int = if (y != 0) x / y else error("can't divide by zero")
  • 9.
    Catching exceptions ● Scala allows you to try/catch any exception in a single block and then perform pattern matching against it using case blocks as shown below: try { val f = new FileReader("input.txt") // Use and close file } catch { case ex: FileNotFoundException => // Handle missing file case ex: IOException => // Handle other I/O error }
  • 10.
    The finally clause ● The finally clause can contain code that you need to be executed, no matter if an exception is thrown or not. val file = new FileReader("input.txt") try { // Use the file } finally { file.close() // Be sure to close the file }
  • 11.
    Yielding a value ● As with most other Scala control structures, try-catch-finally results in a value . def urlFor(path: String) = try { new URL(path) } catch { case e: MalformedURLException => new URL("http://www.scala-lang.org") }
  • 12.
    Match expressions ● Scala’s match expression lets you select from a number of alternatives, just like switch statements in other languages. val firstArg = if (args.length > 0) args(0) else "" firstArg match { case "salt" => println("pepper") case "chips" => println("salsa") case "eggs" => println("bacon") case _ => println("huh?") } –
  • 13.
    Living without breakand continue ● The simplest approach is to replace every continue by an if and every break by a boolean variable. int i = 0; // This is Java boolean foundIt = false; while (i < args.length) { if (args[i].startsWith("-")) {i = i + 1; continue;} if (args[i].endsWith(".scala")) {foundIt = true; break; }i = i + 1;}
  • 14.
    In Scala : In Functional Style : var i = 0 def searchFrom(i: Int): Int = var foundIt = false if (i >= args.length) -1 while (i < args.length && ! foundIt) { else if (args(i).startsWith("-")) if (!args(i).startsWith("-")) { searchFrom(i + 1) if (args(i).endsWith(".scala")) else if foundIt = true (args(i).endsWith(".scala")) i } else searchFrom(i + 1) i=i+1 } val i = searchFrom(0)
  • 15.
    Still Want touse Break ? :( ● In Scala’s standard library. Class Breaks in package scala.util.control offers a break method . breakable { while (true) { println("hiii ") if (in.readLine() == "") break } } –
  • 16.
    For expressions ● It can result in an interesting value, a collection whose type is determined by the for expression’s <- clauses. ● for ( seq ) yield expr seq is a sequence of generators, definitions, and filters . Ex: for { p <- persons // a generator n = p.name // a definition if (n startsWith "To") // a filter }
  • 17.
    Filtering:- filter: an if clause inside the for’s parentheses. val filesHere = (new java.io.File(".")).listFiles for (file <- filesHere if file.getName.endsWith(".scala") ) println(file) Producing a new collection:- Prefix the body of the for expression by the keyword yield. for clauses yield body to find the titles of all books whose author’s last name is “Gosling”: scala> for (b <- books; a <- b.authors if a startsWith "Gosling") yield b.title res4: List[String] = List(The Java Language Specification)
  • 18.
    Translation of forexpressions Every for expression can be expressed in terms of the three higher-order functions ● Map ● FlatMap ● withFilter. Translating for expressions with one generator for (x <- expr1 ) yield expr2 is translated to expr1 .map(x => expr2 ) Translating for expressions starting with a generator and a filter for (x <- expr1 if expr2 ) yield expr3 is translated to: for (x <- expr1 withFilter (x => expr2 )) yield expr3 finally expr1 withFilter (x => expr2 ) map (x => expr3 ) –
  • 19.
    Translating for expressionsstarting with two generators for (x <- expr1 ; y <- expr2 ; seq) yield expr3 is translated to expr1 .flatMap(x => for (y <- expr2 ; seq) yield expr3 ) Ex:- for (b1 <- books; b2 <- books if b1 != b2; a1 <- b1.authors; a2 <- b2.authors if a1 == a2) yield a1 This query translates to the following map/flatMap/filter combination: books flatMap (b1 => books withFilter (b2 => b1 != b2) flatMap (b2 => b1.authors flatMap (a1 => b2.authors withFilter (a2 => a1 == a2) map (a2 => a1)))) •
  • 20.