본문 바로가기
Programming/Scala

Blocks and Lexical Scope - Coursera 강의 ppt 번역

by 유주원 2015. 12. 29.

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


이러한 문제를 해결하기 위한 두 가지 방법이 있는데, 첫 번째는 괄호 안에 묶어서 expression을 표현하는 것이다.

(someLongExpression
 + someOtherExpression)

또는 첫 번째 라인에 operator를 쓰는 방법이다. 이렇게 쓰면 scala 컴파일러에게 expression이 아직 끝나지 않았다고 알려주는 것과 같다.

someLongExpression +
someOtherExpression