가장 순수한 기능적 프로그래밍 언어? [닫은]


20

함수형 프로그래밍을 더 잘 배우고 싶습니다. 그렇게하려면 가장 순수한 함수형 프로그래밍 언어를 사용하도록 강요해야합니다. 따라서 나는 순결에 따라 기능적 프로그래밍 언어의 순서를 묻습니다.

Lisp 또는 Clojure (또는 Scheme 또는 Scala 등)를 배우는 것이 더 실용적이지만, 최근에 들었던 것에 대해 Haskell은 기능 프로그래밍 원칙을 누군가에게 가르치는 데있어서 매우 어렵습니다. 나는 이것에 대해 아직 확실하지 않기 때문에 당신에게 묻습니다 : 가장 순수한 기능적 프로그래밍 언어는 무엇입니까? 여러 사람이 가장 순수한 기능적 프로그래밍 언어의 웅장한 제목을 놓고 경쟁한다면 순서가 좋을 것입니다.


2
나는 대학에서 미란다 를 배웠기 때문에 편견에 시달렸지만, 불순물 의 산만 함없이 기능적 언어 에 빠져들 기를 원하는 사람에게 Haskel 을 제안 할 것이다 . * 8 ')
Mark Booth

2
함수형 프로그래밍 학습을 마친 후에는 표현형 시스템을 사용하여 정적으로 형식화 된 프로그래밍을 배워야합니다. 기능 카테고리와 유형 분류 카테고리에서 Coq> Haskell> OCaml> Scala> 기타를 제안합니다. Coq와 Haskell (Epigram 및 Agda와 같은) 사이에는 적합하지 않은 대안이 있습니다. Haskell은 OCaml의 표현 모듈 시스템을 그리워합니다.
lukstafi

답변:


28

기능적 언어의 순도를 평가할 척도는 없습니다. 언어가 부작용을 허용한다면 불순하고 그렇지 않으면 순수합니다. 이 정의에 따르면 Haskell, Mercury, Clean 등은 순수한 기능 언어입니다. Scala, Clojure, F #, OCaml 등은 불완전한 것들입니다.

편집 : 어쩌면 이것을 "언어가 타입 시스템에 알리지 않고 부작용 을 허용하지 않으면 순수합니다. 그렇지 않으면 불완전합니다."라고 말했을 것입니다.


6
확실하지 않음 : Haskell은 부작용 ( IO모나드)을 허용 합니다. 부작용을 일으키는 코드는 명확하게 표시되어 있습니다. 순수한 / 불순한 언어 를 말하는 것이 전혀 도움이되지 않는다고 생각합니다 (Haskell을 사용하여 프로그래밍 할 수 있습니다! Gasp!). /더러운.
Frank Shearar

8
@ 프랭크 : 그렇습니다. Haskell은 부작용을 허용하지만 부작용을 일으키는 코드를 표시하는 것 이상을 수행합니다. 또한 부작용을 유발하는 코드를 사용할 때에도 참조 투명성을 유지합니다. 그리고 그것이 많은 사람들의 순도에 대한 정의에 의해 순수한 것입니다. 물론 누락 된 faktor의 "no sidefects allowed"라는 정의와 일치하지 않습니다.
sepp2k

4
@Frank Shearar 그러나 IO모나드 순수 하기 때문에 이런 식으로 말하는 것이 유용합니다 . main함수가 기본적으로 거대한 상태 변환기 이기 때문에 코드가 아닌 런타임 라이브러리입니다 . ( main :: World -> World뒤에서 처럼 )
대안

1
내 언어도 참조 투명성이 있습니다. 방금 작성 program = "some C code"하면 런타임 환경이 C 코드를 처리합니다. :-)
Daniel Lubarov 2016 년

3
화면에 인쇄하는 것이 부작용이므로 진정으로 순수한 기능성 프로그램은 지루합니다.

15

학습은 목표이며 프로그램 자체는 작성 하지 않기 때문에 Lambda Calculus 보다 더 순수한 것을 얻을 수 없습니다 .

Lambda Calculus는 컴퓨터가 발명되기 전에있었습니다. 뺄셈을 수행하는 방법을 파악하기 위해 여러 숙련 된 논리학자가 작업했습니다 (한동안 더하기와 곱하기 만 가능하다는 이론이있었습니다).

부울과 숫자가 어떻게 보이는지 배우는 if것만으로도 탱크에 더 많은 가스를 넣지 않아도 탱크가 훨씬 커집니다.


