이글 기다린 사람이 얼마나 될진 모르겠는데 일단 사죄부터 하겠음.
파트 1 올리고 한달 후에 파트 2 올린다고 해 놓고 무려 두달 반을 박아버림. 사실 좀 놀긴 했는데 쓰는거 자체도 생각보다 빡세더라.
그냥 이 파트 자체가 말도 안되게 쓰기 어려웠던것 같다.
이유는 글을 보면 알거다. 내 강의철학의 핵심이 여기 다 들어있다고 해도 좋을 만큼 워낙에 중요한 내용이 많다.
여기서 다루는 게 주로 이상한 비유가지고 모나드 가르쳐주는 튜토리얼들인데
이런 류의 튜토리얼들이야 뭐 굳이 내가 나서서 깔것도 없이 대한민국에서 의무교육 받은 성인이면 척봐도 한눈에 저열함을 눈치챌 수 있어서
그냥 까면 되는걸 고생할게 뭐가 있냐는 의문이 들 것이지만 그게 그렇지가 않음.
이 글의 목적은 물론 거지같은 모나드 튜토리얼들 신명나게 자진모리 장단으로 두들겨패서 독자들에게 카타르시스 주는 것도 있지만 그게 전부는 아니다.
그런 실패의 배경에 어떤 오류가 있는지 분석하고 대안을 제시하는 게 더 중요하다.
어디서부터 손대야 할지도 모를 만큼 잘못된 것들이 더 다루기 힘들다 이말이다. 근본부터 다시 따져 봐야 하니깐.
하여간 그렇다는 얘기고 앞의 파트 1까지 포함된 전문은 여기서 보면 됨.
https://github.com/attltb/Lecture-Monad
애초에 모나드 강의도 아니고 지금까지의 모나드 강의가 왜 실패했느냐에 대한 메타분석 + 해결책 제시가 주제라 독자층이 아주 제한적일 수밖에 없는데
본인이 모나드 강의 만들게 아니라면 그냥 이런게 재밌는 분들만 읽으면 되겠다.
아예 모나드라는 걸 모르거나 들어보긴 했는데 아직 이해하지 못했으면 이글부터 보면 됨.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
3. 위기 - 엇나간 질문
3-1. 이해를 이해하기
'모나드는 무엇인가?' 라는 질문은 물론 잘못된 것이다. 나중에는 거의 모든 사람들이 그것을 이해했다. 문제는 올바른 질문이 무엇인가다.
어떤 사람들은 그 질문이 '모나드는 프로그래밍에 어떻게 활용하는가?' 라고 믿는다. 나는 회의적이다. 모나드를 정의와 활용만 가지고 설명하려 한 시도들은 이미 셀 수도 없을 만큼 많다. 모나드를 설명하는 방법 중 가장 먼저 시도된 것이 그것이었다. '모나드는 무엇인가?' 에 대한 대중의 집착은 오히려 그것이 성공적이지 못했다는 사실의 결과였다.
그렇다면 올바른 질문은 무엇인가? 어떤 질문이 모나드와 같은 추상적인 개념을 진정으로 이해하게 하는가?
어쩌면 모나드는 이런 근본적인 질문을 다루기에는 그리 좋은 소재가 아닐지도 모른다. 그것은 너무 크고 복합적이다. 같은 질문을 더 작은 규모에서 다룰 수 있게 해 주는 좋은 예가 있다. 하스켈의 do, 스칼라의 for 같은 모나드 전용 문법들이 바로 그것이다.
'그것은 어떻게 사용하는가?' 관점을 가진 이들에게 이 문법들은 아주 설명하기 쉬워 보였다. 모나드 전용 문법들은 다소 복잡하지만 외우기 힘들 정도는 아니다. 필요한 것은 독자들이 그 문법들에 익숙해질 수 있도록 충분히 많은 활용 예제를 보여 주는 것 뿐이다. 프로그래밍 언어의 문법을 설명하는 데 정의와 활용 말고 다른 무엇이 필요하겠는가?
그러나 예상치 못한 일이 일어났다. 독자들은 모나드 전용 문법의 형식적인 정의와 각 활용 예제들은 잘 이해하는 듯했다. 이상한 건 그 이후다.
독자들은 그들이 그 문법들을 진정으로 이해했다고는 결코 생각하지 않았다. 그들은 계속해서 무언가가 이해가 가지 않는다고 말하곤 했다. 무엇이 이해가 가지 않는 건지는 그들 자신도 몰랐다. 물어 보면 그들은 '이 do 표기법의 의미는 무엇인가?' 따위의 어리석은 질문이나 할 뿐이었다.
모나드 튜토리얼의 저자들은 기회가 있을 때마다 'do 표기법은 단지 문법 설탕일 뿐이다' 같은 것을 말하며 독자들의 그런 무의미한 의문을 차단하기 위해 최선을 다했다. 그러나 그 노력이 성과를 거두는 일은 없었다. 독자들은 명백히 그들이 그 설탕을 이해하게 해 줄 다른 무언가를 요구하고 있었다. 문제는 그 무언가가 무엇이냐는 것이다.
3-2. 이해는 필연성을 발견하는 것이다.
답은 명백하다. 나는 이 문제에 대해 한 번이라도 진지하게 고찰해 본 사람이라면 다른 결론을 내리는 것이 불가능할 거라고 믿는다. 독자들에게는 그 설탕의 존재가 충분히 개연적인 것으로 보이지 않았다. 그들이 원했던 건 그 개연성을 채워 줄 무언가였다. 그들은 프로그래밍의 관점에서 그 설탕이 왜 충분히 만들어질 만한 것이었는지에 대한 설명을 요구하고 있었던 것이다.
do 표기법과 for 형식을 이루는 규칙들은 복잡하다. 그것은 외우기 힘들 만큼 복잡하지는 않다. 그러나 그것의 동기와 배경을 추측하는 것이 거의 불가능하게 할 만큼은 충분히 복잡하다.
그러한 문법들이 코드를 더 짧고 직관적으로 만들어 준다는 건 사실이다. 문제는 그 원리다. 그것은 왜 유용한가? 그것은 왜 그렇게 기묘하게 정의되어야 유용한가? 그 문법들 가지고 축약할 수 있는 건 람다 정의와 >>= 가 중첩된, 의미가 잘 와닿지 않는 특정 패턴의 코드들 뿐이다. 그런 코드들이 자주 사용될 거라는 것을 어떻게 아는가? 설계자들은 어떻게 그것을 알고 그 문법들을 그렇게 만든 것인가? 우연히? 그런 것이 우연히 발견될 수도 있는 것인가?
물론 아니다. 독자들은 그 문법들의 이면에 무언가 설명되지 않은 것들이 있음을, 바로 거기에 그들이 그 문법들을 진정으로 직관화하게 해 줄 단서가 있음을 느꼈다. 단지 그들은 그것을 어떻게 물어 봐야 할지 몰랐을 뿐이다. 그들의 무의미해 보이는 질문들은 이런 사정의 결과였던 것이다.
그들의 불만족감을 해소해주는 방법은 간단하다. 그들이 원하는 것을 제공하면 된다: 그러한 문법들이 왜 만들어져야 했는지, 만들어지더라도 왜 하필 우리가 아는 그 형태로 만들어져야 했는지로 이어지는 필연적인 논리의 사슬.
그것을 제공하는 것은 물론 어렵다. 그러나 불가능한 일은 아니다. 모나드에 대한 작동하는 설명은 가능한 방법 중 하나를 보여 준다. 우선 그것은 다음과 같은 질문을 던진다: 변수가 여러 개인 계산들은 (A, B)->T<C> 타입의 이변수 함수, 또는 그것을 커링한 A->B->T<C>타입의 함수로 나타낼 수 있을 것이다. 이들을 T<A>, T<B>를 반환하는 다른 계산들과 합성해야 한다고 하자. 어떻게 하면 되는가?
답은 곧 밝혀지지만 그리 간단하지는 않다. 다변수 계산들을 이용할 때마다 매번 그런 조작을 하는 건 아무래도 번거롭다. 무엇보다 상황을 불만족스럽게 만드는 것은 결코 답의 논리 자체가 어려운 것이 아니라는 것이다. 우리는 직관적으로 독립적인 두 변수 x와 y가 포함된 식을 필요에 따라 x의 함수로 보고 조작하는 일을 할 수 있지만 프로그래밍 언어의 문법은 그렇지 않다. 프로그래밍 언어로 같은 일을 하려면 매번 식을 감싸는 함수를 직접 정의해야 한다. 그것이 다변수 계산의 합성 코드를 불필요하게 복잡하게 한다.
어떻게 하면 이 문제를 해결할 수 있을까? 한 가지 방법이 있다. 우리의 직관적인 사고 논리를 더 잘 나타내 주는 새로운 문법을 도입하는 것이다. 하스켈의 do, 스칼라의 for와 같은 모나드 전용 문법들이 바로 그것이다.
모나드 전용 문법들은 상술한 'x와 y가 포함된 식을 x의 함수로 보고 조작하는' 과정을 자동화한다. 모나드에 대한 작동하는 설명은 가상적인 적분 전용 문법과 그것을 비교함으로써 그것이 왜 다변수 조작에 대한 우리의 직관 논리를 더 자연스럽게 표현하는지 가르쳐 준다. 결국 몇개의 예제를 보여 줘도 do 표기법을 이해하지 못한 이들을 이해하게 한 것은 이 설명이었다.
다른 추상적인 개념들을 설명할 때도 마찬가지다. 얼마나 많은 이들이 양자역학을 배우면서, 수반(adjunction)과 같은 수학 개념을 배우면서 무언가가 이해되지 않는다는 어려움을 호소하는지 보라. 그들도 늘 비슷한 무의미한 질문을 던진다. '이 법칙은 왜 성립하는 것인가?' 등등.
교단에 선 이들은 기회가 있을 때마다 '이것은 그냥 자연 법칙일 뿐이다', 또는 '그냥 개념의 정의가 그럴 뿐이다' 같은 말들을 되풀이하며 학생들의 무의미한 의문을 차단하기 위해 최선을 다했다. 그러나 그 노력이 성과를 거두는 일은 없었다. 학생들은 명백히 그들이 그 정의를 이해하게 해 줄 다른 무언가를 요구하고 있었다. 문제는 그 무엇이 무엇이냐다.
일견 무의미해 보이는 그 질문들을 통해 학생들이 진정으로 묻고 있는 것은 무엇일까? 언제나 같다. '이 개념들은 왜 이런 형태로 만들어져야 했는가?' 다.
우리가 어떠한 추상적인 개념을 이해하는 건 그것의 정의를 알았을 때가 아니다. 그것이 왜 그런 정의를 가져야 하는지 설명할 수 있게 되었을 때다. 궁극적으로 우리는 그 개념의 창시자와 동격의 자리에 서서 그 개념을 필연적으로 만들어야 했던 그의 동기와 사고를 이해하기를 원한다. 그것을 할 수 없을 때 우리는 우리가 그 개념들을 이해하지 못했다고 느끼는 것이다.
오늘날 나쁜 강의를 일삼는 이들의 가장 큰 문제는 그들이 정확히 무엇을 가르쳐야 하는지 모른다는 데 있다. 이해는 언제나 무언가의 필연성을 발견하는 것이다. 특히 모나드처럼 추상적인 대상에 대한 강의는 그것을 전달하지 못하면 절대로 작동하지 않는다.
3-3. 은유 기반 튜토리얼들
본격적인 모나드 튜토리얼의 시대가 열린 후 그 사업에 뛰어든 후발주자들은 모나드를 이해하는 것이 단지 그것의 정의를 아는 것과는 다르다는 것은 알았다. 그것을 이해하려면 다른 무언가가 필요했다. 문제는 그것이 무엇이냐였다.
그들은 그들이 직접 모나드를 써 보면서 얻은 모나드가 무엇인가에 대한 어렴풋한 감각에 집착했다. 그들의 관심사는 명확한 말로는 잘 표현되지 않는 그 감각을 어떻게 전달할 것인가였다. 그들은 누구나 이해할 수 있는 쉬운 은유에 그 비결이 있다고 믿었다. "계산" 같은 추상적이고 이해하기 힘든 해석이 아닌, 쉽게 시각화할 수 있는 사물들을 이용하는 쉬운 은유에.
Eric Kow의 Of monads and spacesuits[ 10]는 그러한 시도의 전형적인 사례다. 여기서 저자는 값을 우주 비행사에, 함수를 우주 정거장에 비유한다.
Imagine that we are in some vast expanse of space. Scattered throughout space are a bunch of space stations. A space station is just a metaphor for a function: it takes astronauts in, and spits astronauts out. (우리가 어떤 광대한 우주 공간에 있다고 상상해 보라. 우주 도처에는 우주 정거장들이 흩어져 있다. 우주 정거장은 단지 함수를 은유적으로 나타낸 것에 지나지 않는다. 그것은 우주 비행사를 들여보내고 우주 비행사를 뱉어낸다.)
모나드는 우주복에 비유된다. 모나드 타입을 반환하는 함수들은 우주 비행사를 그냥 내보내는 대신 우주복으로 감싸서 내보내는 우주 정거장과 같다.
... The solution here would be to stick the astronaut into some kind of space suit before sending him or her to the next station. In fact, this is such a good solution, and we the people are so concerned about the well-being of our astronauts that we're going to issue a new directive: All space stations must put their astronauts into space suits before sending them out. (... 해결책은 우주 비행사를 다음 우주 정거장에 보내기 전에 일종의 우주복으로 감싸는 것이다. 이것은 너무나 좋은 해결책이며, 우리는 우주 비행사의 안전에 대해 매우 신경쓰고 있으므로 우리는 새로운 법률을 제정할 것이다: 모든 우주 정거장은 우주 비행사들을 우주에 내보내기 전에 우주복으로 감싸야 한다.)
문제는 이 우주 정거장들이 입력으로는 우주복을 입은 우주 비행사를 요구하지 않는다는 것이다. 입력으로 사용되는 건 여전히 그냥 우주 비행사다. 이 정거장들을 합성하려면 어떻게 해야 할까? 저자는 bind라는 특수한 로봇을 소개한다.
... what we're going to do is create a kind of robot that takes a space suit (containing some astronaut), takes a space station, removes the astronaut from its suit and feeds the naked astronaut to the space station. This robot shall be called bind informally but will be written in Haskell as >>=. (... 우리가 하려 하는 일은 우주복을 입은 우주 비행사와 우주 정거장이 주어지면 우주 비행사로부터 우주복을 벗겨낸 뒤 벌거벗은 우주 비행사를 우주 정거장에 넣는 특수한 로봇을 만드는 것이다. 이 로봇은 비공식적으로는 bind라고 불리지만 하스켈에서는 >>=로 씌여진다.)
대부분의 사람들은 아무래도 떠오르는 의문을 참을 수 없을 것이다. 왜 그냥 우주 정거장을 출력으로도 입력으로도 우주복을 입은 우주 비행사를 이용하도록 설계하지 않는가? 현실의 우주 정거장들은 그렇게 설계될 것이다. 프로그래머들은 정신병자들 또는 동료 프로그래머들을 고문하기를 좋아하는 새디스트들인가? 모나드가 그냥 우주복 같은 것이라면 왜 그들은 굳이 그것을 값을 반환할 때만 사용하고 입력할 때는 사용하지 않음으로써 번거로운 로봇 없이는 함수들을 합성할 수조차 없게 하는가?
프로그래밍에 모나드 타입을 반환하는 함수들이 사용되는 건 그들이 '실패할 수 있는 함수' 나 '부작용을 가진 함수' 등의 고유의 의미를 갖기 때문이다. 우주복은 그렇지 않다. 우주 정거장들이 우주 비행사에 우주복을 입히는 건 그게 우주 정거장에 무슨 새로운 의미를 제공해서가 아니다. 우주 비행사의 안전을 위해서다. 정작 중요한 핵심적인 부분의 논리는 전혀 모나드의 그것과 대응되지 않는 이런 억지 은유가 정말 모나드 초보자들에게 도움이 될까? 혼란만 가져다주지 않을까? [11]
저자의 은유는 점점 더 혼란스러워진다. 우주복이 비어 있을 수 있는 Maybe 모나드와 우주복에 우주 비행사가 여러 명 타고 있을 수 있는 List 모나드를 소개한 뒤, 그가 다음으로 소개하는 것은 글에 명확히 설명되지 않는 어떤 이유로 '함수 실행과 동시에 일부 정보를 전달해야 할 때 유용하다'고 주장되는 State 모나드다. 이 우주복에 대한 그의 묘사는 이렇다.
... in State space, the space suits are very sophisticated: all space suits have a ticket reader, and when you feed a ticket (st) into the space suit, it opens up to reveal an astronaut and ticket (a, st). (State 우주에서 우주복은 매우 정교하다. 모든 우주복에는 티켓 입력기가 달려 있으며 티켓(st)을 우주복에 넣으면 열려서 우주 비행사와 티켓 (a, st)을 드러낸다.)
불행히도 이 우주복을 우주 정거장에 연결하는 bind 로봇에 대한 저자의 설명은 거의 이해가 불가능하다. 내가 이해한 것이 옳다면 그것은 아무런 합리적인 이유도 없이 우리가 처음부터 가지고 있다고 가정되는 어떤 티켓을 주어진 우주복에 넣은 후, 우주 비행사와 새 티켓이 얻어지면 그 중 우주 비행사를 주어진 우주 정거장에 보내고, 갑자기 어떤 '컨테이너 우주복' 을 만드는데 그 컨테이너 우주복에는 우주 비행사가 아니라 티켓이 주어지면 앞에서 설명한 전체 과정을 수행하는 '루브 골드버그 장치 (Rube Goldberg contraption)' 같은 것이 들어 있다.[12]
우리가 앞에서 본 것은 일반적인 State 우주복에 대한 묘사 아니었는가? State 우주복을 우주 정거장에 bind 했을 때 얻어지는 건 State 우주복이어야 한다. 왜 전혀 달라 보이는 '컨테이너 우주복' 이란 것이 얻어지는가? 그 컨테이너 우주복도 State 우주복인가? 그런 것도 우주복의 범주에 드는가? State 우주복은 정말로 무엇인가?
모르겠다. 더 큰 문제가 있다. 저자의 약속은 분명 모나드의 원리를 시각화해서 이해하기 쉽게 하는 것이었다. 이런 괴상한 걸 어떻게 시각화한다는 말인가? 설령 시각화한다 한들 자체로 이미 모나드보다 더 이해하기 힘든 그 이미지가 정말 모나드의 이해에 도움이 되기는 할까?
3-4. 아무것도 아닌 것을 위한
모나드를 처음 배우는 사람이 어떤 기적에 의해 Eric Kow의 은유를 이해했다고 치자. 그는 무엇을 얻은 것인가? 그 은유는 무엇을 가르쳐 주는가?
저자는 그의 은유가 오직 모나드가 내부적으로 어떻게 작동하는지에 관한 것이며 모나드를 어떻게 사용하는지나 그것이 왜 그렇게 만들어졌는지 등의 다른 질문에 답하기 위한 것은 아님을 비교적 솔직하게 밝힌다.
I do not actually explain how to use monads. Instead I mainly focus on how they work. Perhaps the best people to read this page are those who have some vague idea how to manipulate monadic code but would really like to know what's going on under the hood. I also do not explain why certain conceptual choices are made, preferring instead to short circuit this by use of the space station metaphor. (나는 모나드를 어떻게 사용하는지 설명하지는 않을 것이다. 대신 나는 그들이 어떻게 작동하는지에 초점을 맞추고 싶다. 어쩌면 이 글을 읽기 가장 좋은 사람들은 모나드 코드의 조작 방법에 대한 대강의 개념은 가지고 있지만 장막 아래에서 실제로 어떤 일이 일어나는지 알고 싶어하는 사람들일 것이다. 나는 왜 특정한 개념적 선택이 이루어졌는지 설명하는 대신 우주 정거장의 은유를 통해 그 문제를 피해 갈 것이다.)
이것이 정말로 모나드 초보자들에게 도움이 될까? 저자는 모나드를 대강 알지만 그것을 이해하지는 못한 수 많은 모나드 초보자들의 문제가 단지 그것의 작동 방식에 대한 무지 또는 불완전한 직관화에 있다고 믿는 것으로 보인다. 그것은 정말로 옳은가?
물론 아니다. 모나드 초보자들이 흔히 겪는 혼란스러운 느낌은 언제나 그것이 왜 그렇게 만들어져야 했는지에 대한 무지의 결과다.
모나드에 대한 Eric Kow의 은유가, 그리고 그와 유사한 다른 모든 은유가 아무 쓸모가 없을 수밖에 없는 이유가 바로 여기에 있다. 모나드 초보자들이 그 은유들을 이해해도 그들의 모나드에 대한 의문은 조금도 줄어들지 않을 것이다. 설령 모나드가 우주복 같은 거라고 쳐도, 도대체 그런 게 왜 필요하다는 말인가?
독자들은 이미 내가 전통적인 "계산" 해석에 결코 관대하지 않다는 것을 알 것이다. 모나드 프로그래밍의 관점에서 "계산" 의 의미는 명백하다: 순수하지 않은 연산. 그것을 나타내는 것은 모나드 타입을 반환하는 함수 또는 표현식이다. 모나드 자체가 아니다.
전통적인 "계산" 해석을 지지하는 이들은 unit과 >>=를 가진 타입 컨스트럭터와 결합된 모든 타입의 의미를 포괄하는 직관적인 "계산" 의 개념이 존재한다고 믿는다. 그런 믿음은 터무니없는 것이다. 억지로 그렇게 계산을 재정의할 수는 있다. 문제는 그 정의를 직관적으로 정당화할 수 있느냐다. 지난 20년 동안 모나드 전도사들은 그 정의를 정당화하기는커녕 그것을 난해한 용어나 황설수설 없이 설명할 방법조차 찾지 못했다.
그럼에도 불구, 뒤틀린 "계산" 개념에 기반한 해석은 이해하는 것이 어려울지언정 무의미하지는 않았다. 비록 정합적인 언어로 표현될 수 없는 것이었다고는 하나 어떻게든 (주로 독자 자신의 모나드에 대한 축적된 경험을 통해) 그 "계산" 을 이해한 이들은 모나드도 이해했다. 그것은 자체로 왜 모나드라는 개념이 존재해야 하는가에 대한 답이었다.
후발주자들의 은유는 완전히 달랐다. 모나드가 대충 무엇인가에 관한 한 그것은 얼추 잘 작동하는 듯했다. 문제는 뒤틀린 "계산" 에 거의 버금갈 만큼 이해하기 어려운 그것들에 대한 이해가 결코 모나드 자체에 대한 이해를 가져다 주지는 않았다는 것이다.
모나드가 상자나 부리또, 또는 핵폐기물 차폐용기와 같다는 것을 안 후에도 사람들은 여전히 의문을 느꼈다. '이런 상자나 부리또 같은 건 왜 존재하며 왜 다들 이걸 가지고 난리를 치는 것인가?' 그 의문의 크기는 그들이 애초에 모나드를 처음 접했을 때 느꼈던 '모나드가 무엇인가?' 라는 의문의 크기보다 컸으면 컸지 결코 작지 않았다.
완전히 아무것도 아닌 것을 위한 압도적인 노력의 낭비. 그것이 당시의 모나드 전도사들이 앞다투어 만들어낸 여러 무의미한 은유들의 본질이었다.
3-5. 컨테이너라는 은유
오늘날까지도 많은 사람들이 계산과 함께 모나드에 대한 양대 해석 중 하나로 여기는 컨테이너라는 은유도 마찬가지다. 그것은 모나드에서 진정으로 이해되어야 하는 것이 무엇인지조차 몰랐던 이들이 만들어낸 또 하나의 실패작에 지나지 않는다.
컨테이너는 물론 앞에서 본 우주복 등의 다른 은유들처럼 특정 측면에서만 모나드와 유사한 대상은 아니다. 모나드는 단지 컨테이너와 비슷한 것이 아니라 컨테이너라고 주장되었다. Optional과 List는 당연히 컨테이너이며 Reader나 State, 심지어 IO도 어떤 관점에서는 컨테이너라고 볼 수 있었다.
문제는 그 어떤 관점으로써 허용되는 관점의 범위가 어디까지인가다. 모나드가 컨테이너라는 말은 기껏해야 두리뭉실했다.
당신이 컨테이너 해석을 통해 모나드를 처음 배우는 사람이라고 생각해 보라. 처음에는 모든 게 쉬워 보인다. Optional<A>도 List<A>도 명백히 A의 컨테이너이므로. 불행히도 그 느낌은 오래 가지 못한다. 새로 배우는 모나드 전부가 당신을 놀라게 한다. Reader가 어떻게 A의 컨테이너인가? Writer는? State와 Cont, IO모나드 타입의 값들은 어떻게 컨테이너가 되는가?
물론 그것들도 컨테이너라고 보는 것이 불가능하지는 않다. Reader는 가능한 모든 E타입의 값에 A타입의 값 하나를 대응시키는 연관 배열로 볼 수 있으며 그것은 컨테이너다. Writer는 A타입의 값과 함께 W타입의 부가정보도 함께 가지고 있는 컨테이너다. 기타 등등.
문제는 이러한 설명들이 본질적으로 아리송해서 도대체 어디까지가 A의 컨테이너고 어디서부터가 아닌지에 대한 의문을 불러일으킨다는 것이다. A의 컨테이너가 꼭 A타입의 값만 담고 있어야 하는 것도 아니고 애초에 꼭 A타입의 값을 담고 있어야 하는 것도 아니라면 세상에 A의 컨테이너라고 부를 수 없는 것이 어디에 있는가?
어떻게든 모나드가 컨테이너임을 받아들인 후에도 의문은 남는다. 그런 애매하고 두리뭉실한 컨테이너 개념은 왜 필요한 것인가?
물론 bind함수는 List를 비롯한 많은 컨테이너에 유용한 기능을 제공한다. 그러나 컨테이너에 대해 그것은 기껏해야 제한적일 쓰임새만 가질 뿐이다. 일반적인 컨테이너에 대해 유용한 건 lift또는 map함수다. 그리고 컨테이너가 그것을 갖기 위해 꼭 모나드가 되어야 하는 것은 아니다.
요컨대 모나드가 컨테이너라는 해석은 적어도 단독으로는 모나드가 왜 만들어졌는지, 왜 많은 프로그래머들이 그것에 주목했는지에 대한 그럴듯한 설명을 전혀 해 주지 못한다. 문제는 그것들이 우리가 모나드를 이해하기 위해 답해야 하는 가장 중요한 질문들이라는 것이다.
3-6. 발견되지 않은 대안
컨테이너 해석이 무언가 의미있는 일을 하기는 한다. 그것은 독자들에게 대강 어떤 것들이 모나드가 되는지에 대한 어렴풋한 느낌을 준다. 모나드에 대한 다른 은유들도 마찬가지다.
문제는 은유가 적어도 그것을 위한 최선의 수단이기는 했는가다.
앞에서 나는 모나드의 본래 정의가 '스스로를 정당화하기 충분할 만큼 자연스럽다.' 고 말한 바 있다. 정말로 그렇다. 모나드는 그냥 unit과 join만 추가로 더 가진 Functor다. A타입을 T<A>타입으로 바꾸어 주는 함수와 T<T<A>>타입을 T<A>타입으로 바꾸어 주는 함수. T가 추가로 가지고 있을 만한 함수로써 이 둘보다 더 그럴듯한 것이 어디 있는가?
Functor는 정의도 쓰이는 이유도 모나드보다 훨씬 설명하기 쉽다. 그것은 lift, 또는 동치인 map함수를 가진 타입 컨스트럭터를 통칭한다. map이 프로그래밍에 얼마나 유용한 함수인지는 굳이 말할 필요도 없을 것이다. 그것을 가진 타입 컨스트럭터에 가장 있을 법한 함수 두 개만 추가하면 그게 바로 모나드인 것이다.
이 정의는 단지 그럴듯하기만 한 것이 아니다. 그것은 모나드에 대한 훨씬 더 좋은 의미론적 해석의 기초다. 모나드에 대한 작동하는 설명에서 나는 그것을 다음과 같이 묘사한 바 있다.
'모나드는 개념에 대해 한 번만 유효한 의미의 확장이다. 개념 A에 대해 A도 T<A>로 볼 수 있고 T<T<A>>도 T<A>로 볼 수 있는 T가 곧 모나드다.' [13]
가령 Optional이 왜 모나드일까? 간단하다. 그것은 A를 'A또는 아무것도 아닌 것' 이라는 더 넓은 개념으로 확장시킨다. 물론 그 확장은 한 번만 유의미하다. 'A 또는 아무것도 아닌 것 또는 아무것도 아닌 것' 은 'A 또는 아무것도 아닌 것' 과 마찬가지이므로.
모나드가 컨테이너니 맥락이니 하는 어디에든 끼워맞출 수 있는 해석들과 달리 이 해석은 명료하다. 그것은 우리가 실제로 모나드와 모나드가 아닌 것을 구분할 때 쓸 수 있는 직관을 준다.
더 중요한 것은 그것이 모나드 전도사의 주관적인 경험 대신 정의에 기반을 두고 있다는 것이다. 우리는 그 해석과 모나드의 (본래) 정의를 따로 이해할 필요가 없다. 둘은 함께 이해된다. 그 해석은 우리가 모나드의 정의를 직관화하는 것을 돕는다. 모나드의 정의는 그 해석이 정확히 어떤 맥락에서 사용되어야 하는지, 그것이 어떤 가정을 바탕에 깔고 있으며 언제 틀릴 수 있는지 가르쳐 준다.
어떤 이들은 물어볼 것이다. 그것은 너무 어렵지 않은가? 적어도 우주복 같은 것들은 쉽게 시각화할 수 있는 사물들이다. 어떤 조건을 만족하는 개념의 확장은 너무 추상적이지 않은가?
모나드에 관심을 가질 정도의 프로그래머들이 고작 이 정도의 해석을 어려워할 거라는 걱정은 조금 우스꽝스러워 보이기도 한다. 그러나 그들에 의하면 그것은 그들의 경험이 준 지혜다. 그들은 말한다: 모나드 튜토리얼의 독자들은 상상 이상으로 멍청하다. 그들은 조금이라도 추상적인 것은 아무리 쉽게 설명해줘도 알아듣지 못한다. 나도 직접 모나드 튜토리얼을 만들어 보고 그것을 배웠다. 기타 등등.
그런가? 물론 그들의 튜토리얼들이 실패하기는 했을 것이다. 문제는 그들이 그 실패로부터 얻은 것이 정말로 올바른 교훈인가다. 그들의 튜토리얼들은 정말로 너무 어렵기 때문에 실패했을까?
십중팔구 그들은 모나드를 이해하는 것이 곧 '모나드는 XX하는 것이다.' 를 아는 것이라고 착각했을 것이다. 그 XX가 독자들이 모나드에 대해 느끼는 아리송함을 사실 티끌만큼도 줄여 주지 못함에도 불구하고 말이다. 당연한 실패 후, 그들은 실망해서 말한다. '이렇게까지 풀어서 설명해 줬는데도 이 간단한 것을 이해하지 못할 수 있다니!' 이것이 모나드 전도사들의 독자들의 멍청함에 대한 집단적인 경험의 실체다. 요컨대 그들은 올바른 것을 설명할 줄 모르는 그들 자신의 멍청함을 독자들의 것으로 착각했던 것이다.
후기 모나드 전도사들의 독자들의 지성에 대한 불합리한 무시는 실패가 항상 올바른 교훈을 가져다 주지는 않는다는 것을 보여 주는 좋은 사례다. 여기서는 그들의 판단보다는 일반인의 상식이 차라리 옳다. 모나드 튜토리얼의 독자들은 바보가 아니다. 그들은 이미 다형성 등의 많은 추상적인 개념에 익숙할 것이다. 그들이 위 해석을 어려워할 거라는 염려는 정확히 보이는 것만큼 우스꽝스럽다.
3-7. 다시 보는 모나드의 새로운 정의
'모나드가 무엇인가?' 가 모나드의 본래 정의를 통해 간단히 답해질 수 있다는 사실은 굳이 그 정의를 훨씬 더 복잡한 것으로 교체한 선구자들의 선택을 다시 한번 돌아보게 한다.
프로그래밍의 모나드가 순수하지 않은 현실의 프로그램을, 이른바 "계산" 을 순수 함수만으로 프로그래밍할 수 있게 하기 위해 도입된 도구라는 것은 옳다. 그 용도를 이해하는 것이 모나드를 이해하는 것의 핵심임은 의심의 여지가 없다.
그러나 모나드의 정의를 굳이 그 용도에 관계된 더 복잡한 것으로 바꿀 필요가 있는가는 다른 문제다. 그것이 정말로 모나드를 쉽게 설명하는 데 도움이 될까? 그 반대가 사실이 아닐까?
당장 대부분의 카테고리 이론 강의가 모나드를 어떻게 설명하는지 보라. 대부분의 강의는 모나드를 간단한 본래 정의를 통해 소개하고 모나드 프로그래밍의 "계산" 에 상응하는 Kleisli 카테고리는 나중에 따로 다룬다. 이 순서를 뒤집어 Kleisli 카테고리를 만들어내는 것으로 모나드를 정의하고 가르친다고 상상해 보라. 수학과 학생들조차 그런 강의는 어렵다고 할 것이다. 모나드 전도사들은 그런 방법으로 모나드를 가르치고 있는 것이다.
상술했듯이 모나드와 계산의 관계는 기껏해야 간접적이다. Optional<A>라는 타입이 아니라, 그것을 반환하는 표현식이 A를 반환하는 실패할 수 있는 계산의 의미를 갖는다. '모나드 타입은 계산을 나타낸다.' 라는 말은 엄밀히 말해 틀렸다. '모나드 타입은 그것을 반환하는 표현식 또는 함수가 계산으로 해석될 수 있는 것을 나타낸다.' 가 옳다.
문제는 이 간접적인 관계가 정말로 모나드에 대한 필요한 모든 직관을 제공하는가다. 모나드가 그것을 반환하는 표현식 또는 함수가 계산으로 여겨질 수 있는 성질을 가진 타입 컨스트럭터라고 치자. (참으로 복잡하기도 하다.) 그들은 왜 그런 성질을 갖는가? 무엇이 그들이 그런 성질을 갖도록 하는가?
모나드가 단지 우연히 그런 성질을 공유하는 타입 컨스트럭터들의 모임이었다면 이런 질문을 다룰 필요는 없었을 것이다. 문제는 그렇지 않다는 것이다. 그들의 의미 자체에도 공통된 무언가가 있다. 계산과 관계된 모나드의 성질은 그것으로부터 자연스럽게 파생되는 결과라는 것이 더 사실에 가깝다.
주로 이론이 아니라 경험을 통해 모나드를 배운 후발주자들은 그 사실을 알았다. 그들이 그 공통된 무언가를 이해하는 것이 모나드 이해의 핵심이라고 생각한 것은 당연했다.
그들은 그 무언가의 정확한 정체까지는 알지 못했다. 모든 모나드가 A와 T<T<A>>를 T<A>로 볼 수 있는 Functor라는 더 근본적인 사실 대신 그들은 눈에 보이는 그것의 피상적인 결과들에 집착했다. 모나드가 컨테이너 같은 속성을 가진다는 사실, 모나드가 대충 무엇 같거나 무엇 같다는 사실 등이었다. 우리가 본 은유 기반의 모나드 튜토리얼들은 그것을 전달하기 위한 노력이기도 했던 것이다.
3-8. 근본적인 문제
은유 기반의 엉터리 튜토리얼들이 난립하게 된 가장 큰 이유는 물론 얼치기 모나드 전도사들의 '모나드가 무엇인가?' 라는 잘못된 질문에 대한 집착에 있다. 모나드 전도사들이 애초에 이해가 무엇인지 똑바로 이해하기만 했다면 적어도 지금 우리가 본 것 같은 비극은 없었으리라.
그러나 나는 여기에는 보다 근본적인 문제도 있다고 믿는다. 애초에 "계산" 이 단독으로 모나드를 만족스럽게 설명해 줄 수 없다는 것이 바로 그것이다.
이해에 대해 내가 말한 것을 다시 떠올려 보라. 모나드 튜토리얼의 독자들이 원하는 것은 단지 모나드의 정의나 활용에 대한 설명이 아니다. 모나드라는 것이 왜 필연적으로 우리가 아는 그 형태로 존재해야 하는지에 대한 설명이다.
"계산" 과의 간접적인 관계가 그 설명이 될 수 있을까? 모나드 전도사들은 애초에 그 관계를 제대로 설명해 본 적도 없지만 (우리가 보았듯이 그들은 "계산" 자체를 정합적인 개념으로 정의하지 못했다.) 설령 그렇게 했더라도 독자들은 여전히 의문을 느꼈을 것이다. 그들은 물어볼지도 모른다. 왜 모나드는 하필 그런 기이한 방식으로 계산과 연결되도록 정의된 것인가?
그 이유는 명백하다. 애초에 모나드가 계산을 나타내기 위해 만들어진 것이 아니기 때문이다. 모나드는 unit과 join을 가진 Functor다. 이 사실은 단지 모나드의 뿌리만 설명해주는 것이 아니다. 그것은 모나드가 왜 그렇게 보편적인 구조인지, 왜 우리가 대부분의 "계산" 에 대응되는 모나드를 찾을 수 있는 것인지도 설명해 준다. 이것을 설명하지 않고 어떻게 모나드를 설명한다는 말인가.
우리는 전체 모나드 튜토리얼 비극이 어떻게 생겨났는지에 대한 진상에 거의 도달했다. 그것을 정리해 보자.
모나드는 두 얼굴을 가진 입체적인 개념이다. 그것은 계산을 나타내기 위한 유용한 도구지만 동시에 unit과 join을 가진 Functor이기도 하다. 우리가 진정으로 모나드를 이해했다고 할 수 있게 되는 건 전자나 후자를 이해하게 되었을 때가 아니다. 둘 모두를 이해하고 필요에 따라 마음대로 두 관점 사이를 전환할 수 있게 되었을 때다.
불행히도 모나드 선구자들은 모나드를 계산과 관계된 측면 하나만으로 설명할 수 있다고 믿는 오류를 범했다. 그 결과는 무엇이었는가? 그들은 그 "계산" 개념을 뒤틀어 이해하면서 그들이 설명하고자 한 그 한 측면마저도 제대로 설명해내지 못했다.
은유에 집착한 후발주자들이 한 일도 정확히 같다. 어느 쪽을 경시하고 어느 쪽을 뒤틀어 다루었는지만 다를 뿐이다. 결국 모나드의 무엇 하나도 제대로 설명하지 못한 채, 그들은 여기저기 예제만 늘어놓고 그들 스스로는 정합적인 언어로 설명할 능력조차 없음이 명확히 입증된 모나드의 어떤 핵심을 독자들이 그 예제들을 보고 알아서 눈치채주기만을 하염없이 바랬다.
이런 튜토리얼들의 실패에 놀랄 필요는 없을 것이다. 높은 곳에서 떨어뜨린 공이 아래로 떨어지는 것이 놀랍지 않다면 그들의 실패도 마찬가지다. 그 튜토리얼들은 실패할 수밖에 없도록 만들어졌다. 실패는 예견된 결과였다.
참으로 놀라운 사실은 전체 함수형 프로그래밍 커뮤니티가 정당한 자연의 섭리에 의해 발생한 이전 모나드 튜토리얼들의 실패를 특별한 설명이 필요한 놀라운 일로 받아들였다는 것이다. 그 설명들은 다른 요소들에 실패의 책임을 돌렸다. 모나드의 근간이 되는 함수형 프로그래밍의 철학에 대한 독자들의 몰이해, 어려운 수학적인 용어의 사용 등이 그것이었다.
훗날 점점 더 많은 사람들에 의해 수용되어 거의 정설처럼 받아들여지게 된 이 사이비 이론들은 모나드 전도사들이 실패의 진짜 이유를 보지 못하도록 효과적으로 그들의 사고를 마비시켰다. 그들이 그 이론들을 더 깊이 신뢰할수록, 그 이론들이 지적하는 문제들을 해결하는 데 많은 노력을 투자할수록 진정한 문제의 해결은 점점 더 요원해졌다.
모든 것이 칠흑같이 어두운 가운데서도 어쩌면 상황이 나아질 수도 있다는 마지막 희망은 그렇게 사라져 갔다. 아래는 바로 그 과정에 대한 이야기다.
[ 10] Kow, Eric. "Of monads and space suits." Online at http://web.archive.org/web/20081206204420/http://www.loria.fr/~kow/monads/index.html (last accessed 17 November 2022). 2005.
[11] 가령 모나드의 용도를 전혀 모르는 사람이 이 은유를 본다고 생각해 보라. 그는 모나드가 우주복처럼 내용물을 안전하게 보존하는 데 쓰이는 도구라고 생각할 것이다. 불행히도 모나드와 함께 강조되는 "순수성" 등의 키워드는 그 생각을 더욱 그럴듯해 보이게 할 가능성이 높다.
[12] 이 요약이 혼란스럽게 느껴진다면 그것은 내 잘못이 아니다. 요약되지 않은 저자의 설명은 훨씬 더 나쁘다. 나는 독자들의 정신건강을 위해 그것을 이 글에서 직접 인용하지는 않았다. 그러나 '피네간의 경야(Finnegans Wake)' 보다 당혹스럽고 포스트구조주의 철학자들의 담론보다 이해하기 힘든 그 횡설수설을 굳이 읽어보고자 하는 독자가 있다면 해당 튜토리얼의 "State and bind robot" 이라는 소제목이 달린 부분을 확인해 보라.
[13] 물론 unit과 join이 꼭 의미가 유사한 타입들 사이의 무엇을 무엇으로 볼 수 있는 관계를 나타낼 거라는 보장은 없다. 그러나 그들이 그런 관계를 나타낼 개연성은 높다. 모나드 규칙에 의하면 unit과 join은 값들 사이의 함수적 관계 일부를 보존해야 하기 때문이다. 모나드 규칙이 어떤 식으로 위 해석과 연결되는지는 다른 글에서 더 자세히 다루어질 것이다.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
지난번에 이 글이 내가 역대로 써본 글 중 쓰기 어렵기로 톱3에 든다고 했는데 수정해야 할 것 같다. 이글이 압도적인 1황 원탑임.
다행인 건 이후로 여기만큼 쓰기 어려운 부분은 없다는 것 정도?
다음 파트 언제 나온다는 약속은 못하겠지만 이미 내용 다 구상해 놔서 2달은 안걸릴듯.
워낙에 도발적인 글이라 논리가 정말로 정확해야 함.
그래서 글이 빨리빨리 써지지 않는것도 있으니 오래 걸려도 기다려 주길 바란다.
메타적인 지적이라 미안한데 솔직히 글이 너무 길고 너무 늘여쓴것 같다
실패한 모나드 강의가 하나 더 늘어남
잘썼네 - dc App
이글이 그걸 또 한번 해내버렸군
더 볼것도 없네. 깨끗하게 망했음. 인정함.
문제의식에 대해서는 공감함. 근데 은유로 모나드 설명한다던가 하는 글이 요즘에도 계속 재생산 되고 있는건 적어도 영미권에서는 아닌것 같아서 약간 뒷북 아닌가 싶고.
애초에 모나드 튜토리얼의 역사를 가지고 분석하는 글이니까. 여기서 이야기하고 있는 것도 다 과거시제임. 여기까지가 약 2010년까지의 추세를 다룬거. 그냥 내 주제에 이런 역사적 주제를 완전하게 다루려 한 것부터가 문제였다고 본다.
솔직히 글로 하여금 우릴 논리전개로 유도하는 문답식 방법이 잘 와닿지가 않음 혹시 수학적 정의가 있으면 한번 써보는게 좋지않을까
글쎄, 내가 수학적 정의를 제공하지 않은 부분들은 다른 사람들도 수학적 정의를 제공하지 않은 부분들이라고 보는데. 가령 "계산" 을 어떻게 정의할거냐 같은 부분은 내가 수학적 정의를 내놓지는 않았지만 다른 사람들도 수학적 정의를 내놓지는 않았지. 여하간 이 글 자체는 방법론적인 지적이 주를 이루고 있기 때문에 수학적 정의를 쓰고 말고 할 것도 없음. Eric Kow의 튜토리얼이 뭘 잘못했는지를 수학적 정의가지고 분석할 게 있나...
길쭉해요
선추천 후감상
망했음요. 추천하지마셈.
비추날리는 깃갤러들 왤케 차갑게 구냐 열심히 하는구만.. 쿨찐들이 많은듯
탈락!
또 써줘~
번역체 너무 심하다... 영어로 된 글 한번 번역한거 같음
애초에 영어로 번역할걸 전제하고 글을 쓰다보니 그렇게 된듯. 지적 고마움.
설명하는데 이렇게 장문이 필요한 개념이라면 회사에선 최대한 안 쓰는게 맞지 않을까? - dc App
모나드 설명하는데 장문은 안필요하고 지난 20년간의 모나드 강의들이 실패해 온 이유를 설명하는데 장문이 필요한 건데 뭐 됐다. 그것조차 전달이 안될 정도로 내가 글을 못썼다는 거겠지.
개념글에서 못내리나;
원래의 의도가 충족되었는지는 차치하고라도, 이러한 장문의 시도는 그 시도자체만으로도 충분히 의미있고 매우 칭찬받아야 마땅하다고 봅니다. 저자의 오랜기간의 집중적인 사고가 이처럼 응축된 글들은, 설령 부분적인 오류와 불명확한 부분이 있다손 치더라도, 열린 마음을 가지고 이글을 읽는 자들에게 긍정적이든 부정적이든 많은 생각을 야기하게 될 것이기에 이미 소기의 목적을 충분히 달성했다고 생각합니다.
이읗님의 논문을 IEEE Xplore에서 잠깐 본 적이 있는데, 제 기억으로는 아직 학생이 맞나요? 이런저런 이유로 해외에서 근 30년 가까이 지내고 있습니다만, 국내에 남아서 계속해서 이런저런 기여를 해도 매우 훌륭하다고 봅니다만, 이와 같은 치열한 문제의식을 가지고 이를 해결하기 위해 이처럼 끈기있게 노력하는 분이면 기회가 된다면 보다 활발한 지적인 자극을 생산적으로 주고 받을 수 있는 해외로 나와서 본인의 꿈을 펼쳐가는 것도 장기적인 관점에서 본인을 위해서나 우리나라를 위해서 좋다고 생각합니다. 댓글들에 너무 부정적으로 영향받거나 위축되지 말고 앞으로도 이처럼 영양가있고 많은 논의를 촉발하는 글들을 계속해서 써 주시기를 바랍니다.
오..드디어 시간날때 각잡고 읽어봐야지
수고했다
감사히 봤습니다 개추!!