함수형 프로그래밍에 대한 현재의 열정이 필요한 이유 [닫은]


50

최근 스칼라, 클로저 및 F #과 관련하여 함수형 프로그래밍 언어에 대한 많은 열의가 있습니다. 저는 최근 FP 패러다임을 배우기 위해 Haskell을 공부하기 시작했습니다.

나는 그것을 좋아하고, 정말 재미 있고, 수학 배경에 적합합니다.

하지만 정말 중요한가요? 분명히 새로운 아이디어는 아닙니다.

내 질문은 다음과 같습니다.

  1. 최근의 FP 열정에 무엇이 기여 했습니까? OO를 사용하는 것이 지루합니까?
  2. 이것이 FP 미래를 나타내는 것입니까? 아니면 이것이 객체 지향 데이터베이스와 같은 유행입니까?

다시 말해서, 이것이 어디에서 왔으며 어디로 갈지 이해하는 사람이 있습니까?



13
복제본이 아닙니다. 이것은 새로운 아이디어가 아니기 때문에 사람들이 갑자기 소란을 일으키는 이유를 묻습니다 (물론 차이가 더 큰 질문이지만).
피터 Boughton

2
사람들이 최근에 FP를 소란스럽게 만들고 있습니까? 나에게 뉴스, 나는 이것이 항상 일부 그룹이 FP가 명령형 프로그래밍 세계를 어떻게 장악 할 것인지에 대해 소란을 피우고 있다고 생각했다.
Chris

1
이전에 StackOverflow 에서이 질문 에 대답했다고 생각 합니다.
Ken Bloom

1
예-FP는 이미 늙었습니다. 1989 년에 Scheme을 컬럼비아에서 학부로 사용했을 때 생각합니다. 그것은 제가 생각하는 반짝이는 새로운 것입니다.
Tim

답변:


33

관심있는 "폭발"을 초래 한 FP의 주요 혁신 중 하나는 모나드입니다.

1992 년 1 월, 필립와 들러 (Philip Wadler)는 IO를 다루는 방법으로 모나드를 기능적 프로그래밍에 도입 한 기능적 프로그래밍의 정수라는 논문을 썼습니다 .

순수하고 게으른 함수형 프로그래밍 언어의 주요 문제는 IO를 다루는 유틸리티였습니다. 게으름과 부작용은 실제적인 관점에서 호환되지 않기 때문에 프로그래밍에서 "어색한 분대"의 구성원 중 하나입니다. 게으른 언어를 사용하려면 순전히 기능적인 언어 여야합니다. 부작용을 사용하려면 엄격한 언어를 사용하는 것이 좋습니다. " 참고

모나드 이전의 IO 문제는 실제로 유용한 프로그램에서 순도를 유지할 수 없다는 점이었습니다. IO는 사용자 또는 환경으로부터의 입력 및 출력을 포함하여 상태 변경을 처리하는 모든 것을 의미합니다. 순수 기능 프로그래밍에서는 게으름과 순도 (부작용이 없음)를 허용하기 위해 모든 것이 불변입니다.

모나드는 IO의 문제를 어떻게 해결합니까? 글쎄, 모나드에 대해 너무 많이 이야기하지 않고 기본적으로 모나드에 대한 입력으로 "월드"(런타임 환경)를 가져 와서 출력으로 새로운 "월드"를 생성하고 결과 : type IO a = World-> (a, 세계).

따라서 가장 큰 문제인 IO (및 기타)가 해결되었으므로 FP는 점점 더 주류로 진입했습니다. 아시다시피 기존 OO 언어로의 통합도 이루어졌습니다. LINQ는 예를 들어 스루 및 스루 모나드입니다.

자세한 내용은 모나드 및 답변에서 참조되는 논문을 읽어 보는 것이 좋습니다.


매우 유익한 정보입니다. 감사합니다. 이 답변이 옳고 다른 사람들이 잘못했기 때문에가 아니라 (여러 개를 올렸습니다) 그 결과 가시성을 얻을 가치가 있다고 생각하기 때문에이 답변을 수락합니다.
Eric Wilson

