Programing

상태 비 저장 프로그래밍의 장점?

lottogame 2020. 7. 6. 07:47
반응형

상태 비 저장 프로그래밍의 장점?


최근에 함수형 프로그래밍 (특히 Haskell)에 대해 배웠지 만 Lisp 및 Erlang에 대한 자습서도 살펴 보았습니다. 개념이 매우 밝아진 것을 발견했지만 여전히 "부작용 없음"개념의 실제적인 측면을 보지 못했습니다. 그것의 실용적인 장점은 무엇입니까? 나는 기능적 사고 방식을 생각하고 있지만 쉬운 방법으로 상태를 저장할 수있는 능력이 없으면 지나치게 복잡해 보이는 상황이 있습니다 (하스켈의 모나드를 '쉬운'이라고 생각하지 않습니다).

하스켈 (또는 다른 순전히 기능적인 언어)을 계속 깊이 배울 가치가 있습니까? 기능적 또는 상태 비 저장 프로그래밍이 실제로 절차 적보다 더 생산적입니까? 나중에 Haskell 또는 다른 기능적 언어를 계속 사용할 수 있습니까, 아니면 이해를 위해서만 배울 수 있습니까?

생산성보다 성능에 관심이 적습니다. 그래서 나는 주로 절차 적 / 객체 지향적 / 무엇보다 기능적 언어로 더 생산적 일지 묻고 있습니다.


간단히 말해서 기능 프로그래밍을 읽으십시오 .

되어 있지 적어도 어느 비 저장 프로그래밍에 많은 장점이 있습니다 극적으로 멀티 스레드 동시 코드. 솔직히 말하면, 가변 상태는 멀티 스레드 코드의 적입니다. 기본적으로 값을 변경할 수없는 경우 프로그래머는 하나의 스레드가 두 스레드간에 공유 상태 값을 변경하는 것에 대해 걱정할 필요가 없으므로 경쟁 조건과 관련된 전체 멀티 스레딩 버그 클래스를 제거합니다. 경쟁 조건이 없기 때문에 잠금을 사용해야 할 이유가 없으므로 불변성으로 인해 교착 상태와 관련된 또 다른 전체 버그가 제거됩니다.

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


더 많은 프로그램 조각이 상태 비 저장 일수록 더 많은 부분을 나누지 않고 조각을 모을 수있는 더 많은 방법이 있습니다 . 무국적 패러다임의 힘은 무국적 (또는 순도) 자체 가 아니라 강력하고 재사용 가능한 기능 을 작성 하고 결합 할 수있는 능력 입니다.

John Hughes의 논문 Why Functional Programming Matters (PDF) 에서 많은 예제가 포함 된 유용한 자습서를 찾을 수 있습니다 .

당신이 될 것입니다 수병은 당신이 또한 대수 데이터 유형 및 패턴 매칭 (의 Caml, SML, 하스켈)가 있는지 기능적 언어를 선택 특히, 생산성.


다른 많은 답변은 함수 프로그래밍의 성능 (병렬) 측면에 중점을 두 었으며, 이것이 매우 중요하다고 생각합니다. 그러나 생산성과 관련하여 구체적으로 요구 한 것은 명령형 패러다임보다 기능적 패러다임에서 동일한 것을 더 빠르게 프로그래밍 할 수 있습니다.

실제로 F #의 프로그래밍이 내가 생각하는 방식과 일치한다는 것이 개인적 경험에서 알기 때문에 더 쉽습니다. 그것이 가장 큰 차이점이라고 생각합니다. F #과 C #으로 모두 프로그래밍했으며 F #에는 "언어와 싸우기"가 훨씬 적습니다. F #의 세부 사항에 대해 생각할 필요가 없습니다. 내가 찾은 것의 몇 가지 예는 다음과 같습니다.

예를 들어, F #이 정적으로 형식이 지정되었지만 (모든 형식이 컴파일 타임에 해결됨) 형식 유추는 어떤 형식이 있는지 파악하므로 말할 필요가 없습니다. 그리고 그것을 알아낼 수 없다면, 자동으로 함수 / 클래스 / 일반적인 것을 자동으로 만듭니다. 따라서 일반적인 내용을 작성할 필요가 없으며 모두 자동입니다. 즉, 문제에 대해 생각하고 구현하는 방법이 적다는 것을 의미합니다. 실제로 C #으로 돌아올 때 마다이 유형 유추를 놓친다는 것을 알았으므로 더 이상 할 필요가 없을 때까지 어떻게 산만하게하는지 알지 못합니다.

