2015. 12. 29. 10:33ㆍProgramming/Scala
Nested functions
많은 작은 함수 조각으로 분리해서 프로그래밍 하는 것은 좋은 functional programming style이다.
그러나 sqrtIter, improve, isGoodEnough 와 같은 함수들은 sqrt의 구현 부분이지 도움말 같은 요소는 아니다. 게다가 사용자 역시 이러한 함수에 직접적으로 접근하지는 않는다.
우리는 sqrt 내에 이러한 함수들을 집어넣음으로써 "name-space-pollution"을 피할 것이다.
The sqrt Function, Take 2
def sqrt(x: Double) = {
def sqrtIter(guess: Double, x: Double): Double =
if (isGoodEnough(guess, x)) guess
else sqrtIter(improve(guess, x), x)
def improve(guess: Double, x: Double) =
(guess + x / guess) / 2
def isGoodEnough(guess: Double, x: Double) =
abs(square(guess) - x) < 0.001
sqrtIter(1.0, x)
}
Blocks in Scala
블록은 {...} 형태로 결정된다.
{
val x = f(3)
x * x
}
- 블록 안에는 expression이나 definition 덩어리들이 포함된다.
- 블록의 마지막 요소는 값을 정의하는 expression이다.
- return expression이 다른 정의보다 선행될 수도 있다.
- Block 자체가 expression이며, 어디에서든 사용이 가능하다.
Blocks and Visibility
val x = 0
def f(y: Int) = y + 1
val result = {
val x = f(3)
x * x
}
- 블록 안에 있는 정의는 오직 블록 내에서만 효력을 발생한다.
- 블록 내에 정의된 이름은 블록 외부에서는 보이지 않기 때문에 정의된 이름이 동일해도 무방하다.
Lexical Scoping
블록 외부 정의는 블록 내부에서는 보이기 때문에 sqrt 함수의 x 파라미터 발생 빈도를 줄임으로써 함수를 보다 단순하게 만들 수가 있다.
The sqrt Function, Take 3
def sqrt(x: Double) = {
def sqrtIter(guess: Double): Double =
if (isGoodEnough(guess)) guess
else sqrtIter(improve(guess))
def improve(guess: Double) =
(guess + x / guess) / 2
def isGoodEnough(guess: Double) =
abs(square(guess) - x) < 0.001
sqrtIter(1.0)
}
Semicolons
스칼라에서 라인 끝에 붙이는 세미콜론은 선택적이다. 아래와 같이 사용할 수도 있지만,
val x = 1;
대부분의 사람들은 세미콜론을 생략한다.
반면에 하나의 라인에 여러개의 statements를 사용하고 싶을 경우에는 세미콜론으로 분리시켜 주어야 한다.
val y = x + 1; y * y
Semicolons and infix operators
스칼라 세미콜론에 대한 하나의 이슈가 아래와 같이 여러 개의 라인으로 되어 있는 expression일 경우 어떻게 하느냐이다.
someLongExpression
+ someOtherExpression
위 expression을 scala에서는 아래와 같이 두 개의 expression으로 해석할 것이다.
someLongExpression;
+ someOtherExpression