더 적절한 예는 type IO a = UI -> (a, UI)환상적인 답변입니다.
ChaosPandion

@Richard : "type IO a = World-> (a, World)"는 거의 너무 좋아서 사실이 아닙니다 (나는 절대 모나드를 얻지 못할 것이라고 생각했습니다). LINQ를 모나드에 비유 한 것 같습니다. 람다를 LINQ 연산자에 전달하면 람다는 전체 환경을 "인식"하기 때문입니다.
Stefan Monov

@ 스테판 (Stefan) : 람다는 그것이 환경이라는 것을 알기에는 다소 정확한 것처럼 들리지만 100 % 명확하지 않기 때문에 더 배울 때까지 대답하는 것을 망설입니다. 그러나 LINQ는 모나드라고 100 % 확신 할 수 있습니다. 제작자가 여러 차례 그렇게 말했기 때문입니다. SelectMany는 Haskell의 바인드와 정확히 동일합니다. "Monads of Monads"( blogs.msdn.com/b/wesdyer/archive/2008/01/11/… )를 읽지 않았다면 LINQ가 실제로 모나드 ( monad ) 인 방법을 알 수 있습니다. 건배.
Richard Anthony Hein

1
@Job, 위 의견에서 언급 된대로 blogs.msdn.com/b/wesdyer/archive/2008/01/11/… 를 참조 하십시오 .
Richard Anthony Hein

30

어셈블러 등 C, 자바, C #을, 같은 기존의 프로그래밍 언어를 할 때 큰 문제 중 하나는 어색한해야한다는 것입니다 순서 는 먼저 모든 종속성을 준비했습니다해야하기 때문에 주어진 작업을 수행하기 위해 수행해야 할 단계 및 이전에 THEIR 종속성

예 : A를 수행하려면 B와 C가 있어야하고 B는 D와 E에 의존하므로 다음과 같은 결과가 나타납니다.

  • 이자형
  • 에이

재료를 사용하기 전에 준비해야하기 때문입니다.

기능적 언어, 특히 게으른 언어는 이것을 거꾸로 뒤집습니다. A에게 B와 C가 필요하다고 말하고 A와 평가에 필요할 때 평가되는 B와 C를 얻을 수있는 언어 런타임 (D와 E가 필요할 때)을 알아낼 수있게하여 매우 작고 간결하게 만들 수 있습니다. 작고 간결한 프로그램을 만드는 빌딩 블록. 게으른 언어는 또한 실제로 사용 된 요소 만 계산되므로 전체 목록을 메모리에 저장하지 않고도 무한 목록을 사용할 수 있습니다.

정말 좋은 요령은,이 자동 "오, 나는 B와 C가 필요하다"메커니즘은 순차 프로그램에서와 같이이 평가가 언제 어디서 일어날 수 있는지에 대한 제한이 없기 때문에 확장 가능 하다는 것이다. 다른 프로세서 나 컴퓨터에서도 동시에 사용할 수 있습니다.

그건 함수형 언어가 흥미로운 이유입니다 - 때문에 수동으로 할 필요 프로그래머 반대로기구는 런타임 시스템에 의해 점령된다 "때 무엇을해야하는지". 이는 자동 가비지 콜렉션이 Java에서 C에 대한 것과의 차이점이며, C에서보다 Java에서 강력하고 확장 가능한 다중 스레드 소프트웨어를 작성하는 것이 더 쉬운 주요 이유 중 하나입니다. 기능적 언어로 확장 가능한 멀티 스레드 소프트웨어 ...


3
물론 이것은 1950 년에도 마찬가지였습니다.
Eric Wilson

1
@FarmBoy, 실제로는 아니지만 오늘입니다.

5
이것이 의존성 주입과 어떻게 다릅니 까?
Bill K

