기능성 프로그래밍을 사용하여 완전한 엔터프라이즈 응용 프로그램을 개발할 수 있습니까?


19

지금 막 FP (Functional Programming)를 배우기 시작했습니다. 나는 모든 것이 대상이며 대부분 변경 가능한 OOP 세계에서 왔습니다. 함수에는 부작용이 없다는 개념을 둘러보기가 어렵습니다.

변경할 수없는 것이 있으면 Employee 또는 Person과 같은 일반적인 사물이 FP에 어떻게 표시됩니까?

FP를 사용하여 본격적인 엔터프라이즈 응용 프로그램을 만들 수 있습니까?


5
직원의 표현이 변경 가능한 이유는 무엇입니까? 아마도 상태가 있지만 그것은 또 다른 질문입니다.

1
가변 데이터가 사물을 나타냅니다. 반대로 불변의 데이터는 특정 시점에 무언가의 가치를 지니고 있습니다 (단, 이것이 유일한 사용 사례는 아님). 모두 같은 것을 나타내는 두 개의 가변 객체가있는 버그가있는 경우 객체를 사용하여 물건을 나타낼 수있는 경우를 알고 있습니다.
dan_waterworth

2
함수형 프로그래밍 에는 부작용이 있습니다. 그렇지 않으면 아무것도 인쇄 할 수 없습니다.

1
@ Thorbjørn Ravn Andersen : 명령형 (프로 시저, 객체 지향) 프로그래밍에서는 외부 세계 (IO)와의 통신 및 프로그램 내 데이터 변환 계산에 부작용을 사용합니다. FP에서는 두 세계를 명확하게 구분합니다. IO에만 부작용을 사용하지만 (IO가없는 프로그램은 일반적으로 쓸모가 없습니다) 순수한 함수를 사용하여 내부 데이터 변환을 계산합니다. 부작용은 모두 피할 수는 없지만 국소 적이 지 않기 때문에 추론하기가 더 어렵 기 때문에 가능한 한 사용을 제한하는 것이 좋습니다.
Giorgio

"사람"객체와 같은 것은 변경할 필요가 없습니다. 대신, 거의 동일하지만 약간 다른 완전히 새로운 "개인"개체를 만듭니다. 당신은 어딘가에 "person"객체에 대한 참조를 가지고 그것을 이전 사본 대신 새로운 사본을 참조하도록 변경합니다. 물론 그 참조는 일종의 컬렉션에있을 수 있으므로 거의 동일한 컬렉션의 복사본을 만드십시오. 이전 컬렉션을 새 컬렉션으로 교체 할 수 있도록 컬렉션에 대한 참조가 있어야합니다!
Brendan

답변:


17

문제는 엔터프라이즈에서 FP를 사용할 수 없습니까? 그러나 Enteprise에서 FP를 사용해야합니까?

물론 당신은 할 수. 모든 종류의 프로그래밍 언어로 모든 종류의 응용 프로그램을 개발할 수 있으므로 "완료"라고합니다.

이제 "엔터프라이즈에서 사용해야합니까?"라는 질문에 그것은 당신이나 당신의 고용주에게 달려 있습니다. FP는 어떤 종류의 응용 프로그램에서 실제로 유용 할 수 있으며 실제로는 많이 사용됩니다 : Haskell in the industry

이제 "왜 더 많이 사용하지 않습니까?"라고 물을 수도 있습니다. 주로 다른 Imperative / OO 언어가 더 일반적이기 때문에 회사는 Java 또는 C ++에 익숙하기 때문에보다 "이국적인"언어로 변경하기를 거부합니다.


7
You can develop any kind of application with any kind of programming language그것은 매우 약한 논쟁입니다. Turing tarpits를 조심하십시오 ...
yannis

5
@YannisRizos 나는 문제의 모든 탄젠트를 탐구하는 것과는 대조적으로 To-the-Point 답변을 위해 일반화하고 있다고 생각합니다.
Johnny Rotten

2
@YannisRizos을 수행 할 수 있습니다 !=원하는

