삽질의 현장/- ETC

프로그램을 작성하는 33가지 방법 - Chaptor 09 정리

shovelman 2019. 3. 23. 19:45

최근 '프로그래밍 패턴 (프로그램을 작성하는 33가지 방법)' 을 읽기 시작했다.

한 가지의 기능을 Chaptor 마다 각각 다른 패턴으로 구현하여 설명한 책이다.

모두 비슷하게 동작하지만 환경과 상황이라는 제약 조건 안에서 탄생된 패턴을 직접 코드로 보여주고 있어직접 코딩을 하며 이해하고 있는 중이다.

책에서 소개하는 한 가지 기능은 '텍스트 파일을 읽어 단어 빈도 출력' 하는 프로그램이다.


가장 빈도가 높은 단어 순으로 그에 해당하는 빈도를 내림차순으로 출력하는 기능을 구현하고 있다.

이전 Chaptor 보기 :프로그램을 작성하는 33가지 방법 - Chaptor 08 정리


Chaptor 09 유일

  • 값이 변환될 대상인 추상화가 존재한다.
  • 이 추상화는
    • (1) 값을 감싸 그 값을 해당하는 추상화로 만들고
    • (2) 자신을 함수와 결합해 일련의 함수를 수립하며
    • (3) 최종 결과를 살펴볼 수 있도록 그 값을 풀어내는 연산을 제공한다.
  • 규모가 큰 문제를 함수 파이프라인을 함께 결합하고 마지막에 값을 다시 풀어내서 해결한다.
  • 유일 형식에서는 특히 결합 연산에서 주어진 함수를 단순히 호출하기만 하는데,
    이때 연산에서 담고 있는 값을 그 함수에 전달한 다음 그 함수에서 반환된 값을 다시 담는다.


여러 함수를 조합하는 것을 넘어 함수를 배열하고 있다.

class TFTheOne:
    def __init__(self, v):
        self._value = v
    
    def bind(self, func):
        self._value = func(self._value)
        return self

    def printme(self):
        print (self._value)

#
# 주 함수
#
TFTheOne(sys.argv[1])\\
.bind(read_file)\\
.bind(normalize)\\
.bind(scan)\\
.bind(remove_stop_words)\\
.bind(frequencies)\\
.bind(sort)\\
.bind(top25_freqs)\\
.printme()


'TFTheOne' 이라는 클래스를 정의하여 매개변수로 들어온 값을 감싸고(init), 함수 호출을 통해 새로 반환된 결과가 반영된 인스턴스를 반환한다. (bind),

이 형식은 함수형 프로그래밍 언어인 하스켈의 동일성 모나드(Identity monad)에서 유래했다.

모나드란?

일련의 단계로 정의한 계산을 캡슐화한 구조(ex.객체). 모나드에는 두가지 주요 연산이 있다.

  • (1) 모나드 안에 값을 감싸는 생성자
  • (2) 함수를 인자로 취해 이를 어떤 방법으로 모나드에 결합한 다음, 어떤 모나드를 반환하는 결합 연산


대부분 프로그래밍 언어에서는 이 같은 표준적인 함수 합성 형식을 제공해 왔다.

word_freqs = sort(frequencies(remove_stop_words(scan(
		filter_chars_and_normalize(read_file(sys.argv[1]))))))


맺으며

메서드 체이닝을 왼쪽에서 오른쪽으로 하는 특성 외 뭐가 있는가?

연쇄적인 계산을 서로 다른 방법으로 할 수 있다는데, 뭔지 모르겠다. 책을 더 읽어보면 말해준다고 한다.

모나드에 대한 학습이 필요할까?