[functional-programming] 기능 프로그래밍을위한 소프트웨어 엔지니어링 방법론이 있습니까? [닫은]

오늘날 가르치는 소프트웨어 엔지니어링은 전적으로 객체 지향 프로그래밍과 ‘자연적인’객체 지향 관점에 중점을두고 있습니다. 도메인 모델을 여러 단계와 유스 케이스 다이어그램 또는 클래스 다이어그램과 같은 많은 (UML) 아티팩트로 클래스 모델로 변환하는 방법을 설명하는 자세한 방법이 있습니다. 많은 프로그래머들이이 접근 방식을 내재화했으며 처음부터 객체 지향 응용 프로그램을 설계하는 방법에 대한 좋은 아이디어를 가지고 있습니다.

새로운 과대 광고는 기능적인 프로그래밍으로, 많은 서적과 자습서에서 진행됩니다. 그러나 기능적 소프트웨어 엔지니어링은 어떻습니까? Lisp와 Clojure에 대해 읽는 동안 두 가지 흥미로운 진술이 나왔습니다.

  1. 기능 프로그램은 종종 하향식 대신 상향식으로 개발됩니다 ( ‘On Lisp’, Paul Graham)

  2. 기능 프로그래머는 OO 프로그래머가 객체 / 클래스를 사용하는 맵을 사용합니다 ( ‘Clojure for Java Programmers’, Rich Hickley의 대화).

그렇다면 Lisp 또는 Clojure와 같은 기능적 응용 프로그램의 체계적인 (모델 기반?) 디자인 방법론은 무엇입니까? 공통 단계는 무엇이며 어떤 이슈를 사용합니까? 문제 공간에서 솔루션 공간으로 어떻게 매핑합니까?



답변

소프트웨어 엔지니어들이 아직 기능적 프로그래밍을 발견하지 못했음을 하느님 께 감사하십시오. 다음은 몇 가지 유사점입니다.

  • 많은 OO “디자인 패턴”은 고차 함수로 캡처됩니다. 예를 들어, 방문자 패턴은 기능적 세계에서 “접힘”(또는 뾰족한 이론가 인 경우 “변형”)으로 알려져 있습니다. 기능적 언어에서 데이터 유형은 대부분 나무 또는 튜플이며 모든 트리 유형에는 이와 관련된 자연적인 변이 형이 있습니다.

    이러한 고차 함수에는 종종 “자유 정리”라고하는 특정 프로그래밍 법칙이 있습니다.

  • 기능 프로그래머는 OO 프로그래머보다 다이어그램을 훨씬 덜 사용합니다. OO 다이어그램에서 표현되는 대부분은 유형 또는 “서명”으로 표현되며 ,이를 “모듈 유형”으로 생각해야합니다. Haskell에는 인터페이스 유형과 비슷한 “유형 클래스”도 있습니다.

    타입을 사용하는 함수형 프로그래머는 일반적으로 “한 번 타입이 맞으면 코드가 실제로 작성됩니다”라고 생각합니다.

    모든 기능적 언어가 명시 적 유형을 사용 하는 것은 아니지만 Scheme / Lisp / Clojure 학습을위한 훌륭한 책인 How To Design Programs 책은 유형과 밀접한 관련이있는 “데이터 설명”에 크게 의존합니다.

그렇다면 Lisp 또는 Clojure와 같은 기능적 응용 프로그램의 체계적인 (모델 기반?) 디자인 방법론은 무엇입니까?

데이터 추상화에 기반한 모든 설계 방법이 효과적입니다. 언어에 명시 적 유형이 있으면 더 쉽다고 생각하지만 없이도 작동합니다. 함수형 프로그래밍에 쉽게 적용 할 수있는 추상 데이터 형식의 디자인 방법에 대한 좋은 책은 Barbara Liskov와 첫 번째 버전 인 John Guttag의 프로그램 개발의 추상화 및 사양입니다 . Liskov는 그 작업으로 부분적으로 Turing 상을 수상했습니다.

Lisp의 고유 한 또 다른 디자인 방법은 작업중인 문제 영역에서 어떤 언어 확장이 유용한 지 결정한 다음 위생적인 ​​매크로를 사용하여 이러한 구문을 언어에 추가하는 것입니다. 이런 종류의 디자인에 대해 읽을 수있는 좋은 곳은 Matthew Flatt의 기사 (Create Languages ​​in Racket) 입니다. 기사는 페이 월 뒤에있을 수 있습니다. “도메인 특정 내장 언어”라는 용어를 검색하여 이러한 종류의 디자인에 대한보다 일반적인 자료를 찾을 수도 있습니다. Matthew Flatt가 다루는 것 이상의 특별한 조언과 예를 들어 Graham의 On Lisp 또는 ANSI Common Lisp로 시작할 것입니다 .

일반적인 단계는 무엇이며 어떤 이슈를 사용합니까?

일반적인 단계 :

  1. 프로그램의 데이터와 그 조작을 식별하고이 데이터를 나타내는 추상 데이터 유형을 정의하십시오.

  2. 일반적인 동작 또는 계산 패턴을 식별하여 고차 함수 또는 매크로로 표현하십시오. 리팩토링의 일부로이 단계를 수행하십시오.

  3. 형식화 된 기능 언어를 사용하는 경우 형식 검사기를 조기에 자주 사용하십시오. Lisp 또는 Clojure를 사용하는 경우 가장 좋은 방법은 먼저 단위 테스트를 포함한 기능 계약을 작성하는 것입니다. 테스트 중심 개발은 최대입니다. 그리고 플랫폼에 포팅 된 QuickCheck의 모든 버전을 사용하고 싶을 것입니다.이 경우 ClojureCheck 라고 합니다 . 고차 함수를 사용하는 임의의 코드 테스트를 구성하기위한 매우 강력한 라이브러리입니다.


