* 모든 * 프로그램 작업을 상태없이 표현할 수 있습니까?


13

이것은 이론적 인 질문이지만, 현재 C ++을 사용하여 "정상적인"명령 기법으로 수년간의 프로그래밍을 한 후, 다른 기능적 프로그래밍 세계를 발견했습니다. JavaScript를 우연히 배우면서 우연히 넘어졌습니다.

이것은 완전한 상태 지향 프로그램을 순수하게 기능하고 상태가없는 다른 구현으로 기술적으로 대체 할 수 있는지 궁금해했습니다.

흥미로운 아이디어이며, 함수형 프로그래밍에 분명하고 우아함이 있다는 사실을 인정해야합니다.


1
관련 StackOverflow 답변 : stackoverflow.com/questions/3722084/…
jfriend00

특정 시점에서 다음 시점까지 지속되는 상태가 있는지 여부는 사용하는 프로그래밍 패러다임이 아니라 코딩하는 문제 또는 작업에 따라 다릅니다. 버튼을 클릭 한 횟수를 세는 경우 해당 카운터를 기록 할 상태가 분명하며 사용하는 코딩 기술에 관계없이 프로세스 중에 카운트를 추적하는 상태가 있어야합니다. 따라서 특정 작업은 코딩 방법에 관계없이 상태없이 완료 될 수 없습니다.
jfriend00

6
당신이 상태를 논의하고 싶다면; 프로그램 자체에만 필요한 경우 명확하게 진술해야합니다. 그것은 당신이 변하기 쉬운 대 불변의 상태를 생각하고있는 것처럼 들립니다-당신은 질문에서 당신이 의미하는 것을 나타낼 수 있습니다.
Billy ONeal

1
모든 프로그램을 진정한 Turing 머신으로 변환 할 수 있는지 묻는 것과 같습니다. 기술적으로는 데이터베이스에서 저장하고로드하는 프로그램조차 튜링 머신에서이 동작을 시뮬레이션하기가 훨씬 어려워집니다. 마찬가지로 MVC 아키텍처에서 컨트롤러 측을 제거하고 모든 호출을 수행하는 프로그램을 가질 수 있지만 다시 처리하기가 더 어려워집니다 (기본적으로 프로그램을 무국적 상태로 만들기 위해 컨트롤러가됩니다).
Neil

답변:


17

짧은 대답 : 예. Wikipedia에 따르면, Alan Turing은 1937 년에 튜링 머신과 람다 미적분 의 계산이 보편적 인 계산 모델임을 보여 주었다. 튜링 머신의 계산 모델은 명령형 또는 스테이트 풀 프로그래밍에 대해 이야기 할 때 일반적으로 염두에두고 있으며 람다 미적분학은 "순수 함수형 프로그래밍"을 수학적으로 형식화 한 것입니다.

모든 효과적인 계산 모델은 튜링 머신과 동일한 계산을 수행 할 수 있으며 그 반대도 가능합니다. 이것을 교회 튜링 논문 이라고 합니다. 그러나이 계산은 "효과적인 계산 모델"이라는 다소 직관적 인 용어 때문에 입증 될 수 없습니다 (아마도 누군가가 미래에 새로운 모델을 발명 할 것입니까?)


2
당신의 동일한 주장은 투어링 머신과 동등한 λ 계산법이므로 모든 계산은 (거의 숨겨진) 상태를 가져야한다는 것을 되돌릴 수 있습니다. is가 코드 외부 (변수) 또는 플로우 내부 (스택 기반 함수 호출)로 표시되는지 여부는 항상 "상태"입니다.
Emilio Garavaglia

3
람다 미적분학에는 상태가 있습니다. 제약 조건은 상태가 변경 불가능하다는 것입니다. 불변 상태는 여전히 상태입니다. 람다를 포함한 함수에 대한 매개 변수는 여전히 상태입니다. 아마도 다른 매개 변수가 주어지면 함수가 다른 동작을 갖기를 원합니다.
Billy ONeal

@emilio 문제에 대한 동등한 상태 기반 솔루션이 있다고 주장하는 것은 (기술 한 바와 같이) 해당 솔루션의 상태 비 저장 버전이 존재하지 않는다는 증거는 아닙니다.
Billy ONeal

