4일 전

김진철의 How-to-Big Data | 빅데이터의 미래 (5)

김진철 | CIO KR

사이버 물리 시스템의 자원 제어 프로그래밍 모델과 프로그램 환경
클라우드 컴퓨팅이 사이버 물리 시스템의 자원 관리를 위한 운영체제의 역할을 하려면, 이런 운영체제의 자원 관리 기능을 활용할 수 있도록 서비스를 요청하고 제어하는 프로그래밍 인터페이스가 있어야 할 것이다. 지난 서른여덟 번째 글에서 이런 프로그래밍 인터페이스가 오픈스택과 같은 오픈소스 클라우드 컴퓨팅의 발전과, 아마존웹서비스와 마이크로소프트 애저, 구글 클라우드와 같은 주요 클라우드 컴퓨팅 서비스 업체에 의해 산업 표준으로 정의되어 가고, 다양한 클라우드 서비스 제공자와 소프트웨어 간 호환성을 위한 상호운용성 문제가 중요해질 것으로 언급하였다.

클라우드 컴퓨팅의 특성상 네트워크를 통해 원격지에 있는 자원에 접근할 수 있도록 하는 RESTful API와 같은 원격 프로그래밍 인터페이스로 제공될 수밖에 없다. 오픈소스 클라우드 컴퓨팅 소프트웨어인 오픈스택도 모든 API는 RESTful API로 정의되며, 아마존웹서비스와 마이크로소프트 애저, 구글 클라우드와 같은 주요 클라우드 컴퓨팅 서비스 업체의 API도 RESTful API로 정의되어 제공된다.
 

ⓒDreamstime


오픈스택이나 아마존웹서비스의 “아웃포스트(Outposts)”, 마이크로소프트의 “애저스택(Azure Stack)”등을 통해 구축되는 사설 클라우드(private cloud)와 아마존웹서비스와 마이크로소프트 애저, 구글 클라우드와 같은 공용 클라우드(public cloud) 서비스에서 사용가능한 프로그래밍 인터페이스가 현재 클라우드 컴퓨팅의 프로그래밍 모델을 제공하고 있다.

오픈스택이 클라우드 컴퓨팅 분야에서 가장 크게 공헌한 것이 바로 이런 클라우드 컴퓨팅 프로그래밍 모델과 인터페이스에 대해 구체적인 산업계의 합의를 이룰 수 있는 기반이 되었다는 점이다. 오픈스택에서 정의한 프로그래밍 모델과 인터페이스가 실제 기술로서 구현되기 위해 클라우드 컴퓨팅 시스템 내부에서 어떤 방식으로 프로그램되어야 하는지 다양한 실험을 구체적으로 시도하고, 이런 실험과 시행착오의 결과가 오픈스택이라는 하나의 구체적인 소프트웨어로 응집될 수 있도록 하여 클라우드 컴퓨팅이 단순한 용어가 아닌 하나의 구체적인 기술로서 자리를 잡는 데 큰 역할을 한 것이다.

이렇게 오픈스택을 통해 자리를 잡고 구체적으로 모양을 갖추게 된 클라우드 컴퓨팅 기술은 클라우드 컴퓨팅 기술을 이용한 다른 응용 기술을 상상하고 만들 수 있게 해주었다. 제일 대표적인 예가 차세대 이동통신 분야에서 최근 핵심 기술로 부상하고 있는 “네트워크 기능 가상화(Network Function Virtualization; NFV)”이다.

차세대 이동 통신 분야에서 “네트워크 기능 가상화”를 실제 상용 수준의 기술로 만들려고 하는 프로젝트 중의 하나인 가입자망(subscription network) 및 국사(Central Office; CO) 통신 인프라 가상화 기술 개발 프로젝트인 “CORD(Central Office Re-architected as a Datacenter; CORD)”와 같은 프로젝트[8]도 오픈스택을 통해 응집된 클라우드 컴퓨팅 기술이 없었다면 결코 상상하고 실험해볼 수 없는 기술이다. 실제 미국의 이동통신 사업자인 AT&T는 이 CORD 프로젝트를 제안하고 실행하여 미국 내 기가인터넷망의 구조를 오픈스택(OpenStack)과 소프트웨어 정의 네트워크(SDN), 네트워크 기능 가상화(NFV) 기술을 통해 비용을 낮추는 실험을 여전히 진행하고 있다. ONOS라는 오픈소스 네트워크 운영체제로 유명한 ONF에서는 참조(reference) 오픈소스 CORD 구현체인 OpenCORD를 ONOS와 오픈스택을 이용해 개발하는 프로젝트도 진행하고 있다[8].

오픈스택을 기반으로 한 공용 클라우드 서비스를 제공하는 랙스페이스와 같은 회사가 아마존웹서비스와 같은 규모의 비즈니스를 하지 못한다고 해서 실패했거나 영향력이 없는 것이 아니다. 오픈스택으로 산업 표준화된 클라우드 컴퓨팅 API와 프로그래밍 모델이 이를 기반으로 클라우드 컴퓨팅 외의 이동통신과 다른 산업에 필요한 IT 기술의 혁신에 영향을 미치고 있기 때문에 앞으로 비즈니스에의 파급력은 더 커지게 될 것이고, 이러한 영향을 사이버 물리 시스템 기술과 서비스가 받게 될 것이다.

사이버 물리 시스템을 위한 클라우드 컴퓨팅 기술 발전에서 또 하나 필요한 중요한 요소는, 모바일 네트워크와 고성능 유선 네트워크로 연결된 대규모 사이버 물리 시스템을 신속하게 개발할 수 있으면서 안전성과 신뢰성을 손쉽게 확보할 수 있게 해주는 프로그래밍 환경과 런타임 환경이다.

오픈스택이 파이썬(Python) 프로그래밍 환경을 이용해 개발된 것 때문에 파이썬 프로그래밍 언어가 클라우드 컴퓨팅 기술 개발의 표준 개발 환경처럼 부각된 것은 안전성, 신뢰성이 보장된 클라우드 컴퓨팅 기술과 이를 통합하는 사이버 물리 시스템 개발에도 보다 발전된 프로그래밍 언어와 런타임 환경이 필요하다는 것을 간접적으로 암시한다.

파이썬(Python)언어가 오픈스택 개발의 기본 환경으로 사용된 이유는 오픈스택의 전신인 NASA의 네뷸라(Nebula)가 파이썬(Python)으로 개발되었기 때문이다. 이후 랙스페이스(Rackspace)와 같이 공동으로 오픈소스화 하면서 핵심 프로젝트인 노바(Nova)와 스위프트(Swift)를 중심으로 파이썬(Python)이 오픈스택의 공식적인 개발 환경이 되었다. 파이썬 언어가 오픈스택 개발에 사용된 것은 네뷸라 개발팀의 개발 환경 선호도의 영향도 있었던 것 같지만, 파이썬 언어의 특성이 오픈스택 개발의 속도를 유지하고 완성도를 높이는 데 크게 기여한 측면도 있다.

파이썬 언어는 동적 언어여서 저수준의 하드웨어 세부 사항에 신경을 쓰지 않고 프로그램 작성시 개발하려는 알고리즘과 비즈니스 로직에 집중할 수 있게 해주며, 통상적인 의미의 인터프리터 언어이기 때문에(사실은 파이썬 인터프리터가 가상 머신에서 실행하는 바이트코드를 코드 라인 입력 후 즉시 생성하는 컴파일 과정(Just-In-Tim(JIT) compile)이 있기는 해서 완전히 컴파일을 하지 않는다고 보기는 어렵다), 코드를 작성하고 배치함과 동시에 실행시킬 수 있어 개발 시간이 단축되는 장점이 있다.

