4   | 
     4   | 
     5   | 
     5   | 
     6 // Laziness with style  | 
     6 // Laziness with style  | 
     7 //=====================  | 
     7 //=====================  | 
     8   | 
     8   | 
     9 // The concept of lazy evaluation doesn’t really exist in   | 
     9 // The concept of lazy evaluation doesn’t really   | 
    10 // non-functional languages, but it is pretty easy to grasp.   | 
    10 // exist in non-functional languages, but it is   | 
    11 // Consider first   | 
    11 // pretty easy to grasp. Consider first   | 
    12   | 
    12   | 
    13 def square(x: Int) = x * x  | 
    13 def square(x: Int) = x * x  | 
    14   | 
    14   | 
    15 square(42 + 8)  | 
    15 square(42 + 8)  | 
    16   | 
    16   | 
    17 // this is called strict evaluation  | 
    17 // this is called strict evaluation  | 
    18   | 
    18   | 
    19 // pretty expensive operation  | 
    19 // say we have a pretty expensive operation  | 
    20 def peop(n: BigInt): Boolean = peop(n + 1)   | 
    20 def peop(n: BigInt): Boolean = peop(n + 1)   | 
         | 
    21   | 
    21 val a = "foo"  | 
    22 val a = "foo"  | 
    22 val b = "foo"  | 
    23 val b = "foo"  | 
    23   | 
    24   | 
    24 if (a == b || peop(0)) println("true") else println("false") | 
    25 if (a == b || peop(0)) println("true") else println("false") | 
    25   | 
    26   | 
    41 // primes: 2, 3, 5, 7, 9, 11, 13 ....  | 
    42 // primes: 2, 3, 5, 7, 9, 11, 13 ....  | 
    42   | 
    43   | 
    43 def generatePrimes (s: Stream[Int]): Stream[Int] =  | 
    44 def generatePrimes (s: Stream[Int]): Stream[Int] =  | 
    44   s.head #:: generatePrimes(s.tail.filter(_ % s.head != 0))  | 
    45   s.head #:: generatePrimes(s.tail.filter(_ % s.head != 0))  | 
    45   | 
    46   | 
    46 val primes: Stream[Int] = generatePrimes(Stream.from(2))  | 
    47 val primes = generatePrimes(Stream.from(2))  | 
    47   | 
    48   | 
    48 // the first 10 primes  | 
    49 // the first 10 primes  | 
    49 primes.take(10).toList  | 
    50 primes.take(10).toList  | 
    50   | 
    51   | 
    51 //primes.filter(_ > 100).take(2000).toList  | 
         | 
    52   | 
         | 
    53 time_needed(1, primes.filter(_ > 100).take(3000).toList)  | 
    52 time_needed(1, primes.filter(_ > 100).take(3000).toList)  | 
    54 time_needed(1, primes.filter(_ > 100).take(3000).toList)  | 
    53 time_needed(1, primes.filter(_ > 100).take(3000).toList)  | 
    55   | 
    54   | 
    56   | 
    55 // a stream of successive numbers  | 
    57 Stream.from(2)  | 
    56 Stream.from(2)  | 
         | 
    57   | 
    58 Stream.from(2).take(10)  | 
    58 Stream.from(2).take(10)  | 
    59 Stream.from(2).take(10).print  | 
    59 Stream.from(2).take(10).print  | 
    60 Stream.from(10).take(10).print  | 
    60 Stream.from(10).take(10).print  | 
    61   | 
    61   | 
    62 Stream.from(2).take(10).force  | 
    62 Stream.from(2).take(10).force  | 
    63   | 
    63   | 
    64 // itterative version of the Fibonacci numbers  | 
    64 // iterative version of the Fibonacci numbers  | 
    65 def fibIter(a: BigInt, b: BigInt): Stream[BigInt] =  | 
    65 def fibIter(a: BigInt, b: BigInt): Stream[BigInt] =  | 
    66   a #:: fibIter(b, a + b)  | 
    66   a #:: fibIter(b, a + b)  | 
    67   | 
    67   | 
    68   | 
    68   | 
    69 fibIter(1, 1).take(10).force  | 
    69 fibIter(1, 1).take(10).force  | 
    86 case class ALT(r1: Rexp, r2: Rexp) extends Rexp   // alternative  r1 + r2  | 
    86 case class ALT(r1: Rexp, r2: Rexp) extends Rexp   // alternative  r1 + r2  | 
    87 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp   // sequence     r1 . r2    | 
    87 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp   // sequence     r1 . r2    | 
    88 case class STAR(r: Rexp) extends Rexp             // star         r*  | 
    88 case class STAR(r: Rexp) extends Rexp             // star         r*  | 
    89   | 
    89   | 
    90   | 
    90   | 
    91   | 
         | 
    92 // writing (ab)* in the format above is   | 
         | 
    93 // tedious  | 
         | 
    94 val r0 = STAR(SEQ(CHAR('a'), CHAR('b'))) | 
         | 
    95   | 
         | 
    96   | 
         | 
    97 // some convenience for typing in regular expressions  | 
    91 // some convenience for typing in regular expressions  | 
    98 import scala.language.implicitConversions      | 
    92 import scala.language.implicitConversions      | 
    99 import scala.language.reflectiveCalls   | 
    93 import scala.language.reflectiveCalls   | 
   100   | 
    94   | 
   101 def charlist2rexp(s: List[Char]): Rexp = s match { | 
    95 def charlist2rexp(s: List[Char]): Rexp = s match { | 
   105 }  | 
    99 }  | 
   106 implicit def string2rexp(s: String): Rexp =   | 
   100 implicit def string2rexp(s: String): Rexp =   | 
   107   charlist2rexp(s.toList)  | 
   101   charlist2rexp(s.toList)  | 
   108   | 
   102   | 
   109   | 
   103   | 
   110 val r1 = STAR("ab") | 
         | 
   111 val r2 = STAR(ALT("ab", "baa baa black sheep")) | 
         | 
   112 val r3 = STAR(SEQ("ab", ALT("a", "b"))) | 
         | 
   113   | 
         | 
   114 implicit def RexpOps (r: Rexp) = new { | 
   104 implicit def RexpOps (r: Rexp) = new { | 
   115   def | (s: Rexp) = ALT(r, s)  | 
   105   def | (s: Rexp) = ALT(r, s)  | 
   116   def % = STAR(r)  | 
   106   def % = STAR(r)  | 
   117   def ~ (s: Rexp) = SEQ(r, s)  | 
   107   def ~ (s: Rexp) = SEQ(r, s)  | 
   118 }  | 
   108 }  | 
   119   | 
         | 
   120   | 
   109   | 
   121 implicit def stringOps (s: String) = new { | 
   110 implicit def stringOps (s: String) = new { | 
   122   def | (r: Rexp) = ALT(s, r)  | 
   111   def | (r: Rexp) = ALT(s, r)  | 
   123   def | (r: String) = ALT(s, r)  | 
   112   def | (r: String) = ALT(s, r)  | 
   124   def % = STAR(s)  | 
   113   def % = STAR(s)  | 
   142 val number = sign ~ digit ~ digit.%   | 
   131 val number = sign ~ digit ~ digit.%   | 
   143   | 
   132   | 
   144 // task: enumerate exhaustively regular expression  | 
   133 // task: enumerate exhaustively regular expression  | 
   145 // starting from small ones towards bigger ones.  | 
   134 // starting from small ones towards bigger ones.  | 
   146   | 
   135   | 
   147 // 1st idea: enumerate them up to a level  | 
   136 // 1st idea: enumerate them all in a Set  | 
         | 
   137 // up to a level  | 
   148   | 
   138   | 
   149 def enuml(l: Int, s: String) : Set[Rexp] = l match { | 
   139 def enuml(l: Int, s: String) : Set[Rexp] = l match { | 
   150   case 0 => Set(ZERO, ONE) ++ s.map(CHAR).toSet  | 
   140   case 0 => Set(ZERO, ONE) ++ s.map(CHAR).toSet  | 
   151   case n =>    | 
   141   case n =>    | 
   152     val rs = enuml(n - 1, s)  | 
   142     val rs = enuml(n - 1, s)  | 
   154     (for (r1 <- rs; r2 <- rs) yield ALT(r1, r2)) ++  | 
   144     (for (r1 <- rs; r2 <- rs) yield ALT(r1, r2)) ++  | 
   155     (for (r1 <- rs; r2 <- rs) yield SEQ(r1, r2)) ++  | 
   145     (for (r1 <- rs; r2 <- rs) yield SEQ(r1, r2)) ++  | 
   156     (for (r1 <- rs) yield STAR(r1))  | 
   146     (for (r1 <- rs) yield STAR(r1))  | 
   157 }  | 
   147 }  | 
   158   | 
   148   | 
         | 
   149 enuml(1, "a")  | 
   159 enuml(1, "a").size  | 
   150 enuml(1, "a").size  | 
   160 enuml(2, "a").size  | 
   151 enuml(2, "a").size  | 
   161 enuml(3, "a").size // out of heap space  | 
   152 enuml(3, "a").size   | 
         | 
   153 enuml(4, "a").size // out of heap space  | 
   162   | 
   154   | 
   163   | 
   155   | 
   164 def enum(rs: Stream[Rexp]) : Stream[Rexp] =   | 
   156 def enum(rs: Stream[Rexp]) : Stream[Rexp] =   | 
   165   rs #::: enum( (for (r1 <- rs; r2 <- rs) yield ALT(r1, r2)) #:::  | 
   157   rs #::: enum( (for (r1 <- rs; r2 <- rs) yield ALT(r1, r2)) #:::  | 
   166                 (for (r1 <- rs; r2 <- rs) yield SEQ(r1, r2)) #:::  | 
   158                 (for (r1 <- rs; r2 <- rs) yield SEQ(r1, r2)) #:::  | 
   167                 (for (r1 <- rs) yield STAR(r1)) )  | 
   159                 (for (r1 <- rs) yield STAR(r1)) )  | 
   168   | 
   160   | 
   169   | 
   161   | 
   170 enum(ZERO #:: ONE #:: "ab".toStream.map(CHAR)).take(200).force  | 
   162 enum(ZERO #:: ONE #:: "ab".toStream.map(CHAR)).take(200).force  | 
   171 enum(ZERO #:: ONE #:: "ab".toStream.map(CHAR)).take(200000).force  | 
   163 enum(ZERO #:: ONE #:: "ab".toStream.map(CHAR)).take(5000000)  | 
   172   | 
   164   | 
   173   | 
   165   | 
   174 val is =   | 
   166 val is =   | 
   175   (enum(ZERO #:: ONE #:: "ab".toStream.map(CHAR))  | 
   167   (enum(ZERO #:: ONE #:: "ab".toStream.map(CHAR))  | 
   176     .dropWhile(depth(_) < 3)  | 
   168     .dropWhile(depth(_) < 3)  | 
   323   | 
   315   | 
   324   | 
   316   | 
   325   | 
   317   | 
   326   | 
   318   | 
   327   | 
   319   | 
   328 // The End ... Almost Christimas  | 
   320 // The End ... Almost Christmas  | 
   329 //===============================  | 
   321 //===============================  | 
   330   | 
   322   | 
   331 // I hope you had fun!  | 
   323 // I hope you had fun!  | 
   332   | 
   324   | 
   333 // A function should do one thing, and only one thing.  | 
   325 // A function should do one thing, and only one thing.  | 
   334   | 
   326   | 
   335 // Make your variables immutable, unless there's a good   | 
   327 // Make your variables immutable, unless there's a good   | 
   336 // reason not to.  | 
   328 // reason not to.  | 
   337   | 
   329   | 
   338 // I did it, but this is actually not a good reason:  | 
   330 // I did it, but this is actually not a good reason:  | 
   339 // generating new labels  | 
   331 // generating new labels:  | 
         | 
   332   | 
   340 var counter = -1  | 
   333 var counter = -1  | 
   341   | 
   334   | 
   342 def Fresh(x: String) = { | 
   335 def Fresh(x: String) = { | 
   343   counter += 1  | 
   336   counter += 1  | 
   344   x ++ "_" ++ counter.toString()  | 
   337   x ++ "_" ++ counter.toString()  |