--- 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.
-
-