2
@ Bill K, 훌륭한 관찰-나는 그 자신을 연결시키지 못했습니다. 차이점은 주입 될 객체가 적어도 자바에서는 간절히 평가되고 느리게 평가되지 않는다는 것입니다. 무한 목록을 삽입 할 수 없습니다.

1
@ Thorbjørn Ravn Andersen 무한 목록이 왜 유용한 지 잘 모르겠습니다. 실제로 (무한 목록) 유형 연산을 합할 수 있습니까? 거의 없을 것 같습니다. 그렇지 않으면 Java가 반복자를 사용하는 방식과 비슷하게 들릴 수 있습니다. 요청할 때 객체를 요청할 때만 객체를 인스턴스화하는 방식으로 반복자를 코딩하면됩니다. )
Bill K

21

80 년대 후반 / 90 년대 초반 컴퓨터는 스몰 토크 스타일 OOP를 위해 충분히 강력 해졌습니다. 요즘 컴퓨터는 FP에 충분히 강력합니다. FP는 더 높은 수준으로 프로그래밍되기 때문에 프로그래밍이 더 즐거울 수 있지만 가장 효율적인 방법으로 특정 문제를 해결할 수는 없습니다. 그러나 컴퓨터는 너무 빠르므로 신경 쓰지 않아도됩니다.

상태 변경 코드를 분리해야하기 때문에 순전히 기능적인 프로그래밍 언어를 사용하면 멀티 코어 프로그램을보다 쉽게 ​​수행 할 수 있습니다.

또한 프로그래밍 언어의 경계가 오늘날 흐려지고 있습니다. 다른 패러다임을 사용하려는 경우 하나의 패러다임을 포기할 필요가 없습니다. 가장 널리 사용되는 언어로 FP를 수행 할 수 있으므로 진입 장벽이 낮습니다.


6
답을 추가하려고했지만 마지막 문장에서 내 요점을 맞추 었습니다. 기능 프로그래밍은 단일 머신의 코어 수가 증가함에 따라 점점 더 널리 보급 될 것입니다. 본질적으로 상태가 부족하면 프로세서간에 기능 프로그램을 기계적으로 쉽게 분할 할 수 있습니다 (순수하게 기능적인 프로그램이있는 경우 컴파일러는 최소한의 노력으로 병렬 처리를 이론적으로 처리 할 수 ​​있음을 의미합니다. youtube.com/watch? 데이터 병렬 처리에 대한 설명은 v = NWSZ4c9yqW8 ).
Inaimathi

1
@Inaimathi Ditto. 함수형 프로그래밍은 확장 성이 뛰어나므로 멀티 코어 아키텍처에서 의미가 있습니다.
EricBoersma

첫 번째 의견은 추가 진술을 포함하도록 답변을 편집하기 전에 작성되었습니다.
Inaimathi

그 죄송합니다. 나는 단지이 점을 잊었다.
LennyProgrammers

함수형 컴파일러가 OOPS만큼 최적화 된 머신 코드를 생성 할 수 없다는 것이 일반적으로 받아 들여 집니까? 나는 그것이 사실이어야하는 이론적 인 이유를 생각할 수 없다. OOPS보다 더 고급 최적화가 가능한 방법을 생각할 수 있습니다.
Jeremy

7

오늘날 분산 컴퓨팅이 필요합니다.

FP는 함수를 상태가없는 빌딩 블록으로 사용하므로 동일한 매개 변수로 n 번 호출하면 항상 같은 값을 반환해야하며 부작용이 없습니다.

따라서 동일한 기능을 여러 머신에 보내 병렬 작업을 수행하고 수행 할 수 있습니다.

OO 패러다임에서는 빌딩 블록이 거의 정의 형인 객체이므로 객체가 조금 더 어렵습니다. 동일한 메소드를 여러 번 호출하는 경우 데이터 손상을 피하기 위해 내부 데이터 동기화에주의해야합니다. 여전히 가능하지만 FP 패러다임은 계산을 배포해야하는 일부 시나리오에서 OO보다 우수합니다.

