Linux와 오픈 소스는 공통적으로 최첨단 언어 설계 기술과 연관되어 있으며, 언어 설계의 발전에 자양분이 되는 플랫폼의 개방성이나 언어 개발을 지원하는 데 사용 가능한 도구일 수 있다. 또는 오픈 소스 기술을 기반으로 하는 개방형 언어(예: GNU Compiler Collection 패밀리, Ruby, Python, Perl 등)는 Red Hat이 Ceylon 배후에 있는 회사라는 점은 말할 것도 없고, 개발자들이 마음껏 사용하고 이런저런 실험을 해보도록 장려한다는 점에서 훌륭한 언어라고 할 수 있을 것이다. 이유야 무엇이든, Linux 개발자는 점점 사용 빈도가 낮아지는 과거의 언어부터 최신의 첨단 오퍼링까지 다양한 언어를 사용할 수 있다.
그러나 C/C++, Java™ 언어, Scala, Ruby, Python, Perl, Erlang, Lua, Scheme 및 기타 수많은 언어의 세계에서, 비즈니스 지향 엔터프라이즈 소프트웨어 개발에 초점을 맞춘 새로운 언어의 발표에 신경을 써야 할까? 많은 경우, 그 대답은 관심을 둘 필요가 없다는 것이겠지만, Ceylon이라는 Red Hat의 향후 언어 오퍼링을 탐구하여 이 언어가 오늘날 가장 널리 쓰이는 언어들과 경쟁할 정도로 성장할 수 있을지 살펴보자.
Ceylon은 Gavin King이 이끄는 Red Hat의 새 프로젝트이다. King은 Java 언어 내에 있는 지속성 솔루션인 Hibernate 프로젝트의 창시자이다. King이 대규모 개발에 적합한 최초의 언어 중 하나였던 Java 언어 기술의 팬이긴 하지만, 그는 제네릭과 같은 Java 언어의 복잡도, 급히 설계하느라 모호하기 짝이 없는 Standard Edition SDK, 서투른 어노테이션 구문, 엉망인 블록 구조, XML에 대한 종속성 등, Java 언어의 많은 단점에 질린 사람으로도 알려져 있다.
King은 Java 언어와 SDK의 장단점으로부터 배운 교훈을 통해, 언어란 어떤 모습이어야 할까 하는 질문을 던졌다. 그가 내놓은 해답이 바로 Ceylon이며, 이 언어는 Java 언어가 지닌 최고의 특징들을 일부 간직하고 JVM에서 실행되지만 언어의 가독성, 기본 제공되는 모듈성, 고차 함수와 같은 함수형 언어 기능의 통합을 바탕으로 더욱 개선한 정적 타입 언어(statically typed language)이다. Ceylon에는 C와 Smalltalk의 기능도 포함되어 있다. Java 언어와 마찬가지로, 이 새로운 언어는 비즈니스 컴퓨터에 초점을 맞추고 있지만 다른 도메인에서도 유용하고 유연성이 뛰어나다.
어떤 이들은 Ceylon을 "Java 킬러"라고 불렀지만(아마도 Java 언어의 미래에 대한 의문 때문인 듯), 사실 Ceylon은 JVM에서 작동하므로 Java 기술을 대체하는 것이 아니라 확장하는 언어이다. Ceylon의 실행을 지원하기 위해 JVM을 사용하는 것이 이상적인 모델인데, 이는 Ceylon이 Java와 마찬가지로 현재 JVM을 지원하는 다양한 아키텍처 간에 이식 가능하다는 의미이기 때문이다.
오늘날 대부분의 언어는 간단히 카테고리로 분류하기 어려운 일이고, 그 대신 다양한 프로그래밍 스타일을 대변한다고 봐야 할 것이다. Ceylon도 전혀 다르지 않다. Ceylon은 정적 유형 언어이다(유형 검사가 실행 시간에 수행되는 Lisp와 같은 동적 유형 언어에 비해, 유형 검사가 컴파일 시간에 수행된다는 뜻임). Ceylon은 Java 언어와 같이 객체 지향 언어이며, 전형적인 C 구문 스타일을 이용해 고차 함수도 지원한다(즉, 함수가 함수를 입력 또는 출력을 취할 수 있음). Java 언어에서는 고차 함수가 직접적으로 지원되지는 않으므로, 이 기능은 두 언어의 뚜렷한 차이점을 나타낸다.
하지만, 때때로 어떤 언어에서 이루어진 개선이라는 것이 뭔가를 추가한 것보다 제거한 것이 더 많을 때도 있다. Ceylon에서는 Java 언어의 각종
요소를 단순화하고 제거하면서 이들을 더 간단한 요소로 대체했다. 단순화의 한 예를 들자면, public,
protected, private 키워드를 제거했다는 점이다. 그 대신, 단순히 Ceylon에는
클래스의 어떤 요소를 외부에서 볼 수 있을지 정의하는 shared 어노테이션이 포함되어 있다. Ceylon에서는 오버로드 기능도
제거했지만, 더 간단한 구문으로 이 기능을 대신할 수 있는 몇몇 방법을 제공한다(예: 기본형 및 시퀀스형 매개변수).
Ceylon은 상속, 시퀀스(배열 또는 목록 생성), 제네릭, 명명된 인수 등에 대한 지원을 포함한다. 또한, 실행 시간 유형 관리를 위한 기능도 포함한다(이에 대한 예제는 다음 섹션에서 다룸). 이 언어는 나날이 발전되고 있는 중이므로, 최종적인 기능 세트는 아직 확정된 상태가 아니다.
본 기사를 작성하는 현재, 공개적으로 쓸 수 있는 컴파일러는 아직 없지만 Ceylon 언어의 구조가 정의되어 있으므로 용도와 가독성에 대해 탐색하고 추론하기 위한 샘플 애플리케이션을 개발할 수 있다. 이 섹션에서는 Ceylon으로 작성된 샘플 애플리케이션을 몇 가지 살펴보면서 그 구조를 검토한다.
"Hello World" 프로그램을 사용하여 표시장치로 간단한 텍스트 문자열을 내보내는 간단한 프로그램 작성 방법을 보여주겠다. 목록 1에 표시된
예제에서는 writeLine 메소드를 사용하여 표준 출력으로 문자열을 내보내는 hello라는 최상위 레벨
메소드를 보여준다.
목록 1. Ceylon으로 작성된 Hello World 프로그램
doc "Hello World Program"
by "Gavin King"
void hello() {
writeLine( "Hello World." );
}
|
메소드와 작성자를 지정할 수 있도록 해주는 API 문서에 사용되는 어노테이션(doxygen과 같은 도구와 유사함)도 주목하자(각각
doc 및 by 어노테이션).
Ceylon에는 일반 클래스로 구현되는 기존의 유형 세트가 통합된다. 이런 유형은 다음과 같다.
Natural. 0을 포함한 부호 없는 정수Integer. 부호 있는 정수Float. 부동 소수점Whole. 임의 정밀도의 부호 있는 정수Decimal. 임의 정밀도와 임의 배율의 10진수
기본적으로, Natural,
Integer 및 Float 유형은 64비트이지만, 이들을 small로
어노테이션을 작성하여 32비트 정밀도를 지정할 수 있다.
Ceylon은 객체 지향 언어이므로, 클래스 개념을 사용하여 코드를 작성한다. 클래스는 Ceylon에서 사용되는 한 가지 유형으로, 클래스의 오브젝트가 초기화될 때(생성자와 유사한 클래스 이니셜라이저) 상태가 초기화되는 방식에 대한 정의 외에도, 조작 및 상태 세트(메소드라고 함)를 캡슐화한다.
한 가지 간단한 클래스로 Ceylon의 접근 방법을 이해할 수 있다. 목록 2에 카운터 클래스에 대한 간단한 클래스가 나와 있다. 2행에서 선택적
값으로 클래스를 정의하는데, 이는 사용자가 이 값을 제공할 수 있거나 없고 값이 Type? 패턴으로 표시된다는 뜻이다. 클래스 본문에는 생성자 대신
클래스 이니셜라이저가 포함된다. 이 코드는 private 변수(공유로 어노테이션을 작성하지 않으면 아무 것도 표시되지 않음)를 정의한 후 초기화 논리를
정의한다. Start 변수가 있는지 확인하는 작업부터 시작한다. 이 변수가 있으면 계수를 위한 초기값으로 사용된다. shared로
어노테이션이 작성되어 클래스에서 외부적으로 표시되는 첫 번째 메소드는 incrementer를 정의한다.
이 메소드를 호출하면 카운터가 단순히 증가한다.
마지막으로, 사용자에게 현재 카운터 값을 리턴하는 getter 메소드와 현재 카운터 값을 호출자가 입력한 값으로 설정하는 setter 메소드를
정의한다. 여기서 assign 키워드를 사용하여 카운터의 값을 설정하기 위한 변수 속성을 작성한다는 점에 주목하자. 생성자를 다르게
처리한다는 점 외에(클래스 내부에 임베드된 코드), 소멸자가 없고 여러 개의 생성자를 구현할 방법도 없다(Java 언어와의 차이점 중 하나일 뿐임).
목록 2. Ceylon으로 작성된 간단한 클래스
01 doc "Simple Counting Class"
02 class Counter( Natural? start ) {
03
04 doc "Class Initializer"
05 variable Natural count := 0;
06 if (exists start) {
07 count := start;
09 }
10
11 doc "The incrementer"
12 shared void increment() {
13 count++;
14 }
15
16 doc "The getter"
17 shared Natural currentValue {
18 return count;
19 }
20
21 doc "The setter"
22 shared assign currentValue {
23 count := currentValue;
24 }
25
26 }
|
간단한 클래스를 정의한 상태에서, Ceylon에서 클래스를 사용하는 방법을 살펴보자. 목록 3에는 Counter 클래스를
사용하는 코드 블록이 나와 있다. 이 블록은 cnt 오브젝트에 대한 클래스의 인스턴스 생성으로 시작된다. Ceylon에는
new 키워드가 없다. Counter 오브젝트를 새로 정의한 상태에서, increment
메소드를 호출한 다음 getter 메소드를 사용하여 Counter 값을 내보낸다. Ceylon에서 = 및
:= 연산자는 서로 다르고 = 지정자는 불변 값에만 사용하는 반면, :=
연산자로 변수 지정을 수행한다.
목록 3. Counter 클래스 사용
01 Counter cnt = Counter(1); 02 cnt.increment(); 03 writeLine( c.currentValue ); |
Ceylon에서는 가급적이면 불변 속성을 사용하는 것이 좋다. 이는 오브젝트가 어떤 값으로 초기화되고 다시 지정되지 않는다는 뜻이다. 명명된
값이 변경 가능(초기화 후 변경할 수 있음)한 것으로 지정하려면 목록 2의 5행에 표시된 것처럼
variable로 어노테이션을 작성해야 한다.
마지막으로 탐색할 한 가지 요소는 Ceylon의 제어 구조에서 나타나는 주요 차이점이다. 많은 언어에서는 단일
statement가 나타나는 경우와 같이, 조건식 뒤에 중괄호({})를 생략할 수 있다.
if (cnt > 10) statement(); |
Ceylon에서는 이 구문을 금지하므로 중괄호가 있어야 한다. 즉, 위에 표시된 샘플 코드를 Ceylon으로는 다음과 같이 써야 한다는 뜻이다.
if (cnt > 100) { statement(); }
|
이는 C에서 가장 흔한 오류 중 하나를 나타내므로, 이런 종류의 올바른 스타일을 강제 실행하기 위해 추가해도 좋다.
Ceylon에는 1차 함수라는 함수 프로그래밍 스타일이 포함된다. 이는 단순히 함수가 퍼스트클래스 오브젝트로 취급되고 함수에서
리턴될 뿐 아니라 함수에 대한 매개변수로 사용될 수도 있다는 의미다. repeat 메소드 정의를 위해 King의 프리젠테이션에서 발췌한
예제를 살펴보자(목록 4 참조). 이 경우, 반복할 횟수에 대한 Natural과 호출할 함수에 대한 메소드 인수의 두 인수를
취한다. repeat 메소드의 본문 내에서 간단하게 for 루프(범위 조작 사용)를 작성하고 함수 매개변수로
전달할 메소드를 호출한다.
목록 4. Ceylon의 고차 함수
01 void repeat( Natural times, void hfunction() ) {
02 for (Natural n in 1..times) {
03 hfunction();
04 }
05 }
|
목록 5의 7행에 표시된 것처럼, 이 메소드를 사용하는 방법은 간단하다. 보는 바와 같이, 메소드의 이름은 인수 없이 사용된다.
목록 5. Ceylon에서 고차 함수 사용
01 void sayhello() {
02 writeLine( "Hello World." );
03 }
04
05 ...
06
07 repeat( 10, sayhello );
|
함수 지원 기능이 있는 다른 언어와 달리, Ceylon에서는 익명 함수(표현식에 직접 나타나는 이름 없는 함수)를 지원하지 않는다. Ceylon에는 클로저(본질적으로 다른 함수에 있는 상태를 참조할 수 있는 함수)를 위한 지원이 포함된다.
Ceylon에는 Java 언어에 있는 instanceof 연산자가 포함되지 않고, C에서 찾아볼 수 있는 typecasting도 없다. 그 대신,
Ceylon은 한 단계에서 오브젝트 참조의 유형을 테스트하고 범위를 좁히는 데 사용되는 type narrowing이라는 것을 구현한다. 목록 6에서 다음 코드
세그먼트를 고찰해보자. 이 코드에서는 특수한 (is ... ) 생성을 사용하여 주어진 유형에 대한 오브젝트 참조를 테스트한다. 유형이
식별되면 해당 유형에 특정한 메소드가 사용된다. 이런 생성은 앞서 목록 2에서 선택적 매개변수에 대해 살펴본 (exists ...)
생성과 유사하다.
목록 6. Ceylon의 type narrowing
01 Object obj = <some object>;
02
03 switch (obj)
04
05 case (is Counter) {
06 obj.increment();
07 }
08 case (is ComplexCounter) {
09 obj.incrementBy(1);
10 }
11 else {
12 stream.writeLine("Unknown object");
13 }
|
Ceylon에는 (nonempty ...)로 정의되는 유사하지만 다른 생성이 포함되는데, 시퀀스(배열 또는 목록)에 이를 적용하여,
시퀀스에 아무런 요소도 포함되지 않고 따라서 적용되는 시퀀스 조작이 없는지 판단할 수 있다.
마지막으로, Ceylon에서 switch 문에 대한 구문이 있는데, C 및 Java 언어와는 다르다. 두 언어를 사용할 때 오류가
잘 발생할 수 있는 곳에서, Ceylon은 케이스에 블록 구조를 강제 실행하고 else 블록에 대한 환경 설정에서 default
케이스를 제거한다. 또한, Ceylon에서는 (컴파일 시간에) switch 문에 인스턴스 테스트의 전체 목록이 포함되거나, 최소한 전체
적용 범위를 제공하기 위한 else 절이 포함되는지 확인한다.
컴파일러는 이런 switch 문을 자동으로 검사하여 포함되지 않은 인스턴스가 있는 경우 오류를 생성한다.
Ceylon에서는 예상과 같이 일반적인 if...else 문을 구현하고, Java 언어의 예외 처리
기능(try, catch, finally)도 구현한다. 또한, Ceylon에서는
for 루프가 일찍 중단되지 않을 때를 식별하기 위해 루프와 함께 사용되는 fail 블록이라는 것을
작성한다. 목록 7에 표시된 예제를 고찰해보자.
목록 7. Ceylon의 fail 블록 예시
01 for (Instrument i in instruments) {
02 if (i.failing()) {
03 break;
04 }
05 }
06 fail {
07 // All instruments are working...
08 }
|
이는 C 및 Java 언어에서 모두 공통적인 설계 패턴이므로 Ceylon에서도 유용하게 사용된다.
King이 말했듯이, Ceylon은 어느 한 사람이나 회사가 아니라 커뮤니티 전체가 노력하여 만들어가는 것이므로 언어와 SDK의 설계, 빌드 및 유효성 검증에 도움을 줄 엔지니어와 테스터가 필요하다. 이 때문에, Java 언어 사용자들이 적극적으로 피드백을 주어 Java에서 Ceylon으로의 마이그레이션을 지원하는 데 도움을 준다면 크게 환영받을 일이다. King은 아직도 Ceylon의 현재 상태에 대해, ANTLR(Another Tool for Language Recognition) 문법뿐 아니라 언어 스펙이 존재한다고만 말하면서 다소 침묵을 유지하는 입장이다.
새로운 언어가 등장해야 할 필연성에 어떤 걸림돌이 있을 수도 있겠지만, 언어를 보는 또 다른 방식은 바로 문제점 해결에 사용할 수 있는 도구 세트로 보는 것이다. 주어진 문제점을 해결하는 데 모든 언어가 적합하거나 이상적인 것은 아니지만, 언어마다 적합한 특정 솔루션 도메인이 있다. 따라서 여러 가지 언어를 사용할 수 있다는 것은 저주가 아닌 축복이다. Ceylon은 계속 개발 중인 상태이므로, 이 언어가 현재 널리 사용되고 있는 언어들과 어깨를 나란히 할지는 알 수 없다. 그러나 이 언어는 충분히 흥미를 끄는 특징을 많이 가지고 있으므로, 마침내 전체적인 모습을 드러낼 때 더 깊이 탐구해보는 것도 즐거운 일일 것이다.
교육
- Gavin King이 Ceylon 언어를 소개하는 30분 분량의 원본 동영상은 Introducing the
Ceylon Project Video라는 제목의 동영상에서 볼 수 있다. King이 Ceylon을 소개하는 프리젠테이션은 두 가지가 있는데,
introductory presentation과 더 발전된 기능을 다룬 The Ceylon
Type System이라는 제목의 프리젠테이션이 여기에 포함된다.
- Gavin King은 Ceylon 언어를 설명하기 위해 11회에 걸친 시리즈물을 제공한다. 시리즈의 각 요소에 대한
설명에서 알 수 있듯이, 발견되는 문제들을 교정하기 위한 동적 맞춤 교정과 상당한 양의 피드백이 있다. King의
블로그에서 이 시리즈를 찾을 수 있다. Ceylon을 만들어가는 과정에 참여하려면 Gavin King(gavin@hibernate.org)에게 문의하기 바란다.
-
ANTLR은 문법적 설명으로부터 컴파일러, 인터프리터, 변환기 및 인식기를 빌드하는 데 사용되는
언어 도구 및 프레임워크이다. ANTLR은 샌프란시스코대학교(University of San Francisco) Terence Parr의 작업을 기반으로 하고 있다.
- 이 기사에서는 Ceylon으로 구현된 몇 가지 함수형
프로그래밍 기능을 다루었다. Wikipedia에서 first-class functions,
higher-order functions 및 closures에
대한 기본 정보를 확인해보자.
- 리눅스에서는
수백 개의 기술자료 목록과 함께, Linux 개발자와 관리자를 위한
다양한 다운로드, 토론 포럼 및 다른 참고자료를 찾을 수 있다.
- developerWorks 기술 행사 및 웹 캐스트를 통해 다양한 IBM 제품 및 IT 업계의 주제에 관한 최신 정보를 볼 수 있다.
- 무료 developerWorks Live!
briefing을 통해 최신 IBM 제품 및 도구에 대한 정보뿐만 아니라 IT 업계의 최신 경향까지도 빠르게 확인할 수 있다.
- developerWorks
on-demand demos에서는 입문자를 위한 제품 설치 및 설정부터 숙련된 개발자를 위한 고급 기능까지 망라된 다양한 데모를 제공한다.
- Twitter의 developerWorks를 팔로우(follow)하거나 developerWorks에 대한 Linux 트윗(tweet)의 피드를 구독하자.
제품 및 기술
-
자신에게 가장 적합한 방법으로 IBM 제품을 평가해 보자.
시험판 제품을 다운로드하거나 온라인으로 제품을 사용해 보거나 클라우드 환경에서 제품을 사용하거나
SOA Sandbox에서
SOA(Service Oriented Architecture)를 효과적으로 구현하는 방법을 배울 수 있다.
토론
- My developerWorks 커뮤니티에 참여하자.
개발자가 운영하고 있는 블로그, 포럼, 그룹 및 위키를 살펴보면서 다른 developerWorks 사용자와 의견을 나눌 수 있다.
M. Tim Jones는 임베디드 펌웨어 아키텍트이자 Artificial Intelligence: A Systems Approach, GNU/Linux Application Programming(2판이 나왔다), AI Application Programming(2판이 나왔다), BSD Sockets Programming from a Multilanguage Perspective의 저자이기도 하다. Jones의 공학 배경은 정지 위성을 위한 커널 개발에서 시작해 임베디드 시스템 아키텍처와 네트워크 프로토콜 개발에 이르기까지 다양한 분야를 아우른다. Jones는 콜로라도 주, 롱몬트 소재 Emulex 사에서 컨설턴트 엔지니어로 활약한다.