물론 그보다 더 순수한 것은 없지만 우리는 수학 장벽을 약간 넘어 섭니다. 저는 여전히 기능을 익히면서 프로그래밍을 연습하고 새로운 언어를 배우고 싶습니다. 그러나 나는 기능적 패러다임의 기초를 더 잘 이해하고 더 큰 탱크를 가진 람다 미적분학을 연구하는 것이 흥미로울 수 있음에 동의합니다.
Joanis

2
증거를 작성하는 것은 프로그램을 작성하고 프로그램을 작성하는 것은 증거를 작성하는 것입니다. Curry-Howard isomorphism에 대해 배우면 만 라인 전에 수학 장벽을 통과했음을 알게 될 것입니다.
Macneil

1
의 간단한 표현은 없습니다 -1.
Daniel Lubarov 2016 년

2
@Mason Wheeler : λ- 계산만으로는 숫자 나 람다 추상화 외에 어떤 종류의 데이터도 없습니다. 달리 명시되지 않는 한, λ- 미적분학에서 숫자에 대해 이야기하는 사람은 아마도 자연 숫자에 대한 교회의 인코딩을 의미 할 것입니다 . 즉, 누군가 실제로 시도한 후에는 뺄셈을 알아내는 것이 매우 힘들었습니다 . 뺄셈이 가능하다는 추가와 지식의 정의만으로 오후에 스스로 해결했습니다.
CA McCann 2016 년

1
교회 숫자를 사용한 뺄셈은 사례별로 분해되면 쉽습니다. 음수를 지원하기 위해 전체 (유도 된) 미적분학을 작성하는 것이 더 많은 작업입니다.
Donal Fellows

6

불순한 언어는 원칙적으로 더 친숙한 명령형 언어와 크게 다르지 않으며, 특히 많은 기능적 트릭이 복사되었습니다. 다른 점은 스타일입니다. 문제를 해결하는 방법입니다.

Haskell을 순수한 것으로 계산하든 IO 모나드를 불순물로 계산하든 Haskell 스타일은이 스타일의 극단적 인 형태이며 학습 가치가 있습니다.

Haskell IO 모나드는 모나드의 수학 이론에서 비롯됩니다. 그러나 명령형 프로그래머의 경우 모나드에 역방향으로 도달하는 것이 더 합리적이라고 생각합니다.

1 단계-순수한 기능 언어는 결과로 큰 문자열 값을 쉽게 반환 할 수 있습니다. 이 큰 문자열은 요구 사항 지정 매개 변수에서 순수한 기능 방식으로 파생 된 명령형 프로그램의 소스 코드 일 수 있습니다. 그런 다음 코드 생성기를 실행하는 "상위 레벨"컴파일러를 빌드 한 다음 생성 된 코드를 명령형 언어 컴파일러에 자동으로 공급할 수 있습니다.

2 단계-텍스트 소스 코드를 생성하지 않고 강력한 형식의 추상 구문 트리를 생성합니다. 명령형 언어 컴파일러는 "상위 레벨"컴파일러에 흡수되어 AST를 소스 코드로 직접 허용합니다. 이것은 Haskell이하는 일에 훨씬 가깝습니다.

그래도 여전히 어색합니다. 예를 들어, 코드 생성 단계에서 평가 된 기능과 생성 된 프로그램이 실행될 때 실행되는 두 가지 고유 한 기능이 있습니다. C ++에서 함수와 템플릿을 구별하는 것과 약간 비슷합니다.

따라서 3 단계의 경우 두 코드를 동일하게 만듭니다. 동일한 코드를 가진 동일한 함수는 "코드 생성"중에 부분적으로 평가되거나 완전히 평가되거나 전혀 평가되지 않을 수 있습니다. 또한 재귀를 위해 모든 루핑 구성 AST 노드를 삭제하십시오. 실제로, AST 노드에 대한 아이디어를 특별한 종류의 데이터로 버리십시오. "리터럴 값"AST 노드는없고 값만 있습니다.

이것은 IO 모나드가하는 것과 거의 같습니다. 바인드 연산자는 "동작"을 구성하여 프로그램을 형성하는 방법입니다. 특별한 것은 아닙니다-단지 기능입니다. "코드 생성"중에 많은 표현식과 함수를 평가할 수 있지만 I / O 부작용에 의존하는 함수는 런타임까지 평가가 지연되어야합니다. 특별한 규칙이 아니라 데이터 종속성의 자연스러운 결과입니다. 표현.

