내 추상화는 정작 봐야 할 것을 가렸다

나는 깔끔한 추상화를 사랑한다. 지저분하고 복잡한 무언가를 가져다 그 난잡함을 감추는 단정한 인터페이스로 감싸서, 한 단계 위에서 사고하며 그 밑에 깔린 세부사항을 잊어버릴 수 있게 만드는 데에는 진짜 미적 쾌감이 있다. 그래서 나는 끊임없이 추상화에 손을 뻗었다 — 일찍, 열렬히, 그리고 너무도 자주. 그런데 놀라울 만큼 많은 경우, 내가 손을 뻗었던 그 추상화는 복잡성을 전혀 관리해 주지 못했다. 그것은 내가 가장 봐야 했던 바로 그것들을 가려 버렸고, 그 대가로 새로운 한 겹의 혼란을 청구했다.

이것이 뼈아픈 교훈이었던 건 정확히 추상화가 진정으로 좋고 진정으로 강력한 것이기 때문이다. 잘못은 추상화를 쓴 데 있지 않았다. 잘못은 그것을 잘못 쓴 데 있었고, 깔끔한 표면에 대한 나의 애정을 좋은 엔지니어링 판단력으로 착각한 데 있었다.

좋은 추상화가 해야 하는 일

추상화가 무엇을 위한 것인지 분명히 해 둘 가치가 있다. 이 실패 전체가 실재하는 무언가의 왜곡이기 때문이다. 좋은 추상화는 지금 당장 생각할 필요 없는 세부사항을 감춰서, 그 난장판 전체를 한꺼번에 머릿속에 붙들고 있지 않아도 한 단계 위에서 추론할 수 있게 해 준다. 그것은 엔지니어링 전체를 통틀어 가장 강력한 도구 중 하나다 — 어쩌면 바로 그 도구, 한꺼번에 이해하기에는 너무나 복잡한 시스템을 지어 올릴 수 있게 해 주는 바로 그것이다.

추상화가 제대로 작동할 때, 그것은 거의 보이지 않는다. 당신은 그 밑에 무엇이 있는지 생각하지 않고 그것을 쓴다. 연소 과정을 생각하지 않고 차를 모는 것처럼. 그것은 당신의 한정된 주의력을 정작 신경 쓰는 그 단계에 쓰도록 해방시켜 준다. 그것이 꿈이고, 좋은 꿈이며, 실재하는 꿈이다. 그리고 그것이 바로 이 실패 양식을 그토록 매혹적으로 만드는 지점이기도 하다. 모든 추상화가 이것을 약속하지만, 일부만이 실제로 이행한다.

잘못된 추상화는 대신 무슨 일을 하는가

나쁜 추상화는 좋은 추상화와 정반대의 일을 하면서, 그것도 바깥에서 보면 거의 똑같은 모습으로 그렇게 한다. 필요 없는 세부사항을 감추는 대신, 필요한 세부사항을 감춘다. 경계를 엉뚱한 곳에 그어서, 정작 추론해야 할 바로 그것들이 당신 스스로 세운 벽 저편으로 넘어가 버리고, 별안간 손이 닿지 않게 된다.

그리고 그것은 첫 번째 죄 위에 두 번째 죄를 또 저지른다. 밑에 깔린 복잡성을 실제로 제거하지는 못하기 때문이다 — 그 복잡성은 여전히 거기, 손대지 않은 채로, 표면 아래에서 제 일을 하고 있다. 추상화는 그저 그 위에 새로운 한 겹을 더할 뿐이다. 그래서 이제 이해해야 할 복잡한 것이 하나가 아니라 둘이 된다. 밑에 깔린 지저분한 현실, 그리고 그 위에 덮어씌운 어딘가 맞지 않는 추상화, 거기에 늘 헷갈리는 둘 사이의 관계까지. 생각해야 할 양을 줄이려고 나섰다가 오히려 늘려 버린 셈이다.

성급한 추상화: 이해하기도 전에 못박기

내 실수의 가장 흔한 형태는 너무 일찍 추상화하는 것이었다. 나는 문제를 충분히 이해하지도 못해서 올바른 구조가 무엇인지조차 알기 전에, 깔끔하고 일반적이며 우아한 구조를 먼저 지어 올리곤 했다. 그것은 마치 좋고 미래지향적인 설계처럼 느껴졌다. 보통은 정반대였다.

추상화란 근본적으로 특정한 형태에 대한 못박기다 — 경계를 어디에 둘지, 무엇을 감추고 무엇을 드러낼지, 조각들이 어떻게 관계 맺을지에 대한 결정이다. 그리고 빚어낼 대상을 이해하기도 전에 형태를 못박는 것은 잘못된 형태를 고착시키는 확실한 방법이다. 더 나쁜 것은, 일단 그것이 자리를 잡으면 당신은 그 위에 무언가를 쌓아 올리기 시작하고, 새로 쌓는 모든 것이 학습이 아니라 추측으로 정한 구조에 대한 투자를 더 깊게 만든다는 점이다. 성급한 추상화는 단지 틀릴 위험만 있는 게 아니다. 그것은 자기 자신의 틀림을 적극적으로 굳혀 버린다.

새는 추상화는 두 가지를 디버깅하게 만든다