FP (및 NoSQL)의 출현은 수십만 대의 컴퓨터가 병렬로 작동하는 놀라운 컴퓨팅 결과에 대한 이야기와 그것이 얼마나 쉬운 지에 따라 나옵니다.

그러나 아마도 이것은 이런 종류의 설정이 필요한 일종의 응용 프로그램 일뿐입니다. 많은 다른 많은 응용 프로그램 / 시스템의 경우 절차 및 OO가 제대로 작동합니다.

이제 프로그래밍 영역을 확장하고 학계를 넘어서는 것이 아니라고 생각했던 이러한 개념을 다시 생각해 보려고합니다.

나는 몇 년 전에 Lisp에서 프로그램을 배웠지 만 그때는 FP조차 몰랐습니다. 지금까지 나는 그것에 관한 거의 모든 것을 잊어 버렸지 만 재귀와 같은 개념을 매우 쉽게 이해할 수 있도록 확실히 도와줍니다.


2
문제는 FP와 같은 언어의 장점에 대해 묻는 것 입니다 . 설명한 내용은 기존 언어를 사용하여 수행 할 수도 있습니다.
Pacerier

6

우리는 멀티 코어 프로세싱이 과학 실험실의 뒷방이나 특수 하드웨어에서 수행되는 것이 아닌 시대로 이동하고 있습니다. 이제 상용 프로세서로 완료되었습니다. 적어도 내가 접한 변형 중 대부분의 기능적 프로그래밍은 일반적으로 부작용이없는 상태 비 저장 계산 단위에 대한 견해를 밝히려고 시도합니다. 이는 프로세서간에 상태를 혼합 할 필요가 없기 때문에 멀티 코어 작업의 전형적인 패러다임입니다.

이것은 이유 중 하나 일 뿐이지 만 함수형 프로그래밍이 적용되는 것을 볼만한 좋은 이유입니다.


5

그 질문에 대한 주된 대답은 '노출'이라고 생각합니다.

함수형 프로그래밍은 새로운 것이 아닙니다. 저는 12 년 전에 대학에서 Haskell을 배웠고 그것을 좋아했습니다. 그러나 전문적인 작업에서 언어를 거의 사용하지 않았습니다.

최근에 주요 패러다임에서 다중 패러다임 접근법을 사용하는 많은 언어가 인기를 끌고있다. F # , JavaScript가 대표적인 예입니다.

특히 jQuery 또는 Prototype 과 같은 기능적 스타일의 프레임 워크 언어와 함께 사용될 때 특히 JavaScript는 역동적 인 최신 웹 사이트에 대한 모든 작업으로 인해 많은 사람들에게 일상적인 언어가되었습니다. 이러한 기능적 스타일에 대한 노출은 사람들이 부여하는 힘을 실현할 수있게합니다.

일단 사람들이 노출되면,보다 완전한 기능의 변형 된 언어를 시험 해보고 일상 업무에 사용하기 시작합니다.

Visual Studio 2010에서 F #이 일류 언어가되었고 jQuery (et al)가 중요 해짐에 따라 격리 된 프로그램을 가지고 놀거나 모호하게 만드는 것보다는 이러한 언어를 사용하는 것이 현실적으로되었습니다.

코드는 유지 관리가 가능해야합니다. 회사는 코드를 안전하게 사용할 수 있도록 언어를 사용하고 지원해야합니다.


3

에서 이 이야기 앤더스 헤 즐스 버그는 주제에 대한 자신의 견해를 설명합니다.

[편집하다]

죄송합니다. 링크가 잘못되었습니다. 이제는 올바른 장소를 가리 킵니다.

1 시간 통화의 몇 가지 요점을 간략히 요약하면 다음과 같습니다.

기능적 언어는 절차 적 언어보다 더 선언적인 프로그래밍 스타일을 허용하므로 FL로 작성된 프로그램은 일반적으로 how 대신에 무엇에 더 집중 합니다 . 뛰어난 수학적 구조로 인해 FL은 컴파일러로 최적화 및 변환하기가 더 쉬우 며 메타 프로그래밍 및 임베디드 DSL 구성도 용이합니다. 이 모든 것이 함께 기능 프로그램을 절차 프로그램보다 간결하고 자체 문서화합니다.