모나드는 일반적으로 일반화입니다. 인터페이스는 동일하지만 추상 연산을 다르게 구현하므로 명령형 코드에 대한 설명을 평가하는 대신 다른 것으로 평가합니다. 동일한 인터페이스를 사용한다는 것은 어떤 모나드를 신경 쓰지 않고 모나드에 할 수있는 일이 있다는 것을 의미합니다.

이 설명은 의심의 여지없이 순수 주의자들의 머리를 폭발시킬 것이지만 나에게 Haskell이 흥미로운 이유를 설명해줍니다. 프로그래밍과 메타 프로그래밍 사이의 경계를 흐리게하고 기능 프로그래밍 도구를 사용하여 특별한 구문없이 명령형 프로그래밍을 재창조합니다.

C ++ 템플릿에 대한 비판은 그것들이 명령형 언어로 깨진 순수한 기능 하위 언어라는 것입니다. 런타임이 아닌 컴파일 타임에 동일한 기본 기능을 평가하려면 완전히 다른 스타일을 사용하여 다시 구현해야합니다 코딩 Haskell에서, 불순물은 그 유형으로 라벨링되어야하지만, 동일한 프로그램에서 메타 프로그래밍 의미와 런타임 비 메타 프로그래밍 의미로 정확하게 동일한 기능이 평가 될 수 있습니다. 프로그래밍과 메타 프로그래밍 사이.

즉, 표준 Haskell이 수행 할 수없는 메타 프로그래밍 작업이 있습니다. 기본적으로 유형 (및 기타 몇 가지)이 일류 값이 아니기 때문입니다. 그러나이 문제를 해결하려는 언어 변형이 있습니다.

Haskell에 대해 말한 많은 것들이 불완전한 기능적 언어, 때로는 명령형 언어로 적용될 수 있습니다. Haskell은 선택의 여지가 없기 때문에 다릅니다.이 접근법을 취해야합니다. 기본적 으로이 작업 스타일을 배우도록 강요합니다. "ML로 C를 쓸 수는 있지만" "하스켈에 C를 쓸 수는 없습니다".


고맙습니다! C ++ 템플릿의 일반성이 함수 자체로 통합 될 수 있는지 궁금합니다. Haskell이이 작업을 수행하는 것처럼 보이지만 중요한 부분은 컴파일 타임 동안 템플릿에서 일반 함수를 생성하는 동일한 엔진이 런타임 동안이를 평가할 수 있도록 컴파일 된 언어 로 구현할 수 있는지 여부입니다 .
Milind R

5

나는 개인적으로 세 가지 기능 순도의 언어로 언어를 분류합니다.

  • 순수 함수형 언어 - 단독 런타임과의 상호 작용을 통해 순수한 기능과 핸들 가변성로 전체 프로그램을 취급하는 즉, 사람들은 - 하스켈은 아마 정규 예입니다

  • 기능적 언어 즉, 기능적 스타일을 강조하지만 부작용은 허용하는 언어를 불완전하게합니다 . Clojure의가 이 범주에 명확하게, 또한 (그것의 STM 프레임 워크의 한 부분으로 제어 방식으로 돌연변이를 할 수 있습니다) 를 OCaml 또는 F #

  • 다중 패러다임 언어 -이것들은 가장 먼저 기능적 언어는 아니지만 일급 함수 등을 사용하여 기능적 스타일을 지원할 수 있습니다. 스칼라 는 여기에 좋은 예 입니다.이 범주 에 Common Lisp 도 넣었습니다. JavaScript 와 같은 언어 .

귀하의 상황에서는 먼저 Haskell을 배우고 Clojure를 배우는 것이 좋습니다. 이것은 내가 한 일이며 그것은 나를 위해 아주 잘 작동했습니다! Haskell은 아름답고 가장 순수한 기능적 원리를 가르쳐줍니다. Clojure는 훨씬 실용적이며 여전히 많은 기능을 수행하면서도 많은 기능을 수행 할 수 있도록 도와줍니다.

나는 실제로 세 번째 범주를 기능적 언어로 계산하지 않습니다 (하스켈과 클로저를 배우고 나면 기능 기술을 사용할 때 종종 자신을 발견합니다!)


매우 엄격한 제한 내에서 C조차도 기능적 기능을 가지고 있습니다. (주요 제한은 너무 많은 그래서 대부분의 사람들은 할 수없는 주장 것으로, C에서 정말 끔찍한입니다 기능의 런타임 합성에 있습니다.)
DONAL 휄로우