이와 함께 C와 C++로 작성된 저수준 소프트웨어 모듈들을 통합하여 대형 소프트웨어를 만들 수 있도록 하는 접착 언어(glue language)로서 초반부터 개발된 것도 파이썬이 오픈스택 개발 환경으로 채택되는데 공헌한 주요 특성인 것으로 보인다. 리눅스 환경에서 기존에 C와 C++ 언어로 개발된 저수준 시스템 라이브러리와 모듈들을 C/C++ API를 이용해 파이썬 런타임 환경 안에 통합하는 것도 용이했기 때문에 기존의 하드웨어 자원과 리눅스 운영체제 자원을 클라우드 컴퓨팅 로직으로 효과적으로 통합하기에도 용이했다.

오픈스택 개발에 파이썬을 채용한 것은 초반에는 다소 우연이었을 수 있지만, 결론적으로는 파이썬 언어의 특성 때문에 오픈스택이 대대적으로 성공할 수 있었다. 파이썬 언어를 사용하지 않았다면, 광범위한 영역의 하드웨어와 운영체제 자원을 사용하는 오픈스택 주요 핵심 프로젝트 개발에 훨씬 더 많은 개발 시간이 걸렸을 가능성이 높고, 클라우드 컴퓨팅에 본질적인 로직이 아닌 다른 세부 사항을 해결하느라 6개월마다 새로운 릴리즈의 오픈스택 버전을 발표하는 것은 거의 불가능했을 것이다.

광범위한 지역에 걸친 클라우드 컴퓨팅 자원과 자율 에이전트와 같은 물리적 요소가 통합된 대규모 사이버 물리 시스템을 개발하기 위해, 사이버 물리 시스템이 목적으로 하는 서비스와 비즈니스 로직에 집중하여 손쉽게 클라우드 컴퓨팅 자원과 사이버 물리 시스템 컴포넌트를 개발, 통합하고, 저수준의 시스템 자원 관리와 작업들에 대해서는 사이버 물리 시스템을 개발하는 엔지니어들이 되도록 신경을 쓰지 않게 해주는 개발 및 런타임 환경이 필요하게 된다. 

현재까지는 신뢰성과 안전성을 중요하게 생각하는 사이버 물리 시스템의 특성 때문에 미션 크리티컬 시스템을 개발하는데 많이 쓰인 C/C++, 그리고 에이다(Ada)와 같이 실시간 환경 개발을 목적으로 개발된 프로그래밍 언어들이 사이버 물리 시스템의 개발, 통합에 많이 사용되었다. 앞으로 5G 및 차세대 이동통신을 기반으로 한 대규모 사이버 물리 시스템의 개발, 클라우드 컴퓨팅 환경을 다루는데 적합한 프로그래밍 언어와 개발 환경이 사이버 물리 시스템 개발에 새롭게 들어오게 될 것으로 보인다.

파이썬이 좋은 언어이기는 하지만, 엄밀한 소스 코드 정적 분석 및 검증이나 컴파일 타임 메모리 오류 검출과 같은 소프트웨어 신뢰성을 근본적으로 개선, 보장해주는 기능을 지원하기 어려운 측면이 있다. 현재까지는 오픈스택과 같은 클라우드 컴퓨팅 소프트웨어나 클라우드 컴퓨팅 서비스를 다루는 서버리스 컴퓨팅이나 클라우드 네이티브 프로그래밍에 파이썬이 많이 쓰이기는 했지만, 좀더 근본적으로 신뢰성과 안전성을 보장해줄 수 있는 사이버 물리 시스템 소프트웨어 개발 환경이 등장할 것으로 보인다. 이와 함께, 파이썬 환경 자체가 미션 크리티컬 클라우드 컴퓨팅을 위한 요구 사항을 수용해서 새로운 모습으로 진화할 가능성이 있지만, 필자 개인적으로는 파이썬 언어가 개발될 때의 목적이 미션 크리티컬 시스템 개발을 지원하는 것이 아니었기 때문에 이런 변화는 제한적일 것으로 전망한다.

현재 나와 있는 기술중에서 사이버 물리 시스템 개발의 생산성과 안전성에 기여할 수 있을 것으로 보이는 개발 환경은 사용하기 쉽고 클라우드 네이티브 프로그래밍에서 강점을 가지고 있는 “고(go)” 언어, 최근 안드로이드 앱 개발과 마이크로서비스 기반의 분산 컴퓨팅 시스템 개발에 많이 활용되기 시작한 “코틀린(Kotlin)” 언어, 메모리 관리의 안전성을 크게 높이고 간결하고 단순한 구문으로 시스템 프로그래밍과 서버 사이드 프로그래밍에서 각광 받고 있는 “러스트(Rust)” 언어와 같은 특징을 가진 프로그래밍 언어가 사이버 물리 시스템 개발에 많이 활용될 수 있을 것으로 보이는 새로운 프로그래밍 언어이다.

앞으로의 사이버 물리 시스템 개발에는 다양한 계층의 이종(heterogeneous) 자원을 통합해야 하는 이유로 기본적으로 폴리글랏(polyglot) 프로그래밍이 활용될 것으로 보인다. 이 폴리글랏 프로그래밍은 요즘 복잡해지고 있는 인터넷 서비스 개발에서도 빠르게 확산되고 있는 프로그래밍 트렌드이기도 하다. 광범위한 지역에 걸쳐 있는 자율 에이전트와 하부 사이버 물리 시스템 요소들과 클라우드 컴퓨팅 자원이 통합되어 하나의 서비스로서 신뢰성과 안전성을 보장하기 위해 각 계층과 하부 사이버 물리 시스템 요소들의 특성과 요구사항에 맞는 프로그래밍 언어와 런타임 환경이 사용되고, 이들을 통합된 서비스로 엮어내는 점착 프로그래밍 언어와 런타임 환경이 계층을 이루어 서비스를 통합하는 방식으로 개발되어야 하기 때문에 폴리글랏 프로그래밍은 피할 수 없는 트렌드이기도 하다.
 


그럼 앞에서 언급한 “고(go)” 언어, “코틀린(Kotlin)” 언어, 그리고 “러스트(Rust)” 언어의 어떤 측면이 사이버 물리 시스템을 위한 클라우드 컴퓨팅 시스템 통합과 개발에 도움이 되는지 같이 생각해보도록 하자. 사실 대규모 사이버 물리 시스템 개발에는 다양한 측면의 요구 사항이 고려되어야 하는데, 이번 글이 지면이 많이 모자란 관계로 위에서 언급한 고(go)언어, 코틀린(Kotlin)언어, 러스트(Rust)언어가 사이버 물리 시스템 개발에서 클라우드 컴퓨팅 자원 통합과 개발에 어떻게 도움이 되는지에 집중해서 생각해보려고 한다. 클라우드 컴퓨팅 통합 및 개발 외 사이버 물리 시스템 개발에 관련된 빅데이터 처리, 분석 환경과의 통합, IoT, 엣지 컴퓨팅과 사이버 물리 시스템과의 관계, 인공지능 및 기계 학습, 인지 컴퓨팅 기술과의 통합과 관련된 측면은 앞으로 기고할 글에서 다시 자세히 다루기로 한다.

