Code Examples for

Programming in Scala, Fifth Edition

Return to chapter index

7 Built-in Control Structures

Sample run of chapter's interpreter examples

7.1 If expressions


// In file built-in-control-structures/Misc.scala var filename = "default.txt" if !args.isEmpty then filename = args(0)
// In file built-in-control-structures/Misc.scala val filename = if !args.isEmpty then args(0) else "default.txt"
// In file built-in-control-structures/Misc.scala println(if (!args.isEmpty) args(0) else "default.txt")

7.2 While loops


// In file built-in-control-structures/Misc.scala def gcdLoop(x: Long, y: Long): Long = var a = x var b = y while a != 0 do val temp = a a = b % a b = temp b
scala> def greet() = println("hi") def greet(): Unit scala> val iAmUnit = greet() == () hi val iAmUnit: Boolean = true
// In file built-in-control-structures/Misc.scala import scala.io.StdIn.readLine while val line = readLine() println(s"Read: $line") line != "" do ()
var line = "" // This doesn't compile! while (line = scala.io.StdIn.readLine()) != "" do println(s"Read: $line")
// In file built-in-control-structures/Misc.scala def gcd(x: Long, y: Long): Long = if y == 0 then x else gcd(y, x % y)

7.3 For expressions


// In file built-in-control-structures/Files.scala val filesHere = (new java.io.File(".")).listFiles for file <- filesHere do println(file)
scala> for i <- 1 to 4 do | println(s"Iteration $i") Iteration 1 Iteration 2 Iteration 3 Iteration 4
scala> for i <- 1 until 4 do | println(s"Iteration $i") Iteration 1 Iteration 2 Iteration 3
// In file built-in-control-structures/Files.scala // Not common in Scala... for i <- 0 to filesHere.length - 1 do println(filesHere(i))
// In file built-in-control-structures/Files.scala val filesHere = (new java.io.File(".")).listFiles for file <- filesHere if file.getName.endsWith(".scala") do println(file)
// In file built-in-control-structures/Files.scala for file <- filesHere do if file.getName.endsWith(".scala") then println(file)
// In file built-in-control-structures/Files.scala for file <- filesHere if file.isFile if file.getName.endsWith(".scala") do println(file)
// In file built-in-control-structures/Files.scala def fileLines(file: java.io.File) = scala.io.Source.fromFile(file).getLines().toArray def grep(pattern: String) = for file <- filesHere if file.getName.endsWith(".scala") line <- fileLines(file) if line.trim.matches(pattern) do println(s"file: {line.trim}") grep(".*gcd.*")
// In file built-in-control-structures/Files.scala def grep(pattern: String) = for file <- filesHere if file.getName.endsWith(".scala") line <- fileLines(file) trimmed = line.trim if trimmed.matches(pattern) do println(s"file: trimmed") grep(".*gcd.*")
// In file built-in-control-structures/Files.scala def scalaFiles = for file <- filesHere if file.getName.endsWith(".scala") yield file
// In file built-in-control-structures/Files.scala val forLineLengths = for file <- filesHere if file.getName.endsWith(".scala") line <- fileLines(file) trimmed = line.trim if trimmed.matches(".*for.*") yield trimmed.length

7.4 Exception handling with try expressions


// In file built-in-control-structures/Exceptions.scala throw new IllegalArgumentException
// In file built-in-control-structures/Exceptions.scala def half(n: Int) = if n % 2 == 0 then n / 2 else throw new RuntimeException("n must be even")
// In file built-in-control-structures/Exceptions.scala import java.io.FileReader import java.io.FileNotFoundException import java.io.IOException 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
// In file built-in-control-structures/Exceptions.scala import java.io.FileReader val file = new FileReader("input.txt") try println(file.read()) // Use the file finally file.close() // Be sure to close the file
// In file built-in-control-structures/Exceptions.scala import java.net.URL import java.net.MalformedURLException def urlFor(path: String) = try new URL(path) catch case e: MalformedURLException => new URL("http://www.scala-lang.org")
// In file built-in-control-structures/Exceptions.scala def f(): Int = try return 1 finally return 2
// In file built-in-control-structures/Exceptions.scala def g(): Int = try 1 finally 2

7.5 Match expressions


// In file built-in-control-structures/Match.scala val firstArg = if !args.isEmpty then args(0) else "" firstArg match case "salt" => println("pepper") case "chips" => println("salsa") case "eggs" => println("bacon") case _ => println("huh?")
// In file built-in-control-structures/Match.scala val firstArg = if !args.isEmpty then args(0) else "" val friend = firstArg match case "salt" => "pepper" case "chips" => "salsa" case "eggs" => "bacon" case _ => "huh?" println(friend)

7.6 Living without break and continue


// In file built-in-control-structures/Break.java 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 file built-in-control-structures/Breakless1.scala var i = 0 var foundIt = false while i < args.length && !foundIt do if !args(i).startsWith("-") then if args(i).endsWith(".scala") then foundIt = true else i = i + 1 else i = i + 1
// In file built-in-control-structures/Breakless2.scala def searchFrom(i: Int): Int = if i >= args.length then -1 else if args(i).startsWith("-") then searchFrom(i + 1) else if args(i).endsWith(".scala") then i else searchFrom(i + 1) val i = searchFrom(0)
import scala.util.control.Breaks.* import java.io.* val in = new BufferedReader(new InputStreamReader(System.in)) breakable { while (true) { println("? ") if (in.readLine() == "") break } }

7.7 Variable scope


// In file built-in-control-structures/MultiTable.scala def printMultiTable() = var i = 1 // only i in scope here while i <= 10 do var j = 1 // both i and j in scope here while j <= 10 do val prod = (i * j).toString // i, j, and prod in scope here var k = prod.length // i, j, prod, and k in scope here while k < 4 do print(" ") k += 1 print(prod) j += 1 // i and j still in scope; prod and k out of scope println() i += 1 // i still in scope; j, prod, and k out of scope
while i <= 10 do var j = 1 ...
val a = 1 val a = 2 // Does not compile println(a)
// In file built-in-control-structures/Misc.scala val a = 1 if a == 1 then val a = 2 // Compiles just fine println(a) println(a)
scala> val a = 1 a: Int = 1 scala> val a = 2 a: Int = 2 scala> println(a) 2

7.8 Refactoring imperative-style code


// In file built-in-control-structures/MultiTable2.scala // Returns a row as a sequence def makeRowSeq(row: Int) = for col <- 1 to 10 yield val prod = (row * col).toString val padding = " " * (4 - prod.length) padding + prod // Returns a row as a string def makeRow(row: Int) = makeRowSeq(row).mkString // Returns table as a string with one row per line def multiTable() = val tableSeq = // a sequence of row strings for row <- 1 to 10 yield makeRow(row) tableSeq.mkString("\n")

7.9 Conclusion

For more information about Programming in Scala, Fifth Edition (the "Stairway Book"), please visit:

http://www.artima.com/shop/programming_in_scala_5ed

and:

http://booksites.artima.com/programming_in_scala_5ed

Copyright © 2007-2020 Artima, Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.