불완전하게 감추는 추상화 — 대체로 작동하다가 어느 순간 작동하지 않는 그런 것들 — 에게는 특별한 고문이 예약되어 있다. 추상화가 감춰 주기로 했던 그 현실 저 아래에서 무언가 잘못될 때, 그 누수는 당신으로 하여금 두 층을 한꺼번에 이해하게 강요한다. 그 안에서 사고할 수 있다고 약속받았던 깔끔한 표면, 그리고 그것이 완전히 감추지 못한 밑의 난장판 둘 다를.

이것은 유난히 사람을 지치게 한다. 추상화의 핵심은 애초에 한 가지만 생각하게 해 주는 것이었다. 그런데 이제 어떤 실패가 당신을 두 가지를 생각하는 처지로 끌고 들어왔다. 게다가 둘 사이의 대응 관계, 거기에 버그가 실제로 어느 층에 사는지의 문제까지. 당신은 추상화와 그것이 추상화하는 대상을 동시에 디버깅하고 있고, 도와주기로 했던 그 추상화는 이제 당신과 문제 사이를 가로막는 추가 장애물이 되어 있다. 새는 추상화는 차라리 추상화가 아예 없느니만 못할 수 있다. 적어도 추상화가 없으면 당신을 헷갈리게 할 층이 하나뿐이었으니까.

필요하지도 않았던 한 겹의 비용

내가 제대로 셈하지 못했던 것은, 모든 추상화 한 겹이 곧 간접화 한 겹이기도 하다는 점이다 — 당신과 실제로 벌어지는 일 사이에 끼어드는 또 하나의 무언가다. 모든 것이 잘 돌아갈 때 그 거리는 이점이다. 그것이 바로 더 낮은 층을 생각하지 않아도 되게 해 준다. 그러나 무언가를 이해하거나 디버깅해야 하는 순간, 바로 그 거리가 순수한 비용으로 돌변한다. 한 겹 한 겹이 들여다봐야 할 또 한 곳이고, 머릿속에서 수행해야 할 또 하나의 번역이며, 문제가 숨어 있을지 모를 또 하나의 후보지다.

그러니 진정으로 제 값을 하지 못하는 추상화는 중립적이지 않다. 그것은 상시 세금이다. 시스템에 대해 추론해야 할 때마다 청구되며, 알고 보니 필요하지도 않았던 편의의 대가로 매겨진다. 나는 깔끔한 표면에 홀려서 이 세금들을 열심히 덧붙이고 있었다. 그 대부분에 대해서는 비용만 치르고 일부에 대해서만 이득을 보고 있다는 걸 알아채지 못한 채로.

추상화는 구체적인 것으로부터 벌어들여라

마침내 도움이 된 규율은 내 본능의 거의 정반대였다. 결국 필요해지리라는 추측으로부터 추상화를 앞당겨 부과하지 마라. 구체적이고 반복된 경험으로부터 그것을 벌어들여라. 구체적이고 못생기고 개별적인 그것을 먼저 몇 번 지어 봐라. 진짜 이음매가 어디 있는지 — 자연스러운 경계가 실제로 어디에 떨어지는지, 어떤 세부사항이 진짜로 한데 뭉치고 어떤 것은 그렇지 않은지 — 를 느껴 봐라. 그러고 나서야, 현실이 그 관절을 당신에게 보여 준 다음에야, 현실이 실제로 그어 놓은 선을 따라 추상화하라.

좋은 추상화는, 나는 깨닫게 되었는데, 구체적인 것에 부과되는 것이 아니라 구체적인 것으로부터 발견된다. 그것은 이미 깊이 이해하고 있는 것들의 압축이지, 그것들을 이해하는 일을 건너뛰는 지름길이 아니다. 그렇게 지은 추상화 — 늦게, 마지못해, 구체적인 것이 그것들이 있어야 할 자리를 가르쳐 준 뒤에 지은 것들 — 이 실제로 버텨 준 것들이었다. 영리함과 미학으로부터 일찍 지은 것들은, 그 후 몇 달을 싸우며 보내야 했던 것들이었다.

더 깊은 교훈: 추상화는 복잡성을 관리할 뿐, 이해를 대체하지 않는다

이 모든 것이 환원되는 지점은 추상화가 무엇을 위한 것인지에 대한 혼동이다. 나는 추상화를 문제를 이해하는 일의 대체물로서 손에 쥐고 있었다 — 마치 깔끔한 인터페이스가 밑에 깔린 그 지저분한 것을 실제로 이해하는 고된 작업을 건너뛰게 해 줄 수 있기라도 한 것처럼. 그럴 수는 없다. 추상화는 이미 이해하고 있는 복잡성을 관리하는 도구이지, 그것을 이해하는 일을 회피하는 도구가 아니다.

무언가를 이해하지 못한 상태를 추상화로 벗어날 수는 없다. 당신은 그저 자신의 혼란을 더 단정해 보이는 표면 아래 감출 수 있을 뿐이고, 그 혼란은 이제 깔끔한 인터페이스를 걸친 채 나중에 당신을 매복 습격하려고 참을성 있게 기다릴 것이다. 먼저 그것을 이해하라. 추상화는 그다음이다. 그리고 추상화할 때는, 무엇이 어디에 있는지 알기도 전에 그저 우아해 보였던 선이 아니라, 이해가 드러내 준 이음매를 따라 경계를 그어라.

— 신호도, 수익도 없습니다. 투자 자문이 아닙니다.