제일 먼저 고(go)언어가 사이버 물리 시스템 개발에 던져주는 시사점에 대해서 같이 생각해보자. 고(go)언어는 구글에서 일하던 로버트 그리즈머, 롭 파이크, 그리고 C언어의 설계자로 유명한 켄 톰슨이 2007년 구글 내부에서 인페르노 분산 운영 체제와 관련된 문제를 해결하기 위해 설계, 개발한 프로그래밍 언어이다. 고(go)언어가 왜 사이버 물리 시스템 개발에 중요한 특성이 있는지 이해하기 위해 어떤 배경에서 고(go)언어가 설계되었는지 같이 생각해보도록 하자.

고(go)언어는 먼저 소프트웨어 개발의 복잡성을 줄이는 것을 최소화하려는 목적으로 개발된 언어이다. 이 때문에, 고(go)언어의 예약어를 보면 최근 유행하는 다른 프로그래밍 언어에 비해서 예약어가 많지 않고 단순해서 정말로 현대 프로그래밍 언어가 맞는지 의심하게 된다. 코드 재사용을 위해 객체지향 프로그래밍을 위한 예약어와 표현 방법들이 기본적으로 포함되는 것이 요즘 추세이지만, 객체지향 프로그래밍 언어에서 흔한 클래스 선언, 정의 관련 예약어도 없다[9, 11].

객체지향 프로그래밍 언어에서 흔한 클래스 선언, 정의 관련 예약어가 없다고 해서 객체지향 프로그래밍이 불가능한 것은 아니지만, C++, 자바(Java)의 문법과 객체지향 프로그래밍에 익숙한 사람들은 뭔가 모를 이질감과 불편함을 느끼며, 예전 Objective-C가 나올 즈음에 C언어의 예약어만을 이용해서 객체지향 프로그래밍을 하려고 했던 시절을 떠올리게 한다. 고(go)언어에서 객체지향 프로그래밍을 아예 제외하려고 했던 것은 아니지만, 현대 프로그래밍 언어에서 생기는 많은 복잡성들이 객체지향 프로그래밍을 하는 과정에서 생긴다는 것을 안 고(go)언어 설계자들이 C++스타일의 객체지향 프로그래밍언어에서 나타나는 복잡성을 줄이기 위해 의도적으로 관련된 많은 예약어들을 삭제하고 C와 비슷하게 단순한 언어로 만들었다.

객체지향 프로그래밍 언어에서 흔하게 나타나는 예약어들을 생략한 대신, 클로저를 통해 코드 재사용성을 함수형 프로그래밍을 통해 지원하는 방식으로 디자인되었다. 함수형 프로그래밍은 익숙해지려면 객체지향 프로그래밍보다 어렵지만, 극도로 추상화된 함수로 정의된 프로그래밍 패턴들을 통해서 코드를 간결하게 하고 복잡성을 줄일 수 있으며, 현대 인터넷 프로그래밍에서 자주 요구되는 확장성(scalability)과 병행성(concurrency)을 지원하기 쉽다는 장점이 있다[9-11].

주요 현대 프로그래밍 언어에서 필수적으로 지원하는 객체지향 프로그래밍 관련 예약어를 의도적으로 없애면서까지 프로그래밍 언어의 디자인을 단순하게 만든 고(go)언어가 사이버 물리 시스템 기술에 주는 의미는 명확하다. 인터넷과 5G 및 그 이후의 차세대 이동통신망으로 엮여 시스템의 복잡도가 급격하게 높아지는 사이버 물리 시스템을 디자인하고 구현하는데 시스템의 복잡도를 줄이고 제어하기 위해서는 단순히 아키텍처 설계 과정에서 복잡도를 줄이는 설계를 한다고 해서 근본적으로 해결되지 않는다는 것이다. 사이버 물리 시스템이 구성되고 동작하는 방식을 기술하는 프로그래밍 언어 수준에서 복잡도를 제어하고 줄일 수 있는 방법이 근본적으로 새로이 고안되어야 하는 것이다.

복잡한 실세계를 포함하기 위해서는 프로그래밍 언어도 이런 실세계의 복잡성을 포용할 수 있도록 만들어져야 한다는 생각으로 디자인, 개발되기 시작한 객체지향 프로그래밍 언어들은 실제로 클래스와 객체라는 개념을 통해 소스 코드 수준에서 실세계 객체들을 직관적으로 추상화할 수 있는 방법을 제공함으로써 실세계 문제들을 표현하고 해결하는데 큰 기여를 해왔다. 객체지향 프로그래밍을 통해 코드 재사용성이 높아지면서, 오히려 소프트웨어의 복잡성은 전반적으로 높아지기 시작했으며, 객체지향 프로그래밍 언어들의 단점이 드러나기 시작했다.

고(go)언어의 설계자중 한 사람인 켄 톰슨은 C언어를 설계, 개발한 컴퓨터 과학자로 유명하며, C언어를 통해서 현대 프로그래밍 언어 역사에 굵직한 한 획을 그은 사람이다. 켄 톰슨은 프로그래밍이 복잡해지는 문제 때문에 C++를 극도로 싫어해서, C++에서 나타나는 복잡성을 최소한으로 줄일 수 있는 단순한 프로그래밍 언어를 만들기 위해 고(go)언어를 디자인했다고 알려져 있다[9, 11].

C와 같은 간결한 문법과, C언어에서는 지원되지 않던 가비지 콜렉션을 제공함으로써 C언어에서 다루기 가장 어려운 부분이었던 메모리 관리를 단순화한 점, 그리고 클로저(closure)를 지원하여 함수형 프로그래밍을 포용함으로써 객체지향 프로그래밍과는 다른 방식의 코드 재사용성을 지원하는 점, 병렬, 분산 컴퓨팅과 멀티 코어 아키텍처가 부상하면서 중요해진 “고 루틴(Go-routine)”을 이용한 병행성(concurrency) 지원과 고(go)언어 구문의 단순명료함이 소프트웨어의 복잡성을 낮추는 데 기여하고 있다.

이렇게 프로그래밍 언어 수준에서 소프트웨어의 복잡성을 근본적으로 줄이기 위해 설계된 고(go)언어의 설계 철학과 특성들은, 5G 이동통신과 저지연, 광대역 유선 네트워크를 통해 다수의 클라우드 컴퓨팅 자원을 끌어와 복잡한 대규모의 연산을 해야 하는 지능형 서비스를 개발하는 개발 환경이 어떤 식으로 발전되어 갈 것인지 엿볼 수 있게 하는 트렌드로 볼 수 있다.

고(go)언어와 함께 또 살펴보아야 할 프로그래밍 언어는 “코틀린(Kotlin)”이다. “코틀린(Kotlin)”은 고(go)언어와는 달리 “자바 가상 머신(Java Virtual Machine; 이하 JVM)” 계열의 언어이다. 자바(Java)와 JVM 계열 언어의 특성을 다수 채용하면서, 자바(Java)언어로 개발된 소프트웨어 모듈들을 별다른 수정과 포팅 없이 코틀린(Kotlin)으로 개발된 소프트웨어에서 바로 불러 사용할 수 있도록 자바(Java)언어와의 100% 상호호환성을 지원한다. 자바(Java)언어의 단점으로 지목되어 온 같은 기능을 표현하는데 다른 언어보다 장황한 표현이 필요한 점도 코틀린(Kotlin)의 간결한 구문과 람다식(lambda expression), 클로저(closure) 등의 함수형 프로그래밍 개념의 도입을 통해 상당히 많이 개선되었다[13-17].