답변

Clojure의 경우 좋은 관계형 모델링으로 돌아가는 것이 좋습니다. Tarpit 에서 영감을 얻은 내용이 있습니다.


답변

개인적으로 저는 OO 개발의 모든 일반적인 모범 사례가 함수형 프로그래밍에도 적용된다는 사실을 알게되었습니다. 방법 론적 관점에서 근본적으로 다른 것을 할 필요는 없습니다.

내 경험은 최근 몇 년 동안 Java에서 Clojure로 옮겨 왔습니다.

몇 가지 예 :

  • 비즈니스 도메인 / 데이터 모델 이해 -개체 모델을 디자인하거나 중첩 된 맵으로 기능적인 데이터 구조를 만들지 여부와 마찬가지로 중요합니다. 어떤면에서 FP는 함수 / 프로세스와 별도로 데이터 모델에 대해 생각하도록 권장하지만 여전히 두 가지를 모두 수행해야하기 때문에 FP가 더 쉬울 수 있습니다.

  • 디자인의 서비스 방향 -일반적인 서비스는 실제로 일부 부작용이있는 기능이기 때문에 FP 관점에서 실제로 잘 작동합니다. Lisp 세계에서 간혹 소프트웨어 개발에 대한 “하단”관점은 실제로 다른 서비스에서 좋은 서비스 지향 API 디자인 원칙이라고 생각합니다.

  • 테스트 주도 개발 -FP 언어에서 잘 작동합니다. 순수한 기능은 상태 저장 환경을 설정할 필요없이 명확하고 반복 가능한 테스트를 작성하는 데 매우 적합하기 때문에 때로는 더 좋습니다. 또한 데이터 무결성을 확인하기 위해 별도의 테스트를 구축 할 수도 있습니다 (예 :이 맵에는 예상되는 모든 키가 포함되어 있으며, OO 언어에서 클래스 정의가 컴파일 타임에이를 강제한다는 사실의 균형을 유지합니다).

  • 프로토 타이핑 / 반복-FP 와 마찬가지로 작동합니다. 도구 / DSL을 작성하고 REPL에서 사용하는 데 매우 능숙하다면 사용자와 함께 라이브 프로토 타입을 제작할 수도 있습니다.


답변

OO 프로그래밍은 데이터를 동작과 밀접하게 연결합니다. 함수형 프로그래밍은 둘을 분리합니다. 따라서 클래스 다이어그램은 없지만 데이터 구조, 특히 대수 데이터 유형이 있습니다. 이러한 유형은 구성으로 불가능한 값을 제거하는 것을 비롯하여 도메인과 매우 밀접하게 일치하도록 작성 될 수 있습니다.

따라서 거기에는 책과 책이 없지만 말이 진행되는 동안 불가능한 가치를 표현할 수없는 잘 확립 된 접근법이 있습니다.

이렇게하면 특정 유형의 데이터를 함수로 나타내는 대신 선택적으로, 직렬화,보다 엄격한 사양, 최적화 등을 얻을 수 있도록 데이터 유형의 합집합으로 특정 함수를 나타내는 방법을 선택할 수 있습니다. .

그런 다음, adts에 함수를 작성하여 일종의 대수 합니다. 일부는 여러 응용 프로그램 후에 동일합니다. 일부는 연관성이 있습니다. 일부는 전이 등입니다.

이제 당신은 잘 작동하는 법률에 따라 구성하는 기능을 가진 도메인을 갖게되었습니다. 간단한 임베디드 DSL!

아, 그리고 속성이 주어지면 물론 자동화 된 무작위 테스트 (ala QuickCheck)를 작성할 수 있습니다. 그리고 그것은 시작에 불과합니다.


답변

객체 지향 디자인은 소프트웨어 엔지니어링과 다릅니다. 소프트웨어 엔지니어링은 요구 사항에서 작업 시스템으로 진행하는 방법과 결함률이 낮은 전체 프로세스와 관련이 있습니다. 함수형 프로그래밍은 OO와 다를 수 있지만 요구 사항, 높은 수준의 상세 설계, 검증 및 테스트, 소프트웨어 메트릭스, 추정 및 기타 “소프트웨어 엔지니어링 요소”를 없애지 않습니다.

또한 기능적 프로그램은 모듈 성과 기타 구조를 나타냅니다. 세부 설계는 해당 구조의 개념으로 표현되어야합니다.


답변

한 가지 방법은 선택한 기능적 프로그래밍 언어 내에서 내부 DSL을 만드는 것입니다. “모델”은 DSL로 표현 된 일련의 비즈니스 규칙입니다.


답변

다른 게시물에 대한 내 답변보기 :

Clojure는 우려 분리를 어떻게 극복합니까?

FP 접근 방식을 사용하는 대규모 응용 프로그램을 구성하는 방법에 대해 더 많은 주제를 작성해야한다는 데 동의합니다 (FP 기반 UI를 문서화하려면 더 많은 작업을 수행해야 함).