관리 메뉴

HAMA 블로그

스칼라를 이용한 개발 이후.. 본문

소프트웨어 사색

스칼라를 이용한 개발 이후..

[하마] 이승현 (wowlsh93@gmail.com) 2016. 12. 10. 15:41


스칼라를 이용한 개발 이후..


폴리글랏 (C++,Java,Python,Swift,Javascript) 언어로 개별 작업하면서 동시에 스칼라를 이용해 (Programming in Scala 와 FPiS 빨강책으로 공부)  EV 충전 인프라 서비스를 위한 마이크로서비스(서버 인프라와 웹서비스에 각각 적용하고 난 후 가장 아쉽게 느끼는 점은 akka 나 play2의 문제점 같은게 아니라 내가 짠 것은 함수형 프로그래밍은 아니다. 였습니다. 아시다시피 스칼라는 하이브리드언어입니다. 객체지향식으로 코딩 할 수 도 있고 함수형으로 코딩 할 수 도 있습니다. 따라서 기존 자바나 C++ , 파이썬 개발자들이 순수 함수형 언어인 하스켈이나 거의 순수형인 클로저 보다는 쉽게 접근 할 수 있는데요. 저도 스칼라를 선택한 이유 중 하나에 포함됩니다. (기타 : "Typesafe 사 및 대기업에서의 적극적인 사용, 자바라이브러리사용, Akka 라이브러리, 강력한 정적 타입시스템, Play2, Intellij IDE, 가상머신상에서 돌아감등 ") 

하지만 하이브리드라는 것 은 이것도 해주고 저것도 해주고 장점을 믹스하고 자유도를 높혀 준다 라고 말 할 수 도 있지만 거꾸로 보면 난해하다는것을 말합니다. (다른 사람이 짜놓은 코드가 객체지향인지 함수형인지.. immutable인지 아닌지..버그들을 눈을 부릅뜨고 찾아봐야하며 ..울분에 날 밤을 새야 할지도..) 함수형과 객체지향은 완전 상반된 개념인데 이것을 같이 사용하게 하면 어떤 일이 벌어 질까요? 

예를들어 동시성에 대해서 생각해 봅시다.

무어의 법칙이 한물가고 이제 암달의 법칙이 지배하는 세상입니다. 객체지향이니 함수지향이니 보다는 동시성지향프로그래밍으로 대동단결 할 것으로 보이는데요. lock 이나 뮤텍스,쓰레드등을 직접 요리하는 시대는 갔습니다. 그 우연적복잡성,경쟁상태,메모리가시화,데드락을 해결 하기가 너무 힘듭니다.(나는 저런거만 써서도 잘 할 수 있다는 사람이 주변에 있으면 조심하세요. 요주의 인물입니다 -.-;;)  그래서 어려운 동시성 문제를 해결 하기 위해 여러 방법들이 생겨 났습니다.  크게 보면 3가지 인데요. 참고=> 7가지 동시성 모델

첫째. 변하지 않는 데이터로 공유하라. (immutable 은 함수형파라다임의 대표적 속성 중 하나)
둘째. 공유되지 않게 하라. (
객체지향파라다임에서 메세지 패스를 통해서 해결 하라는 것 이며, 예를들어 Actor 모형입니다.)
셋째. 가변상태에서 아이덴터티를 포착하라. ( STM 을 말함) 

이 얘기는 앞으로 점점 더 동시성 프로그래밍이 대세가 될 텐데  그걸 기본적으로 해결 해주는것이 함수형 파라다임이고 그 이유로 요즘 F#,하스켈,스칼라,클로저,얼랭등이 인기를 얻고 있다는 뜻이기도 합니다. 음 먼가 말이 샌거 같기도 한데...-.-;;

여기서 스칼라는 두둥~~ 네 객체지향이자 함수형이고 가변성질을 느슨하게 포함하고 있는 상태에서 다양한 동시성 모형을 여러가지로 가져 갈 수 있는데.., 그 말은 복잡도가 *100 증가 했습니다와 마찬가지입니다. 한가지만 제공하는 언어를 사용하면 누가 짠 코드이던지 그 본질에 대해 확신이 들지만 이것도 되고 저것도 된다면 확인해 봐야 할것들이 늘어잖겠습니까.. OTL  

뭐 이런 고민 상황에서  허둥지둥 스칼라로 프로젝트를 하였고..스칼라의 반 쪽 밖에 맛을 못본것은 좀 아쉬웠습니다. 특히 그 반쪽보다는 다른 쪽 반쪽에 대한 장점을 가져가고 싶었는데 말이죠. 시간이 없었다는 핑계를 댈 수 도 있겠지만 그것 보다는 우선 순서가 잘못된게 아닌가 느꼈는데요. 결국 "스칼라"라는 하이브리드 언어에서 나머지 한쪽 맛 (함수형) 을 보려면, 순수 함수형을 먼저 공부하는게 순서가 아니겠느냐 하는 점이죠. (이것은  C++ 개발자에게 자바,스몰톡을 공부 해 보라고 권유하는 것과 동일합니다. 자바개발경험이 있으면 C++ 개발에 대한 식견도 꽤 높아질것입니다.) 즉 스칼라를 더 잘 사용하기 위해서 즉 객체지향의 강점과 함수형의 강점을 극대화 하여 사용하기 위해 순수 함수형 언어를 공부해야겠다고 생각 하게 되었습니다.(사실 공부만 해서 별 의미 없을 거 같기도 합니다. 다른 언어를 한 1년 정도 안하고 순수 함수형만 가지고 놀 수 있는 환경에 있다면 좋을텐데.. 여러가지 언어로 개발하면 온전히 함수형 마인드를 갖기는 어렵지 않을까 하는)

그럼 어떤 함수형언어를 공부 해 볼까 고민하다가 발견한 글 중에 하나가 이것입니다. 뭐 시간 있으면 하스켈,클로저 둘 다 공부해 보면 좋겠지만 시간도 없거니와 이왕하는 거 순수 함수형 언어인 하스켈을 선택하자 하고 몇가지 글을  찾았고 그 중 하나를 정리 해보았습니다. 항상 그러하지만 번역 상태에 대해 만족스럽지 못할 수 있다는 점 송구스럽게 생각하며.. ㅜㅜ  시작해 봅니다. =@@



Clojure 를 넘어 Haskell 로  

http://martintrojer.github.io/beyond-clojure/2016/04/21/beyond-clojure-haskell

타입을 가진 함수형 언어에 관심이 있는 경우 결국 하스켈을 만나게 될 것 입니다. 배우기가 극도로 어렵고 마스터 하기는 더 어렵다는 평판에도 불구하고 훌륭한 자료들이 있으며 귀중한 교훈을 많이 배울 수 있습니다.

하스켈은 매우 순수하며 핵심 아이디어와 라이브러리의 간결함은 환상적입니다. 그것은 명령형 문제 해결 스타일을 뛰어 넘고 높은 수준에서 문제를 매우 깔끔하게 다룹니다. 하스켈에 관해 내가 정말 좋아하는 한 가지는 명백한 학문적 용어를 사용하여 '사물'이 무엇인지 불리는 것입니다. 모나드 (Monads) 등을 가지고 있는 다른 언어들의 경우 수줍어(?)하며 다른 이름을 쓰는 경향이 있습니다.이 점은 혼란만 가중 시킬 것이라고 생각합니다.

핵심 라이브러리 (하스켈 literature 의 대부분인)의 벽으로 둘러싸인 정원에 머물러있는 한 간결하고 아름다운 세계가 제공됩니다. 문제 해결에 영감을 불어 넣고 다양한 각도에서 문제를 바라 보는 환경인데요. 그래도 항상 더 깔끔하게 문제를 해결할 수 있는 방법들이 있으며, 이러한 탐구적인 태도와 성향은 하스켈 커뮤니티에  널리 퍼져 있습니다. Haskell 초급 모임 및 채팅룸에서 경험이 많은 개발자들이 따뜻한 도움을 주고 있으며, 답을 주는 것보다 스스로 문제를 해결할 수 있게끔 유도 합니다. 그것은 언어를 즐겁게 배우게 만드는데 도움을 준다고 생각합니다.

성공하는 대신 결점을 찾아라

Haskell에 대해 이해해야 할 때 중요한 한 가지! 이 언어는 "연구 언어" 란 건데요. 이 사실은 다른 '현장 언어' 들과는 매우 다른 점입니다. 좀 어리둥절 할 수 도 있는 하스켈의 모순 된 모토는  '모든 비용을 들여서라도 성공을 피하십시오'. 입니다. 이 말을 해석해보자면 언어의 안정성에 의존하는 대규모 사용자 기반을 피함으로써 작성자 / 연구자가 마음을 바꾸면 나중에 제거하고 마음 편하게 새로운 아이디어를 탐색 할 수 있다는 것입니다. 대성공의 희생자이며 성공을 했다는 이유로 십 수년 동안 혁신 마비에 빠져있는 Java와 같은 언어와 대조해 보시면 됩니다. (역주: 개인적으로 자바는 혁신 하지말고 그냥 자바 그 자체로 남아 있길 바라는 마음도 있습니다. 혁신하다보면 오히려 정체성만 없어지고 조잡한 언어가 되지 않을까 하는 우려 때문인데요. 오랫동안 혁신하지 않고도 자바가 필요한 분야는 많이 있을 겁니다. 목숨 줄 억지로 늘리지 말고 때가되면 자연스레 은퇴하길...) 가장 유명한 Haskell 컴파일러 인 GHC에서 명백하게 느낄 수 있는데 GHC는 최신 Haskell 표준 Haskell2010을 지원하며 그 위에 다양한 언어 확장 기능을 제공합니다. 

여러분이 핵심 라이브러리의 벽으로 막힌 정원 밖으로 여행을 떠나서 하스켈을 '진짜로'사용하기 시작하면, 거의 모든 모듈에서 이러한 언어 확장을 피할 수 없습니다. 모두는 아니더라도 대부분의 라이브러리는 확장 기능을 사용하고 일부는 코드에서 사용해야합니다. 이것이 얼마나 큰 거래인지는 미래의 변화에 ​​대해  당신이 얼마나 대처 할 수 있을지에 달려 있습니다.

하스켈을 주 언어로 사용하고 5 년 이상 일하는 것에 대해 생각하고 있다면, 이것은 불안의 원인이 될 수 있습니다. 비즈니스 핵심 서비스를 위해 GHC (컴파일러 '모두 사용')를 사용할 계획이라면 언어 / 컴파일러 변경 사항을 지키기 위한 전략과 팀에 부과하는 추가 작업을 고려해야합니다. 개발자가 사용하는 확장 기능에 대한 규율도 중요합니다. (역주 : 역시 공부목적으로만 해야 하는.. -.-a)

게으름

Haskell 의 핵심 설계 원칙 중 하나는 게으른 평가입니다. 이것은 다른 함수형 언어에서 볼 수 있는 게으른 시퀀스 이상입니다. 기본적으로 모든 표현식은 다른 표현식이 결과를 땡겨 올 때만 실현됩니다. 하스켈의 아름다움은 이 기법에서 비롯되었지만 실제적인 문제는 많습니다. 가장 중요한 것은 기능의 시간 / 공간 복잡성을 해결하는 것이 매우 어렵다는 것이며 다른 함수의 표현식은 현재 벤치마킹중인 함수의 문맥상에서 방아쇠가 당겨 질 수 있습니다. 그밖에 따로 방법이 없으며, 적극적 평가(eager evaluation) 가 그 부분에서는 더 쉽지만, 하스켈의 접근법을 무효화하지 않습니다.(??)

또 다른 문제점은 일반적으로 런타임 예외시 스택 트래이스를 얻지 못한다는 것입니다. 그것은 컴파일 타임에 활성화되어야하며 프로덕션 빌드의 경우 일반적으로 실행되지 않습니다. 트레이스를 얻었을 때도, 게으른 것으로 평가되기 때문에, 자바 스택 트레이스와 똑같지는 않습니다.

늘 그렇듯이 몇가지 대안이 있지만,  간단하지 않은 상황 (예 : 생산 중단 시간 시나리오가 그러하듯) 에서는 Java와 유사한 프로파일링 도구가 필요 합니다. 필연적으로 compiler optimization flagsbang patterns 및 기타 어려운 교훈을 배우고 베스트 프랙티스를 수집하는 과정을  거친 후에야 제대로된  응용 프로그램을 만들 수 있을 것 입니다. OTL

타입 언어와 함께 춤을

하스켈과 클로저의 차이는 꽤 있는데요 Clojure에서는 var에서 작업하고자 하는 데이터를 저장하고 변환 작업을 시작합니다. 표현식을 데이터 모양과 일치 시키려 할 때 피드백은 종종 Clojure 런타임 오류입니다. 하스켈에서 추상화 (유형)에 대해 생각하기 시작하고 컴파일러의 주요 오류는 컴파일러가 자신을 모순하는 곳을 가리키는 유형 오류입니다. 또한 런타임 오류가 거의 발생하지 않기 때문에 '컴파일하면 작동합니다'라는 강한 확신감각하에 개발을 합니다. 이것은 결코 테스트의 중요성을 없애지는 않지만 테스트는 Clojure 코드 -베이스에서와 동일한 역할을 하지 않습니다. Haskell에서 나는 코드가 올바르게 붙어 있거나 GADT의 변경으로 인해 case 표현식을 바꾸는 것을 잊지 않았다는 확신을 줄 수있는 테스트가 필요하지 않습니다. 컴파일러는 나를 위해 모든 것을 검사하고 "그것은  여기, 여기, 여기 그리고 여기에 더 많은 수정이 필요합니다"라고 말합니다. 나에게 이것은 엄청난 것이지요.

툴과 함께 춤을 

'Haskell IDE'는 전통적으로 Emacs / Vim과 터미널 입니다. 매우 즐거운 개발자 경험을 주는 여분의 도우미가 많이 있습니다. 전통적인 IDE를 위한 플러그인이 있지만 일반적으로 덜 정교합니다. 나는 대화형 작업 흐름을 제공하는 Emacs, haskell-mode, ghc-mod, hlint 설정에 만족합니다. 좀 더 전통적인 IDE 설정이 필요하다면, IDE-Haskell과 Haskell for Mac이 괜찮아 보입니다.

라이브러리로 작업하고 의존성을 다루는 것은 cabal로 수행됩니다. Cabal은 하스켈 서클 내부와 외부에서 많은 쟁점과 명성을 얻었습니다. Haskell 개발자들은 여러 문제에 대해 다양한 해결책을 찾기 위해 광범위하게 노력해 왔습니다. 그 문제의 일부는 라이브러리의 버전 (및 그 의존성)뿐만 아니라 컴파일러의 버전이 그것을 생성하는 데 사용되었다는 것입니다. 컴파일러는 기계어 코드를 생성하므로 크로스 컴파일 문제도 있습니다. Mac에서 실행 파일을 컴파일하는 작업은 Linux 서버에서 실행되지 않습니다.

최근 Cabal과 관련된 많은 불평은 Stack이라는 도구로 해결되었습니다. 나는 아주 만족하고 있습니다.(그리고 Nix를 필요로 하지 않습니다.). Stack은 하스켈 툴링 스토리에 대한 커다란 개선점입니다.

라이브러리와 함께 춤을 

사용할 수있는 하스켈 라이브러리는  많이 있습니다. 좋은 라이브러리를 찾는 것은 좀 어렵기도 하지만요 웹어플리케이션을 구축하는 경우 대부분의 기반들을  커버 할 수 있습니다. 웹 프레임워크, 데이터베이스 연결, 템플릿 등에 대해 좋은것들이 있습니다. 그러나 자바 생태계와는 여전히 비교 되긴 힘듭니다. Haskell은 닭이 먼저냐 달걀이 먼저냐인 상황에 갇혀 있는데요. Java 는 서드파티제품들에 대해 상호 작용하는 많은 라이브러리가 존재합니다. 하지만 하스켈은 최신 AWS API를 사용하거나 Riak 데이터 저장소에 연결하기 쉬운 경로를 원할 경우 길이 없습니다. 기본 빌딩 블록은 있지만 거기에 앞서 당신은 꽤 많은 일을 해야 할 것입니다. 이러한 상황은 개발자들의  Haskell 채택을 머뭇거리게 하고 있으며, 이는 결국이 라이브러리가 만들어지는것을 또한 머뭇거리게 만들 고 있습니다.

하스켈 라이브러리에 대한 문서는 대개 꽝입니다. 초보자 친화적인 문서를 기대하지는 마십시오. 나는 스택 오버 플로우등에 대한 검색에 의존하고 있습니다. 라이브러리에 관한 여러 문제점은 하스켈을 실제 시나리오에서 '사용할 언어'로 채택 할 때 주로 우려되는 사항입니다. 


Comments