1
때로는 특정 종류의 엔터프라이즈 솔루션에 대해 튜링 언어가 완성되어서는 안된다고 느끼는 경우가 있습니다.
shabunc

2
언어에 관해서는 기술적 인 관점에서 볼 때 최선을 다하는 것은 엔지니어 자신의 몫입니다.
shmish111

11

저는 2 년 전 (Haskell, Scala, Scheme) FP 언어에 대해 배우기 시작했으며, 전문가가 아니더라도 C ++ 또는 Java 이상의 특정 작업에서 생산성이 크게 향상 될 수 있음을 알게되었습니다. .

FP 언어의 장점 중 일부는 다음과 같습니다.

  • 그들은 매우 간결한 경향이 있지만 명확한 의미를 유지합니다.
  • 선언적 스타일을 사용할 수 있으며 구현 세부 사항에 대해 너무 많이 생각할 필요가 없습니다.
  • Haskell과 같은 풍부한 유형의 시스템은 컴파일 시간에 많은 논리적 오류를 매우 일찍 포착 할 수 있습니다. 내가 아는 한 (실제로 많지는 않지만) SML과 Ocaml은 비슷한 장점을 제공합니다.

지금까지 나는 FP 패러다임으로의 전환이 매우 흥미롭고 충분한 시간을 보내고 나면 그리 어렵지 않다는 것을 알았습니다. (그러나 C 또는 C ++를 배우는 데 얼마나 많은 시간을 보냈습니까?

따라서 기술적 관점에서 기능적 프로그래밍 언어를 사용하여 전체 엔터프라이즈 응용 프로그램을 개발하는 것이 완벽하게 의미가 있다고 생각합니다.

불행히도이 패러다임은 주류가 아닙니다. 대부분의 회사는 잘 테스트 된 기술 만 채택하는 경향이 있으므로 실제로 작동한다는 충분한 증거가 있고 개발자, 도구, 라이브러리, 프레임 워크가 충분하다는 증거가있을 때까지 FP에서 멀리 떨어져 있습니다. 그러므로 지금 당장 FP 프로그래밍을 할 수있는 직업을 찾는 것이 훨씬 더 어렵습니다.

멀티 코어 프로세서의 사용 증가로 FP 언어에 더 많은 투자를 장려 할 경우 현재 상황이 바뀔 수 있습니다. 이는 동시 소프트웨어를 작성하는 데 상당히 강력한 것 같습니다.

또한 프로그래머가 완전한 패러다임 스위치없이 일부 FP를 사용할 수 있도록 일부 FP 기능을 C #, C ++와 같은 비 기능 언어로 도입하는 경향이 있습니다. 아마도 지금부터 10 년 후에이 언어들은 충분한 기능의 FP 기능을 다루어 순전히 기능적인 언어로의 전환이 훨씬 쉬워 질 것입니다.


10

나는 그것이 반드시 최고의 아이디어라고 생각하지 않습니다. 그러나 특정 응용 프로그램의 특성에 따라 다릅니다.

Eric Evans의 저서 인 Domain-Driven Design에 설명 된 철학 에 따르면 문제를 해결하는 데 도움이 될 수있는 문제를 나타내는 도메인 모델을 만들어야합니다. Evans는 특정 문제에 적합한 프로그래밍 언어를 찾는 것을 제안합니다. 예를 들어 그는 수학적 문제를 해결하는 방법으로 Fortran을 언급했습니다. 또는 문제에 대한 전문화 된 도메인 별 언어를 만들 수도 있습니다.

좋은 도메인 모델을 성공적으로 만들면 프레젠테이션 코드가 도메인 계층 위에 얇은 껍질로 표시됩니다.

이제 엔터프라이즈 애플리케이션의 경우이 유형의 애플리케이션 (엔터프라이즈 애플리케이션에 대해 일반화 할 수있는 경우)에는 ID가 중요한 엔티티의 상태를 수정하고 수정 된 엔티티를 데이터베이스에 유지하는 것이 종종 포함됩니다. 이 매우 일반적인 유형의 문제는 기능적 모델보다 객체 지향 모델을 사용함으로써 훨씬 더 잘 해결됩니다.

이것은 기능적 패러다임으로 더 잘 해결할 수없는 엔터프라이즈 응용 프로그램 영역이 있다는 것을 의미하지는 않습니다. 예를 들어 은행 응용 프로그램의 위험 분석 모듈 또는 운송 응용 프로그램의 경로 계획 모듈입니다. 그리고 기능적 패러다임을 사용하여 일부 엔터프라이즈 응용 프로그램을 전체적으로 구현할 수도 있습니다.

그러나 일반적으로 객체 지향 패러다임을 통해 대부분의 엔터프라이즈 응용 프로그램에보다 유용한 도메인 모델을 만들 수 있다고 생각합니다.

편집하다

약간의 공감대가 있었기 때문에이 답변에주의를 집중 시켰습니다.이 글을 쓴 이후로 FP에 대해 더 많이 배웠습니다. 더 이상 제 자신의 답변에 동의한다고 확신 할 수 없습니다. 일부 기능적 언어는 사용 사례를 매우 잘 설명 할 수 있습니다. 그러나 완전히 다른 사고 방식을 배워야합니다.


2
+1 : 매우 훌륭하고 자극적 인 답변. FP에 대한 제한된 지식으로 인해 이것이 올바른지 확실하지 않지만 모나드 또는 고유 유형을 사용하여 영구 객체를 모델링 할 수 있다고 생각합니다 (깨끗한 상태). 다른 기능으로 변형되었습니다. 그러나 나는 이것을 뒷받침하기 위해 FP 전문가의 의견이 정말로 필요합니다.
Giorgio

3

예, 그럴 수 있습니다. Google은 약간만 사용하면 순수한 기능 언어로 코딩 된 실제 소프트웨어를 찾을 수 있습니다.

비즈니스 객체에 대한 귀하의 질문에 관해서는 귀하의 실제 문제는 불변성이라고 생각합니다. 이 경우 명령형 언어를 사용하는 경우 변경할 때마다 새로운 "사람"을 반환한다고 가정하십시오.

이 기술은 명령형 언어를 사용하여 구현할 수도 있습니다!


3

객체 지향 프로그래밍 (OOP)과 같은 함수 프로그래밍 (FP)은 패러다임입니다. 프로그래밍 문제에 대한 다른 패턴이나 접근 방식을 나타냅니다. 이러한 다양한 접근 방식으로 확장 가능하고 유지 관리 가능하며 확장 가능한 소프트웨어를 생성 할 수있는 능력이 필요하지 않습니다. 접근 방식이 모든 문제 유형에 대해 동일하다는 것은 아닙니다. 그렇지 않습니다. 특정 문제는 특정 패러다임에 더 잘 맞거나 나빠질 수 있습니다. 예를 들어 FP는 부작용이있는 종속적 인 작업 순서를 가진 프로그램에 대한 첫 번째 선택이 아닙니다. 그러나 그러한 프로그램은 잘 작성되고 작성되었을 수 있습니다.


3

예, 엔터프라이즈 애플리케이션에서 FP를 사용할 수 있습니다. Clojure는 기업에서 성공한 FP 언어의 한 예입니다. http://cognitect.com/clojure#successstories

상태를 나타내는 것은 FP에서 도전이 될 수 있으며 FP에 맞게 패러다임을 변경하는 것은 약간의 왜곡 일 수 있습니다. 일부 FP 언어는 부작용과 변경 가능한 상태를 완전히 허용하지 않습니다. Clojure는 이러한 패러다임을 낙담 또는 격리 할 수는 있지만 둘 다 허용합니다.

요컨대, 상태 표현은 OO와 매우 유사 할 수 있습니다. 매우 다른 상태 수정입니다. 예를 들어, FP 상태에서 목록과 맵으로 표시 될 수 있습니다. 직원 목록은 다음과 같습니다.

[[name: "James Brown" address: "Barnwell, SC"]
 [name: "Elvis Presley" address: "Tupelo, MS"]]

FP에서 상태 수정을 처리하는 방법에는 두 가지가 있습니다. 하나는 기능적 반응성 프로그래밍과 같은 것입니다. 이 패러다임에서 모든 상태는 최상위 수준에서만 처리됩니다. 예를 들어 응용 프로그램의 HTML보기에는보기에 사람의 이름, 주소 등의 상태가 있습니다. "이름 업데이트"를 클릭하면 실제로 이름 변경을 제외하고 이름 업데이트에 관한 모든 것을 처리하는 함수가 호출됩니다. 이상하게 들리 겠지만 ... 그러면 변경된 이름이 함수에 의해 반환되고 뷰 (또는 영구 데이터 저장소 등)에 새 이름이 표시됩니다. 또는 업데이트 된 이름의 전체 새 구조가 반환됩니다. 그렇다면 기능은 무엇입니까? 이름을 확인하고 유효하면 새 이름을 반환하고 유효하지 않으면 오류를 반환합니다. 새로운보기 또는 탐색 링크를 따라갈 수 있습니다. 이름 변경보다 복잡한 것은 더 많은 일을 할 수 있습니다.

따라서 FRP의 경우 함수에 의해 반환되는 객체는 새로운 상태이며 뷰 또는 상위 레벨에있는 모든 것에 직접 제공 될 수 있습니다. 경우에 따라 FRP는 전체 상태를 함수로 전달하고 전체 상태를 다시 가져옵니다.

이 패러다임을 사용하면 컨테이너 또는 프레임 워크가 디스플레이, 데이터베이스 또는 기타 새로운 상태에서 업데이트해야 할 업데이트를 처리해야합니다. 따라서 응용 프로그램을 화면에 그리는 프레임 워크를 상상할 수 있습니다. 사용자가 클릭하면 함수가 호출되고 새로운 상태가 반환됩니다. 그런 다음 프레임 워크는 모든 것을 다시 그리거나 디스플레이의 일부를 지능적으로 다시 그려서 화면을 업데이트합니다. http://blog.getprismatic.com/om-sweet-om-high-functional-frontend-engineering-with-clojurescript-and-react/를 참조하십시오

Clojure는 제가 접한 두 번째 패러다임을 사용하며 이는 상태 변경을 격리하지만 반드시 최상위 수준으로 제한하지는 않습니다. Clojure를 사용하면 원자, 에이전트 또는 참조에 의해 변경 가능한 모든 상태가 "유지"되어야합니다 (상태에 Java 오브젝트를 사용하지 않는 한). 이것이 작동하는 방식은 atom / agent / ref가 보유하거나 가리 키거나 참조한 (그러나 호출하려는) 오브젝트는 변경할 수 없지만 atom / agent / ref는 새 오브젝트를 가리 키도록 변경할 수 있습니다. 이 경우 아톰 / 에이전트 / 참조에 특별한 방법을 사용합니다. "아톰 / 에이전트 / 참조를 새 객체에 다시 할당하여 여기에서 객체를 업데이트합니다"라는 메시지가 표시됩니다.

이것이 유익한 이유는 무엇입니까? 이러한 Clojure 구문에 의해 참조되는 불변의 객체는 무언가를 수행하는 함수로 전달 될 수 있으며 해당 함수가 실행되는 동안 객체에 대한 참조는 변경되지 않습니다. 즉, atom / agent / ref는 함수로 전달되지 않지만 이들이 가리키는 불변 객체는 전달됩니다. 원자, 에이전트 및 참조에는 언어의 안전하고 일부 방식으로 업데이트 및 동시성을 처리하는 특수 속성이 있습니다. http://clojure.org/state 참조

이게 도움이 되길 바란다. FP에서 직원과 사람을 대변 할 수있는 방법에 대한 이해를 돕기 위해 Clojure 주 및 FRP에 대해 자세히 읽어보십시오. 실제 표현은 객체 지향 프로그래밍과 유사하지만 실제로는 다른 가변성입니다.

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