또한 가까운 미래의 많은 시대에 직면하여 프로그래밍 언어는 다양한 방식으로 멀티 스레딩 / 프로세싱을 활용할 수 있어야합니다. 단일 코어 머신의 멀티 스레딩은 사실상 시간 공유 메커니즘이었으며 시스템 아키텍처는이를 반영했습니다. 많은 코어 머신의 멀티 스레딩은 매우 다릅니다. Funcional 언어는 대부분 상태를 피하기 때문에 병렬화에 특히 적합하므로 공유 가변 데이터의 무결성에 대해 크게 걱정할 필요가 없습니다 (공유 가변 데이터가없는 경향이 있기 때문에).


1
요약 해 주시겠습니까?

1
@Thorbjorn 그것은 요약 할 수없는 사람을 생각 나게한다 . (지시하지 말고 저자에게 대답하십시오.)
Mark C

1
링크는 올바른 위치로 연결되지 않습니다.
Ken Bloom

2

기능 프로그래밍 패러다임과 웹 프로그래밍 간의 밀접한 상관 관계와 관련이 있다고 생각합니다.

Ruby on Rails는 기능적 (heh hehh) 웹 애플리케이션으로의 매우 빠른 경로를 제공했기 때문에 전체 기능적 프로그래밍 접근 방식을 예리하게 개선했습니다. 이에 대한 흥미로운 토론 이 있으며 한 가지 특별한 답변이 있습니다.

함수형 프로그래밍은 웹앱과 매우 잘 일치합니다. 웹 앱은 HTTP 요청을 수신하고 HTML 결과를 생성합니다. 이것은 요청에서 페이지로의 기능으로 간주 될 수 있습니다.

일반적으로 장기 실행 프로세스, 상태 저장 UI 및 여러 방향의 데이터 흐름이있는 데스크톱 앱과 비교하십시오. 이것은 상태 및 메시지 전달이있는 객체에 관심이있는 OO에 더 적합합니다.

함수형 프로그래밍이 오랫동안 사용되어 왔기 때문에 Greenfield 웹 프로젝트를 위해 Lisp 개발자를 찾는 구인 광고가 많이 보이지 않는 이유가 궁금합니다.


기본 프로토콜이 무국적이기 때문에 기능적 비유가 우연히 웹에만 적용된다고 생각합니다. 웹 응용 프로그램은 실제로 상태 비 저장이 아니기 때문에 실제로 HTTP를 항상 해결해야하는 이유입니다.
Mladen Jablanović

@Mladen Hmmm, 클라이언트-서버 통신 상태 (HTTP)를 응용 프로그램 상태 (DAO 등)와 혼동시킬 수 있습니까? " 여기서 Stefan Tilkov 인용 ( codemonkeyism.com/stateless-applications-illusion )"웹 응용 프로그램에서 각 개별 요청에는 이전 요청의 발생 여부와 관계없이 처리 할 수있는 충분한 정보가 포함되어 있어야합니다. 지속적인 서버 측 리소스 상태는 양호하고 클라이언트 측 상태는 양호하며 일시적 통신 (세션) 상태는 확장 성과 북마크 기능을 망치기 때문에 아닙니다. " 이것이 REST의 기초입니다.
게리 로우

1
Lisp 개발자를 찾는 구인 광고가 많지 않은 이유를 더 잘 이해하려면 paulgraham.com/avg.html 을 읽으 십시오 .

@ Thorbjørn Ravn Andersen 좋은 기사. Lisp 편집기를 시작하도록 영감을줍니다.
게리 로우

1

함수형 프로그래밍은 몇 년 전에 객체를 처음 사용했을 때 와 같은 " 와우, 이것은 새로운 것 " 이라는 느낌을 줍니다.