“코틀린(Kotlin)”언어가 사이버 물리 시스템과 클라우드 컴퓨팅에 주는 의미는 소프트웨어 개발 과정의 협업과 생산성을 중시하고 이를 개선하기 위한 디자인이 상당수 포함되었다는 것이다.  “코틀린(Kotlin)” 언어를 개발한 “젯브레인즈(JetBrains)”사가 프로그래밍 언어 개발을 위한 통합 개발 환경(Integrated Development Environment; IDE)”과 개발 도구를 개발하는 회사라는 것도 눈여겨봐야 할 점이다. 코틀린(Kotlin)은 애초부터 통합 개발 환경과 개발 도구를 통한 자동화를 염두에 두고 개발된 언어이기 때문에 개발 도구와의 통합이 용이한 디자인을 가지고 있고, 코틀린(Kotlin)을 개발한 젯브레인즈가 자사의 IntelliJ 개발 환경에서 100% 코틀린(Kotlin)을 지원하고 있기 때문에 다른 프로그래밍 언어에 비해 통합 개발 환경 지원과 개발 도구 지원이 탄탄하다.

코틀린(Kotlin)이 소프트웨어 엔지니어들의 고충을 해결하고 팀 단위로 소프트웨어를 개발할 때 겪게 되는 소프트웨어 엔지니어링 문제들을 해결하기 위해 디자인된 프로그램 언어 특성들을 보면서 이런 것들이 사이버 물리 시스템 개발에 어떤 의미를 갖는지 같이 생각해보자.

코틀린(Kotlin)의 데이터 클래스(data class)는 스칼라(Scala)언어의 케이스 클래스(case class)의 기능을 일부 차용한 자질(feature)로, 자바(Java)언어에서 데이터를 전달하는 객체로서 많이 쓰이는 자바 빈즈(Java beans)의 고질적인 문제였던 코드 라인수가 길어지고 지나치게 소스 코드가 장황해지는 문제를 간결하게 해결해준다[13-14, 17]. 

데이터 클래스는 자바 빈즈(Java beans)를 선언, 정의할 때 getter, setter함수를 일일이 선언, 정의해주어야 하는 문제 때문에 순식간에 코드량이 늘어나는 자바(Java)의 단점을 개선하고, 데이터를 전달하는 객체 사용을 단순히 해당 필드를 public으로 선언하고 접근하도록 하며, 코틀린(Kotlin)에서 데이터 클래스로 선언된 클래스는 해당하는 자바(Java) 표현에서 자동으로 getter, setter함수를 생성하도록 컴파일하게 되어 있어 데이터 객체를 다루기 위해 길어진 소스 코드를 작성하고 다루느라 낭비하는 시간과 노력을 줄일 수 있게 해준다.

C언어에서 소프트웨어 엔지니어들의 가장 큰 고충사항이 포인터를 통한 메모리 관리 과정에서 생기는 실행시간 오류(runtime error)라면, 자바(Java)에서는 가비지 콜렉션을 통해 메모리 관리의 어려움은 많이 해소되지만, “널(null)” 체크 및 처리를 제대로 하지 못해서 생기는 “널 포인터 예외(NullPointerException)” 때문에 많은 고충을 겪는다. 코틀린(Kotlin)의 “널 가능(Nullable)” 형 표현은 “널(null)” 체크 및 이에 따른 형변환과 문제들을 경감해주는 소프트웨어 엔지니어들에게 유용한 언어적 자질중의 하나이다[13-14, 17].

코틀린(Kotlin)에서 “널 가능(Nullable)”로 선언된 변수는 if문을 통해서 널(null) 값인지 여부를 체크하거나, is연산자를 사용해서 객체의 타입을 검사하면 맥락에 맞게 자동으로 형변환을 해준다. 코틀린(Kotlin)언어의 이런 자질은 개발자들이 널(null) 체크와 “널 포인터 예외(NullPointerException)”를 다루기 위해 들여야 하는 노력을 크게 경감시켜 주기 때문에 코틀린(Kotlin)으로 개발된 언어가 예상치 못한 널(null) 값 발생과 이를 제대로 예외 처리하지 않아 생기는 다양한 결함들을 손쉽게 포용하고 소프트웨어의 안전성을 높일 수 있게 해주어 소프트웨어 엔지니어들의 수고를 덜어준다.

코틀린(Kotlin)의 눈에 띄는 특징 중 하나는 역시 함수형 프로그래밍을 지원하면서 소스 코드가 장황해지지 않고 양이 크게 감소하며, 표현이 간결해지는 것이다. 이는 스칼라(Scala)언어의 장점을 많이 도입한 것에서 오는 특성인데, 스칼라(Scala)언어의 경우 자바(Java)언어에 비해 소스 코드 양이 크게 줄고 표현도 훨씬 간결해진다. 필자의 경우 자바(Java)언어에서 몇십 줄에 이르는 소스 코드가 스칼라(Scala)로 표현하면서 단 3~4줄이면 끝나는 경우를 많이 경험했다. 코틀린(Kotlin)이 클로저(closure)와 함수형 프로그래밍을 지원하면서 역시 스칼라(Scala)의 이런 장점을 수용한 것이다[17].

같은 기능을 구현하는데 소스 코드 양을 줄이는 것이 소프트웨어 엔지니어들의 수고를 왜 줄여주는지 선뜻 이해가 안 가시는 분들도 있을 법하다. 더군다나 이 글을 읽으시는 분들 중 CIO와 같은 의사 결정을 주로 하시는 분들이라면 프로그래밍 언어를 디자인할 때부터 소스 코드 양이 대폭 줄어들도록 표현을 간결하게 디자인하는 것이 왜 중요한지 이해가 가지 않을 수 있다.

소스 코드 양이 줄어들면 우선 오류나 버그가 줄어들게 된다. C언어나 자바(Java)와 같은 언어로 프로그래밍을 할 때 소프트웨어 엔지니어들을 가장 괴롭히는 것 하나가 {}나 ()와 같은 코드 블록이나 스코프를 표현하는 기호들을 짝이 맞게 매치하는 것이다. 코드가 표현하는 내용이 복잡해지고 길어지면 이런 블록을 아무리 정성 들여 보기 좋게 표현해도 실수를 하게 마련이고, 또한 예약어와 다르게 이런 블록 표현들은 여러 개가 중첩되어 표현되면 짝이 맞지 않는 부분을 찾기도 어렵다. 그런데, 스칼라(Scala)와 코틀린(Kotlin)의 클로저(closure)와 함수형 프로그래밍을 지원하는 구문을 사용하면 소스 코드의 구조도 단순해지고 읽기도 쉬워진다.

소스 코드 양이 줄어들게 되면 소프트웨어 엔지니어들이 같은 기능을 작성할 때 들이는 시간과 노력이 줄어들어 생산성 향상에도 도움이 된다. 프로그래밍 언어를 배울 때 짜는 예제 정도의 몇십, 몇백 줄 정도의 소스 코드를 작성할 때에는 소스 코드 양을 줄이는 것이 얼마나 도움이 되는지 체감하기 어렵다. 그렇지만, 현대 소프트웨어의 상당수는 분산 컴퓨팅 소프트웨어인 데다가, 시스템의 규모와 복잡성에 따라 소프트웨어의 크기도 몇십만, 몇백만 라인을 넘기는 것은 그리 어렵지 않다. 더군다나 이런 대형 소스 코드는 한 사람이 작성하는 것이 아니라 팀이 개발하게 된다. 프로그래밍 스타일과 생각도 많이 다른 여러 사람이 작성한 대형 소스 코드를 읽고 이해하면서 개발하는 것은 정말 어려운 일이며, 이런 대형 소프트웨어의 소스 코드 수준에서의 품질을 관리하기는 정말 쉽지 않은 일이다.

 




