Last updated on
Week 1 Debrief: Setup, Recursion exercises
Congratulations on completing your first week of CS-214! Here is a round-up of interesting questions, tips for exercises and labs, and general notes about the course.
Errata
-
This course uses Scala 3.7.2, but the first lab and exercises were released with Scala
3.5.0
, which isn’t supported by Metals. We have updated them: if you run into version issues, undo any manual fixes and pull the newest version withgit pull
. -
We moved one exam lab session from November 5th to October 29th. You can double-check your assigned slot on Moodle.
Announcements you might have missed
-
We don’t have a classroom on Monday, so we’ll use prerecorded videos.
-
If you’re not available on your assigned exam-lab slot, we have a dedicated Ed thread to find a swap.
-
We are trialing extra help sessions on Mondays. The first one is 13:00-15:00 this Monday in INM 200 and ELA 1. Later ones will be announced in the syllabus.
-
Don’t forget to bring scissors to the help sessions this week: some cutting will be required!
Administrivia
-
CS-214 labs are typically due on Fridays, and
degrees
was no exception. If you missed thedegrees
deadline, don’t panic:degrees
doesn’t count.find
(released last Wednesday) does count, however, and is due next Friday. Don’t miss that deadline! -
Many schedule, grading, and exam questions are already answered in our policies page. For setup issues, checkout our new troubleshooting guide, and let us know if you run into issues not listed there!
-
We have posted a transcript of Wednesday’s Git lecture to help you get familiar with Git. We recommend reproducing the commands, not just reading them.
-
Once you’re done with exercises, check out the solutions, and ask us if anything is unclear or you want feedback!
-
As a reminder,
degrees
covers the following:- How to use the SBT build tool and start up Visual Studio Code and the Metals extension
- How to quickly experiment with your code using a worksheet.
- How to run specific tests with SBT.
Interesting links and Ed questions
- Setup issues
- Exercises
Deep dives and tips
How to deal with stack overflows and never-ending programs 📘
When dealing with recursive functions, it’s easy to run into an infinite loop and obtain a never-ending test, or an error such as:
java.lang.StackOverflowError
at factorial(file.scala:9)
at factorial(file.scala:9)
at factorial(file.scala:9)
at factorial(file.scala:9)
at factorial(file.scala:9)
...
This error means that your program exhausted the call stack, a designated memory area where your program stores information about the function currently executing. Every time you make a recursive call, an entry get added to the call stack: if you recurse too deep, it runs out of space, and your program throws a StackOverflowError
.
Sometimes, the compiler can optimize away uses of recursion. This is called “tail recursion elimination”; we will study it in week 10.
If you run into this issue, look out for the following points:
-
Make sure that your function can stop at some point: It needs a base case. For example, the length function stops when encountering an empty list:
def length(l: IntList): Int = if l.isEmpty then 0 // base case, this is where the method stops else 1 + length(l.tail) // recursive call
2025-09-14/code/stackOverflow.worksheet.sc
Starting to write your recursive method by asking “What happens in this trivial case (
0
,Nil
, etc.)?” can help you think about the whole problem. -
Check that the recursive call is decreasing: for the whole function to terminate, each call must get a bit closer to the end of the problem. Here is an obviously bad example:
def badLength(l: IntList): Int = if l.isEmpty then 0 else 1 + badLength(l) // Woops, nondecreasing call!
2025-09-14/code/stackOverflow.worksheet.sc
Sometimes, a function that looks fine may have incorrect behavior for unexpected inputs. What happens if the function below is called on
-1
?def factorial(n: Int): Int = if n == 0 then 1 else n * factorial(n - 1)
2025-09-14/code/stackOverflow.worksheet.sc
There are various strategies in this case. You can extend the scope of the base case:
def factorialDefault(n: Int): Int = if n <= 0 then 1 else n * factorialDefault(n - 1)
2025-09-14/code/stackOverflow.worksheet.sc
… or you can rule out illegal values:
def factorialRequire(n: Int): Int = require(n >= 0, "Illegal negative value passed to factorial.") // check for illegal values def rec(n: Int): Int = if n == 0 then 1 else n * rec(n - 1) rec(n)
2025-09-14/code/stackOverflow.worksheet.sc
You can use if
inside val
! 📘
Remember that, in Scala, if
is an expression. This means that you can use it in all contexts:
(if b1 then 1 else 2) + (if b2 then 10 else 20)
2025-09-14/code/find.worksheet.sc
val result =
if x == y then
println("They are equal!")
true
else false
println(result)
2025-09-14/code/find.worksheet.sc