In a language with the first class of functions, even if the syntax of the language is fixed, you can effectively create a new control structure. All you have to do is create a method that takes a function as a parameter. For example, here is a "double" control structure that can repeat an action two times and return the result:
Scala> def twice (op:double => Double, x:double) =
op (OP (x))
Twice: ((Double) => double,double) Double
Scala> twice (_ +
1, 5)
res9:double = 7.0
In this example, the OP type is a double => double, which means that it is a function that takes a double and returns another double.
You should consider implementing a new control structure whenever you find that multiple areas of your code have duplicate control patterns. Earlier in this chapter you saw Filesmatching, an extremely special control pattern. Now consider a more broadly used code pattern: open a resource, manipulate it, and then close the resource. You can capture it and put it in the control abstraction using the following methods:
def withprintwriter (file:
file, op:printwriter => unit) {
Val writer = new PrintWriter (file)
try {
OP (writer)
finally {
Writer.close ()
}
}
With this method, you can use this:
Withprintwriter (
New File
("Date.txt"),
Writer => writer.println (new java.util.Date)
)
The advantage of using this method is that the confirmation file is closed at the end by Withprintwriter instead of the user's code. So it's impossible to forget to close the file. This technique is called the lending pattern: loan patterns, because control of abstract functions, such as Withprintwriter, opens the resource and "lends" to the function. For example, the withprintwriter in the previous example lends PrintWriter to a function op. When the function completes, it signals that it no longer requires a "borrowed" resource. The resource is then closed in a finally block to make sure it is actually closed, ignoring whether the function returned gracefully or throws an exception.
One way to make the client code look more like a built-in control structure is to surround the argument list with braces instead of parentheses. Any Scala method calls, if you do pass in only one parameter, you can optionally use braces to override the parentheses to enclose the arguments. For example, instead:
Scala> println ("Hello, world!")
Hello, world!.
You can write:
scala> println {"Hello, world!"}
Hello,
world!.