4일 전

김진철의 How-to-Big Data | 빅데이터의 미래 (5)

김진철 | CIO KR

사이버 물리 시스템의 자원 제어 프로그래밍 모델과 프로그램 환경
클라우드 컴퓨팅이 사이버 물리 시스템의 자원 관리를 위한 운영체제의 역할을 하려면, 이런 운영체제의 자원 관리 기능을 활용할 수 있도록 서비스를 요청하고 제어하는 프로그래밍 인터페이스가 있어야 할 것이다. 지난 서른여덟 번째 글에서 이런 프로그래밍 인터페이스가 오픈스택과 같은 오픈소스 클라우드 컴퓨팅의 발전과, 아마존웹서비스와 마이크로소프트 애저, 구글 클라우드와 같은 주요 클라우드 컴퓨팅 서비스 업체에 의해 산업 표준으로 정의되어 가고, 다양한 클라우드 서비스 제공자와 소프트웨어 간 호환성을 위한 상호운용성 문제가 중요해질 것으로 언급하였다.

클라우드 컴퓨팅의 특성상 네트워크를 통해 원격지에 있는 자원에 접근할 수 있도록 하는 RESTful API와 같은 원격 프로그래밍 인터페이스로 제공될 수밖에 없다. 오픈소스 클라우드 컴퓨팅 소프트웨어인 오픈스택도 모든 API는 RESTful API로 정의되며, 아마존웹서비스와 마이크로소프트 애저, 구글 클라우드와 같은 주요 클라우드 컴퓨팅 서비스 업체의 API도 RESTful API로 정의되어 제공된다.
 

ⓒDreamstime


오픈스택이나 아마존웹서비스의 “아웃포스트(Outposts)”, 마이크로소프트의 “애저스택(Azure Stack)”등을 통해 구축되는 사설 클라우드(private cloud)와 아마존웹서비스와 마이크로소프트 애저, 구글 클라우드와 같은 공용 클라우드(public cloud) 서비스에서 사용가능한 프로그래밍 인터페이스가 현재 클라우드 컴퓨팅의 프로그래밍 모델을 제공하고 있다.

오픈스택이 클라우드 컴퓨팅 분야에서 가장 크게 공헌한 것이 바로 이런 클라우드 컴퓨팅 프로그래밍 모델과 인터페이스에 대해 구체적인 산업계의 합의를 이룰 수 있는 기반이 되었다는 점이다. 오픈스택에서 정의한 프로그래밍 모델과 인터페이스가 실제 기술로서 구현되기 위해 클라우드 컴퓨팅 시스템 내부에서 어떤 방식으로 프로그램되어야 하는지 다양한 실험을 구체적으로 시도하고, 이런 실험과 시행착오의 결과가 오픈스택이라는 하나의 구체적인 소프트웨어로 응집될 수 있도록 하여 클라우드 컴퓨팅이 단순한 용어가 아닌 하나의 구체적인 기술로서 자리를 잡는 데 큰 역할을 한 것이다.

이렇게 오픈스택을 통해 자리를 잡고 구체적으로 모양을 갖추게 된 클라우드 컴퓨팅 기술은 클라우드 컴퓨팅 기술을 이용한 다른 응용 기술을 상상하고 만들 수 있게 해주었다. 제일 대표적인 예가 차세대 이동통신 분야에서 최근 핵심 기술로 부상하고 있는 “네트워크 기능 가상화(Network Function Virtualization; NFV)”이다.

차세대 이동 통신 분야에서 “네트워크 기능 가상화”를 실제 상용 수준의 기술로 만들려고 하는 프로젝트 중의 하나인 가입자망(subscription network) 및 국사(Central Office; CO) 통신 인프라 가상화 기술 개발 프로젝트인 “CORD(Central Office Re-architected as a Datacenter; CORD)”와 같은 프로젝트[8]도 오픈스택을 통해 응집된 클라우드 컴퓨팅 기술이 없었다면 결코 상상하고 실험해볼 수 없는 기술이다. 실제 미국의 이동통신 사업자인 AT&T는 이 CORD 프로젝트를 제안하고 실행하여 미국 내 기가인터넷망의 구조를 오픈스택(OpenStack)과 소프트웨어 정의 네트워크(SDN), 네트워크 기능 가상화(NFV) 기술을 통해 비용을 낮추는 실험을 여전히 진행하고 있다. ONOS라는 오픈소스 네트워크 운영체제로 유명한 ONF에서는 참조(reference) 오픈소스 CORD 구현체인 OpenCORD를 ONOS와 오픈스택을 이용해 개발하는 프로젝트도 진행하고 있다[8].

오픈스택을 기반으로 한 공용 클라우드 서비스를 제공하는 랙스페이스와 같은 회사가 아마존웹서비스와 같은 규모의 비즈니스를 하지 못한다고 해서 실패했거나 영향력이 없는 것이 아니다. 오픈스택으로 산업 표준화된 클라우드 컴퓨팅 API와 프로그래밍 모델이 이를 기반으로 클라우드 컴퓨팅 외의 이동통신과 다른 산업에 필요한 IT 기술의 혁신에 영향을 미치고 있기 때문에 앞으로 비즈니스에의 파급력은 더 커지게 될 것이고, 이러한 영향을 사이버 물리 시스템 기술과 서비스가 받게 될 것이다.

사이버 물리 시스템을 위한 클라우드 컴퓨팅 기술 발전에서 또 하나 필요한 중요한 요소는, 모바일 네트워크와 고성능 유선 네트워크로 연결된 대규모 사이버 물리 시스템을 신속하게 개발할 수 있으면서 안전성과 신뢰성을 손쉽게 확보할 수 있게 해주는 프로그래밍 환경과 런타임 환경이다.

오픈스택이 파이썬(Python) 프로그래밍 환경을 이용해 개발된 것 때문에 파이썬 프로그래밍 언어가 클라우드 컴퓨팅 기술 개발의 표준 개발 환경처럼 부각된 것은 안전성, 신뢰성이 보장된 클라우드 컴퓨팅 기술과 이를 통합하는 사이버 물리 시스템 개발에도 보다 발전된 프로그래밍 언어와 런타임 환경이 필요하다는 것을 간접적으로 암시한다.

파이썬(Python)언어가 오픈스택 개발의 기본 환경으로 사용된 이유는 오픈스택의 전신인 NASA의 네뷸라(Nebula)가 파이썬(Python)으로 개발되었기 때문이다. 이후 랙스페이스(Rackspace)와 같이 공동으로 오픈소스화 하면서 핵심 프로젝트인 노바(Nova)와 스위프트(Swift)를 중심으로 파이썬(Python)이 오픈스택의 공식적인 개발 환경이 되었다. 파이썬 언어가 오픈스택 개발에 사용된 것은 네뷸라 개발팀의 개발 환경 선호도의 영향도 있었던 것 같지만, 파이썬 언어의 특성이 오픈스택 개발의 속도를 유지하고 완성도를 높이는 데 크게 기여한 측면도 있다.

파이썬 언어는 동적 언어여서 저수준의 하드웨어 세부 사항에 신경을 쓰지 않고 프로그램 작성시 개발하려는 알고리즘과 비즈니스 로직에 집중할 수 있게 해주며, 통상적인 의미의 인터프리터 언어이기 때문에(사실은 파이썬 인터프리터가 가상 머신에서 실행하는 바이트코드를 코드 라인 입력 후 즉시 생성하는 컴파일 과정(Just-In-Tim(JIT) compile)이 있기는 해서 완전히 컴파일을 하지 않는다고 보기는 어렵다), 코드를 작성하고 배치함과 동시에 실행시킬 수 있어 개발 시간이 단축되는 장점이 있다.

