검수요청.png검수요청.png

하스켈

위키원
kang (토론 | 기여)님의 2019년 8월 21일 (수) 20:08 판 (특징)
이동: 둘러보기, 검색
하스켈 로고

하스켈 또는 해스켈(Haskell)은 1985년에 개발된 순수 함수형 프로그래밍 언어이며, 논리학자 '해스켈 커리'(Haskell Brooks Curry)에서 따온 명칭이다.

개요

하스켈은 순수 함수형 프로그래밍 언어이다. 또한 지연계산(Lazy), 함수형(Functional), 정적 타입 지정(Statically Typed)의 프로그래밍 언어이다. 하스켈의 로고는 람다 대수에서의 'λ'와 모나드(monad)에 사용하는 bind 연산자인 '>>='를 겹쳐놓은 이미지다. 1980년대 프로그래밍 언어 연구자들이 만든 위원회에서 정의한 언어이며, 순수 함수형 프로그래밍 언어로 입·출력 같이 필요한 경우가 아니면 부작용이 없는 순수 함수로만 만들어졌다. 가장 많이 쓰이는 하스켈 컴파일러로는 GHC가 있으며, 여기에 패키지 매니저를 추가한 플랫폼이 스택(Stack)이다.

등장배경과 역사

컴퓨터가 발명되기 전, 수학자인 알론조 처치(Alonzo Church)가 람다 계산법(lambda calculus)이라고 불리는 언어를 개발했다. 이는 수학의 기초를 연구하기 위한 도구로 쓰이도록 고안한 것이다. 그 후, 일반 프로그래밍과 람다 계산법 사이의 실질적인 연결고리를 인식한 첫번째 사람은 존 맥카시(John McCarthy) 이며 그는 1958년 립스(Lisp)를 개발했다.

이후 1960년대에 컴퓨터 과학자들은 람다 계산법의 중요성을 인식하고 연구하기 시작했다. 대표적으로 피터 랜딘(Peter Landin)과 크리스토퍼 스트라키(Christopher Strachey)는 프로그램 언어의 기반이 되는 공식들을 만들어 나갔다. 그들은 컴퓨터가 무엇을 했는지 추론하는 방법과 프로그래밍 무엇을 의미하는지 알 수 있는 밥법에 대해 연구했다.

앞서 언급된 연구들을 바탕으로 1970년대 초반에 로빈 밀너(Robin Milner)는 좀 더 엄격한 함수형 언어인 ML을 개발했다. ML은 수학 이론의 자동화된 증명을 위해 개발된 데 반해 좀 더 일반적인 계산 작업을 위해 필요한 것들을 취했다. 이후 1970년대에는 지연 계산법(lazy evaluation), 데이비드 터너(Davide Turner)가 개발한 SASKRC 등이 등장한다. 또한 이 시기에 로드 버스털(Rod Burstall)과 존 달링스톤(John Darlington)은 NPLHope를 개발한다. NPL, KRC, ML은 후에 개발된 Lazy ML, Clean, 미란다를 포함해 1980년대 만들어진 몇몇 언어들의 개발에 영향을 주었다.

