본문 바로가기

개발

[Scala] Call-by-value 와 Call-by-name

Call by value는 매개변수에 대한 계산을 끝낸 후 함수로 진입하고

Call by name은 함수 내에서 매개변수가 쓰일 때 비로소 계산을 시작합니다. 

 

// a와 b를 받아서 a를 return 하는 함수입니다. 
def test(a:Int, b:loop) = a 

// Call-by-Value : b에 대한 계산이 끝나지 않기 때문에 return을 돌려주지 않습니다.
def test(a:Int, b:loop) = a

// Call-by-Name : b는 함수 내부에서 쓰이지 않기 때문에 a를 돌려줍니다. 
def test(a:Int, b:loop) = a

 

스칼라는 대부분의 경우 Call-by-Value를 사용하지만, 함수가 일급 객체로서 매개변수로 넘어갈 때는 Call-by-Name을 사용합니다. 

함수를 선언할 때 매개변수 타입을 =>로 하면 Call by Name을 하도록 만들 수 있습니다. 

// 무한루프 함수
def loop:Boolean = loop

// Call-by-Vale
def and(x: Boolean, y: Boolean): Boolean = if (x) y else false
and(false, loop) 
// Output : 무한루프


// Call-by-Name
def and(x: Boolean, y: => Boolean): Boolean = if (x) y else false
and(false, loop)
// Output : false 

 

즉 아래와 같이 익명함수를 이용해서 상수값마저 Call By Name을 적용할 수 있지만 특별한 경우가 아니면 사용하지 않는다. 

def CallName(i: => Int) = println(i)
def CallValue(i: Int) = println(i)

CallName(3)
CallValue(3)

// Output
// 3
// 3