문제

나는 최근에 대한 학습 프로그래밍 기능(특별 특성을 나타내는지를 통해 갔어요 튜토리얼에서 패키지와 얼랑뿐만 아니라).는 동안 내가 찾는 개념을 매우 깨달음,나는 아직 보지 않는 실제적인 측면의"부작용 없이"개념입니다.은 무엇 실용적 장점을까요?내가 하려고 생각에 기능적인 사고,그러나 몇 가지 상황을 그냥 지나치게 복잡하지 않고는 능력을 저장하는 상태에서 쉬운 방법(고려하지 않켈의 사용해'쉽').

그것은 가치는 학습을 계속 하스켈(또는 다른 순전히 기능적인 언어)에서 깊이 있는?기능적 또는 무국적 프로그래밍이 실제로 더 많은 생산성 보다 절차?은 그것을 가능성이 높다는 것을 계속 사용켈 또는 다른 기간 후에,또는 나 그것을 배울만한 이해입니까?

나에게 관심 성능보다 생산성을 높입니다.그래서 나는 주로 묻는 것입니다있다면 더 생산적인 기능적인 언어보다는 절차상/객체 지향/무엇입니다.

도움이 되었습니까?

해결책

읽다 간단히의 기능적 프로그래밍.

무국적 프로그래밍에는 많은 장점이 있습니다. 극적으로 다중 스레드 및 동시 코드. 무뚝뚝하게 말하면, 돌연변이 상태는 다중 스레드 코드의 적입니다. 기본적으로 값이 불변이되지 않으면 프로그래머는 두 스레드 사이의 공유 상태 값을 변호하는 하나의 스레드에 대해 걱정할 필요가 없으므로 레이스 조건과 관련된 전체 클래스의 멀티 스레딩 버그가 제거됩니다. 레이스 조건이 없기 때문에 자물쇠를 사용할 이유가 없으므로 불변성은 교착 상태와 관련된 또 다른 전체 클래스의 버그를 제거합니다.

이것이 기능 프로그래밍이 중요한 이유이며 아마도 기능 프로그래밍 트레인을 뛰어 넘는 가장 좋은 이유입니다. 단순화 된 디버깅 (즉, 기능은 순수하고 응용 프로그램의 다른 부분에서는 상태를 돌연변이하지 않음), 더 많은 간결하고 표현 코드, 설계 패턴에 크게 의존하는 언어에 비해 보일러 플레이트 코드가 적고, 보일러 플레이트 코드가 적고, 보일러 코드가 적습니다. 컴파일러는 코드를보다 적극적으로 최적화 할 수 있습니다.

다른 팁

프로그램의 더 많은 부분은 무국적입니다. 휴식을 취하지 않고 조각을 모으는 방법이 더 많을수록. 무국적 패러다임의 힘은 무국적 (또는 순도)에 있지 않습니다. 그 자체, 그러나 그것이 당신에게 강력한 글을 쓸 수있는 능력, 재사용 가능 기능과 결합.

John Hughes의 논문에서 많은 예제가 포함 된 좋은 튜토리얼을 찾을 수 있습니다. 기능 프로그래밍이 중요한 이유 (PDF).

당신은 될 것입니다 gobs 더 생산적, 특히 대수 데이터 유형과 패턴 매칭 (Caml, SML, Haskell)이있는 기능적 언어를 선택하는 경우.

다른 답변 중 많은 사람들이 기능 프로그래밍의 성능 (병렬) 측면에 초점을 맞추 었으며, 이는 매우 중요하다고 생각합니다. 그러나, 당신은 구체적으로 생산성에 대해 묻었습니다.

나는 실제로 (개인적인 경험에서) F#의 프로그래밍이 내가 생각하는 방식과 일치한다는 것을 알게되므로 더 쉽습니다. 나는 그것이 가장 큰 차이라고 생각합니다. 나는 F#과 C#모두에서 프로그래밍했으며, 내가 좋아하는 F#에는 "언어 싸움"이 훨씬 적습니다. F#의 세부 사항에 대해 생각할 필요가 없습니다. 내가 정말로 좋아하는 것을 찾은 것의 몇 가지 예가 있습니다.

