라벨이 implicit인 게시물 표시

[Scala] implicit keyword (4) - 마치며

지난 3번의 posting으로 Scala에서 implicit keyword의 3가지 사용법인 implicit converter, implicit classimplicit parameter에 대해서 알아봤다. 이 3가지 모두 약간씩 다르지만, 명시적으로 적어야 하는 코드를 줄여 코드를 간편하게 만들어 주는 역할을 해준다.
 그 때문에 적절하게 사용하면 verbose 코드를 줄여주어 가독성을 높여줄 뿐 아니라, Scala를 이용하여 domain-specific language(a.k.a. DSL)를 만들기 쉽게 만들어 준다. 실제로 많이 쓰이는 Play framework의 Configuration file이나 route file 또는 Scala와 Java 양쪽에서 많이 쓰이는 SBT는 Scala로 구현한 일종의 DSL로 Scala를 이용하여 static하게 compile 가능하게 되어있다.

 하지만 이런 power는 잘못 사용하면 해가 된다. 뭐 어떤 기능이 안 그러겠는가만은 특히 DSL을 만들기 쉽게 해준다는 것은 결국 기존의 언어가 아닌 새로운 언어를 정의하기 쉽게 된다는 것이고, 너무 많이 사용된 라이브러리는 Scala가 아닌 새로운 언어를 다시 배워야 한다는 문제가 생기기도 한다.
 실제로 SBT가 Scala로 컴파일되는 DSL이지만 필자는 아직도 SBT의 문법을 완벽히 이해하지 못했을 정도로 완전히 새로운 언어가 되었다. 또한, 많은 사람이 Scala를 처음 사용하면서 어려워하는 부분이 implicit converter와 implicit class로 인해 현재 class에 정의되지 않은 함수가 호출되는 것이다.1)

 Implicit keyword는 Scala의 난이도를 높여주는 장애물인 것은 분명하지만, 제대로 이해하고 있으면 새로운 세상을 보여주는 받침대가 된다.
1)이전 글에서도 말했지만, 이러한 특성 때문에 Scala를 처음 사용할 때는 다른 언어보다 더욱더 IDE가 필요하다. 다시 한 번 IntelliJ IDEA를 추천한다.
Scala impl…

[Scala] implicit keyword (3) - Implicit parameter

implicit keyword의 3번째 사용법은 implicit parameter와 implicit value를 선언하는 것이다. implicit parameter는 함수를 호출할 때 인자를 생략할 수 있도록 해준다. 정확히는 함수를 호출할 때 인자를 생략하면 자동으로 그 인자를 채워서 실행시켜준다.
 이때 무엇으로 채워주는지를 정하는 규칙은 2가지가 있다. 1)

 첫 번째 규칙은 함수가 호출된 scope에서 prefix 없이 접근할 수 있는 implicit parameter와 같은 타입의 변수 중에 implicit label이 붙은 변수를 사용하는 것이다. 이 규칙에는 2가지 타입의 변수가 해당한다. 하나는 implicit parameter이고, 다른 하나는 해당 스코프에 선언된 implicit modifier가 붙은 local 변수이다. 이때 함수가 호출된 스코프에서 해당하는 규칙에 적용되는 변수가 2개 이상 있으면 "ambiguous implicit values"라는 메시지와 함께 컴파일 에러를 발생시킨다. 여기서 주의해야 할 점은 반드시 implicit parameter와 같은 타입의 변수여야 한다는 것이다. 설령 implicit converter로 변환 가능한 변수가 있어도 이는 implicit parameter로 넘어가지 않는다.

 두 번째 규칙은 companion object에 정의된 변수 중 implicit parameter와 같은 타입으로 선언된 implicit label이 붙은 변수를 사용하는 것이다. 이는 첫 번째 규칙에 해당하는 변수가 없을 때 사용되고, 첫 번째 규칙과 마찬가지로 두 번째 규칙에 해당하는 변수가 2개 이상 있으면 "ambiguous implicit values"라는 메시지와 함께 컴파일 에러를 발생시킨다. implicit converter를 적용하지 않는 것도 첫 번째 규칙과 같다.

 Scala library에서 implicit parameter를 잘 활용하는 대표적인 예는 Futu…

[Scala] implicit keyword (2) - Implicit class