또한 F #에서는 루프를 작성하는 대신 함수를 호출합니다. 루프 구성에 대해 더 이상 생각할 필요가 없기 때문에 미묘한 변화이지만 중요합니다. 예를 들어, 여기에 가서 무언가를 일치시키는 코드 조각이 있습니다 (프로젝트 오일러 퍼즐의 내용을 기억할 수는 없습니다).

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

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

나는 또한 F #을 ocaml과 다른 기능적 언어와 분리한다고 생각하는 |> 연산자를 좋아합니다. 파이프 연산자이므로 한 표현식의 출력을 다른 표현식의 입력으로 "파이프"할 수 있습니다. 코드가 내가 생각하는 방식을 따르게합니다. 위의 코드 스 니펫에서와 같이 "인수 시퀀스를 가져 와서 필터링 한 다음 매핑하십시오." 루프와 if 문을 작성하는 데 너무 바빠서 명령형 프로그래밍 언어를 사용하지 않는 매우 높은 수준의 사고입니다. 다른 언어로 갈 때마다 가장 그리워하는 것은 바로 하나입니다.

따라서 일반적으로 C #과 F #으로 프로그래밍 할 수 있지만 더 높은 수준으로 생각할 수 있기 때문에 F #을 사용하는 것이 더 쉽다는 것을 알았습니다. 기능적 프로그래밍에서 최소한의 세부 사항이 제거 되었기 때문에 (적어도 F #에서는) 더 생산적이라고 주장합니다.

편집 : 나는 함수형 프로그래밍 언어에서 "상태"의 예를 요청한 의견 중 하나를 보았습니다. F #은 필수적으로 작성 될 수 있으므로 F #에서 변경 가능한 상태를 갖는 방법에 대한 직접적인 예는 다음과 같습니다.

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

디버깅에 오랜 시간을 소비 한 모든 어려운 버그를 고려하십시오.

자, 프로그램의 두 개별 구성 요소 사이에 "의도하지 않은 상호 작용"으로 인해 이러한 버그 중 몇 개가 발생 했습니까? (거의 모든 스레딩 버그는 다음과 같은 형식을 갖습니다. 공유 데이터 작성, 교착 상태 등. ... 또한 전역 상태에 예기치 않은 영향을 미치는 라이브러리를 찾거나 레지스트리 / 환경을 읽거나 쓰는 등이 일반적입니다.) I '하드 버그'3 개 중 1 개 이상이이 범주에 속한다고합니다.

Now if you switch to stateless/immutable/pure programming, all those bugs go away. You are presented with some new challenges instead (e.g. when you do want different modules to interact with the environment), but in a language like Haskell, those interactions get explicitly reified into the type system, which means you can just look at the type of a function and reason about the type of interactions it can have with the rest of the program.

That's the big win from 'immutability' IMO. In an ideal world, we'd all design terrific APIs and even when things were mutable, effects would be local and well-documented and 'unexpected' interactions would be kept to a minimum. In the real world, there are lots of APIs that interact with global state in myriad ways, and these are the source of the most pernicious bugs. Aspiring to statelessness is aspiring to be rid of unintended/implicit/behind-the-scenes interactions among components.


One advantage of stateless functions is that they permit precalculation or caching of the function's return values. Even some C compilers allow you to explicitly mark functions as stateless to improve their optimisability. As many others have noted, stateless functions are much easier to parallelise.

But efficiency is not the only concern. A pure function is easier to test and debug since anything that affects it is explicitly stated. And when programming in a functional language, one gets in the habit of making as few functions "dirty" (with I/O, etc.) as possible. Separating out the stateful stuff this way is a good way to design programs, even in not-so-functional languages.

Functional languages can take a while to "get", and it's difficult to explain to someone who hasn't gone through that process. But most people who persist long enough finally realise that the fuss is worth it, even if they don't end up using functional languages much.


Without state, it is very easy to automatically parallelize your code (as CPUs are made with more and more cores this is very important).


I wrote a post on just this subject awhile back: On The Importance of Purity.


Stateless web applications are essential when you start having higher traffic.

There could be plenty of user data that you don't want to store on the client side for security reasons for example. In this case you need to store it server-side. You could use the web applications default session but if you have more than one instance of the application you will need to make sure that each user is always directed to the same instance.

Load balancers often have the ability to have 'sticky sessions' where the load balancer some how knows which server to send the users request to. This is not ideal though, for example it means every time you restart your web application, all connected users will lose their session.

A better approach is to store the session behind the web servers in some sort of data store, these days there are loads of great nosql products available for this (redis, mongo, elasticsearch, memcached). This way the web servers are stateless but you still have state server-side and the availability of this state can be managed by choosing the right datastore setup. These data stores usually have great redundancy so it should almost always be possible to make changes to your web application and even the data store without impacting the users.

참고URL : https://stackoverflow.com/questions/844536/advantages-of-stateless-programming

반응형