On curly braces and thunks in Scala

Today I spent some time going down the road of “What is a thunk in Scala?” Here’s some relevant text from this Wikipedia page. Note that I have deleted some lines, and modified others:

In computer programming, a thunk is a subroutine used to inject an additional calculation into another subroutine. Thunks are primarily used to delay a calculation until its result is needed, or to insert operations at the beginning or end of the other subroutine.

The term originated as a humorous, incorrect, past participle of “think.” That is, a “thunk value” becomes available after its calculation routine is thought through, or executed.

Background

The early years of compiler research saw broad experimentation with different evaluation strategies. A key question was how to compile a subroutine call if the arguments can be arbitrary mathematical expressions rather than constants. One approach, known as “call by value,” calculates all of the arguments before the call and then passes the resulting values to the subroutine. In the rival “call by name” approach, the subroutine receives the unevaluated argument expression and must evaluate it.

Applications

Functional programming

Although the software industry largely standardized on call-by-value and call-by-reference evaluation, active study of call-by-name continued in the functional programming community. This research produced a series of lazy evaluation programming languages in which some variant of call-by-name is the standard evaluation strategy. Compilers for these languages, such as the Glasgow Haskell Compiler, have relied heavily on thunks, with the added feature that the thunks save their initial result so that they can avoid recalculating it; this is known as memoization or call-by-need.

Functional programming languages have also allowed programmers to explicitly generate thunks. This is done in source code by wrapping an argument expression in an anonymous function that has no parameters of its own. This prevents the expression from being evaluated until a receiving function calls the anonymous function, thereby achieving the same effect as call-by-name. The adoption of anonymous functions into other programming languages has made this capability widely available.

Again, almost all of that previous text comes from Wikipedia.

Other resources

Here are some other resources related to this and the use of curlya braces for blocks of code in Scala:

Here are some phrases from that last SO page:

  • Parenthesis can be used to make subexpressions
  • Curly braces can be used to make blocks of code (this is not a function literal)
  • A block of code consists of multiple statements, each of which can be an import statement, a declaration, or an expression
  • Blocks of code are also expressions, so you can use them anywhere inside an expression