그 중 1985년에 개발된 미란다가 하스켈의 전신이라고 할 수 있다. 1987년 오리건주 포틀랜드에서 열린 '함수형 프로그래밍 언어와 컴퓨터 구조에 관한 총회'(Functional Programming Languages and Computer Architecture, FPCA '87)에서 있었던 회의에서 난립하고 있는 함수형 언어들을 통합 정리하여 훗날 언어 설계의 기반이 될 수 있는 일반적인 순수 함수형 프로그래밍 언어를 만들자는 데에 참가자들의 뜻이 모였고 위원회가 발족되었다. [1]

그렇게 하스켈의 첫 버전인 '하스켈 1.0'은 1990년에 완성되었다. 이처럼 1990년 대의 하스켈은 두 가지 주요 목적을 수행했다. 한 가지는 지연 함수형 언어를 효율적으로 실행시키고자 하는 실험에 안정적인 언어를 연구원에서 제공한 것이었다. 다른 연구원들은 지연 함수 기술을 사용해 어떻게 프로그램을 작성할 것인가를 연구했다. 그 외 연구원들은 여전히 하스켈을 가르치는 언어로 사용했다. 이후 위원회는 노력하여 1997년 말까지 다양한 설계안으로 이어져 마침내 '하스켈 98'이라는 성과가 나왔다. 하스켈 98은 교육용이나 확장을 덧붙이는 토대로 사용할 수 있는 안정적이며, 작고 이식성 좋은 언어 표준을 의도한 결과물로써 표준 라이브러리가 포함되어 있었다. 또한 위원회는 하스켈 98의 확장 기능과 더불어서 하스켈 98에 실험적인 기능을 덧붙이거나 합친 변형이 만들어지는 것을 열렬히 환영하였다. 하스켈 98 언어 표준은 1999년 1월 '하스켈 98 보고서'(The Haskell 98 Report)라는 이름으로 정식 공개되었다. 이후 하스켈 언어 표준은 98 버전을 포험하여 현재까지 5번의 개정을 거쳤다.

파스칼의 첫 번째 개정은 2003년 1월에는 '하스켈 98 언어와 라이브러리: 개정 보고서'(Haskell 98 Language and Libraries: The Revised Report)라는 이름으로 개정판이 나왔다. 하스켈을 실제 컴퓨터에서 사용할 수 있도록 구현한 '글래스고 하스켈 컴파일러'와 '허그스'가 사실상의 표준 역할을 하면서 하스켈은 지금도 끊임없이 발전하고 있다. 이후 2006년 초, 하스켈98 표준의 뒤를 이을 표준에 관한 논의가 시작되었다. 새로운 표준은 비공식적으로 '하스켈 프라임'이라는 이름으로 불렸으며, 2009년 11월 새로운 표준의 첫 번째 판인 하스켈 2010이 발표되었다. 하스켈 2010은 다른 프로그래밍 언어와 호환 가능한 인터페이스인 외부 함수 인터페이스를 지원하며, 일부 문법이 변경되었고, n+k 패턴이라 불리는 문법 형식이 금지되었다. 이러한 개정 과정으로 인해 하스켈 구현은 상당히 이뤄졌고, 그 중 일부는 지금도 개발 중이다. [2]

1990년대의 기초적인 연구가 진행되는 동안 하스켈은 학문적으로 확고한 위치를 유지했다. 하스켈 커뮤니티 내부의 비공식적 슬로건은 "모든 비용을 들여 성공을 피해라" 였다. 이 언어에 관해 알고 있는 외부 사람들은 거의 없었다. 애초에 당시 함수형 프로그래밍은 잘 알려지지 않은 분야였다. 이 시기에 주류 프로그래밍은 C에서 C++, Java였다. 이 언어들은 상대적으로 다른 프로그래밍 언어들에 비해 약간씩 수정되고 있다. 한편, 다른 프로그래머들은 좀 더 새로우면서 동적인 언어를 손보기 시작하고 있었다. 귀도 반 로섬(Guido van Rossum)이 이 때, 파이썬을 설계했고 래리 월Larry Wall(Perl)을 개발했다. 그리고 마츠모토 유키히로(Yukihiro Matsumoto)는 루비를 개발했다.

새로 개발된 이 언어들은 사용자에게 널리 스며들기 시작하면서 몇 가지 중요한 아이디어를 전파 했다. 첫 번째로, 프로그래머들은 아무리 유능하더라도 표현력 있는 언어로 작업하기 위해서는 그런 능력을 별개로 개발해야 한다는 것이다. 가지고 있지 않다는 것이다. 두 번째는 현대의 컴퓨팅 파워가 빠르게 성장한 결과가 이 프로그래밍 언어들이란 사실이다. 프로그래머가 생산성을 향상시키기 위해서 프로그램 실행 성능을 희생하는 것은 좋은 결과를 낳기도 했다. 마지막으로 몇멸 프로그래밍 언어들은 함수형 프로그래밍에서 시작되었다는 것이다.

지난 5년 간 하스켈은 학계에서 성공적으로 발전하여 파이썬, 루비, 자바 스크립트 분야의 부분적인 부표가 되었다. 지금 하스켈은 오픈 소스, 상용 사용자, 연구원들에 의해 성능과 표현력의 경계를 넓히는데 계속 사용되고 있고 빠른 성장을 보이고 있다.

특징

하스켈의 특징으로는 '패턴 맞춤', '커링', '가드', '조건제시법', '연산자' 정의 등을 들 수 있다. 재귀 함수나 대수적 자료형도 지원되며, 느긋한 계산법 [3] 또한 하스켈의 특징으로 유명하다. 단일체, 타입 클래스 등은 하스켈만의 독창적인 개념이며, 이러한 특징들은 절차적인 프로그래밍 언어에서 매우 힘들었던 함수 정의를 손쉽게 만들어버린다. 수학의 한 특이 분야인 범주론의 개념들, 특히 함수의 개념이 추상화된 형태인 사상과 모나드를 차용하여 가져온 언어인데, 이를 통해 함수를 대상으로 다룸에 있어 명확성을 가질 수 있다. 2002년을 기준으로 하스켈은 느긋한 계산법을 쓰는 함수형 언어 가운데 가장 활발한 연구가 이루어지는 언어였다. 언어의 변형도 몇 가지 개발되었다. 매사추세츠 공과대학교와 글래스고 대학교가 개발한 버전은 병렬화가 가능하기에 '병렬 하스켈'이라고 불렸다. 이후 병렬화와 분산 처리를 더욱 강화한 '분산 하스켈'과 에덴 프로그래밍 언어가 개발되었고, 느긋한 계산법 대신 적극적인 계산법을 활용한 '적극적 하스켈'이 있으며, 하스켈에 객체 지향 프로그래밍 개념을 도입한 버전으로 '하스켈++', '오하스켈', 몬드리안 프로그래밍 언어 등등이 있다.

함수형 프로그래밍 언어 비교
기본 평가 효과 타자 순도
하스켈 게으른 계산법 IO 타입 + 모나드 정적 있다
퓨어스크립트 조급한 계산법 이펙트 타입 + 모나드 정적 있다
Elm 조급한 계산법 Cmd / Sub 이벤트 정적 있다
Clean 게으른 계산법 독특한 유형 정적 있다
미란다 게으른 계산법 게으른 유형 정적 있다
F# 조급한 계산법 부수효과 정적 없다
ML 조급한 계산법 부수효과 정적 없다
Scheme 조급한 계산법 부수효과 동적 없다
Typed Racket 조급한 계산법 부수효과 점진적 없다
Clojure 조급한 계산법 부수효과 동적 + 유형 힌트 없다
Erlang 조급한 계산법 부수효과 동적 + 유형 힌트 없다

순수 함수형 언어

보통 순수 함수형 언어의 가장 큰 특징은 부수효과(Side Effect)가 없는 것이다. 하지만, 사실 이것은 함수형 언어보단 순수 선언형 언어의 특징에 가깝다. 함수형 언어는 순수 선언형 언어의 하위 카테고리라 볼 수 있다. 순수 함수형 언어에서 함수는 수학에서의 함수와 같아서 부수효과가 없는 것을 의미한다. 즉, 순수 함수형 언어에서 함수의 결과 값은 파라미터(parameter)로 넘겨진 입력값에 의해 결정된다. 여기서 말하는 부수효과란, 같은 입력임에도 불구 출력이 달라지는 것을 말한다.

느긋한 계산

느긋한 계산(Lazy Evaluation)은 계산이 필요한 순간까지 계산을 미루어 둔다는 의미이다. 따라서 그때 그때 필요한 만큼만 계산하는 것이 가능하다. 이 느긋한 계산의 개념으로 인해 하스켈은 프로그램에 대한 무한의 개념을 쉽게 적용할 수 있다. 오히려 필요할 때 필요한 만큼 동적으로 리스트를 생성하므로 유연한 프로그래밍을 위해 필요한 경우에는 무한을 사용하는 쪽으로 권장된다.

장단점

장점

  • 프로그래밍 생산성이 실직적으로 향상
  • 더 짧고 명확하여 유지 보수가 쉬운 코드
  • 오류가 적으며 높은 신뢰성
  • 프로그래머와 언어 사이의 작은 '의미상의 간격'(Semantic Gap)
  • 더 짧은 리드 타임 [4]

단점

표현력이 좋고, 코드가 간결하며, 알고리즘의 구현이 직관적이고, 부수효과가 없고, 동시성이 보장되는 등 많은 장점이 있지만 애초 함수형 언어란 일반적인 프로그래밍 언어와 체계가 달라서 쉽게 익숙해지기 어려우며, 사용하기 어려운 점이 많다. 그 결과 시도하는 사람 자체가 적으며 잘 아는 사람이 많지 않으니 사용 예가 적고, 사용 예가 적으니 배우려는 사람이 적다. 재귀코드를 짜는 것 역시 상당한 두뇌노동을 필요로 하며, 수리 논리학 전공으로 꽤 지식이 있어야 이해가 가능하다는 점 또한 단점이다.

적용

하스켈의 사용자 수는 상대적으로 적은 편이지만, 그 강력함 때문에 몇몇 프로젝트를 쉽게 해주었다. 퍼그스(Pugs)는 펄6의 컴파일러와 인터프리터를 구현한 것인데, 개발 기간은 지극히 짧았지만 만들어진 지 몇 달도 채 되지 않아 좋은 평가를 받았다. 서브버전과 비슷한 버전 관리 체계인 다크스(Darcs)가 하스켈로 만들어졌으며, 린스파이어는 시스템 도구 개발을 위한 언어로 하스켈을 선택하였다.

영향받은 언어

  • 미란다 : 미란다는 상업적으로 지원된 최초의 함수형 언어로 하스켈과 유사한 부분이 많은 언어이다.
  • 리스프 : 리스프(LISP) 혹은 리습은 프로그래밍 언어의 계열로서, 오랜 역사와 독특하게 괄호를 사용하는 문법으로 유명하다. 1958년에 초안이 작성된 이 언어는 현재 널리 사용되는 포트란에 이어 두 번째로 오래된 고급 프로그래밍 언어이다.
  • APL : APL(A Programming Language)은 고급 수학용 프로그래밍 언어이다. 1957년 하버드 대학에서 발명되었다. 금융 및 보험 애플리케이션, 시뮬레이션, 수학 응용 프로그램 등 다양한 응용에서 사용된다.
  • ML : ML은 범용 함수형 프로그래밍 언어이다.

영향 준 언어

구현

  • 글래스고 하스켈 컴파일러는 하스켈 컴파일러(GHC)와 대화식 환경으로 되어 있다.
  • Hugs는 하스켈 인터프리터이다.

예제

다음은 계승을 하스켈로 구현하는 몇 가지 방법이다.

fac 0 = 1
fac a = a * fac (a-1)
fac a = if a > 1 then a * fac (a-1) else 1
  • 고차 함수(High-Drder Function)을 이용한 방법
fac a = foldl1 (*) [a..1]
  • Product 함수를 이용한 방법(Product 함수는 위의 foldl1 (*)과 같다)
fac a = product [a..1]

각주

  1. Template tips,〈0. 왜 함수형 프로그램인가? 왜 하스켈인가?〉, 《동우 홈페이지》
  2. 하스켈〉, 《위키백과》
  3. 토이팹, 〈느긋한 계산법〉, 《티스토리》, 2009-03-12
  4. 하스켈〉, 《하스켈위키》

참고자료

같이 보기


  검수요청.png검수요청.png 이 하스켈 문서는 프로그래밍에 관한 글로서 검토가 필요합니다. 위키 문서는 누구든지 자유롭게 편집할 수 있습니다. [편집]을 눌러 문서 내용을 검토·수정해 주세요.