Parameters by name : one of the main motives was maintaining dsls. They allow you to have really good syntax in APIs that almost feel like they are built into the language. For example, you can easily define your own repeat -loop:
def repeat(body: =>Unit)(until: =>Boolean): Unit = { body if (until) {} else repeat(body)(until) }
And then use it as if it were part of the language.
var i = 0 repeat { println(i) i += 1 } (i < 3)
Or you could create a new thread in the same way as follows: spawn { println("on the new thread!") } , Or you could automate the resource management of your FileInputStream as follows: withFile("/home/john/.bashrc") { println(_.contents) } .
The lazy meanings are the motives here:
- lazy data structures such as
Stream s , which are popular in functional languages that can be used to implement an efficient data structure a-la Okasaki functional queues. - to avoid allocating or initializing some expensive resources if they are never used in any object, for example. file descriptors or database connections.
- to initialize the fields of objects in the correct order for objects consisting of many mixins.
- to achieve the correct semantics of "initialize only once" when there are many threads sharing the same value (see the introduction here ).
- have a translation scheme for nested singleton objects:
class A { object B }
becomes something like:
class A { class A$B$ lazy val B = new A$B$ }
source share