생성기와 람다를 사용하여 Python으로 함수형 프로그래밍을 수행 할 수 있습니다. 루비에서도 같은 결과를 얻을 수 있습니다.
문제는 왜 Erlang, Haskell, Scheme과 같은 특정 기능 프로그래밍 언어가 필요한가? 이 특정 기능 프로그래밍 언어가 제공하는 것과 다른 점이 있습니까? 함수형 프로그래밍에 파이썬을 사용할 수없는 이유는 무엇입니까?
생성기와 람다를 사용하여 Python으로 함수형 프로그래밍을 수행 할 수 있습니다. 루비에서도 같은 결과를 얻을 수 있습니다.
문제는 왜 Erlang, Haskell, Scheme과 같은 특정 기능 프로그래밍 언어가 필요한가? 이 특정 기능 프로그래밍 언어가 제공하는 것과 다른 점이 있습니까? 함수형 프로그래밍에 파이썬을 사용할 수없는 이유는 무엇입니까?
답변:
개인적으로 파이썬과 기능적 스타일의 프로그래밍 모두에 대한 열렬한 팬이기 때문에 질문에 감사드립니다. 저는 Python에 대한 오랜 경력을 가지고 있으며 최근 Haskell을 배우기 시작했습니다. 따라서 기능적 관점에서 이러한 언어 간의 차이점에 대한 개인적인 경험을 바탕으로 한 몇 가지 사항이 있습니다.
청정
기능의 순도 (예 : 부작용 없음)에 대해 신경 쓰지 않아도 코드를 읽는 것이 얼마나 쉬운 지, 그에 대한 추론에 실질적인 영향을 미칩니다. 자신의 파이썬 함수에서 순도를 유지하더라도 컴파일러가 순도를 시행하고, 순도 및 불변의 데이터 구조 측면에서 표준 라이브러리를 구축하는 데 큰 차이가 있습니다.
공연
응용 프로그램 도메인에 따라 성능에 신경 쓰거나 신경 쓰지 않을 수도 있지만 정적 타이핑 및 순도 보장은 컴파일러를 파이썬 및 기타 동적 언어와 비교하여 더 많은 작업을 제공합니다 (PyPy가 훌륭하다는 것을 인정해야하지만) 예를 들어 LuaJIT는 기적적으로 접하고 있습니다).
테일 콜 최적화
성능과 관련이 있지만 약간 다릅니다. 런타임 성능에 신경 쓰지 않아도 테일 콜 최적화 (특히 테일 재귀)를 사용하지 않으면 스택 제한에 도달하지 않고 Python에서 알고리즘을 구현할 수있는 방법이 제한됩니다.
통사론
이것이 바로 함수형 스타일로 파이썬을 사용하는 대신 "실제"기능 언어를보기 시작한 가장 큰 이유입니다. 파이썬은 일반적으로 표현력이 매우 뛰어나다 고 생각하지만 기능적 코딩과 관련된 약점이 있습니다. 예를 들면 다음과 같습니다.
f = g . h
vs.f = lambda *arg: g(h(*arg))
f = map g
vs.f = functools.partial(map, g)
sum = reduce (+) lst
대sum = reduce(operator.add, lst)
y = func1 $ func2 $ func3 x
보다 읽기 쉽습니다 y = func1(func2(func3(x)))
.가장 중요한 차이점은 다음과 같습니다.
하스켈
하스켈과 얼랑
에를 랑
계획
모든 언어
또한 ML과 기능 프로그래밍을 새로운 방식으로 융합하는 SML, Ocaml 및 F # 및 Scala와 같은 ML 제품군의 언어를 살펴 봐야합니다. 이 모든 언어에는 고유하고 흥미로운 기능이 있습니다.
나열한 언어 중에서 "기능적 언어"가 무엇인지 정확히 정의하기는 어렵습니다. Haskell 만 순전히 기능적입니다 (다른 모든 것들은 일종의 하이브리드 방식을 채택합니다). 함수형 프로그래밍에 매우 유용한 특정 언어 기능이 있지만 Ruby와 Python에는 FP를위한 매우 좋은 환경이 될 수 없습니다. 중요한 순서대로 내 개인 체크리스트는 다음과 같습니다.
(1)의 필요성은 명백해야합니다. 일류 함수가 없으면 고차 함수는 극히 어렵습니다. 사람들이 루비와 파이썬이 FP를위한 좋은 언어라고 이야기 할 때, 그들은 보통 이것에 대해 이야기하고 있습니다. 그러나이 특정 기능이 필요하지만 FP에 적합한 언어를 만들기에는 충분하지 않습니다.
(2) Scheme이 발명 된 이래 FP는 전통적으로 필요했습니다. TCO가 없으면 스택 오버플로가 발생하기 때문에 FP의 초석 중 하나 인 깊은 재귀로 프로그래밍 할 수 없습니다. 이것을 갖지 않는 유일한 "기능적"(일반적으로 정의 된) 언어는 Clojure (JVM의 제한 때문에)이지만 Clojure는 TCO를 시뮬레이션하기위한 다양한 핵을 가지고 있습니다. 참고로, Ruby TCO는 구현별로 다르지만 Python 에서는이를 지원하지 않습니다 . TCO가 보장되어야하는 이유는 구현별로 깊은 재귀 함수가 일부 구현에서 중단되므로 실제로는이를 수행 할 수 없기 때문입니다. 전혀 사용하지 마십시오.
(3)은 현대의 기능적 언어 (특히 Haskell, Erlang, Clojure 및 Scala)가 루비와 파이썬이 가지고 있지 않은 또 다른 큰 것입니다. 너무 자세하게 설명하지 않으면 서, 불변성이 보장되면 특히 동시 상황에서 모든 종류의 버그가 제거되고 지속적인 데이터 구조 와 같은 깔끔한 것들이 가능해 집니다. 언어 수준의 지원 없이는 이러한 이점을 활용하기가 매우 어렵습니다.
(4)는 순수 기능 언어 (하이브리드 언어와 반대)에 관해 가장 흥미로운 것입니다. 다음과 같은 매우 간단한 Ruby 함수를 고려하십시오.
def add(a, b)
a + b
end
이것은 순수한 기능처럼 보이지만 작업자 과부하로 인해 매개 변수를 변경하거나 콘솔에 인쇄하는 등의 부작용을 일으킬 수 있습니다. 누군가가 +
운영자에게 과부하를 가하여 부작용을 일으킬 가능성은 낮지 만 언어는 보장하지 않습니다. (이 특정 예제에서는 그렇지 않지만 Python에도 동일하게 적용됩니다.)
반면 순수하게 기능적인 언어에서는 기능이 참조 적으로 투명하다는 언어 수준의 보장이 있습니다. 이것은 많은 장점을 가지고 있습니다 : 순수한 기능은 쉽게 기억 될 수 있습니다; 어떤 종류의 전역 상태에 의존하지 않고 쉽게 테스트 할 수 있습니다. 그리고 함수 내의 값은 동시성 문제에 대해 걱정하지 않고 느리게 또는 병렬로 평가할 수 있습니다. Haskell은 이것을 최대한 활용하지만 다른 기능 언어에 대해서는 잘 모릅니다.
모든 말로, 거의 모든 언어 (Java까지)에서 FP 기술을 사용할 수 있습니다. 예를 들어 Google의 MapReduce 는 기능적인 아이디어에서 영감을 얻었지만 큰 프로젝트에 "기능적"언어를 사용하지 않는 한 (주로 C ++, Java 및 Python을 사용한다고 생각합니다).
언급 한 언어는 매우 다릅니다.
Python과 Ruby는 동적으로 입력되는 언어이지만 Haskell은 정적으로 입력됩니다. Erlang은 동시 언어이며 액터 모델을 사용하며 언급 한 다른 모든 언어와는 매우 다릅니다.
파이썬과 루비에는 많은 명령 구조가 있지만 Haskell과 같은 더 순수한 기능 언어에서는 모든 것이 무언가를 반환합니다. 즉, 모든 것이 함수입니다.
평소와 같이 파티에 늦었지만 어쨌든 말할 것입니다.
함수형 프로그래밍 언어는 함수형 프로그래밍을 허용 하는 언어가 아닙니다 . 우리가 그 정의에 따라 가면, 거의 모든 언어가 기능적 프로그래밍 언어입니다. (동시에 OOP에도 동일하게 적용됩니다. 원하는 경우 C에서 OOP 스타일로 작성할 수 있습니다. 따라서 논리에 따라 C는 OOP 언어입니다.)
함수형 프로그래밍 언어를 만드는 것은 프로그래밍을 허용 하는 것이 아니라 쉽게 프로그래밍 할 수있게하는 것 입니다. 이것이 핵심입니다.
따라서 파이썬에는 람다 (놀랍게도 빈약 한 폐쇄와 같은 사건)가 있으며 "map"및 "fold"와 같이 기능 라이브러리에서 볼 수있는 몇 가지 라이브러리 함수를 제공합니다. 그러나 함수형 프로그래밍 언어로 만들기에는 충분하지 않습니다. 적절한 함수형 스타일 로 일관되게 프로그래밍하기가 어렵 기 때문입니다 (언어가 확실히이 스타일을 강요하지는 않습니다!). 핵심 파이썬은 상태 및 상태 조작 연산과 관련된 명령형 언어이며 이는 단순히 기능 언어의 표현 및 표현 평가 의미와 상충됩니다.
파이썬 (또는 루비 (또는 원하는 언어를 삽입))이 "기능적 프로그래밍"을 할 수있을 때 왜 기능적 프로그래밍 언어를 사용합니까? 파이썬 등은 적절한 함수형 프로그래밍을 할 수 없기 때문입니다. 그 이유입니다.
Java로 기능 프로그래밍을 수행 할 수 있습니다 (예 : http://functionaljava.org/ 참조 ). C에서 객체 지향 프로그래밍을 수행 할 수도 있습니다 . 그것은 관용적이지 않습니다.
따라서 Erlang, Haskell, Scheme 또는 특정 프로그래밍 언어가 절대적으로 필요 하지는 않지만 , 각각 다른 접근 방식과 다른 절충점을 나타내므로 일부 작업을 쉽고 어렵게 만듭니다. 사용해야 할 것은 달성하려는 것에 달려 있습니다.
이 질문은 무한한 언어와 패러다임에 적용될 수 있습니다.
대부분의 언어가 특정 이유로 존재하는 것은 아닙니다. 그것들은 누군가 현재 언어를 채우지 않거나 빈약하게 채울 필요가 없기 때문에 존재합니다. (물론 이것은 모든 언어에 적용되는 것은 아니지만 잘 알려진 대부분의 언어에 적용된다고 생각합니다.) 예를 들어, 파이썬은 원래 Amoeba OS [ 1 , 2 ]와 인터페이스하기 위해 개발 되었으며 Erlang은 전화 응용 프로그램의 개발에서 [ 3 ]. "왜 다른 기능적 언어가 필요한가?"라는 질문에 대한 답변 [insert-name-of-someone-who-know-how-to-design-languages]는 파이썬이하는 방식을 좋아하지 않았기 때문에 간단 할 수 있습니다.
그것은 내가 생각하는 답을 요약합니다. 함수형 언어로 할 수있는 파이썬으로 무엇이든 할 수 있지만 정말로하고 싶습니까? C에서 할 수있는 모든 일, 어셈블리에서 할 수있는 일을 원하십니까? 다른 언어는 항상 다른 일을하는 데 가장 좋을 것이며, 그렇게해야합니다.
함수형 프로그래밍은 특정 언어 기능과 마찬가지로 디자인 패러다임에 관한 것입니다. 또는 달리 말하면, 람다와 맵 함수는 함수형 프로그래밍 언어가 아닙니다. 파이썬과 루비는 함수형 프로그래밍 언어에서 영감을 얻은 일부 기능을 가지고 있지만 일반적으로 매우 필수적인 방식으로 코드를 작성합니다. (C와 비슷합니다. C로 OO와 유사한 코드를 작성할 수 있지만 C를 OO 언어로 진지하게 고려하는 사람은 없습니다.)
살펴보기 : 함수형 프로그래밍은 단순한 람다 map
또는 고차 함수가 아닙니다 . 디자인 에 관한 것 입니다 . "진정한"기능 프로그래밍 언어로 작성된 프로그램은 기능 구성을 통해 문제를 해결합니다. Ruby 또는 Python으로 작성된 프로그램은 FP와 유사한 기능을 사용할 수 있지만 일반적으로 구성된 기능 세트처럼 읽지는 않습니다.
lambda-calculus, LISP 및 Scheme에서 사용 가능한 모든 개념은 Python에서 사용할 수 있으므로 기능 프로그래밍을 수행 할 수 있습니다. 편리하거나 그렇지 않은 경우 상황과 취향의 문제입니다.
파이썬 (Ruby, Scala)으로 LISP (또는 다른 기능적 언어) 인터프리터를 쉽게 작성할 수 있습니다 (무엇을 의미합니까?). 순수한 기능을 사용하여 Python에 대한 인터프리터를 작성할 수 있지만 많은 작업이 필요합니다. 오늘날 "기능적" 언어 조차도 다중 패러다임입니다.
이 낡고 아름다운 책 은 함수형 프로그래밍의 본질이 무엇인지에 대한 답을 대부분은 아니지만 대부분 가지고 있습니다.
eval()
함수를 제공 하지만 더 나아가 LISP에서와 같이 대부분의 런타임 환경을 수정할 수 있습니다.
eval()
는 런타임 메타 프로그래밍입니다. 때로는 유용하지만 매우 비쌉니다. Lisp 매크로는 다릅니다. 컴파일 시간 메타 프로그래밍입니다. 파이썬에서는 어떤 형태로든 사용할 수 없습니다.
파이썬은 또한 비 기능적인 스타일로 프로그래밍 할 수 있기 때문에 FP 순수 주의자에게는 충분하지 않습니다. 그러나 실용적인 실용적인 코더는 기능적인 스타일의 이점을 독단적으로 즐기지 않아도됩니다.
“기능적 프로그래머는 중세 스님처럼 들리며, 자신을 덕으로 만들 겠다는 희망으로 인생의 즐거움을 거부합니다. 물질적 이점에 더 관심이있는 사람들에게는 이러한“장점”이 설득력이 없습니다. 기능적인 프로그래머들은 큰 물질적 이점이 있다고 주장하지만… 할당 문을 생략하면 엄청난 이점이 생기면 FORTRAN 프로그래머는 20 년 동안 그렇게했을 것입니다. 아무리 나쁜 기능이라도 기능을 생략하여 언어를 더 강력하게 만드는 것은 논리적으로 불가능합니다.”
-John Hughes, 함수형 프로그래밍이 중요한 이유
goto
는 끔찍합니다.
call-with-current-continuation
.