이와 함께 C와 C++로 작성된 저수준 소프트웨어 모듈들을 통합하여 대형 소프트웨어를 만들 수 있도록 하는 접착 언어(glue language)로서 초반부터 개발된 것도 파이썬이 오픈스택 개발 환경으로 채택되는데 공헌한 주요 특성인 것으로 보인다. 리눅스 환경에서 기존에 C와 C++ 언어로 개발된 저수준 시스템 라이브러리와 모듈들을 C/C++ API를 이용해 파이썬 런타임 환경 안에 통합하는 것도 용이했기 때문에 기존의 하드웨어 자원과 리눅스 운영체제 자원을 클라우드 컴퓨팅 로직으로 효과적으로 통합하기에도 용이했다.

오픈스택 개발에 파이썬을 채용한 것은 초반에는 다소 우연이었을 수 있지만, 결론적으로는 파이썬 언어의 특성 때문에 오픈스택이 대대적으로 성공할 수 있었다. 파이썬 언어를 사용하지 않았다면, 광범위한 영역의 하드웨어와 운영체제 자원을 사용하는 오픈스택 주요 핵심 프로젝트 개발에 훨씬 더 많은 개발 시간이 걸렸을 가능성이 높고, 클라우드 컴퓨팅에 본질적인 로직이 아닌 다른 세부 사항을 해결하느라 6개월마다 새로운 릴리즈의 오픈스택 버전을 발표하는 것은 거의 불가능했을 것이다.

광범위한 지역에 걸친 클라우드 컴퓨팅 자원과 자율 에이전트와 같은 물리적 요소가 통합된 대규모 사이버 물리 시스템을 개발하기 위해, 사이버 물리 시스템이 목적으로 하는 서비스와 비즈니스 로직에 집중하여 손쉽게 클라우드 컴퓨팅 자원과 사이버 물리 시스템 컴포넌트를 개발, 통합하고, 저수준의 시스템 자원 관리와 작업들에 대해서는 사이버 물리 시스템을 개발하는 엔지니어들이 되도록 신경을 쓰지 않게 해주는 개발 및 런타임 환경이 필요하게 된다. 

현재까지는 신뢰성과 안전성을 중요하게 생각하는 사이버 물리 시스템의 특성 때문에 미션 크리티컬 시스템을 개발하는데 많이 쓰인 C/C++, 그리고 에이다(Ada)와 같이 실시간 환경 개발을 목적으로 개발된 프로그래밍 언어들이 사이버 물리 시스템의 개발, 통합에 많이 사용되었다. 앞으로 5G 및 차세대 이동통신을 기반으로 한 대규모 사이버 물리 시스템의 개발, 클라우드 컴퓨팅 환경을 다루는데 적합한 프로그래밍 언어와 개발 환경이 사이버 물리 시스템 개발에 새롭게 들어오게 될 것으로 보인다.

파이썬이 좋은 언어이기는 하지만, 엄밀한 소스 코드 정적 분석 및 검증이나 컴파일 타임 메모리 오류 검출과 같은 소프트웨어 신뢰성을 근본적으로 개선, 보장해주는 기능을 지원하기 어려운 측면이 있다. 현재까지는 오픈스택과 같은 클라우드 컴퓨팅 소프트웨어나 클라우드 컴퓨팅 서비스를 다루는 서버리스 컴퓨팅이나 클라우드 네이티브 프로그래밍에 파이썬이 많이 쓰이기는 했지만, 좀더 근본적으로 신뢰성과 안전성을 보장해줄 수 있는 사이버 물리 시스템 소프트웨어 개발 환경이 등장할 것으로 보인다. 이와 함께, 파이썬 환경 자체가 미션 크리티컬 클라우드 컴퓨팅을 위한 요구 사항을 수용해서 새로운 모습으로 진화할 가능성이 있지만, 필자 개인적으로는 파이썬 언어가 개발될 때의 목적이 미션 크리티컬 시스템 개발을 지원하는 것이 아니었기 때문에 이런 변화는 제한적일 것으로 전망한다.

현재 나와 있는 기술중에서 사이버 물리 시스템 개발의 생산성과 안전성에 기여할 수 있을 것으로 보이는 개발 환경은 사용하기 쉽고 클라우드 네이티브 프로그래밍에서 강점을 가지고 있는 “고(go)” 언어, 최근 안드로이드 앱 개발과 마이크로서비스 기반의 분산 컴퓨팅 시스템 개발에 많이 활용되기 시작한 “코틀린(Kotlin)” 언어, 메모리 관리의 안전성을 크게 높이고 간결하고 단순한 구문으로 시스템 프로그래밍과 서버 사이드 프로그래밍에서 각광 받고 있는 “러스트(Rust)” 언어와 같은 특징을 가진 프로그래밍 언어가 사이버 물리 시스템 개발에 많이 활용될 수 있을 것으로 보이는 새로운 프로그래밍 언어이다.

앞으로의 사이버 물리 시스템 개발에는 다양한 계층의 이종(heterogeneous) 자원을 통합해야 하는 이유로 기본적으로 폴리글랏(polyglot) 프로그래밍이 활용될 것으로 보인다. 이 폴리글랏 프로그래밍은 요즘 복잡해지고 있는 인터넷 서비스 개발에서도 빠르게 확산되고 있는 프로그래밍 트렌드이기도 하다. 광범위한 지역에 걸쳐 있는 자율 에이전트와 하부 사이버 물리 시스템 요소들과 클라우드 컴퓨팅 자원이 통합되어 하나의 서비스로서 신뢰성과 안전성을 보장하기 위해 각 계층과 하부 사이버 물리 시스템 요소들의 특성과 요구사항에 맞는 프로그래밍 언어와 런타임 환경이 사용되고, 이들을 통합된 서비스로 엮어내는 점착 프로그래밍 언어와 런타임 환경이 계층을 이루어 서비스를 통합하는 방식으로 개발되어야 하기 때문에 폴리글랏 프로그래밍은 피할 수 없는 트렌드이기도 하다.
 


그럼 앞에서 언급한 “고(go)” 언어, “코틀린(Kotlin)” 언어, 그리고 “러스트(Rust)” 언어의 어떤 측면이 사이버 물리 시스템을 위한 클라우드 컴퓨팅 시스템 통합과 개발에 도움이 되는지 같이 생각해보도록 하자. 사실 대규모 사이버 물리 시스템 개발에는 다양한 측면의 요구 사항이 고려되어야 하는데, 이번 글이 지면이 많이 모자란 관계로 위에서 언급한 고(go)언어, 코틀린(Kotlin)언어, 러스트(Rust)언어가 사이버 물리 시스템 개발에서 클라우드 컴퓨팅 자원 통합과 개발에 어떻게 도움이 되는지에 집중해서 생각해보려고 한다. 클라우드 컴퓨팅 통합 및 개발 외 사이버 물리 시스템 개발에 관련된 빅데이터 처리, 분석 환경과의 통합, IoT, 엣지 컴퓨팅과 사이버 물리 시스템과의 관계, 인공지능 및 기계 학습, 인지 컴퓨팅 기술과의 통합과 관련된 측면은 앞으로 기고할 글에서 다시 자세히 다루기로 한다.

