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

하스켈

위키원
이동: 둘러보기, 검색
하스켈(Haskell)
하스켈(Haskell)

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

특징

하스켈에 있어서 가장 중요한 특징은 바로 순수 함수형 프로그래밍 언어라는 점이다. 순수 함수형 프로그래밍 언어는 어떤 작업을 하라고 컴퓨터에게 명령하는 것이 아니라, 그 작업이 무엇인지를 직접 알려주는 것이다. 예를 들어 컴퓨터에게 숫자의 팩토리얼은 1부터 그 숫자까지 있는 모든 정수의 곱이라고 말한다거나, 숫자 리스트의 합은 첫 번째 숫자들의 합을 더하는 것이라고 말하는 것 등을 하는 것이다. 그리고 이러 작업들은 함수로 표현할 수 있다. 그리고 이 언어에서는 변수에 하나의 값을 설정하고 나면 나중에 다른 값으로 바꿀 수 없다.

이 언어에 사용되는 함수엔 부작용이 없다. 함수로 할 수 있는 것은 어떤 것을 계산하여 그 결과를 반환하는 것 뿐이다. 이를 참조투명성이라고 하는데 이는 어떤 함수를 동일한 매개변수로 두번 설정하면 두 번 모두 동일한 결과를 낸다는 것이 보장되는 것을 뜻한다. 그리고 하스켈은 함수의 결과를 표시해야만 할 때까지 함수를 실행하지 않는다. 그렇기 때문에 만약 어떤 함수의 결과가 그 함수에 주어진 매개변수에만 영향을 받는다는 것을 알게 된다면 그 함수의 결과가 언제 계산되는 지는 상관없다. 값은 똑같기 때문이다.

그리고 하스켈은 정적으로 입력된다. 즉, 프로그램을 컴파일할 때 숫자인 코드와 문자열인 코드가 무엇인지 알게 된다는 것이다. 정적 타이핑이란 말은 수많은 오류들이 컴파일을 할 때 밝견될 수 있다는 뜻이기도 하다. 그리고 하스켈은 타입유추(Type Inference)를 가진 시스템을 사용한다. 이 말인 즉슨 모든 코드마다 타입을 명확하게 지정할 필요가 없다는 뜻이기도 하다. 그리고 하스켈은 수준 높은 개념들을 많이 사용하기 때문에 일반적으로 다른 언어에 비해서 더 짧게 작성된다. [3]

그리고 하스켈의 다른 특징으로는 '패턴 맞춤', '커링', '가드', '조건제시법', '연산자' 정의 등을 들 수 있다. 재귀 함수나 대수적 자료형도 지원되며, 느긋한 계산법 [4] 또한 하스켈의 특징으로 유명하다.

또한 단일체, 타입 클래스 등 역시 하스켈만의 독창적인 개념이며, 이러한 특징들은 절차적인 프로그래밍 언어에서 매우 힘들었던 함수 정의를 손쉽게 만들어버린다. 하스켈은 수학의 한 특이 분야인 범주론의 개념들, 특히 함수의 개념이 추상화된 형태인 사상과 모나드를 차용하여 가져온 언어인데, 이를 통해 함수를 대상으로 다룸에 있어 명확성을 가질 수 있다.

2002년을 기준으로 하스켈은 느긋한 계산법을 쓰는 함수형 언어 가운데 가장 활발한 연구가 이루어지는 언어였다. 언어의 변형도 몇 가지 개발되었다. 매사추세츠 공과대학교와 글래스고 대학교가 개발한 버전은 병렬화가 가능하기에 '병렬 하스켈'이라고 불렸다. 이후 병렬화와 분산 처리를 더욱 강화한 '분산 하스켈'과 에덴 프로그래밍 언어가 개발되었고, 느긋한 계산법 대신 적극적인 계산법을 활용한 '적극적 하스켈'이 있으며, 하스켈에 객체 지향 프로그래밍 개념을 도입한 버전으로 '하스켈++', '오하스켈', 몬드리안 프로그래밍 언어 등등이 있다.

다음은 하스켈과 다른 함수 프로그래밍 언어들의 특징을 한 표로 정리한 것이다.[5]

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

순수 함수형 언어

보통 순수 함수형 언어의 가장 큰 특징은 부수효과(Side Effect)가 없는 것이다. 여기서 부수효과란 같은 입력을 했는데도 출력이 달라지는 것을 말한다. 사실 이것은 함수형 언어보단 순수 선언형 언어의 특징에 가깝다. 함수형 언어는 순수 선언형 언어의 하위 카테고리라 볼 수 있다. 순수 함수형 언어에서 함수는 수학에서의 함수와 같아서 부수효과가 없는 것을 의미한다. 그리고 순수한 함수들로 구성된 프로그램은 부수효과가 없어 실행 순서의 영향에서 자유롭기 때문에 병행성을 가지기 좋다. 즉, 순수 함수형 언어에서 함수의 결과 값은 파라미터(parameter)로 넘겨진 입력값에 의해 결정된다. 하스켈은 System.IO.Unsafe 모듈의 unsafePerformIO 등을 제외하면 순수 함수형 언어로 규정할 수 있다.

