"하스켈"의 두 판 사이의 차이
hayeon1006 (토론 | 기여) (→장단점) |
hayeon1006 (토론 | 기여) |
||
29번째 줄: | 29번째 줄: | ||
== 적용 == | == 적용 == | ||
하스켈의 사용자 수는 상대적으로 적은 편이지만, 그 강력함 때문에 몇몇 프로젝트를 쉽게 해주었다. [[퍼그스]](Pugs)는 펄6의 컴파일러와 [[인터프리터]]를 구현한 것인데, 개발 기간은 지극히 짧았지만 만들어진 지 몇 달도 채 되지 않아 좋은 평가를 받았다. [[서브버전]]과 비슷한 버전 관리 체계인 [[다크스]](Darcs)가 하스켈로 만들어졌으며, [[린스파이어]]는 시스템 도구 개발을 위한 언어로 하스켈을 선택하였다. | 하스켈의 사용자 수는 상대적으로 적은 편이지만, 그 강력함 때문에 몇몇 프로젝트를 쉽게 해주었다. [[퍼그스]](Pugs)는 펄6의 컴파일러와 [[인터프리터]]를 구현한 것인데, 개발 기간은 지극히 짧았지만 만들어진 지 몇 달도 채 되지 않아 좋은 평가를 받았다. [[서브버전]]과 비슷한 버전 관리 체계인 [[다크스]](Darcs)가 하스켈로 만들어졌으며, [[린스파이어]]는 시스템 도구 개발을 위한 언어로 하스켈을 선택하였다. | ||
+ | |||
+ | == 영향받은 언어 == | ||
+ | [[리스프]], 미란다, [[스킴]], [[APL]], [[ML]] | ||
+ | == 영향 준 언어 == | ||
+ | [[머큐리]], [[비주얼 베이직 닷넷]], [[파이썬]], [[F샤프]] | ||
== 구현 == | == 구현 == |
2019년 8월 20일 (화) 14:59 판
하스켈 또는 해스켈(Haskell)은 1985년에 개발된 순수 함수형 프로그래밍 언어이며, 논리학자 '해스켈 커리'(Haskell Brooks Curry)에서 따온 명칭이다.
목차
개요
하스켈은 지연계산(Lazy), 함수형(Functional), 정적 타입 지정(Statically Typed)의 프로그래밍 언어이다. 하스켈의 로고는 람다 대수에서의 'λ'와 모나드(monad)에 사용하는 bind 연산자인 '>>='를 겹쳐놓은 이미지다. 1980년대 프로그래밍 언어 연구자들이 만든 위원회에서 정의한 언어이며, 순수 함수형 프로그래밍 언어로 입·출력 같이 필요한 경우가 아니면 부작용이 없는 순수 함수로만 만들어졌다. 가장 많이 쓰이는 하스켈 컴파일러로는 GHC가 있으며, 여기에 패키지 매니저를 추가한 플랫폼이 스택(Stack)이다.
등장배경과 역사
1985년에 개발된 미란다가 하스켈의 전신이라고 할 수 있다. 1987년 오리건주 포틀랜드에서 열린 '함수형 프로그래밍 언어와 컴퓨터 구조에 관한 총회'(Functional Programming Languages and Computer Architecture, FPCA '87)에서 있었던 회의에서 난립하고 있는 함수형 언어들을 통합 정리하여 훗날 언어 설계의 기반이 될 수 있는 일반적인 순수 함수형 프로그래밍 언어를 만들자는 데에 참가자들의 뜻이 모였고 위원회가 발족되었다. 하스켈의 첫 버전인 '하스켈 1.0'은 1990년에 완성되었다. 위원회의 노력은 1997년 말까지 다양한 설계안으로 이어져 마침내 '하스켈 98'이라는 성과가 나왔다. 하스켈 98은 교육용이나 확장을 덧붙이는 토대로 사용할 수 있는 안정적이며, 작고 이식성 좋은 언어 표준을 의도한 결과물로써 표준 라이브러리가 포함되어 있었다. 또한 위원회는 하스켈 98의 확장 기능과 더불어서 하스켈 98에 실험적인 기능을 덧붙이거나 합친 변형이 만들어지는 것을 열렬히 환영하였다. 하스켈 98 언어 표준은 1999년 1월 '하스켈 98 보고서'(The Haskell 98 Report)라는 이름으로 정식 공개되었다. 2003년 1월에는 '하스켈 98 언어와 라이브러리: 개정 보고서'(Haskell 98 Language and Libraries: The Revised Report)라는 이름으로 개정판이 나왔다. 하스켈을 실제 컴퓨터에서 사용할 수 있도록 구현한 '글래스고 하스켈 컴파일러'와 '허그스'가 사실상의 표준 역할을 하면서 하스켈은 지금도 끊임없이 발전하고 있다. 2006년 초, 하스켈98 표준의 뒤를 이을 표준에 관한 논의가 시작되었다. 새로운 표준은 비공식적으로 '하스켈 프라임'이라는 이름으로 불렸으며, 2009년 11월 새로운 표준의 첫 번째 판인 하스켈 2010이 발표되었다. 하스켈 2010은 다른 프로그래밍 언어와 호환 가능한 인터페이스인 외부 함수 인터페이스를 지원하며, 일부 문법이 변경되었고, n+k 패턴이라 불리는 문법 형식이 금지되었다.
특징
하스켈의 특징으로는 '패턴 맞춤', '커링', '가드', '조건제시법', '연산자' 정의 등을 들 수 있다. 재귀 함수나 대수적 자료형도 지원되며, 느긋한 계산법 [1] 또한 하스켈의 특징으로 유명하다. 단일체, 타입 클래스 등은 하스켈만의 독창적인 개념이며, 이러한 특징들은 절차적인 프로그래밍 언어에서 매우 힘들었던 함수 정의를 손쉽게 만들어버린다. 수학의 한 특이 분야인 범주론의 개념들, 특히 함수의 개념이 추상화된 형태인 사상과 모나드를 차용하여 가져온 언어인데, 이를 통해 함수를 대상으로 다룸에 있어 명확성을 가질 수 있다. 2002년을 기준으로 하스켈은 느긋한 계산법을 쓰는 함수형 언어 가운데 가장 활발한 연구가 이루어지는 언어였다. 언어의 변형도 몇 가지 개발되었다. 매사추세츠 공과대학교와 글래스고 대학교가 개발한 버전은 병렬화가 가능하기에 '병렬 하스켈'이라고 불렸다. 이후 병렬화와 분산 처리를 더욱 강화한 '분산 하스켈'과 에덴 프로그래밍 언어가 개발되었고, 느긋한 계산법 대신 적극적인 계산법을 활용한 '적극적 하스켈'이 있으며, 하스켈에 객체 지향 프로그래밍 개념을 도입한 버전으로 '하스켈++', '오하스켈', 몬드리안 프로그래밍 언어 등등이 있다.
순수 함수형 언어
보통 순수 함수형 언어의 가장 큰 특징은 부수효과(Side Effect)가 없는 것이다. 하지만, 사실 이것은 함수형 언어보단 순수 선언형 언어의 특징에 가깝다. 함수형 언어는 순수 선언형 언어의 하위 카테고리라 볼 수 있다. 순수 함수형 언어에서 함수는 수학에서의 함수와 같아서 부수효과가 없는 것을 의미한다. 즉, 순수 함수형 언어에서 함수의 결과 값은 파라미터(parameter)로 넘겨진 입력값에 의해 결정된다. 여기서 말하는 부수효과란, 같은 입력임에도 불구 출력이 달라지는 것을 말한다.
느긋한 계산
느긋한 계산(Lazy Evaluation)은 계산이 필요한 순간까지 계산을 미루어 둔다는 의미이다. 따라서 그때 그때 필요한 만큼만 계산하는 것이 가능하다. 이 느긋한 계산의 개념으로 인해 하스켈은 프로그램에 대한 무한의 개념을 쉽게 적용할 수 있다. 오히려 필요할 때 필요한 만큼 동적으로 리스트를 생성하므로 유연한 프로그래밍을 위해 필요한 경우에는 무한을 사용하는 쪽으로 권장된다.
장단점
장점
- 프로그래밍 생산성이 실직적으로 향상
- 더 짧고 명확하여 유지 보수가 쉬운 코드
- 오류가 적으며 높은 신뢰성
- 프로그래머와 언어 사이의 작은 '의미상의 간격'(Semantic Gap)
- 더 짧은 리드 타임 [2]
단점
표현력이 좋고, 코드가 간결하며, 알고리즘의 구현이 직관적이고, 부수효과가 없고, 동시성이 보장되는 등 많은 장점이 있지만 애초 함수형 언어란 일반적인 프로그래밍 언어와 체계가 달라서 쉽게 익숙해지기 어려우며, 사용하기 어려운 점이 많다. 그 결과 시도하는 사람 자체가 적으며 잘 아는 사람이 많지 않으니 사용 예가 적고, 사용 예가 적으니 배우려는 사람이 적다. 재귀코드를 짜는 것 역시 상당한 두뇌노동을 필요로 하며, 수리 논리학 전공으로 꽤 지식이 있어야 이해가 가능하다는 점 또한 단점이다.
적용
하스켈의 사용자 수는 상대적으로 적은 편이지만, 그 강력함 때문에 몇몇 프로젝트를 쉽게 해주었다. 퍼그스(Pugs)는 펄6의 컴파일러와 인터프리터를 구현한 것인데, 개발 기간은 지극히 짧았지만 만들어진 지 몇 달도 채 되지 않아 좋은 평가를 받았다. 서브버전과 비슷한 버전 관리 체계인 다크스(Darcs)가 하스켈로 만들어졌으며, 린스파이어는 시스템 도구 개발을 위한 언어로 하스켈을 선택하였다.
영향받은 언어
영향 준 언어
머큐리, 비주얼 베이직 닷넷, 파이썬, F샤프
구현
예제
다음은 계승을 하스켈로 구현하는 몇 가지 방법이다.
fac 0 = 1 fac a = a * fac (a-1)
- if-then-else와 꼬리 순환을 이용한 방법
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]