2
@Donal Fellows : 간결함이 무한대로됨에 따라 모든 Turing-complete 언어는 작동합니다. 언어로 Lisp 인터프리터를 구현 한 다음 사용하면됩니다. :]
CA McCann 2016 년

모든 것이 튜링이 완료되어 다른 모든 것을 에뮬레이트 할 수 있다는 관점을 취하면 패러다임은 의미가 없습니다. 패러다임에 대해 생각할 때 언어가 관용어를 만드는 것과 그것을 방해하거나 예방하는 것에 중점을 두어야합니다. 필자의 관점에서 기능적 언어로 계산하려면 돌연변이와 부작용이 일관적인 (FP 불순의 경우) 또는 금지 (순수한 FP의 경우) 여야합니다. 이는 C가 작동하지 않음을 의미합니다. 스칼라와 같은 다중 패러다임 언어도 아닙니다.
mikera

@mikera : 나는 당신의 대답은 매우 흥미 : 스칼라가 작동 안하지만 경우 에만 멀티 패러다임, 당신은 어떻게 기능 프로그래밍 ++ 11 C, C #, 또는 심지어 자바 (람다의 계획 소개)의 기능을 판단합니까?
Giorgio

@Giorgio : 당신이 언급 한 모든 언어의 기능적 특징은 아마도 좋은 생각이라고 생각합니다. 그것들은 단지 그것들을 "기능적 언어"로 만들지 않습니다. 또는 반대 방향에서 볼 때, 명령형 monadic IO를 할 수 있다는 사실은 Haskell을 명령형 언어로 만들지 않습니다 :-). 다중 패러다임 언어는 기본적으로 많은 다른 패러다임의 기능을 하나로 모으고 특정 스타일을 최우선으로 생각하지 않는 결과입니다. IMHO C ++, C # 및 Java는 모두 다중 패러다임으로 이동하고 있지만 클래스 기반 OOP가 여전히 지배적이므로 아직 그리 멀지 않습니다.
mikera

3

순수한 기능 언어가 순수한 기능 (부작용이없는 루틴) 만있는 경우 입력을 읽거나 출력을 쓸 수 없으므로 약간 의미가 없습니다.)

이건 정말 학습이기 때문에, 나는 분리가 반드시 아니라고 생각 갈 방법입니다. 함수형 프로그래밍은 패러다임입니다. 어떤 패러다임이 어떤 문제에 적합한 지, 더 중요하게는 어떻게 가장 잘 조합 될 수 있는지 이해하는 것이 중요합니다.

프로그래밍 패션은 어리 석고 역효과를 낳습니다. 중요한 것은 프로그램이 짧고 작성하기 쉽고 유지 관리가 쉽고 올바르게 작동한다는 것입니다. 이를 달성하는 방법은 프로그래밍 유행과 아무 관련이 없습니다. - 리차드 존스

그 외에, "순도"를 찾고 있다면 Pure를 보고 싶을 것이다 . 그러나 C 루틴을 호출하는 것이 매우 쉬워 기능적으로 불완전합니다 (그러나 매우 강력 함).


3

완전히 심각한 답변은 아니지만 Unlambda 는 경쟁자 여야합니다. SKI 결합기보다 더 "순수한 기능"을 얻을 수 없습니다.


4
광기! 이교! 부작용이있는 조합 자와 같은 부조리가있는 순수한 언어에는 어떤 것이 있습니까? 아니 아니. 여기서 정말로 원하는 것은 Lazy K 입니다.
CA McCann 2016 년

2

Erlang, Haskell, Scheme, Scala, Clojure 및 F #

이 질문은 아마 가장 당신은 검색에서와 같이 도움이 될 .


감사합니다. 흥미로운 질문입니다. PLT-Scheme / Racket으로 시작했지만 SICP는 아직 보지 못했습니다 ... Real World Haskell은 저에게도 흥미로워 보입니다.
Joanis

체계는 기능적인 스타일을 권장하지만 set!다른 것들도 있습니다 ...
Daniel Lubarov

내가 가장 좋아하는 OCaml을 추천합니다. 그리고 그것은 Haskell과 F #이 놓친 모듈 시스템을 가지고 있습니다.
lukstafi

@lukstafi는 지난 3 년 동안 haskell이 바뀌었을 수도 있지만 (난 미친 것처럼 자랐습니다) haskell에는 분명히 모듈이 있습니다.
sara

@kai 모듈 시스템이란 다른 모듈 (모듈의 람다 미적분)에 의해 매개 변수화 된 모듈을 의미했습니다.
lukstafi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.