2
@EmilioGaravaglia 당신은 다음 람다 미적분 통역의 상태를 참조하고 있습니다. 람다 미적분에서 추론 할 때 상태에 대해 추론 할 필요가 없습니다. 또한 "돌연변이 성"측면도 다릅니다.
wirrbel

1
@EmilioGaravglia : 명령형 프로그래밍의 상태는 한 번에 메모리 구성입니다. 여기에서 매개 변수 공간은 가능한 모든 메모리 값으로 제공되며 상태는 한 번에 하나의 구성 (튜링 머신의 대역)입니다. 람다 미적분학에서 프로그램을 작성할 때 메모리 필드와 같은 직접적인 실체는 없습니다. 프로그램 실행은 람다 변환의 적용입니다. 중간 단계는 "상태"와 유사 할 수 있지만 동일한 값의 동등한 표현 일뿐입니다. 평가하는 동안 아무것도 변경되지 않고 표현식은 다시 작성되고 "간단한"형식으로 처리됩니다.
wirrbel

14

어떤 역동적 인 시스템에서 "상태"는 당신의 현재가 과거미래의 영향을받는 것 입니다.

"기억해야 할"것이 있거나 수행 한 작업에 따라 달라지는 상태가됩니다.

상태가없는 시스템은 "동적"이 아니라 결합 기능 일뿐입니다. 상태가 없을 수도 있지만 다른 결과를 생성하려면 어떻게 든 상태를 제공해야합니다.

이제 참조하는 계산 모델에 따라 상태를 명시 적으로 (변수 형식으로) 또는 내재적으로 ( "반환 주소"형식으로) 나타낼 수 있습니다.

당신이 fna(fnb(x))할 때 당신은 fna에 대한 상태를 생성하는 fnb 상태를 제공하고 있습니다. 이것은 xfnb가 호출되기 전에 존재하기 때문입니다 (따라서 자체 "과거"에서 나옵니다).

"국가 존재"또는 "국가가 존재하지 않음"의 문제는 아닙니다. 그것은 "나는 상관한다"또는 "나는 상관 없다"의 교인이다.


0

상태는 현재 자극에 기초한 것이 아니라 과거 자극에 의존하는 방식으로 현재 자극에 반응하는 능력을 의미합니다.

순전히 기능적인 프로그램은 기능 일뿐입니다. 따라서 실제 응용 프로그램의 경우 순수 기능 프로그램은 쌍 (old_state * present_stimulus)을 입력하고 쌍 (new_state * present_response)을 출력합니다. 다음 자극을 기다리고 상태를 전파하려면 외부의 상태 저장 "루퍼"가 필요합니다.

순전히 기능적인 프로그램은 본질적으로 상태를 갖지 않으며 실제 응용 프로그램에 직접 사용할 수 없습니다.

따라서 어떠한 상태 지향 프로그램은 순전히 기능적 상태없이 다른 구현으로 대체 될 수 없다.


0

외부 세계와 상호 작용할 필요가없는 한 명시적인 변경 가능한 상태를 피할 수 있습니다.

자바 스크립트에서 프로그램이 실제로 프로세서주기를 넘어서는 효과를 가지려면 Dom 또는 Window 객체를 수정해야하며 이러한 API는 상태 저장 상태입니다. 그러나 Dom 및 Window 객체를 매개 변수로 JavaScript 코드에 전달한 다음 새로운 Dom / Window를 출력으로받는 래퍼를 만들 수 있다고 가정합니다. 이것은 JavaScript 코드를 변경 가능한 상태에서 격리시킵니다.

물론 브라우저 창과 DOM은 본질적으로 상태가 풍부하기 때문에 여전히 상태에 의존하고 있습니다. 모든 대화 형 응용 프로그램은 기본적으로 상태 저장 기능이지만 명시 적 상태를 최소화하도록 코드를 구조화 할 수 있습니다.

다른 질문은 그것이 좋은 아이디어인지의 여부입니다. 설계 상 순수한 기능 언어 인 Haskell조차도 변경 가능한 상태를 시뮬레이션 할 수있는 '상태'모나드를 포함합니다. 이것은 명백한 변경 가능한 상태가 때때로 바람직한 패턴임을 보여줍니다.


0

상태가없는 프로그래밍 언어로 "상태 머신"을 구현하는 방법에 대해 생각해보십시오.

실제로 할 수도 있지만 함수 이름을 스토리지로 사용하게 될 것입니다. gobblyday gook로 끝나는 :

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