# Extracts of Programming in Scala

CHAPTERS 7 - 9

## Chapter 7

• The only control structures are if, while, for, try, match, and function calls.
• Almost all of Scala's control structures result in some value.
• Scala adopts the ternary operator model, but calls it if. In other words, Scala's if can result in a value.
• Scala also has a do-while loop. This works like the while loop except that it tests the condition after the loop body instead of before.
• The while and do-while constructs are called "loops", not expressions, because they don't result in an interesting value.
• Whereas in Java, assignment results in the value assigned, in Scala assignment always results in the unit value, (). Thus, the value of the assignment "line = readLine()" will always be () and never be "".
• for (file <- filesHere) println(file) With the "file <- filesHere" syntax, which is called a generator.
• If you don't want to include the upper bound of the range in the values that are iterated over, use until instead of to.
• Sometimes you don't want to iterate through a collection in its entirety; you want to filter it down to some subset. You can do this with a for expression by adding a filter, an if clause inside the for's parentheses.
xxxxxxxxxxfor (file <- filesHere if file.getName.endsWith(".scala"))  println(file)
• You can include more filters if you want. Just keep adding if clauses.
• If you add multiple <- clauses, you will get nested "loops".
• If you prefer, you can use curly braces instead of parentheses to surround the generators and filters. One advantage to using curly braces is that you can leave off some of the semicolons that are needed when you use parentheses because the Scala compiler will not infer semicolons while inside parentheses.
• We can bind the result to a new variable using an equals sign (=). The bound variable is introduced and used just like a val, only with the val keyword left out.
xxxxxxxxxxfor {  file <- filesHere  if file.getName.endsWith(".scala") line <- fileLines(file)  trimmed = line.trim  if trimmed.matches(pattern)} println(file + ": " + trimmed)
• You can also generate a value to remember for each iteration. To do so, you prefix the body of the for expression by the keyword yield.
• The syntax for catch clauses was chosen for its consistency with an important part of Scala: pattern matching.
xxxxxxxxxxtry {  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}
• You can wrap an expression with a finally clause if you want to cause some code to execute no matter how the expression terminates.
• The idiomatic way to ensure a non-memory resource, such as file, socket, or database connection, is closed. First you require the resource. Then you start a try block in which you use the resource. Lastly, you close the resource in a finally block.
• try-catch-finally results in a value.
• Java's try-finally does not result in a value. As in Java, if a finally clause includes an explicit return statement, or throws an exception, that return value or exception will "overrule" any previous one that originated in the try block or one of its catch clauses.
• The default case is specified with an underscore (_), a wildcard symbol frequently used in Scala as a placeholder for a completely unknown value.
• Any kind of constant, as well as other things, can be used in cases in Scala.
• match expressions result in a value.
• The simplest approach is to replace every continue by an if and every break by a boolean variable.
• To use break, you need to enclose the block with breakable.
xxxxxxxxxxbreakable {  while (true) {    println("? ")    if (in.readLine() == "") break    }}
• Scala allows you to define variables of the same name in nested scopes.

## Chapter 8