예를 들어, F#이 정적으로 입력 되더라도 (모든 유형은 컴파일 시간에 분해 됨) 유형 추론은 어떤 유형을 가지고 있는지 알 수 없으므로 말할 필요가 없습니다. 그리고 그것을 알아낼 수 없다면, 그것은 자동으로 당신의 기능/클래스/일반적인 것을 만듭니다. 따라서 일반적인 것을 쓸 필요는 없습니다. 모두 자동입니다. 나는 그것이 문제에 대해 생각하고 그것을 구현하는 방법을 적게 생각하는 데 더 많은 시간을 소비한다는 것을 알았습니다. 사실, 내가 C#로 돌아올 때마다, 나는이 유형의 추론을 정말로 그리워한다는 것을 알게되면, 더 이상 할 필요가 없을 때까지 그것이 얼마나 산만 해지는 지 알지 못합니다.

또한 F#에서는 루프를 쓰는 대신 기능을 호출합니다. 더 이상 루프 구조에 대해 생각할 필요가 없기 때문에 미묘한 변화이지만 중요합니다. 예를 들어, 다음은 무언가를 통과하고 일치시키는 코드가 있습니다 (나는 무엇을 기억할 수 없습니다, 그것은 프로젝트 Euler 퍼즐에서 나온 것입니다) :

let matchingFactors =
    factors
    |> Seq.filter (fun x -> largestPalindrome % x = 0)
    |> Seq.map (fun x -> (x, largestPalindrome / x))

필터를 수행 한 다음 C#에서 맵 (각 요소의 변환)은 매우 간단하지만 더 낮은 수준에서 생각해야한다는 것을 알고 있습니다. 특히, 당신은 루프 자체를 작성하고 자신의 명시 적 진술과 그런 종류의 것들이 있어야합니다. F#을 배우기 때문에 기능적 방식으로 코딩하기가 더 쉽다는 것을 알았습니다. 필터를 필터링하려면 "필터"를 작성하고 맵핑하려면 구현하는 대신 "지도"를 작성합니다. 각 세부 사항.

나는 또한 |> 연산자를 좋아합니다. 이는 OCAML과 다른 기능적 언어와 f#을 분리한다고 생각합니다. 그것은 파이프 연산자이며, 하나의 표현식의 출력을 다른 표현식의 입력에 "파이프"할 수 있습니다. 그것은 코드가 내가 생각하는 방식을 따릅니다. 위의 코드 스 니펫과 마찬가지로 "요인 시퀀스를 가져 가서 필터링 한 다음 매핑하십시오." 그것은 매우 높은 수준의 사고이며, 당신은 루프를 작성하고 진술을 작성하기 때문에 명령적인 프로그래밍 언어를 얻지 못합니다. 내가 다른 언어로 갈 때마다 내가 가장 그리워하는 한 가지입니다.

따라서 일반적으로 C#과 F# 모두에서 프로그래밍 할 수 있지만 더 높은 수준에서 생각할 수 있기 때문에 F#을 사용하기가 더 쉽습니다. 더 작은 세부 사항이 기능 프로그래밍 (F#에서)에서 제거되기 때문에 더 생산적이라고 주장합니다.

편집하다: 나는 당신이 기능 프로그래밍 언어로 "상태"의 예를 요구 한 의견 중 하나를 보았습니다. F#은 필수적으로 작성 될 수 있으므로 다음은 F#에서 변이 가능한 상태를 가질 수있는 방법에 대한 직접적인 예입니다.

let mutable x = 5
for i in 1..10 do
    x <- x + i

오랜 시간을 보낸 어려운 버그를 오랫동안 디버깅하는 버그를 고려하십시오.