나는 FP가 지금까지 새로운 개념은 아니지만, "모두"가 갑자기 절차 적 프로그래밍에서 배를 뛰어 넘어 90 년대에 실제로 돌파했을 때 OO도 아니었다는 것을 알고있다. 이것은 Java와 그 이후의 C #의 적시에 성공했기 때문입니다.

다음 번 언어 배치가 같은 방식으로 확산되기 시작하면 FP에서도 동일한 일이 일어날 것이라고 생각합니다. 스칼라와 F #과 같은 언어로 적어도 일부 서클에서 이미 가지고있는 것처럼.


OO는 FP보다 훨씬 젊지 만, 이전에는 각광을 받았습니다. 나는 괄호가 너무 많은 사람들을 겁 먹은 것 같아요
Javier

1

내 질문은 다음과 같습니다. 1. 최근 FP 열정에 기여한 것은 무엇입니까? OO를 사용하는 것이 지루합니까? 2. 이것이 FP 미래를 나타내는 것입니까? 아니면 이것이 객체 지향 데이터베이스와 같은 유행입니까?

다른 사람들은 좋은 기술적 이유를 제시했습니다.

FP가 일반적인 개발자 및 관리자 유형 사이에서 주목을받는 주된 이유는 멀티 코어 CPU를 더 잘 사용할 수 있다는 약속 때문입니다. 내가 읽은 모든 것에서 FP는 더 쉬운 (쉽지 않은) 병렬 프로그래밍을 허용합니다.

약속이 현실적이고 성취된다면 미래에 널리 사용될 것입니다.


큰 "if"입니다. COBOL은 "영어"는 누구나 프로그램을 할 수 있음을 의미했습니다. AI는 프로그래밍을 쓸모 없게 만들려고했다. OO는 땜장이 장난감을 조립하는 것처럼 프로그래밍을 간단하게 만들려고했습니다. 코더는 항상 "다음 큰 것"을 찾고, 바위 광팬처럼, 그 후 다른 하나는 하나 ...
마이크 Dunlavey

0

나는 그것이 두 가지 추세의 조합이라고 생각합니다.

  1. 주류 언어 (예 : C #)에 추가되는 기능 기능.
  2. 새로운 기능 언어가 생성되고 있습니다.

첫 번째 경향에는 당연히 한계가 있지만, 새로운 언어는 진지하게 받아들이 기 위해서는 적어도 옵션으로 기능 프로그래밍을 지원해야 할 것입니다.


0

예전에는 사람들이 운영 체제의 기본 API를 사용하여 데스크톱에서 실행할 프로그램을 작성하고 있었고 이러한 API는 (일반적으로) C로 작성되었으므로 대부분의 경우 기본 API 용 프로그램을 작성하려는 경우 C로 그 프로그램을 썼습니다

지난 10 년 동안의 새로운 혁신은 특히 API가 관련이없는 웹 개발 (웹 페이지를 구성하는 것은 기본적으로 문자열 조작을 포함하기 때문에)과 같은 다양한 API를위한 것이라고 생각합니다. Win32 API 또는 POSIX API로 직접 코딩하지 않기 때문에 사람들이 기능적 언어를 자유롭게 사용할 수 있습니다.


0

엉뚱하고 깔끔하며 뇌를 간질입니다. 괜찮아.

또한 IMHO는 클래식 악 대차입니다. 문제를 찾는 솔루션.

엔지니어가 설립 한 모든 스타트 업 회사가 좋아하는 아이디어로 현혹되어 한동안 밝게 타 오르지 만 필요한 것을 제공하기 위해 설립 된 회사가 조용히 인수 한 것과 같습니다.

이것이 내가 아이디어 기반 프로그래밍이 아니라 필요 기반 프로그래밍을 시작하고자하는 새로운 아이디어입니다. 어쩌면 그것은 평범한 것처럼 들리지만 실제로는 꽤 창의적이고 멋질 수 있다고 생각합니다.


-1

F # 때문에 확실히, 어떤 것이 원인인지 어떤 것이 효과인지를 말하기가 어렵습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.