Your SlideShare is downloading. ×
0
Functional ObjectsEelco Visser         Delft                                           http://twitter.com/TI1220         U...
Recapgetting started with ScalaObject-Oriented Programming in Scala•   Expressions•   Immutable and mutable variables (val...
Overviewtoday’s lectureNames•   Binding, name spacesFunctional objects•   Objects without mutable state•   Defining operat...
IConcept: Name Binding          B:6.1         TI 1220 - Lecture 2: Functional Objects   4
Binding Variable Identifiers  name binding                              bindingdefining occurrence        val msg = "Hello...
Binding Variable Identifiers   name binding                              bindingdefining occurrence    var greeting = "Hel...
Binding Function Identifiers  name binding                                                      bindingdefining occurrence...
Binding Class Identifiers name binding                                  bindingdefining occurrence  class ChecksumAccumula...
Rebinding vs Mutationname binding class ChecksumAccumulator {   var sum = 0 }                    binding var acc = new Che...
Name Spacesname binding       object foo {         val foo : Int = 0         def foo(x : Int) = x + 1       }       object...
Substitutionname binding    val msg = "Hello, " + "world!"    println(msg)                                 ?    println("H...
IIFunctional Objects           B:6.1     TI 1220 - Lecture 2: Functional Objects 12
Rational Numbersmathematical laws•   Rational = Int x Int•   Notation: numerator/denominator•   Addition    •   example: 1...
Constructing a Rationalclass parametersclass Rational(n: Int, d: Int) {  println("Created " + n + "/" + d)}scala> new Rati...
Immutable Object Trade-offsAdvantages•   easier reasoning•   pass around freely (no risk of undesired mutations)•   cannot...
Reimplementing toStringoverriding methodsclass Rational(n: Int, d: Int) {  override def toString = n + "/" + d}scala> val ...
Checking Preconditionsclass Rational(n: Int, d: Int) {  require(d != 0)  override def toString = n + "/" + d}scala> val ha...
Visibility of Class Parametersclass Rational(n: Int, d: Int) {  require(d != 0)  override def toString = n + "/" + d  def ...
Adding Fieldsclass Rational(n: Int, d: Int) {  require(d != 0)  val numer: Int = n  val denom: Int = d  override def toStr...
Non-Functional Objectsdestructive updateclass ImperativeRational(n: Int, d: Int) {  require(d != 0)  var numer: Int = n  v...
Self Referencesthisdef lessThan(that: Rational) =  this.numer * that.denom < that.numer * this.denomdef max(that: Rational...
Auxiliary Constructorsclass Rational(n: Int, d: Int) {  require(d != 0)  val numer = n  val denom = d  def this(n: Int) = ...
Private Fields and Methodsclass Rational(n: Int, d: Int) {  require(d != 0)  private val g = gcd(n.abs, d.abs)  val numer ...
Defining Operatorsuse functions as infix operatorsdef add(that: Rational): Rational =  new Rational(numer * that.denom + t...
Invoking Operatorsoperator call is method call                B:6.7          TI 1220 - Lecture 2: Functional Objects 25
Defining Operatorsoperator identifiersdef +(that: Rational): Rational =  new Rational(numer * that.denom + that.numer * de...
Identifierslexical syntaxAlphanumeric identifier•   identifier: [$A-Za-z_][$A-Za-z_0-9]* ($ reserved for Scala compiler)• ...
Method Overloadingfor different argument types def *(that: Rational): Rational =   new Rational(numer * that.numer, denom ...
Method Overloadingdoes not apply to this def *(that: Rational): Rational =   new Rational(numer * that.numer, denom * that...
Implicit Conversionsdef *(that: Rational): Rational =  new Rational(numer * that.numer, denom * that.denom)def *(i: Int): ...
Summaryfunctional objectsImmutable objects•   class parameters•   immutable fields (val)•   methods don’t change object, b...
Exam QuestionHow many Rational objects are created while executing:class Rational(n: Int, d: Int) {  require(d != 0)  val ...
coffee break               B:6.1   TI 1220 - Lecture 2: Functional Objects 33
IIBuilt-in Control Structures             B:6         TI 1220 - Lecture 2: Functional Objects 34
Control-Flow StructuresControl-Flow Structures•   ordering execution•   choice, iteration, exceptionFunctional Control Str...
If Expressionsconditional choicevar filename = "default.txt"if (!args.isEmpty)                           imperative style ...
Equational Reasoningreplace equals by equalsval filename =  if (!args.isEmpty) args(0)  else "default.txt"println(filename...
Equational Reasoningreplace equals by equalsval x = e; f(x)             <=>          f(e)if e has no side effects         ...
While Loopsiterationdef gcdLoop(x: Long, y: Long): Long = {  var a = x  var b = y  while (a != 0) {    val temp = a    a =...
Do-While Loopsiterationvar line = ""do {  line = readLine()  println("Read: " + line)} while (line != "")                 ...
Assignment has Type Unitvar line = ""while ((line = readLine()) != "") // This doesn’t work!  println("Read: " + line)    ...
Iteration vs Recursion                         def gcd(x: Long, y: Long): Long =                           if (y == 0) x e...
For Expressionsfunctional iterationval filesHere = (new java.io.File(".")).listFilesfor (file <- filesHere)  println(file)...
Rangesiterating over sequence of numbersscala> for (i <- 1 to 4)     |   println("Iteration " + i)Iteration 1Iteration 2It...
Filteringiterating over subset of a collectionfor (file <- filesHere)  if (file.getName.endsWith(".scala"))    println(fil...
Multiple Filtersfor (  file <- filesHere if file.isFile;  if file.getName.endsWith(".scala")) println(file)               ...
Nested Iterationdef fileLines(file: java.io.File) =  scala.io.Source.fromFile(file).getLines.toListdef grep(pattern: Strin...
Mid-Stream Variable Bindingdef grep(pattern: String) =  for {    file <- filesHere    if file.getName.endsWith(".scala")  ...
Producing a New Collectionyielddef scalaFiles =  for {    file <- filesHere    if file.getName.endsWith(".scala")  } yield...
Composing filtersval forLineLengths =  for {    file <- filesHere    if file.getName.endsWith(".scala")    line <- fileLin...
Throwing Exceptionsexception handlingval half =  if (n % 2 == 0)    n / 2  else    throw new RuntimeException("n must be e...
Catching Exceptionsexception handlingimport java.io.FileReaderimport java.io.FileNotFoundExceptionimport java.io.IOExcepti...
Finallyexception handlingimport java.io.FileReaderval file = new FileReader("input.txt")try {  // Use the file} finally { ...
Yielding a Valueexception handlingimport java.net.URLimport java.net.MalformedURLExceptiondef urlFor(path: String) =  try ...
Match Expressionschoosing between actionsval firstArg = if (args.length > 0) args(0) else ""firstArg match {  case "salt" ...
Match Expressionschoosing between valuesval firstArg = if (!args.isEmpty) args(0) else ""val friend =  firstArg match {   ...
Break and Continue in Javanot in Scalaint i = 0; // This is Javaboolean foundIt = false;while (i < args.length) {  if (arg...
Replace Break/Continue with If ...var i = 0var foundIt = falsewhile (i < args.length && !foundIt) {  if (!args(i).startsWi...
... or with Recursiondef searchFrom(i: Int): Int =  if (i >= args.length) 1  else if (args(i).startsWith("")) searchFrom(i...
Variable Scopealmost identical to JavaVariables are declared in a scope•   { var j = 1; ... }Inner scopes shadow variables...
Multiplication Table$ scala printmultitable.scala   1   2   3   4   5   6   7     8    9 10   2   4   6   8 10 12 14      ...
def printMultiTable() {  var i = 1  // only i in scope here  while (i <= 10) {    var j = 1    // both i and j in scope he...
Refactoring Imperative-Style Code// Returns a row as a sequencedef makeRowSeq(row: Int) =  for (col <- 1 to 10) yield {   ...
VIISummary          Term Rewriting 64
Summarylessons learnedFunctional Objects•   immutable objects•   operations create new objectsFunctional Control Structure...
Literaturerequired readingProgramming in Scala•   Chapter 6: Functional Objects•   Chapter 7: Built-in Control Structures ...
Exercises Week 2complex numbersScala Test•   using unit testing framework to define executable testsComplex numbers•   def...
http://www.scala-lang.org/api/current/index.html                                 TI 1220 - Lecture 2: Functional Objects 68
Scala Style Guideformatting rulesindentation: 2 spaces   http://www.codecommit.com/scala-style-guide.pdf                  ...
Outlookcoming nextLecture 3: Functions & Closures•   Chapters 8, 9Lecture 4: List Programming•   Chapters 15, 16, 17Lectur...
Exam Question (Week 1)What happens when we execute the following code:val greetStrings = new Array[String](3)greetStrings(...
Exam Question (Week 1)What happens when we execute the following code:val greetStrings = new Array[String](3)greetStrings(...
Exam Question (Week 2)What is the return type of makeRowSeq:def makeRowSeq(row: Int) =  for (col <- 1 to 10) yield {    va...
PicturescopyrightsSlide 1:   A Plumpish Proportion by SSG Robert Stewart some rights reservedSlide 3:   McPhillips’ Map of...
PicturescopyrightsSlide:    Dinner at Roussillon (Martin Odersky) by Miles Sabin, some rights reservedSlide:    Portrait: ...
Upcoming SlideShare
Loading in...5
×

Ti1220 Lecture 2

893

Published on

Lecture 2 of course on concepts of programming languages at Delft University of Technology

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
893
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
17
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Ti1220 Lecture 2"

  1. 1. Functional ObjectsEelco Visser Delft http://twitter.com/TI1220 University of Technology Concepts of Programming Languages Challenge the future
  2. 2. Recapgetting started with ScalaObject-Oriented Programming in Scala• Expressions• Immutable and mutable variables (val, var)• Function definitions• Classes and objects• Class members • instance variables • methods• Singleton objects B:6.1 TI 1220 - Lecture 2: Functional Objects 2
  3. 3. Overviewtoday’s lectureNames• Binding, name spacesFunctional objects• Objects without mutable state• Defining operatorsBuilt-in Control Structures• If, While, For, Exceptions• Variable scope B:6.1 TI 1220 - Lecture 2: Functional Objects 3
  4. 4. IConcept: Name Binding B:6.1 TI 1220 - Lecture 2: Functional Objects 4
  5. 5. Binding Variable Identifiers name binding bindingdefining occurrence val msg = "Hello, " + "world!" println(msg) applied occurrence val variables cannot be rebound B:6.1 TI 1220 - Lecture 2: Functional Objects 5
  6. 6. Binding Variable Identifiers name binding bindingdefining occurrence var greeting = "Hello, world!" greeting = "Leave me alone, world!"rebinding var variables can be rebound B:6.1 TI 1220 - Lecture 2: Functional Objects 6
  7. 7. Binding Function Identifiers name binding bindingdefining occurrence def widthOfLength(s: String) = s.length.toString.length val maxWidth = widthOfLength(longestLine) applied occurrence B:6.1 TI 1220 - Lecture 2: Functional Objects 7
  8. 8. Binding Class Identifiers name binding bindingdefining occurrence class ChecksumAccumulator { var sum = 0 } var acc = new ChecksumAccumulator var csa = new ChecksumAccumulator acc.sum = 3 csa = acc applied occurrence TI 1220 - Lecture 2: Functional Objects 8
  9. 9. Rebinding vs Mutationname binding class ChecksumAccumulator { var sum = 0 } binding var acc = new ChecksumAccumulator var csa = new ChecksumAccumulator mutation acc.sum = 3 csa = acc rebinding TI 1220 - Lecture 2: Functional Objects 9
  10. 10. Name Spacesname binding object foo { val foo : Int = 0 def foo(x : Int) = x + 1 } object bar { def bar() = foo.foo(foo.foo) } variables, functions, objects are in separate name spaces B:6.1 TI 1220 - Lecture 2: Functional Objects 10
  11. 11. Substitutionname binding val msg = "Hello, " + "world!" println(msg) ? println("Hello, " + "world!") can we replace applied occurrence with bound expression/value? B:6.1 TI 1220 - Lecture 2: Functional Objects 11
  12. 12. IIFunctional Objects B:6.1 TI 1220 - Lecture 2: Functional Objects 12
  13. 13. Rational Numbersmathematical laws• Rational = Int x Int• Notation: numerator/denominator• Addition • example: 1/2 + 2/3 = 3/6 + 4/6 = (3 + 4)/6 = 7/6 • general: n1/d1 + n2/d2 = (n1*d2 + n2*d1) / (d1*d2)• Multiplication • n1/d1 + n2/d2 = (n1 * n2) / (d1 * d2)• Division • n1/d1 / n2/d2 = n1/d2 * d2/n2 B:6.1 TI 1220 - Lecture 2: Functional Objects 13
  14. 14. Constructing a Rationalclass parametersclass Rational(n: Int, d: Int) { println("Created " + n + "/" + d)}scala> new Rational(1, 2)Created 1/2res0: Rational = Rational@2d83e895 B:6.2 TI 1220 - Lecture 2: Functional Objects 14
  15. 15. Immutable Object Trade-offsAdvantages• easier reasoning• pass around freely (no risk of undesired mutations)• cannot be changed concurrently in two threads• immutable object make safe hashtable keysDisadvantages• copying large object graphs vs in-place update B:6.1 TI 1220 - Lecture 2: Functional Objects 15
  16. 16. Reimplementing toStringoverriding methodsclass Rational(n: Int, d: Int) { override def toString = n + "/" + d}scala> val half = new Rational(1, 2)half: Rational = 1/2 B:6.3 TI 1220 - Lecture 2: Functional Objects 16
  17. 17. Checking Preconditionsclass Rational(n: Int, d: Int) { require(d != 0) override def toString = n + "/" + d}scala> val half = new Rational(1, 0)java.lang.IllegalArgumentException: requirement failed B:6.4 TI 1220 - Lecture 2: Functional Objects 17
  18. 18. Visibility of Class Parametersclass Rational(n: Int, d: Int) { require(d != 0) override def toString = n + "/" + d def add(that: Rational): Rational = new Rational(n * that.d + that.n * d, d * that.d)}$ fsc Rational.scalaRational.scala:5: error: value d is not a member of Rational new Rational(n * that.d + that.n * d, d * that.d) ^Rational.scala:5: error: value d is not a member of Rational new Rational(n * that.d + that.n * d, d * that.d) ^two errors found B:6.5 TI 1220 - Lecture 2: Functional Objects 18
  19. 19. Adding Fieldsclass Rational(n: Int, d: Int) { require(d != 0) val numer: Int = n val denom: Int = d override def toString = numer + "/" + denom def add(that: Rational): Rational = new Rational( numer * that.denom + that.numer * denom, denom * that.denom)}scala> new Rational(1,2) add new Rational(2,3)res0: Rational = 7/6 B:6.5 TI 1220 - Lecture 2: Functional Objects 19
  20. 20. Non-Functional Objectsdestructive updateclass ImperativeRational(n: Int, d: Int) { require(d != 0) var numer: Int = n var denom: Int = d override def toString = numer + "/" + denom def add(that: ImperativeRational) { numer = numer * that.denom + that.numer * denom; denom = denom * that.denom; }} scala> val half = new ImperativeRational(1, 2) half: ImperativeRational = 1/2 scala> val twothirds = new ImperativeRational(2,3) twothirds: ImperativeRational = 2/3 scala> half.add(twothirds) scala> half res1: ImperativeRational = 7/6 B:6.1 TI 1220 - Lecture 2: Functional Objects 20
  21. 21. Self Referencesthisdef lessThan(that: Rational) = this.numer * that.denom < that.numer * this.denomdef max(that: Rational) = if (this.lessThan(that)) that else this B:6.6 TI 1220 - Lecture 2: Functional Objects 21
  22. 22. Auxiliary Constructorsclass Rational(n: Int, d: Int) { require(d != 0) val numer = n val denom = d def this(n: Int) = this(n, 1) // auxiliary constructor ...}scala> new Rational(6)res1: Rational = 6/1 B:6.7 TI 1220 - Lecture 2: Functional Objects 22
  23. 23. Private Fields and Methodsclass Rational(n: Int, d: Int) { require(d != 0) private val g = gcd(n.abs, d.abs) val numer = n / g val denom = d / g ... private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)}scala> new Rational(6,42)res1: Rational = 1/7 B:6.7 TI 1220 - Lecture 2: Functional Objects 23
  24. 24. Defining Operatorsuse functions as infix operatorsdef add(that: Rational): Rational = new Rational(numer * that.denom + that.numer * denom, denom * that.denom)scala> new Rational(1,2).add(new Rational(2,3))res0: Rational = 7/6scala> new Rational(1,2) add new Rational(2,3)res0: Rational = 7/6 B:6.7 TI 1220 - Lecture 2: Functional Objects 24
  25. 25. Invoking Operatorsoperator call is method call B:6.7 TI 1220 - Lecture 2: Functional Objects 25
  26. 26. Defining Operatorsoperator identifiersdef +(that: Rational): Rational = new Rational(numer * that.denom + that.numer * denom, denom * that.denom)def *(that: Rational): Rational = new Rational(numer * that.numer, denom * that.denom)scala> val d = a + b * cd: Rational = 11/14scala> val d = a.+(b.*(c))d: Rational = 11/14scala> val d = a * b + cd: Rational = 16/21scala> val d = (a.*(b)).+(c)d: Rational = 16/21 B:6.7 TI 1220 - Lecture 2: Functional Objects 26
  27. 27. Identifierslexical syntaxAlphanumeric identifier• identifier: [$A-Za-z_][$A-Za-z_0-9]* ($ reserved for Scala compiler)• camel-case convention: toString, HashSetOperator identifier• Unicode set of mathematical symbols(Sm) or other symbols(So), or to the 7-bit ASCII characters that are not letters, digits, parentheses, square brackets, curly braces, single or double quote, or an underscore, period,semi-colon, comma, or back tick character.Literal Identifier• arbitrary string enclosed in back ticks (` . . . `). B:6.1 TI 1220 - Lecture 2: Functional Objects 27
  28. 28. Method Overloadingfor different argument types def *(that: Rational): Rational = new Rational(numer * that.numer, denom * that.denom) def *(i: Int): Rational = new Rational(numer * i, denom) scala> val c = new Rational(3,7) c: Rational = 3/7 scala> c * 2 res1: Rational = 6/7 B:6.1 TI 1220 - Lecture 2: Functional Objects 28
  29. 29. Method Overloadingdoes not apply to this def *(that: Rational): Rational = new Rational(numer * that.numer, denom * that.denom) def *(i: Int): Rational = new Rational(numer * i, denom) scala> 2 * c <console>:7: error: overloaded method value * with alternatives: (Double) Double <and> (Float)Float <and> (Long)Long <and> (Int)Int <and> (Char)Int <and> (Short)Int <and> (Byte)Int cannot be applied to (Rational) 2 * c ^ B:6.1 TI 1220 - Lecture 2: Functional Objects 29
  30. 30. Implicit Conversionsdef *(that: Rational): Rational = new Rational(numer * that.numer, denom * that.denom)def *(i: Int): Rational = new Rational(numer * i, denom)implicit def intToRational(x: Int) = new Rational(x)scala> 2 * cres4: Rational = 6/7 B:6.1 TI 1220 - Lecture 2: Functional Objects 30
  31. 31. Summaryfunctional objectsImmutable objects• class parameters• immutable fields (val)• methods don’t change object, but return valueNatural, concise notation• methods as infix operators, operator identifiers• method overloading• implicit conversion B:6.1 TI 1220 - Lecture 2: Functional Objects 31
  32. 32. Exam QuestionHow many Rational objects are created while executing:class Rational(n: Int, d: Int) { require(d != 0) val numer: Int = n val denom: Int = d override def toString = numer + "/" + denom def +(that: Rational): Rational = new Rational( numer * that.denom + that.numer * denom, denom * that.denom)}var half = new Rational(1,2)half = half + half + half(a) 1(b) 2(c) 3(d) 4 TI1220 - Introduction 32
  33. 33. coffee break B:6.1 TI 1220 - Lecture 2: Functional Objects 33
  34. 34. IIBuilt-in Control Structures B:6 TI 1220 - Lecture 2: Functional Objects 34
  35. 35. Control-Flow StructuresControl-Flow Structures• ordering execution• choice, iteration, exceptionFunctional Control Structures• can be used as expression• return a valueMinimal set of built-in control structures• control abstraction using function literals (next week) B:6.1 TI 1220 - Lecture 2: Functional Objects 35
  36. 36. If Expressionsconditional choicevar filename = "default.txt"if (!args.isEmpty) imperative style filename = args(0)val filename = if (!args.isEmpty) args(0) functional style else "default.txt" B:7.1 TI 1220 - Lecture 2: Functional Objects 36
  37. 37. Equational Reasoningreplace equals by equalsval filename = if (!args.isEmpty) args(0) else "default.txt"println(filename)println(if (!args.isEmpty) args(0) else "default.txt") B:7.1 TI 1220 - Lecture 2: Functional Objects 37
  38. 38. Equational Reasoningreplace equals by equalsval x = e; f(x) <=> f(e)if e has no side effects B:7.1 TI 1220 - Lecture 2: Functional Objects 38
  39. 39. While Loopsiterationdef gcdLoop(x: Long, y: Long): Long = { var a = x var b = y while (a != 0) { val temp = a a = b % a b = temp } b} B:7.2 TI 1220 - Lecture 2: Functional Objects 39
  40. 40. Do-While Loopsiterationvar line = ""do { line = readLine() println("Read: " + line)} while (line != "") B:7.2 TI 1220 - Lecture 2: Functional Objects 40
  41. 41. Assignment has Type Unitvar line = ""while ((line = readLine()) != "") // This doesn’t work! println("Read: " + line) B:7.2 TI 1220 - Lecture 2: Functional Objects 41
  42. 42. Iteration vs Recursion def gcd(x: Long, y: Long): Long = if (y == 0) x else gcd(y, x % y)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} B:7.2 TI 1220 - Lecture 2: Functional Objects 42
  43. 43. For Expressionsfunctional iterationval filesHere = (new java.io.File(".")).listFilesfor (file <- filesHere) println(file) B:7.3 TI 1220 - Lecture 2: Functional Objects 43
  44. 44. Rangesiterating over sequence of numbersscala> for (i <- 1 to 4) | println("Iteration " + i)Iteration 1Iteration 2Iteration 3Iteration 4// Not common in Scala...for (i <- 0 to filesHere.length - 1) println(filesHere(i)) B:7.3 TI 1220 - Lecture 2: Functional Objects 44
  45. 45. Filteringiterating over subset of a collectionfor (file <- filesHere) if (file.getName.endsWith(".scala")) println(file)for (file <- filesHere if file.getName.endsWith(".scala")) println(file) B:6.1 TI 1220 - Lecture 2: Functional Objects 45
  46. 46. Multiple Filtersfor ( file <- filesHere if file.isFile; if file.getName.endsWith(".scala")) println(file) B:7.3 TI 1220 - Lecture 2: Functional Objects 46
  47. 47. Nested Iterationdef fileLines(file: java.io.File) = scala.io.Source.fromFile(file).getLines.toListdef grep(pattern: String) = for ( file <- filesHere if file.getName.endsWith(".scala"); line <- fileLines(file) if line.trim.matches(pattern) ) println(file + ": " + line.trim)grep(".*gcd.*") B:7.3 TI 1220 - Lecture 2: Functional Objects 47
  48. 48. Mid-Stream Variable Bindingdef grep(pattern: String) = for { file <- filesHere if file.getName.endsWith(".scala") line <- fileLines(file) trimmed = line.trim if trimmed.matches(pattern) } println(file + ": " + trimmed)grep(".*gcd.*") B:7.3 TI 1220 - Lecture 2: Functional Objects 48
  49. 49. Producing a New Collectionyielddef scalaFiles = for { file <- filesHere if file.getName.endsWith(".scala") } yield file B:7.3 TI 1220 - Lecture 2: Functional Objects 49
  50. 50. Composing filtersval forLineLengths = for { file <- filesHere if file.getName.endsWith(".scala") line <- fileLines(file) trimmed = line.trim if trimmed.matches(".*for.*") } yield trimmed.length B:7.3 TI 1220 - Lecture 2: Functional Objects 50
  51. 51. Throwing Exceptionsexception handlingval half = if (n % 2 == 0) n / 2 else throw new RuntimeException("n must be even") B:7.4 TI 1220 - Lecture 2: Functional Objects 51
  52. 52. Catching Exceptionsexception handlingimport java.io.FileReaderimport java.io.FileNotFoundExceptionimport java.io.IOExceptiontry { 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} B:7.4 TI 1220 - Lecture 2: Functional Objects 52
  53. 53. Finallyexception handlingimport java.io.FileReaderval file = new FileReader("input.txt")try { // Use the file} finally { file.close() // Be sure to close the file} B:7.4 TI 1220 - Lecture 2: Functional Objects 53
  54. 54. Yielding a Valueexception handlingimport java.net.URLimport java.net.MalformedURLExceptiondef urlFor(path: String) = try { new URL(path) } catch { case e: MalformedURLException => new URL("http://www.scalalang.org") } B:7.4 TI 1220 - Lecture 2: Functional Objects 54
  55. 55. Match Expressionschoosing between actionsval 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?")} B:7.5 TI 1220 - Lecture 2: Functional Objects 55
  56. 56. Match Expressionschoosing between valuesval firstArg = if (!args.isEmpty) args(0) else ""val friend = firstArg match { case "salt" => "pepper" case "chips" => "salsa" case "eggs" => "bacon" case _ => "huh?" }println(friend) B:7.5 TI 1220 - Lecture 2: Functional Objects 56
  57. 57. Break and Continue in Javanot in Scalaint i = 0; // This is Javaboolean 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;} B:7.6 TI 1220 - Lecture 2: Functional Objects 57
  58. 58. Replace Break/Continue with If ...var i = 0var foundIt = falsewhile (i < args.length && !foundIt) { if (!args(i).startsWith("")) { if (args(i).endsWith(".scala")) foundIt = true } i = i + 1} B:7.6 TI 1220 - Lecture 2: Functional Objects 58
  59. 59. ... or with Recursiondef searchFrom(i: Int): Int = if (i >= args.length) 1 else if (args(i).startsWith("")) searchFrom(i + 1) else if (args(i).endsWith(".scala")) i else searchFrom(i + 1)val i = searchFrom(0) B:7.6 TI 1220 - Lecture 2: Functional Objects 59
  60. 60. Variable Scopealmost identical to JavaVariables are declared in a scope• { var j = 1; ... }Inner scopes shadow variables in outer scopes• { var j = 1; { var j = 2; ... } } B:7.7 TI 1220 - Lecture 2: Functional Objects 60
  61. 61. Multiplication Table$ scala printmultitable.scala 1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100 B:6.1 TI 1220 - Lecture 2: Functional Objects 61
  62. 62. def printMultiTable() { var i = 1 // only i in scope here while (i <= 10) { var j = 1 // both i and j in scope here while (j <= 10) { 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) { 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} B:7.7 TI 1220 - Lecture 2: Functional Objects 62
  63. 63. Refactoring Imperative-Style Code// Returns a row as a sequencedef 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 stringdef makeRow(row: Int) = makeRowSeq(row).mkString// Returns table as a string with one row per linedef multiTable() = { val tableSeq = // a sequence of row strings for (row <- 1 to 10) yield makeRow(row) tableSeq.mkString("n")} B:6.1 TI 1220 - Lecture 2: Functional Objects 63
  64. 64. VIISummary Term Rewriting 64
  65. 65. Summarylessons learnedFunctional Objects• immutable objects• operations create new objectsFunctional Control Structures• return a value• have a type• can be used as expressions TI 1220 - Lecture 2: Functional Objects 65
  66. 66. Literaturerequired readingProgramming in Scala• Chapter 6: Functional Objects• Chapter 7: Built-in Control Structures TI 1220 - Lecture 2: Functional Objects 66
  67. 67. Exercises Week 2complex numbersScala Test• using unit testing framework to define executable testsComplex numbers• define class to represent complex numbers• define testsNote: all assignments should be done individually! B:6.1 TI 1220 - Lecture 2: Functional Objects 67
  68. 68. http://www.scala-lang.org/api/current/index.html TI 1220 - Lecture 2: Functional Objects 68
  69. 69. Scala Style Guideformatting rulesindentation: 2 spaces http://www.codecommit.com/scala-style-guide.pdf B:6.1 TI 1220 - Lecture 2: Functional Objects 69
  70. 70. Outlookcoming nextLecture 3: Functions & Closures• Chapters 8, 9Lecture 4: List Programming• Chapters 15, 16, 17Lecture 5: Trees• Chapters 26, 22, 23Lab Week 2• Complex numbers in Scala B:6.1 TI 1220 - Lecture 2: Functional Objects 70
  71. 71. Exam Question (Week 1)What happens when we execute the following code:val greetStrings = new Array[String](3)greetStrings(0) = "Hello"greetStrings(1) = ", "greetStrings(2) = "world!n"(a) Error: greetStrings is an immutable variable that cannot be assigned to(b) Error: Array is a immutable data structure that cannot be assigned to(c) No error: greetStrings is a mutable variable that can be assigned to(d) No error: Array is a mutable data structure that can be assigned to TI1220 - Introduction 71
  72. 72. Exam Question (Week 1)What happens when we execute the following code:val greetStrings = new Array[String](3)greetStrings(0) = "Hello"greetStrings(1) = ", "greetStrings(2) = "world!n"(a) Error: greetStrings is an immutable variable that cannot be assigned to(b) Error: Array is a immutable data structure that cannot be assigned to(c) No error: greetStrings is a mutable variable that can be assigned to(d) No error: Array is a mutable data structure that can be assigned to TI1220 - Introduction 72
  73. 73. Exam Question (Week 2)What is the return type of makeRowSeq:def makeRowSeq(row: Int) = for (col <- 1 to 10) yield { val prod = (row * col).toString val padding = " " * (4 - prod.length) padding + prod }(a) String(b) Int(c) IndexedSeq[String](d) IndexedSeq[Int] TI1220 - Introduction 73
  74. 74. PicturescopyrightsSlide 1: A Plumpish Proportion by SSG Robert Stewart some rights reservedSlide 3: McPhillips’ Map of the City of Winnipeg by Manitoba Historical Maps, some rights reservedSlide 19: Envelopes by benchilada, some rights reservedSlide 20: Report card by Carosaurus, some rights reservedSlide 30: Sun is Shining by el patojo, some rights reserved B:6.1 TI 1220 - Lecture 2: Functional Objects 74
  75. 75. PicturescopyrightsSlide: Dinner at Roussillon (Martin Odersky) by Miles Sabin, some rights reservedSlide: Portrait: Alex Payne by Dave Fayram, some rights reservedSlide: “Plumbing Nightmare” by Natalie Wilkie, some rights reservedSlide: HIV: The Moleskine Summary by Niels OlsonSlide: remember to thank all the books you haven’t read over the past three years by Natalia Osiatynska, Some rights reservedSlide: Stupid Exam by Remi Carreiro, Some rights reservedSlide: Practice makes perfect by Simon Proberthttp://www.flickr.com/photos/garrettc/3747802654/ Bombe detail by Garret Coakley, Some rightsreserved B:6.1 TI 1220 - Lecture 2: Functional Objects 75
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×