본문 바로가기

Languages/Scala

[스칼라] 함수 - 기초

반응형

스칼라에서는 '재활용 가능한 이름을 가진 표현식'을 함수라 칭하며, 이 표현식의 마지막줄이 반환값이 됩니다.

함수형 프로그래밍에서 함수란 '일급 객체 First-class object'이며, 이는 다른 객체들에 일반적으로 적용 가능한 연산(매개변수화, 수정, 변수에 할당 등)을 지원하는 객체를 의미합니다.

위키피디아의 일급 객체 정의 : https://ko.wikipedia.org/wiki/%EC%9D%BC%EA%B8%89_%EA%B0%9D%EC%B2%B4

 

일급 객체 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 컴퓨터 프로그래밍 언어 디자인에서, 일급 객체(영어: first-class object)란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다. 보통 ��

ko.wikipedia.org

스칼라에서 함수는 다음과 같이 정의합니다 : 

def 식별자:타입 = 표현식

 

반환값을 가지지 않는(반환값이 Unit 타입인 경우) 함수를 '프로시저라고 부르며, 빈 괄호를 가지는 경우 괄호를 빼고도 호출할 수 있습니다. (역은 성립하지 않습니다.)

 

함수에는 다른 프로그래밍 언어와 마찬가지로 매개변수를 지정할 수 있으며,

def 식별자(매개변수:타입) = 표현식

 

매개변수에 값을 미리 지정하는 경우에는 해당 매개변수 없이도 함수를 호출할 수 있습니다.

 

불변 매개변수 뒤에 가변 매개변수를 받을 수도 있으며, 이 경우에는 매개변수 타입 뒤에 *를 붙여줍니다.

컬렉션을 매개변수로 받을 경우에는 매개변수 타입을 _*로 지정해주면 됩니다.

def 식별자(식별자:타입*)	//가변 매개변수
함수명(매개변수명:_*)	//컬렉션을 매개변수로 받을 경우

또한 매개변수를 그룹으로 지정할 수도 있으며, 이는 함수 리터럴을 매개변수로 넘기는 경우에 유용하게 사용할 수 있습니다.

 

함수 리터럴이란, 이름을 가지지 않는 함수를 말하며, 익명으로 정의된 함수를 의미합니다.

이렇게 적어놓고 보니 뭔가 이상하긴 한데, 그 '값' 자체를 의미한다고 생각하시면 편할 것 같습니다.

 

함수 리터럴을 사용한 예제는 다음과 같습니다.

val Adder:Int=>Int = x => x + 1

Adder(2)

 

한 줄 이상의 함수 리터럴을 작성할 때에는 중괄호로 감싸면 됩니다.

val Adder:Int=>Int = {
  x:Int =>
    val y:Int = x + 1
    y
}

Adder(2)

 

위 소스코드를 함수 리터럴을 사용하지 않고, 함수를 생성하여 할당하도록 작성하면 다음과 같습니다.

def add(x:Int):Int = x + 1

val Adder:Int=>Int = add

Adder(2)

 

위 소스코드는 중괄호로 둘러싸인 '함수 리터럴'을 Adder에 할당하였고, 아래 소스코드는 일급 객체인 함수 add를 Adder에 할당해 주었습니다. 이런 익명함수들은 Functional trait를 확장하여 만들어졌으며, 이에 대한 자세한 내용는 트레이트를 소개할 때 다루도록 하겠습니다. 

 

이런 함수들은 매개변수로 사용할 수 있으며, 매개변수로 사용할 때 타입은 입력값타입=>반환값타입 으로 작성하시면 됩니다.

def calculator(x:Int, y:Int, f:(Int,Int) => Int) = f(x,y)

def add(x:Int, y:Int) = x + y

val Adder = calculator(_, _, add)

Adder(2,3)

 

위와 같이 작성하거나, 와일드카드 연산자 (_)로 미래의 함수 호출에 대한 자리표시자 역할을 수행해 줄 수 있습니다.

def add(x:Int, y:Int) = x + y

val Adder = add _

Adder(2,3)

 

또한, 위에서 설명했던 매개변수 그룹 지정을 통해 함수 리터럴을 매개변수로 넘기게 되면 다음과 같이 작성할 수 있습니다.

def calculator(x:Int, y:Int)(f:(Int, Int) => Int) = f(x,y)

val Adder = calculator(_:Int, _:Int) {
  (x, y) => x + y
}

Adder(2,3)

 

위 소스코드를 함수 리터럴만을 사용하여 작성하면 다음과 같습니다.

val Adder = (x:Int, y:Int) => x + y

Adder(2,3)

 

위와 같이 다른 함수를 매개변수로 사용하거나 반환값으로 함수를 사용하는 함수를 '고차 함수'라 칭하며, 함수 매개변수를 취하고 이를 사용하여 하나 또는 그 이상의 항목을 새로운 값이나 타입으로 전환합니다.

이를 통해 데이터를 실제 처리하는 방법(how)은 고차 함수의 세부 구현사항으로 남겨두고, 호출자는 무엇(what)이 되어야 하는지를 지정하게 됩니다.

 

함수에 대한 스칼라의 다양한 특성들은 다음 글에서 다루도록 하겠습니다.

반응형

'Languages > Scala' 카테고리의 다른 글

[Scala Cats] Cats의 타입 클래스  (0) 2020.12.07
[Scala Cats] 스칼라 타입 클래스 기초  (0) 2020.11.13
[스칼라] 반복문  (0) 2020.04.27
[스칼라] 매치 표현식  (0) 2020.03.23
[스칼라] 데이터 타입, 표현식  (0) 2020.03.18