느긋한 계산

느긋한 계산(Lazy Evaluation)은 계산이 필요한 순간까지 계산을 미루어 둔다는 의미이다. 따라서 그때 그때 필요한 만큼만 계산하는 것이 가능하다. 그리고 느긋한 계산법을 사용하는 프로그래밍 언어들은 '이름으로 호출'하거나 '필요할 때 호출'하는 계산 전략을 사용하는 나눌 수 있다. 대부분의 느긋한 언어들은 성능상의 이유로 '필요할 때 호출' 전략을 사용한다. 하스켈도 그런 전략을 사용하는 프로그래밍 언어 중 하나이다.

느긋한 계산법은 지연 계산법과 최소 계산법으로 나뉜다. 그 중 지연 계산법은 함수형 프로그래밍 언어에서 주로 사용한다. 지연 계산법을 사용하면 수식이 변수에 접근하는 순간 계산되는 것이 아니라, 강제로 계산값을 출력하라고 할 때까지 계산을 늦춘다. 언어 중에는 수식의 계산을 기본으로 늦추는 프로그래밍 언어도 있고 함수나 특별한 구문으로 계산을 늦추는 언어도 있다. 미란다와 하스켈은 기본으로 계산을 늦춘다.

이러한 느긋한 계산의 개념으로 인해 하스켈은 프로그램에 대한 무한의 개념을 쉽게 적용할 수 있다. 오히려 필요할 때 필요한 만큼 동적으로 리스트를 생성하므로 유연한 프로그래밍을 위해 필요한 경우에는 무한을 사용하는 쪽으로 권장된다.

장단점

장점

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

단점

표현력이 좋고, 코드가 간결하며, 알고리즘의 구현이 직관적이고, 부수효과가 없고, 동시성이 보장되는 등 많은 장점이 있지만 애초 함수형 언어란 일반적인 프로그래밍 언어와 체계가 달라서 쉽게 익숙해지기 어려우며, 사용하기 어려운 점이 많다. 그렇기 때문에 현실적으로 프로그래머들에게 인기가 없다. 함수형 언어 중에선 LISP가 비중이 커서 그에 밀리고, 자바와 호환되며 OOP도 지원하는 스칼라 역시 큰 인기를 얻고 있어서 하스켈은 이 둘에 비하면 경쟁력이 많이 떨어진다. 그 원인 중에서는 C언어 방식의 코딩이 불가능한 것도 있다. 그 결과 시도하는 사람 자체가 적으며 잘 아는 사람이 많지 않으니 사용 예가 적고, 사용 예가 적으니 배우려는 사람이 적다. 재귀코드를 짜는 것 역시 상당한 두뇌노동을 필요로 하며, 수리 논리학 전공으로 꽤 지식이 있어야 이해가 가능하다는 점 또한 단점이다.

적용

하스켈의 사용자 수는 상대적으로 적은 편이지만, 그 강력함 때문에 몇몇 프로젝트를 쉽게 해주었다. 퍼그스(Pugs)는 펄6의 컴파일러와 인터프리터를 구현한 것인데, 개발 기간은 지극히 짧았지만 만들어진 지 몇 달도 채 되지 않아 좋은 평가를 받았다.

영향받은 언어

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

영향 준 언어