제일 먼저 고(go)언어가 사이버 물리 시스템 개발에 던져주는 시사점에 대해서 같이 생각해보자. 고(go)언어는 구글에서 일하던 로버트 그리즈머, 롭 파이크, 그리고 C언어의 설계자로 유명한 켄 톰슨이 2007년 구글 내부에서 인페르노 분산 운영 체제와 관련된 문제를 해결하기 위해 설계, 개발한 프로그래밍 언어이다. 고(go)언어가 왜 사이버 물리 시스템 개발에 중요한 특성이 있는지 이해하기 위해 어떤 배경에서 고(go)언어가 설계되었는지 같이 생각해보도록 하자.

고(go)언어는 먼저 소프트웨어 개발의 복잡성을 줄이는 것을 최소화하려는 목적으로 개발된 언어이다. 이 때문에, 고(go)언어의 예약어를 보면 최근 유행하는 다른 프로그래밍 언어에 비해서 예약어가 많지 않고 단순해서 정말로 현대 프로그래밍 언어가 맞는지 의심하게 된다. 코드 재사용을 위해 객체지향 프로그래밍을 위한 예약어와 표현 방법들이 기본적으로 포함되는 것이 요즘 추세이지만, 객체지향 프로그래밍 언어에서 흔한 클래스 선언, 정의 관련 예약어도 없다[9, 11].

객체지향 프로그래밍 언어에서 흔한 클래스 선언, 정의 관련 예약어가 없다고 해서 객체지향 프로그래밍이 불가능한 것은 아니지만, C++, 자바(Java)의 문법과 객체지향 프로그래밍에 익숙한 사람들은 뭔가 모를 이질감과 불편함을 느끼며, 예전 Objective-C가 나올 즈음에 C언어의 예약어만을 이용해서 객체지향 프로그래밍을 하려고 했던 시절을 떠올리게 한다. 고(go)언어에서 객체지향 프로그래밍을 아예 제외하려고 했던 것은 아니지만, 현대 프로그래밍 언어에서 생기는 많은 복잡성들이 객체지향 프로그래밍을 하는 과정에서 생긴다는 것을 안 고(go)언어 설계자들이 C++스타일의 객체지향 프로그래밍언어에서 나타나는 복잡성을 줄이기 위해 의도적으로 관련된 많은 예약어들을 삭제하고 C와 비슷하게 단순한 언어로 만들었다.

객체지향 프로그래밍 언어에서 흔하게 나타나는 예약어들을 생략한 대신, 클로저를 통해 코드 재사용성을 함수형 프로그래밍을 통해 지원하는 방식으로 디자인되었다. 함수형 프로그래밍은 익숙해지려면 객체지향 프로그래밍보다 어렵지만, 극도로 추상화된 함수로 정의된 프로그래밍 패턴들을 통해서 코드를 간결하게 하고 복잡성을 줄일 수 있으며, 현대 인터넷 프로그래밍에서 자주 요구되는 확장성(scalability)과 병행성(concurrency)을 지원하기 쉽다는 장점이 있다[9-11].

주요 현대 프로그래밍 언어에서 필수적으로 지원하는 객체지향 프로그래밍 관련 예약어를 의도적으로 없애면서까지 프로그래밍 언어의 디자인을 단순하게 만든 고(go)언어가 사이버 물리 시스템 기술에 주는 의미는 명확하다. 인터넷과 5G 및 그 이후의 차세대 이동통신망으로 엮여 시스템의 복잡도가 급격하게 높아지는 사이버 물리 시스템을 디자인하고 구현하는데 시스템의 복잡도를 줄이고 제어하기 위해서는 단순히 아키텍처 설계 과정에서 복잡도를 줄이는 설계를 한다고 해서 근본적으로 해결되지 않는다는 것이다. 사이버 물리 시스템이 구성되고 동작하는 방식을 기술하는 프로그래밍 언어 수준에서 복잡도를 제어하고 줄일 수 있는 방법이 근본적으로 새로이 고안되어야 하는 것이다.

복잡한 실세계를 포함하기 위해서는 프로그래밍 언어도 이런 실세계의 복잡성을 포용할 수 있도록 만들어져야 한다는 생각으로 디자인, 개발되기 시작한 객체지향 프로그래밍 언어들은 실제로 클래스와 객체라는 개념을 통해 소스 코드 수준에서 실세계 객체들을 직관적으로 추상화할 수 있는 방법을 제공함으로써 실세계 문제들을 표현하고 해결하는데 큰 기여를 해왔다. 객체지향 프로그래밍을 통해 코드 재사용성이 높아지면서, 오히려 소프트웨어의 복잡성은 전반적으로 높아지기 시작했으며, 객체지향 프로그래밍 언어들의 단점이 드러나기 시작했다.

고(go)언어의 설계자중 한 사람인 켄 톰슨은 C언어를 설계, 개발한 컴퓨터 과학자로 유명하며, C언어를 통해서 현대 프로그래밍 언어 역사에 굵직한 한 획을 그은 사람이다. 켄 톰슨은 프로그래밍이 복잡해지는 문제 때문에 C++를 극도로 싫어해서, C++에서 나타나는 복잡성을 최소한으로 줄일 수 있는 단순한 프로그래밍 언어를 만들기 위해 고(go)언어를 디자인했다고 알려져 있다[9, 11].

C와 같은 간결한 문법과, C언어에서는 지원되지 않던 가비지 콜렉션을 제공함으로써 C언어에서 다루기 가장 어려운 부분이었던 메모리 관리를 단순화한 점, 그리고 클로저(closure)를 지원하여 함수형 프로그래밍을 포용함으로써 객체지향 프로그래밍과는 다른 방식의 코드 재사용성을 지원하는 점, 병렬, 분산 컴퓨팅과 멀티 코어 아키텍처가 부상하면서 중요해진 “고 루틴(Go-routine)”을 이용한 병행성(concurrency) 지원과 고(go)언어 구문의 단순명료함이 소프트웨어의 복잡성을 낮추는 데 기여하고 있다.

이렇게 프로그래밍 언어 수준에서 소프트웨어의 복잡성을 근본적으로 줄이기 위해 설계된 고(go)언어의 설계 철학과 특성들은, 5G 이동통신과 저지연, 광대역 유선 네트워크를 통해 다수의 클라우드 컴퓨팅 자원을 끌어와 복잡한 대규모의 연산을 해야 하는 지능형 서비스를 개발하는 개발 환경이 어떤 식으로 발전되어 갈 것인지 엿볼 수 있게 하는 트렌드로 볼 수 있다.

고(go)언어와 함께 또 살펴보아야 할 프로그래밍 언어는 “코틀린(Kotlin)”이다. “코틀린(Kotlin)”은 고(go)언어와는 달리 “자바 가상 머신(Java Virtual Machine; 이하 JVM)” 계열의 언어이다. 자바(Java)와 JVM 계열 언어의 특성을 다수 채용하면서, 자바(Java)언어로 개발된 소프트웨어 모듈들을 별다른 수정과 포팅 없이 코틀린(Kotlin)으로 개발된 소프트웨어에서 바로 불러 사용할 수 있도록 자바(Java)언어와의 100% 상호호환성을 지원한다. 자바(Java)언어의 단점으로 지목되어 온 같은 기능을 표현하는데 다른 언어보다 장황한 표현이 필요한 점도 코틀린(Kotlin)의 간결한 구문과 람다식(lambda expression), 클로저(closure) 등의 함수형 프로그래밍 개념의 도입을 통해 상당히 많이 개선되었다[13-17].