Scala에서 implicit keyword를 사용하는 또 다른 예제는 Implicit class이다.

 Implicit class는 이미 존재하는 class에 새로운 함수를 추가하여 확장하기 위해서 사용된다.
 정확히 말하면 원래 있던 클래스 자체를 바꾸지는 않고, class를 implicit conversion해서 호출할 수 있는 함수를 추가할 수 있게 해준다.
 Standard library에 있는 implicit class의 대표적인 예는 Duration class들이다.

 위의 예제에서 보듯이 DurationIntDurationDouble이라는 implicit class가 각각  Int와 Double을 확장시켜서 seconds/milliseconds/nanoseconds 같은 method를 추가해서 Duration 객체를 만들 수 있게 해준다.

 이 설명을 보면 지난 글에서 설명해줬던 implicit converter가 해줄 수 있는 일과 크게 다르지 않아 보인다.
 사실 Implicit class는 implicit converter의 syntactic sugar에 불과하다. 내부적으로 implicit class로 정의된 class는 class의 이름과 같은 implicit converter를 같은 scope에 추가한다.
 즉, 아래와 같이 정의된 implicit class는

 아래와 같이 변환된다.


 내부적으로 implicit converter에 해당하는 함수를 정의하는 것이기 때문에 몇 가지 제약사항이 있다.
 첫 번째 제약사항으로 implicit class는 trait이나 classobject 안에 정의되어야 한다.
 이는 함수의 정의가 trait이나 class나 object 안에 정의되어야 하기 때문이다. 그래서 보통 implicit class들은 package object 안에 정의된다.
 두 번째 제약사항은 non-implicit인 parameter가 반드시 1개인 constructor를 가지고 있어야 하는 것이다.
 implic…

[Scala] implicit keyword (1) - implicit converter

Implicit converter가 하는 일은 이름 그대로 value를 적절한 type으로 implicit하게 convert하는 것이다.
 Scala는 기본적으로 strong typed language이기 때문에 implicit conversion을 지원하지 않는다. 함수를 호출할 때 함수의 symbol에 맞지 않으면 바로 컴파일에러가 발생한다.
 implicit conversion을 하기 위해서는 해당 scope 안에 implicit converter를 구현해두어야 한다.

 Implicit converter의 선언은 다음과 같다.

 Implicit converter는 unary function에 implicit keyword를 붙여주는 것으로 정의된다.
 이렇게 Implicit converter를 구현해두면, sizeToRectangle 함수가 정의되어 있는 scope에서는 Size 객체가 Rectangle 객체로 implicit conversion이 가능해진다.

 예를 들어 Scala에서 자주 쓰이는 Option이라는 class를 보자.
 Option은 c#의 nullable과 유사한 type으로 원소가 없을 수 있는 객체이다. 이는 다른 관점에서 보면 최대 원소가 1개인 collection이라고 볼 수 있고, Option을 사용할 때 collection처럼 list comprehensive method1)를 사용하는 것을 권장한다.
 하지만 Option코드를 보면 Option은 Iterable이나 Traversable을 상속받지 않았고, 일부 함수를 제외하고 collection처럼 이용는데 필요한 모든 함수를 가지고 있지도 않다.
 하지만 Option을 Iterable로 변환해주는 option2Iterable이라는 implicit converter가 있기 때문에 iterable이 필요한 경우 자동으로 convert해서 넘겨준다.

 Implicit converter에 대응되는 개념이 다른 언어에 없는 것은 아니다.
 C++에서는 unary constru…

[Scala] implicit keyword (0)

Scala의 가장 인상적인 keyword를 말하라고 하면 많은 사람이 implicit을 꼽을 것이다.
 implicit은 scala의 확장성에 무한한 힘을 주는 keyword임과 동시에 코드를 읽을 때 헬 게이트를 여는 주범이기도 하다. 1)

 implicit keywod는 Implicit converter, Implicit class, Implicit parameter의 3가지 목적으로 이용된다.
 앞으로 3번에 걸쳐서 각각에 대해 설명하도록 하겠다.
1) 개인적으로 코딩할 때 대부분 언어를 vim으로 작업해왔지만, scala를 배우면서 IntelliJ라는 IDE를 사용하기 시작했다.
Scala implicit keyword