이제 프로그램의 두 개의 별도 구성 요소 사이의 "의도하지 않은 상호 작용"으로 인한 버그 중 몇 개가 있었습니까? (거의 모든 스레딩 버그는이 형태를 가지고 있습니다. 공유 데이터 작성, 교착 상태 등은 ... 글로벌 상태에 예상치 못한 영향을 미치는 라이브러리를 찾거나 레지스트리/환경을 읽고 쓰기 등을 찾는 것이 일반적입니다. 3 '하드 버그'중 1 개 이상 이이 범주에 속한다고 주장 할 것입니다.

이제 Stateless/Emutable/Pure 프로그래밍으로 전환하면 모든 버그가 사라집니다. 대신 몇 가지 새로운 도전이 제시됩니다 (예 : 하다 Haskell과 같은 언어에서는 다른 모듈이 환경과 상호 작용하기를 원합니다. 이러한 상호 작용은 유형 시스템으로 명시 적으로 재구성됩니다. 즉 나머지 프로그램.

그것이 '불변성'IMO의 큰 승리입니다. 이상적인 세상에서, 우리는 모든 훌륭한 API를 설계했으며 상황이 변하는 경우에도 효과는 국부적이고 잘 문서화되어 있으며 '예기치 않은'상호 작용이 최소로 유지 될 것입니다. 현실 세계에는 무수한 방식으로 글로벌 상태와 상호 작용하는 API가 많이 있으며, 이것이 가장 악의적 인 버그의 원천입니다. 무국적으로 열망하는 것은 구성 요소 간의 의도하지 않은/암시 적/비하인드 스토리 상호 작용을 없애기를 열망하고 있습니다.

무국적 기능의 장점 중 하나는 함수의 반환 값의 사전 계산 또는 캐싱을 허용한다는 것입니다. 일부 C 컴파일러조차도 최적 기능을 향상시키기 위해 기능을 상태를 명시 적으로 표시 할 수 있습니다. 다른 많은 사람들이 언급했듯이 무국적 기능은 평행을 훨씬 쉽게합니다.

그러나 효율성만이 유일한 관심사는 아닙니다. 순수한 기능은 명시 적으로 명시되어 있기 때문에 테스트하고 디버깅하기가 더 쉽습니다. 그리고 기능적 언어로 프로그래밍 할 때 가능한 한 적은 기능을 "더러운"(I/O 등)로 만드는 습관이 있습니다. 이런 식으로 상태의 상태를 분리하는 것은 기능이 아닌 언어로도 프로그램을 설계하는 좋은 방법입니다.

기능적 언어는 "얻는"데 시간이 걸릴 수 있으며, 그 과정을 거치지 않은 사람에게 설명하기가 어렵습니다. 그러나 충분히 오래 지속되는 대부분의 사람들은 마침내 기능적 언어를 많이 사용하지 않더라도 소란이 그만한 가치가 있음을 깨닫습니다.

상태가 없으면 코드를 자동으로 병렬화하기가 매우 쉽습니다 (CPU는 점점 더 많은 코어로 만들어 지므로 매우 중요합니다).

나는이 주제에 대한 글을 썼다. 순결의 중요성에.

Stateless 웹 응용 프로그램은 필수적인 시작할 때 높은 트래픽이다.

될 수 있습을 많이 사용자 데이터를 저장하고 싶지 않은 클라이언트 측에서 보안상의 이유로 대한 예입니다.이 경우에 당신은 그것을 저장하는 데 필요 server-side.당신이 사용할 수 있습 웹 응용 프로그램의 기본 세션이지만 경우에 당신은 하나 이상의 인스턴스의 응용 프로그램을 것입니다 있는지 확인해야 각 사용자는 언제나 감독은 동일한 인스턴스입니다.

로드 밸런서 자주하는 능력이 있는가'스티커션'어디로 로드 밸런서 어떤 방법을 알고 있는 서버에 보낼 사용자가 요청니다.이것은 이상적이지 않지만,예를 들어 의미를 다시 시작할 때마다 당신의 웹 응용 프로그램,모든 연결된 사용자를 잃을 것이 자신의 세션이 있습니다.

더 나은 방법은 저장소의 세션 뒤에는 웹 서버에 어떤 종류의 데이터 저장,이러한 일이 있 관 nosql 사용할 수 있는 제품에 대한 이(redis,몽고,동 방법,memcached).이 방법으로 웹 서버는 무국적이지만 당신은 여전히 상태가 서버 측의 가용성이 상태로 관리할 수 있는 권리를 선택하여 데이터 저장소 설치.이러한 데이터 저장 일반적으로 좋은 중복 그래서 그것은 거의 항상될 가능한 변경 사항을 귀하의 웹 응용 프로그램 및 데이터 저장에 영향을 주지 않고 사용자.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top