• The most common way to define a function is as a member of some object; such a function is called a method.
• You can define functions inside other functions. Just like local variables, such local functions are visible only in their enclosing block.
• Local functions can access the parameters of their enclosing function.
• Function literals exist in the source code, whereas function values exist as objects at runtime.
• One way to define a function literal more brief is to leave off the parameter types. This is called target typing because the targeted usage of an expression (i.e., .filter()) is allowed to influence the typing of that expression (i.e., the type of the x parameter).
xxxxxxxxxxsomeNumbers.filter((x: Int) => x > 0)someNumbers.filter((x) => x > 0)
• Sometimes when you use underscores as placeholders for parameters, the compiler might not have enough information to infer missing parameter types. In such cases, you can specify the types using a colon like this:
xxxxxxxxxxval f = _ + _ // ERRORval f = (_: Int) + (_: Int)
• Multiple underscores mean multiple parameters, not reuse of a single parameter repeatedly.
• someNumbers.foreach(println _) The underscore in this case is not a placeholder for a single argument. It is a placeholder for an entire parameter list.
• 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. For example, to create a partially applied function expression involving sum, in which you supply none of the three required arguments, you just place an underscore after "sum". The resulting function can then be stored in a variable. val a = sum _
• Given this code, the Scala compiler instantiates a function value that takes the three integer parameters missing from the partially applied function expression, sum _, and assigns a reference to that new function value to the variable a. When you apply three arguments to this new function value, it will return around and invoke sum, passing in those same three arguments: a(1,2,3)
• A partial function has this name because you are not applying that function to all of its arguments. In the case of sum _, you are applying it to none of its arguments. But you can also express a partially applied function by supplying only some of the required arguments.
xxxxxxxxxxval b = sum(1, _: Int, 3)
• Since only one argument is missing, the Scala compiler generates a new function class whose apply method takes one argument.
• If you are writing a partially applied function expression in which you leave off all parameters, such as println _ or sum _, you can express it more concisely by leaving off the underscore if a function is required at that point in the code. someNumbers.foreach(println)
• (x: Int) => x + more more is a free variable because the function literal does not itself give a meaning to it. The x variable, by contrast, is a bound variable because it does have a meaning in the context of the function: it is defined as the function's lone parameter, an Int. If you try using this function literal by itself, without any more defined in its scope, the compiler will complain.
• The function value (the object) that's created at runtime from this function literal is called a closure.
• A function literal with no free variables, such as (x: Int) => x + 1, is called a closed term.
• What happens if more changes after the closure is created? In Scala, the answer is that the closure sees the change.
• Changes made by a closure to a captured variable are visible outside the closure.
• The instance used is the one that was active at the time the closure was created.
• The Scala compiler rearranges things in cases like these so that the captured parameter lives out on the heap, instead of the stack, and thus can outlive the method call that created it. This rearrangement is all taken care of automatically, so you don't have to worry about it. Capture any variable you like: val, var, or parameter.
xxxxxxxxxxdef makeIncreaser(more: Int) = (x: Int) => x + more  // more is on heap
• Scala allows you to indicate that the last parameter to a function may be repeated. This allows clients to pass variable length argument lists to the function. To denote a repeated parameter, place an asterisk after the type of the parameter.
xxxxxxxxxxdef echo(args: String*) =  for (arg <- args) println(arg)
• If you have an array of the appropriate type, and you attempt to pass it as a repeated parameter, you'll get a compiler error. To accomplish this, you'll need to append the array argument with a colon and an _* symbol, like this:
xxxxxxxxxxecho(arr: _*)
• Named arguments allow you to pass arguments to a function in a different order. The syntax is simply that each argument is preceded by a parameter name and an equal sign.
• Default parameters are especially helpful when used in combination with named parameters.
xxxxxxxxxxdef printTime2(out: java.io.PrintStream = Console.out,        divisor: Int = 1) =   out.println("time = " + System.currentTimeMillis() / diviosr)​printTime2(out = Console.err)printTime2(divisor = 1000)
• You can turn off tail-call optimization by giving the following argument to the scala shell or to the scalac compiler:
xxxxxxxxxx-g:notailcalls
• If the recursion is indirect, as in the example of two mutually recursive functions, no optimization is possible.

## Chapter 9

• A more concise way to define the method, though, is by calling the higher-order function exists on a passed list, like this:
xxxxxxxxxxdef containsNeg(nums: List[Int]) = nums.exists(_ < 0)
• Instead of one list of two Int parameters, you apply this function to two lists of one Int parameter each.
xxxxxxxxxxdef curriedSum(x: Int)(y: Int) = x + ycurriedSum(1)(2)
• Nevertheless, there is a way to get an actual reference to curriedSum's "second" function. You can use the placeholder notation to use curriedSum in a partially applied function expression, like this:
xxxxxxxxxxval onePlus = curriedSum(1)_
• Loan pattern
xxxxxxxxxxdef withPrintWriter(file: File, op: PrintWriter => Unit) = {  val writer = new PrintWriter(file)  try {    op(writer)  } finally {    writer.close()  }}​withPrintWriter {  new File("data.txt"),  writer => writer.println(new java.util.Date)}
• In any method invocation in Scala in which you're passing in exactly one argument, you can opt to use curly braces to surround the argument instead of parentheses.
• Curried definition of withPrintWriter
xxxxxxxxxxdef withPrintWriter(file: File)(op: PrintWriter => Unit) = {  val writer = new PrintWriter(file)  try {    op(writer)  } finally {    writer.close()  }}​val file = new File("date.txt")withPrintWriter(file) {  writer => writer.println(new java.util.Date)}
• To make a by-name parameter, you give the parameter a type starting with => instead of () =>.
xxxxxxxxxxdef byNameAssert(predicate: => Boolean) =  if (assertionsEnabled && !predicate)    throw new AssertionError    byNameAssert(4 > 2)
• There is no such thing as a by-name variable or a by-name field.
• One difference exists between these two approaches that is important to note. Because the type of boolAssert's parameter is Boolean, the expression inside the parentheses in boolAssert(5 > 3) is evaluated before the call to boolAssert. The expression 5 > 3 yields true, which is passed to boolAssert. By contrast, because the type of byNameAssert's predicate parameter is => Boolean, the expression inside the parentheses in byNameAssert(5 > 3) is not evaluated before the call to byNameAssert. Instead a function value will be created whose apply method will evaluate 5 > 3, and this function wil be passed to byNameAssert.