“코틀린(Kotlin)”언어가 사이버 물리 시스템과 클라우드 컴퓨팅에 주는 의미는 소프트웨어 개발 과정의 협업과 생산성을 중시하고 이를 개선하기 위한 디자인이 상당수 포함되었다는 것이다.  “코틀린(Kotlin)” 언어를 개발한 “젯브레인즈(JetBrains)”사가 프로그래밍 언어 개발을 위한 통합 개발 환경(Integrated Development Environment; IDE)”과 개발 도구를 개발하는 회사라는 것도 눈여겨봐야 할 점이다. 코틀린(Kotlin)은 애초부터 통합 개발 환경과 개발 도구를 통한 자동화를 염두에 두고 개발된 언어이기 때문에 개발 도구와의 통합이 용이한 디자인을 가지고 있고, 코틀린(Kotlin)을 개발한 젯브레인즈가 자사의 IntelliJ 개발 환경에서 100% 코틀린(Kotlin)을 지원하고 있기 때문에 다른 프로그래밍 언어에 비해 통합 개발 환경 지원과 개발 도구 지원이 탄탄하다.

코틀린(Kotlin)이 소프트웨어 엔지니어들의 고충을 해결하고 팀 단위로 소프트웨어를 개발할 때 겪게 되는 소프트웨어 엔지니어링 문제들을 해결하기 위해 디자인된 프로그램 언어 특성들을 보면서 이런 것들이 사이버 물리 시스템 개발에 어떤 의미를 갖는지 같이 생각해보자.

코틀린(Kotlin)의 데이터 클래스(data class)는 스칼라(Scala)언어의 케이스 클래스(case class)의 기능을 일부 차용한 자질(feature)로, 자바(Java)언어에서 데이터를 전달하는 객체로서 많이 쓰이는 자바 빈즈(Java beans)의 고질적인 문제였던 코드 라인수가 길어지고 지나치게 소스 코드가 장황해지는 문제를 간결하게 해결해준다[13-14, 17]. 

데이터 클래스는 자바 빈즈(Java beans)를 선언, 정의할 때 getter, setter함수를 일일이 선언, 정의해주어야 하는 문제 때문에 순식간에 코드량이 늘어나는 자바(Java)의 단점을 개선하고, 데이터를 전달하는 객체 사용을 단순히 해당 필드를 public으로 선언하고 접근하도록 하며, 코틀린(Kotlin)에서 데이터 클래스로 선언된 클래스는 해당하는 자바(Java) 표현에서 자동으로 getter, setter함수를 생성하도록 컴파일하게 되어 있어 데이터 객체를 다루기 위해 길어진 소스 코드를 작성하고 다루느라 낭비하는 시간과 노력을 줄일 수 있게 해준다.

C언어에서 소프트웨어 엔지니어들의 가장 큰 고충사항이 포인터를 통한 메모리 관리 과정에서 생기는 실행시간 오류(runtime error)라면, 자바(Java)에서는 가비지 콜렉션을 통해 메모리 관리의 어려움은 많이 해소되지만, “널(null)” 체크 및 처리를 제대로 하지 못해서 생기는 “널 포인터 예외(NullPointerException)” 때문에 많은 고충을 겪는다. 코틀린(Kotlin)의 “널 가능(Nullable)” 형 표현은 “널(null)” 체크 및 이에 따른 형변환과 문제들을 경감해주는 소프트웨어 엔지니어들에게 유용한 언어적 자질중의 하나이다[13-14, 17].

코틀린(Kotlin)에서 “널 가능(Nullable)”로 선언된 변수는 if문을 통해서 널(null) 값인지 여부를 체크하거나, is연산자를 사용해서 객체의 타입을 검사하면 맥락에 맞게 자동으로 형변환을 해준다. 코틀린(Kotlin)언어의 이런 자질은 개발자들이 널(null) 체크와 “널 포인터 예외(NullPointerException)”를 다루기 위해 들여야 하는 노력을 크게 경감시켜 주기 때문에 코틀린(Kotlin)으로 개발된 언어가 예상치 못한 널(null) 값 발생과 이를 제대로 예외 처리하지 않아 생기는 다양한 결함들을 손쉽게 포용하고 소프트웨어의 안전성을 높일 수 있게 해주어 소프트웨어 엔지니어들의 수고를 덜어준다.

코틀린(Kotlin)의 눈에 띄는 특징 중 하나는 역시 함수형 프로그래밍을 지원하면서 소스 코드가 장황해지지 않고 양이 크게 감소하며, 표현이 간결해지는 것이다. 이는 스칼라(Scala)언어의 장점을 많이 도입한 것에서 오는 특성인데, 스칼라(Scala)언어의 경우 자바(Java)언어에 비해 소스 코드 양이 크게 줄고 표현도 훨씬 간결해진다. 필자의 경우 자바(Java)언어에서 몇십 줄에 이르는 소스 코드가 스칼라(Scala)로 표현하면서 단 3~4줄이면 끝나는 경우를 많이 경험했다. 코틀린(Kotlin)이 클로저(closure)와 함수형 프로그래밍을 지원하면서 역시 스칼라(Scala)의 이런 장점을 수용한 것이다[17].

같은 기능을 구현하는데 소스 코드 양을 줄이는 것이 소프트웨어 엔지니어들의 수고를 왜 줄여주는지 선뜻 이해가 안 가시는 분들도 있을 법하다. 더군다나 이 글을 읽으시는 분들 중 CIO와 같은 의사 결정을 주로 하시는 분들이라면 프로그래밍 언어를 디자인할 때부터 소스 코드 양이 대폭 줄어들도록 표현을 간결하게 디자인하는 것이 왜 중요한지 이해가 가지 않을 수 있다.

소스 코드 양이 줄어들면 우선 오류나 버그가 줄어들게 된다. C언어나 자바(Java)와 같은 언어로 프로그래밍을 할 때 소프트웨어 엔지니어들을 가장 괴롭히는 것 하나가 {}나 ()와 같은 코드 블록이나 스코프를 표현하는 기호들을 짝이 맞게 매치하는 것이다. 코드가 표현하는 내용이 복잡해지고 길어지면 이런 블록을 아무리 정성 들여 보기 좋게 표현해도 실수를 하게 마련이고, 또한 예약어와 다르게 이런 블록 표현들은 여러 개가 중첩되어 표현되면 짝이 맞지 않는 부분을 찾기도 어렵다. 그런데, 스칼라(Scala)와 코틀린(Kotlin)의 클로저(closure)와 함수형 프로그래밍을 지원하는 구문을 사용하면 소스 코드의 구조도 단순해지고 읽기도 쉬워진다.

소스 코드 양이 줄어들게 되면 소프트웨어 엔지니어들이 같은 기능을 작성할 때 들이는 시간과 노력이 줄어들어 생산성 향상에도 도움이 된다. 프로그래밍 언어를 배울 때 짜는 예제 정도의 몇십, 몇백 줄 정도의 소스 코드를 작성할 때에는 소스 코드 양을 줄이는 것이 얼마나 도움이 되는지 체감하기 어렵다. 그렇지만, 현대 소프트웨어의 상당수는 분산 컴퓨팅 소프트웨어인 데다가, 시스템의 규모와 복잡성에 따라 소프트웨어의 크기도 몇십만, 몇백만 라인을 넘기는 것은 그리 어렵지 않다. 더군다나 이런 대형 소스 코드는 한 사람이 작성하는 것이 아니라 팀이 개발하게 된다. 프로그래밍 스타일과 생각도 많이 다른 여러 사람이 작성한 대형 소스 코드를 읽고 이해하면서 개발하는 것은 정말 어려운 일이며, 이런 대형 소프트웨어의 소스 코드 수준에서의 품질을 관리하기는 정말 쉽지 않은 일이다.

 


X