Skip to content

Commit 22f3e07

Browse files
Restore automatic-closures.md from the deads
It looks like it was deleted by mistake in 915e64e
1 parent 1402546 commit 22f3e07

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

_tour/automatic-closures.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
layout: tour
3+
title: Automatic Type-Dependent Closure Construction
4+
5+
discourse: true
6+
7+
partof: scala-tour
8+
---
9+
10+
Scala allows parameterless function names as parameters of methods. When such a method is called, the actual parameters for parameterless function names are not evaluated and a nullary function is passed instead which encapsulates the computation of the corresponding parameter (so-called *call-by-name* evalutation).
11+
12+
The following code demonstrates this mechanism:
13+
14+
object TargetTest1 extends Application {
15+
def whileLoop(cond: => Boolean)(body: => Unit): Unit =
16+
if (cond) {
17+
body
18+
whileLoop(cond)(body)
19+
}
20+
var i = 10
21+
whileLoop (i > 0) {
22+
println(i)
23+
i -= 1
24+
}
25+
}
26+
27+
The function whileLoop takes two parameters `cond` and `body`. When the function is applied, the actual parameters do not get evaluated. But whenever the formal parameters are used in the body of `whileLoop`, the implicitly created nullary functions will be evaluated instead. Thus, our method `whileLoop` implements a Java-like while-loop with a recursive implementation scheme.
28+
29+
We can combine the use of [infix/postfix operators](operators.html) with this mechanism to create more complex statements (with a nice syntax).
30+
31+
Here is the implementation of a loop-unless statement:
32+
33+
object TargetTest2 extends Application {
34+
def loop(body: => Unit): LoopUnlessCond =
35+
new LoopUnlessCond(body)
36+
protected class LoopUnlessCond(body: => Unit) {
37+
def unless(cond: => Boolean) {
38+
body
39+
if (!cond) unless(cond)
40+
}
41+
}
42+
var i = 10
43+
loop {
44+
println("i = " + i)
45+
i -= 1
46+
} unless (i == 0)
47+
}
48+
The `loop` function just accepts a body of a loop and returns an instance of class `LoopUnlessCond` (which encapsulates this body object). Note that the body didn't get evaluated yet. Class `LoopUnlessCond` has a method `unless` which we can use as a *infix operator*. This way, we achieve a quite natural syntax for our new loop: `loop { < stats > } unless ( < cond > )`.
49+
50+
Here's the output when `TargetTest2` gets executed:
51+
52+
i = 10
53+
i = 9
54+
i = 8
55+
i = 7
56+
i = 6
57+
i = 5
58+
i = 4
59+
i = 3
60+
i = 2
61+
i = 1

0 commit comments

Comments
 (0)