progs/lecture4.scala
changeset 384 6e1237691307
parent 383 c02929f2647c
child 418 fa7f7144f2bb
--- a/progs/lecture4.scala	Mon Dec 07 01:25:41 2020 +0000
+++ b/progs/lecture4.scala	Fri Jan 15 02:40:57 2021 +0000
@@ -249,6 +249,57 @@
 // Source.fromFile(name)(encoding)
 
 
+// Tail recursion
+//================
+
+@tailrec
+def fact(n: BigInt): BigInt = 
+  if (n == 0) 1 else n * fact(n - 1)
+
+
+fact(10)          
+fact(1000)        
+fact(100000)       
+
+def factB(n: BigInt): BigInt = 
+  if (n == 0) 1 else n * factB(n - 1)
+
+def factT(n: BigInt, acc: BigInt): BigInt =
+  if (n == 0) acc else factT(n - 1, n * acc)
+
+
+factB(1000)
+
+
+factT(10, 1)
+println(factT(500000, 1))
+
+
+// there is a flag for ensuring a function is tail recursive
+import scala.annotation.tailrec
+
+@tailrec
+def factT(n: BigInt, acc: BigInt): BigInt =
+  if (n == 0) acc else factT(n - 1, n * acc)
+
+factT(100000, 1)
+
+// for tail-recursive functions the Scala compiler
+// generates loop-like code, which does not need
+// to allocate stack-space in each recursive
+// call; Scala can do this only for tail-recursive
+// functions
+
+// Moral: Whenever a recursive function is resource-critical
+// (i.e. works with a large recursion depth), then you need to
+// write it in tail-recursive fashion.
+// 
+// Unfortuantely, Scala because of current limitations in 
+// the JVM is not as clever as other functional languages. It can 
+// only optimise "self-tail calls". This excludes the cases of 
+// multiple functions making tail calls to each other. Well,
+// nothing is perfect. 
+
 
 
 
@@ -391,66 +442,22 @@
 
 
 
-// Tail recursion
-//================
-
-@tailrec
-def fact(n: BigInt): BigInt = 
-  if (n == 0) 1 else n * fact(n - 1)
-
-
-fact(10)          
-fact(1000)        
-fact(100000)       
-
-def factB(n: BigInt): BigInt = 
-  if (n == 0) 1 else n * factB(n - 1)
-
-def factT(n: BigInt, acc: BigInt): BigInt =
-  if (n == 0) acc else factT(n - 1, n * acc)
-
-
-factB(1000)
-
-
-
-
-factT(10, 1)
-println(factT(500000, 1))
-
-
-
-
-
-// there is a flag for ensuring a function is tail recursive
+// tail recursive version that searches 
+// for all Sudoku solutions
 import scala.annotation.tailrec
 
 @tailrec
-def factT(n: BigInt, acc: BigInt): BigInt =
-  if (n == 0) acc else factT(n - 1, n * acc)
-
-factT(100000, 1)
-
-// for tail-recursive functions the Scala compiler
-// generates loop-like code, which does not need
-// to allocate stack-space in each recursive
-// call; Scala can do this only for tail-recursive
-// functions
-
-// tail recursive version that searches 
-// for all Sudoku solutions
-
-@tailrec
-def searchT(games: List[String], sols: List[String]): List[String] = games match {
-  case Nil => sols
-  case game::rest => {
-    if (isDone(game)) searchT(rest, game::sols)
-    else {
-      val cs = candidates(game, emptyPosition(game))
-      searchT(cs.map(c => update(game, empty(game), c)) ::: rest, sols)
-    }
-  }
-}
+def searchT(games: List[String], sols: List[String]): List[String] = 
+ games match {
+    case Nil => sols
+    case game::rest => {
+      if (isDone(game)) searchT(rest, game::sols)
+      else {
+        val cs = candidates(game, emptyPosition(game))
+        searchT(cs.map(c => update(game, empty(game), c)) ::: rest, sols)
+     }
+   }
+ }
 
 searchT(List(game3), List()).map(pretty)
 
@@ -487,17 +494,6 @@
 searchT(List(game3), Nil).map(pretty)
 search1T(List(game3)).map(pretty)
 
-// Moral: Whenever a recursive function is resource-critical
-// (i.e. works with a large recursion depth), then you need to
-// write it in tail-recursive fashion.
-// 
-// Unfortuantely, Scala because of current limitations in 
-// the JVM is not as clever as other functional languages. It can 
-// only optimise "self-tail calls". This excludes the cases of 
-// multiple functions making tail calls to each other. Well,
-// nothing is perfect. 
-
-