개발 프로그램

  • 에이다  : 에이다IOHK에서 개발한 카르다노(Cardano) 플랫폼에서 사용하는 암호화폐이다. 이더리움에서 영감을 얻은 카르다노 팀은 스마트 계약 플랫폼을 만들기로 한다. 이를 위해 여러 연구를 한 결과 이들은 개발 언어로 하스켈 언어를 선택하여 처음부터 설계하였다. 하스켈은 함수형 언어로서 카르다노 백서에 제시된 수학적 표현을 완벽하게 설명하고 입증한다.
  • 린스파이어 : 린스파이어는 리눅스 배포판 데비안(Debian)을 기반으로 했던 상용 운영체제이다. 현재는 개발되지 않고 단절되었다. 시스템 도구 개발을 위한 언어로 하스켈을 선택하였다. [7]
  • xmonad : 엑스모니드(xmonad)는 하스켈로 작성하고 구성된 동적 타일링 윈도우 매니저이다. 엑스모나드는 창을 정렬하고 검색하는 데 걸리는 시간을 절반으로 줄여준다. 그리고 이를 자동화하여 더 쉽게 작업하게 만들어준다. [8]
  • Darcs : 다크스(Darcs)는 git , 머큐리얼(mercurial) 또는 svn과 같은 무료 오픈 소스 크로스 플랫폼 제어 시스템이다.[9] 또한 다크스는 하스켈 프로그램답게 지속적으로 퍼포먼스를 개선하는 등 구조와 디자인 면에서 많은 찬사를 받는 버전 컨트롤 시스템이다.
  • Pandoc : 팬닥(Darcs)은 문서 상호 변환 프로그램이자 라이브러리이다. 다목적 주머니칼로 유명한 스위스 군용 단검처럼 워드 프로세서, HTML, 페이지 레이아웃, 전자책, 슬라이드 쇼 등 다양한 포맷의 문서로 파일 변환이 가능하다. [10]
  • House : 하우스(House)는 하스켈로 만든 운영체제(OS)이다. 하우스는 높은 수준의 기능적 언어로 수준이 낮은 시스템 프로그래밍과 관련된 다양한 아이디어를 탐구하는 플랫폼 역할을 하도록 만들어졌다. [11] 또한 하우스는 함수형 언어로 시스템 프로그래밍을 하도록 지원한다.
  • Kinetic : 키네틱(Kinetic)은 하우스와 비슷한 운영체제(OS)이다. 미국 시애틀에서 사는 컴퓨터 과학자 팀 칼스텐스가 개발했다. 어셈블리, C++, 하스켈(GHC로 컴파일) 등을 조합하여 설계되었다. [12] 그러나 운용성이나 안정성은 하우스보다 떨어진다는 판단을 받았다.
  • Haxl: : Haxl페이스북에서 2015년에 공개한 오픈 소스 프로젝트로, 스팸 필터이다. 이 필터의 개발 책임자인 사이먼 말로우는 기존의 C++를 바탕으로 작업하던 FXL이라는 필터로는 전 세계에서 쏟아지는 스팸을 감당할 수 없어서 하스켈로 개발을 시작했다. 그의 말에 따르면 기능적이고 강하며, 자동으로 배치 및 오버랩 데이터가 패치되고, 코드 변경 사항을 빠르게 생산되며, 대화식 개발 지원을 하는 데 유용하기때문에 선택했다고 한다. 하스켈을 적용한 후 2~30% 정도 성능이 좋아졌고, 복잡한 문제일수록 더 빨리 처리하게 되었다. [13]
  • Semantics : 시맨틱스(Semantics)는 2019년 깃허브에서 개발한 소스코드 분석 프로그램이다. 이 프로젝트는 소스 코드의 분석 및 평가와 관련이 있는데, 다른 언어들은 실제 소스 분석 문제에 적용하는 데 많은 시간이 걸렸다. 그러나 하스켈은 언어 기능을 통해 데이트 구조와 알고리즘을 간경하고 정확하며 우아하게 표현할 수 있다. 깃허브는 하스켈을 통해 언어 구문 용어와 DIFF의 대수적 표현을 구성할 수 있었다. 그렇기 때문에 깃허브는 하스켈 언어로 이 프로젝트를 개발했다. [14]
  • 렉사 : 렉사(Lekcsah)는 하스켈 전용 IDE이다. 렉사는 하스켈 개발 프로세스를 실용적으로 이용하기 위해 만들어진 도구이다. 따라서 하스켈 언어로 작성되었고, Gtk 프로그래밍을 사용한다. 그리고 렉사는 리눅스(Linux)와 윈도우 및 운영체제에서 실행할 수 있다. 또한 렉사를 사용하기 위해선 글래스고 하스켈 컴파일러(GHC)가 필요하다. 렉사는 무료로 사용할 수 있으며, GNU 일반 공중 사용 허가서 2.0에 따라 배포된다. [15]

구현

  • 글래스고 하스켈 컴파일러는 하스켈 컴파일러(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. 하스켈의 특징(철학)〉, 《갈루야의 반서재》
  4. 토이팹, 〈느긋한 계산법〉, 《티스토리》, 2009-03-12
  5. 함수형 프로그래밍 언어 비교〉, 《하스켈 위키》
  6. 하스켈〉, 《하스켈위키》
  7. 린도우즈〉, 《나무위키》
  8. xmonad란 무엇입니까?〉, 《엑스모나드 공식 홈페이지》
  9. 다크스란 무엇인가?〉, 《다크스 공식 홈페이지》
  10. xmonad 팬닥-범용 문서 변환기〉, 《팬닥 공식 홈페이지》
  11. 하우스〉, 《하우스 공식 홈페이지》
  12. 키네틱〉, 《Integer Overflow》
  13. 하스켈로 벌인 스팸 전쟁〉, 《페이스북 엔지니어링 공식 홈페이지》, 2015-06-26
  14. 시맨틱스-왜 하스켈인가?〉, 《깃허브》, 2019-06-04
  15. 렉사〉, 《렉사 공식 홈페이지》

참고자료

같이 보기


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