# Simple Made Easy

00:00:00 Simple Made Easy

카테고리 이론을 더 들어볼 준비가 되셨나요?

[청중 박수]

여러분 모두 방을 잘못 찾아오셨습니다.

[청중 웃음]

이 강연이 너무 뻔해 보였으면 좋겠습니다. 이 컨퍼런스의 좋은 점 중 하나는 여기 모인 청중이 상당히 최첨단이라는 점입니다. 많은 분들이 새로운 기술을 채택하고 있습니다. 많은 분들이 함수형 프로그래밍을 하고 계십니다. 그리고 여러분은 고개를 끄덕이며 '그래, 그래, 그래'라고 말할지도 모릅니다. 익숙한 부분이 있다면 다행입니다. 다른 한편으로는, 여러분이 옳은 일을 하도록 설득하려는 다른 사람들과 이 강연과 비슷한 종류의 토론을 하는 데 사용할 수 있는 몇 가지 도구를 가지고 이 강연을 떠나셨으면 좋겠습니다.

Hi. So who is ready for some more category theory?

[Audience applause]

You're all in the wrong room.

[Audience laughter]

This talk I hope seems deceptively obvious. One of the things that's great about this conference is this is a pretty cutting edge crowd. A lot of you are adopting new technologies. A lot of you are doing functional programming. And you may be nodding, saying yeah, yeah, yeah through parts of this. And if some of it is familiar, that's great. On the other hand, I think that I would hope that you would come away from this talk with some tools you could use to help conduct a similar kind of discussion to this talk with other people that you're trying to convince to do the right thing.

00:01:00 Edsger W. Dijkstra quote

그래서 저는 권위에 호소하는 것부터 시작하겠습니다. 단순함은 신뢰성을 위한 전제 조건입니다. 저는 이 점에 확실히 동의합니다. 저는 다익스트라(Dijkstra)가 말한 모든 것에 동의하지 않으며, 특히 증거에 관해서는 그가 매우 틀렸을 수도 있다고 생각합니다. 하지만 이 부분에 대해서는 그가 옳다고 생각합니다. 좋은 시스템을 구축하려면 간단한 시스템을 구축해야 합니다. 우리는 그 점에 충분히 집중하지 않는다고 생각합니다.

So, I'll start with an appeal to authority. Simplicity is a prerequisite for reliability. I certainly agree with this. I don't agree with everything Dijkstra said, and I think he might have been very wrong about proof in particular. But I think he's right about this. We need to build simple systems if we want to build good systems. I don't think we focus enough on that.

에츠허르 다익스트라(Edsger W. Dijkstra, 1930년 5월 1일 ~ 2002년 8월 27일)는 네덜란드의 컴퓨터 과학자입니다. 그는 다익스트라 알고리즘을 개발한 것으로 가장 잘 알려져 있습니다. 다익스트라 알고리즘은 컴퓨터 과학에서 가장 중요한 알고리즘 중 하나로 간주됩니다. 이 알고리즘은 그래프에서 한 노드에서 다른 노드로 가는 최단 경로를 찾는 데 사용됩니다.

다익스트라는 1930년 네덜란드 아른헴에서 태어났습니다. 그는 1956년 암스테르담 대학교에서 수학 박사 학위를 받았습니다. 졸업 후 그는 네덜란드 국립 컴퓨터 센터에서 연구원으로 일했습니다. 1962년 그는 암스테르담 대학교로 돌아와 교수로 재직했습니다. 1984년부터 1986년까지 그는 국제 컴퓨터 과학 연맹의 회장을 역임했습니다.

다익스트라는 다익스트라 알고리즘 외에도 많은 다른 공헌을 했습니다. 그는 1965년에 큐브 루트 알고리즘을 개발했습니다. 이 알고리즘은 큐브의 제곱근을 구하는 데 사용됩니다. 그는 또한 1972년에 데이크스트라 탐색 알고리즘을 개발했습니다. 이 알고리즘은 그래프에서 한 노드에서 다른 노드로 가는 경로를 찾는 데 사용됩니다. 다익스트라는 2002년 네덜란드 암스테르담에서 72세에 사망했습니다.

# Word Origins

00:01:21 Word Origins

저는 단어의 어원을 좋아합니다. 정말 재미있거든요. 단어가 재미있는 이유 중 하나는 단어는 결국 우리 모두가 그 의미를 받아들이는 대로 의미하게 되기 때문입니다. 일반적으로 이해되는 뜻이 바로 그 뜻이 되는 것이죠. 그래서 그 단어의 진짜 의미로 돌아가서 그 단어를 사용할 수 있으면 좋겠다고 말하는 것은 종종 흥미롭습니다. 특히 소프트웨어에 대해 이야기할 때 여러분이 그 기원을 알고 더 정확하게 사용했으면 하는 몇 가지 단어를 이 강연에서 사용하려고 합니다.

첫 번째 단어는 간단합니다. 이 단어의 어원은 심과 플렉스로, 한 번 접거나 한 번 땋거나 꼬는 것을 의미합니다. 그리고 말 그대로 한 번 접히거나 꼬인다는 특징, 물론 한 번 꼬인다는 특징, 한 번 꼬인다는 것은 어떻게 생겼나요? 사실 꼬임이 없습니다.

그리고 이 단어의 반대말은 복잡하다는 뜻으로 서로 꼬이거나 접힌다는 뜻입니다. 소프트웨어가 서로 꼬여 있는지 여부에 따라 소프트웨어를 생각할 수 있다는 것이 이 강연의 핵심입니다.

심플과 같은 의미로 자주 사용되는 또 다른 단어는 이지(easy)라는 단어입니다. 이 단어는 프랑스어에서 파생된 단어인데, 이 파생어의 마지막 단계는 사실 사변적이지만 이 강연에 정말 잘 어울리기 때문에 제가 구입했는데, 이 단어는 인접하다, 가까이 있다는 뜻의 라틴어 어근인 인접에서 유래한 단어입니다. 그리고 그 반대는 하드입니다. 물론 hard의 어근은 가까이 누워있는 것과는 아무 관련이 없습니다. 멀리 떨어져 있다는 뜻이 아닙니다. 실제로는 강하거나 힘들게라는 뜻입니다.

I love word origins. They're tremendous fun. One of the reasons why they're fun is because words eventually come to mean whatever we all accept them to mean. You know, whatever is commonly understood to be the meaning is what it means. And it's often interesting to say, well, I wish I could; I wish we could go back to what it really means and use that. And I think there's a couple of words that I'm going to use in this talk that I would love for you to come away knowing the origins of and try to use more precisely, especially when talking about software.

So the first word is simple. And the roots of this word are sim and plex, and that means one fold or one braid or twist. And that characteristic about being about one literally fold or twist, of course one twist, what's one twist look like? No twists, right, actually.

And the opposite of this word is complex, which means braided together or folded together. Being able to think about our software in terms of whether or not it's folded together is sort of the central point of this talk.

The other word we frequently use interchangeably with simple is the word easy. And the derivation there is to a French word, and the last step of this derivation is actually speculative, but I bought it because it serves this talk really well, and that is from the Latin word that is the root of adjacent, which means to lie near and to be nearby. And the opposite is hard. Of course, the root of hard has nothing to do with lying near. It doesn't mean lie far away. It actually means like strong or tortuously so.

# Simple

00:03:19 Simple

따라서 우리가 하는 일에 단순함을 적용하려면 먼저 하나의 브레이드라는 개념부터 시작해야 합니다. 그리고 몇 가지 다른 차원에서 바라보세요. 디자인 작업을 하는 데 있어 치수는 분명히 큰 부분을 차지하기 때문에 Eric의 강연에서 치수에 대해 이야기하는 것이 흥미로웠다고 생각했습니다. 그래서 단순한 것을 찾고 싶다면 한 가지 역할을 하는 것을 찾아야 합니다. 그런 것들은 하나의 역할이 있습니다. 하나의 작업이나 직무를 수행합니다. 하나의 목표를 달성하는 것입니다. 보안과 같은 하나의 개념에 관한 것일 수도 있습니다.

그리고 해결하려는 문제의 특정 차원에 관한 것일 수도 있습니다. 하지만 여기서 중요한 것은 단순한 것을 찾을 때는 이러한 영역에 초점을 맞추는 것을 원한다는 것입니다. 여러 가지를 결합하는 것을 보고 싶지 않을 것입니다.

반면에 한 가지에 너무 집착해서는 안 됩니다. 특히 단순하다고 해서 그 중 하나만 있는 것은 아닙니다. 그렇죠? 또한 조작이 하나만 있는 인터페이스를 의미하지도 않습니다. 따라서 카디널리티를 구분하는 것이 중요합니다. 카디널리티는 사물을 세는 것과 실제 인터리빙을 구분하는 것입니다. 단순성을 위해 중요한 것은 인터리빙이 없다는 것이지 한 가지만 있다는 것이 아니며, 이것이 매우 중요합니다.

좋아요, 방금 설명한 것처럼 단순함의 또 다른 중요한 점은 인터리빙이 있는지 없는지 여부는 일종의 객관적인 것입니다. 직접 가서 보면 알 수 있습니다. 어떤 연결도 보이지 않습니다. 이 반전이 다른 무언가인 것처럼 보이는 곳이 없으니 단순함은 사실 객관적인 개념입니다. 이는 단순함과 쉬움의 차이를 결정하는 데에도 매우 중요합니다.

So if we want to try to apply simple to the kinds of work that we do, we're going to start with this concept of having one braid. And look at it in a few different dimensions. I thought it was interesting in Eric's talk to talk about dimensions because it's definitely a big part of doing design work. And so if we want to look for simple things, we want to look for things that have sort of one of something. They do, they have one role. They fulfill one task or job. They're about accomplishing sort of one objective. They might be about one concept like security.

And sort of overlapping with that is they may be about a particular dimension of the problem that you're trying to solve. The critical thing there, though, is that when you're looking for something that's simple, you want to see it have focus in these areas. You don't want to see it combining things.

On the other hand, we can't get too fixated about one. In particular, simple doesn't mean that there's only one of them. Right? It also doesn't mean an interface that only has one operation. So it's important to distinguish cardinality, right, counting things from actual interleaving. What matters for simplicity is that there is no interleaving, not that there's only one thing, and that's very important.

Okay, the other critical thing about simple, as we've just described it, right, is if something is interleaved or not, that's sort of an objective thing. You can probably go and look and see. I don't see any connections. I don't see anywhere where this twist was something else, so simple is actually an objective notion. That's also very important in deciding the difference between simple and easy.

# Easy

00:05:16 Easy

쉽게 살펴봅시다. 저는 친밀함이라는 개념이 정말 멋지다고 생각합니다. 특히, 무언가가 가까이 있을 수 있는 방법에는 분명히 여러 가지가 있습니다. 그렇죠? 가까이 있다는 물리적인 개념도 있죠. 그렇죠? 바로 저기 있는 것이죠. 이 단어의 어원이 바로 거기서 나온 것 같아요. 근처에 있기 때문에 쉽게 구할 수 있죠. 옆 마을에 있지 않아요. 말 같은 걸 타고 갈 필요도 없고요. 소프트웨어에 반드시 같은 물리적 개념이 있는 것은 아니지만, 자체 하드 드라이브나 자체 도구 세트가 있거나 설치 프로그램 등을 통해 사물을 물리적으로 가깝게 만들 수 있는 기능이 있습니다.

두 번째 근접성의 개념은 우리가 이해하고 있는 것, 즉 현재 기술 수준에서 근접한 것을 말합니다. 여기서 말하는 가깝다는 것은 우리가 이해하는 능력에 가깝다는 뜻이 아닙니다. 말 그대로 우리가 이미 알고 있는 것에 가깝다는 뜻입니다. 따라서 이 경우의 단어는 친숙하다는 뜻입니다.

총체적으로 볼 때 우리는 이 두 가지 쉬운 개념에 매료되어 있다고 생각합니다. 우리는 이 두 가지 측면에 너무 몰두하고 있으며, 이는 우리에게 엄청난 상처를 주고 있습니다. 그렇죠? 우리가 신경 쓰는 것은 이걸 즉시 받아서 5초 안에 실행할 수 있을까? 거대한 헤어볼일 수도 있지만, 우리는 그것을 얻을 수 있는지에만 관심이 있습니다.

게다가 우리는 '안 돼, 못 읽겠어'에 집착합니다. 이제 저는 독일어를 읽을 수 없습니다. 독일어를 읽을 수 없다는 뜻인가요? 아니요, 독일어를 몰라요. 따라서 이런 접근 방식은 확실히 도움이 되지 않습니다. 특히 모든 것이 익숙해지기를 원한다면 이미 알고 있는 것과 크게 다를 수 없고 익숙함에서 벗어나지 못하기 때문에 새로운 것을 배우지 못할 것입니다.

우리가 충분히 생각하지 않은 세 번째 측면인 '쉬움'은 이제 우리의 역량에 가까워지고 있는 이 논의에서 중요하게 다뤄져야 할 부분이라고 생각합니다. 그리고 우리는 어떤 종류의 역량에 대해 이야기하는 것이 불편하기 때문에 이런 이야기를 하고 싶지 않습니다. 바이올린 연주나 피아노 연주, 등산 같은 것의 경우 쉽게 이야기한다면, 저는 바이올린을 전혀 연주하지 않기 때문에 바이올린을 잘 연주하지 못해도 개인적으로 기분이 나쁘지 않습니다.

So let's look at easy. I think this notion of nearness is really, really cool. In particular, obviously there's many ways in which something can be near. Right? There's sort of the physical notion of being near. Right? Is something, you know, right there. And I think that's where the root of the word came from. You know, this is easy to obtain because it's nearby. It's not in the next town. I don't have to take a horse or whatever to go get to it. We don't have the same notion of physicality necessarily in our software, but we do sort of have, you know, our own hard drive or our own toolset, or it's sort of the ability to make things physically near by getting them through things like installers and stuff like that.

The second notion of nearness is something being near to our understanding, right, or in our current skill set. And I don't mean in this case near to our understanding meaning a capability. I mean literally near something that we already know. So the word in this case is about being familiar.

I think that, collectively, we are infatuated with these two notions of easy. We are just so self-involved in these two aspects; it's hurting us tremendously. Right? All we care about is, you know, can I get this instantly and start running it in five seconds? It could be this giant hairball that you got, but all you care is, you know, can you get it.

In addition, we're fixated on, oh, I can't; I can't read that. Now I can't read German. Does that mean German is unreadable? No. I don't know German. So, you know, this sort of approach is definitely not helpful. In particular, if you want everything to be familiar, you will never learn anything new because it can't be significantly different from what you already know and not drift away from the familiarity.

There's a third aspect of being easy that I don't think we think enough about that's going to become critical to this discussion, which now is being near to our capabilities. And we don't like to talk about this because it makes us uncomfortable because what kind of capabilities are we talking about? If we're talking about easy in the case of violin playing or piano playing or mountain climbing or something like that, well, you know, I don't personally feel bad if I don't play the violin well because I don't play the violin at all.

하지만 우리가 하는 일은 개념적인 작업이기 때문에, 무언가가 우리의 능력을 벗어난다고 이야기하기 시작하면 우리의 자존심이 크게 짓밟히기 시작합니다. 그래서 자만심과 불안감의 조합으로 인해 우리는 무언가가 우리의 능력을 벗어난 것인지 아닌지에 대해 이야기하지 않습니다. 결국 그 분야에서 우리의 능력이 크게 차이가 나지 않기 때문에 그렇게 부끄럽지 않다는 결론에 도달하게 됩니다.

마지막으로 '쉬움'과 '단순함'을 구분하는 데 있어 중요한 것은 '쉬움'은 상대적이라는 점입니다. 그렇죠? 바이올린 연주와 독일어 읽기는 저에게는 정말 어렵습니다. 다른 사람, 특정 사람에게는 쉬운 일이지만요. 따라서 인터리빙을 찾거나 땋는 방법을 찾을 수 있는 단순과 달리, 쉬움은 항상 누구에게는 쉬울 수 있고 누구에게는 어려울 수 있습니다. 상대적인 용어입니다.

우리가 이런 것들을 아무렇지 않게 던지면서 '아, 이 기술은 간단해서 좋아해요'라고 말하는 것은 사실 간단하다는 것은 쉬운 것을 의미합니다. 그리고 간단하다는 말은 이미 이와 매우 유사한 기술을 알고 있다는 뜻입니다. 이런 식으로 모든 것이 저하되고 소프트웨어에서 우리에게 중요한 품질에 대해 객관적인 토론을 할 수 없습니다.

But the work that we're in is conceptual work, so when we start talking about something being outside of our capability, well, you know, it really starts trampling on our egos in a big way. And so, you know, due to a combination of hubris and insecurity, we never really talk about whether or not something is outside of our capabilities. It ends up that it's not so embarrassing after all because we don't have tremendously divergent abilities in that area.

The last thing I want to say about easy and the critical thing to distinguish it from simple is that easy is relative. Right? Playing the violin and reading German are really hard for me. They're easy for other people, certain other people. So unlike simple where we can go and look for interleavings, look for braiding, easy is always going to be, you know, easy for whom, or hard for whom? It's a relative term.

The fact that we throw these things around sort of casually saying, oh, I like to use that technology because it's simple, and when I'm saying simple, I mean easy. And when I am saying easy, I mean because I already know something that looks very much alike that. It's how this whole thing degrades and we can never have an objective discussion about the qualities that matter to us in our software.

# Construct vs Artifact

00:09:06 Construct vs Artifact

그렇다면 이 두 가지를 구분하여 쉽고 단순하다는 관점에서 바라봐야 하는 중요한 영역은 무엇일까요? 그것은 바로 구조와 아티팩트와 관련이 있습니다. 그렇죠? 우리는 구조체로 프로그래밍합니다. 프로그래밍 언어가 있습니다. 우리는 특정 라이브러리를 사용하며, 우리가 작성하는 코드를 볼 때와 같이 라이브러리를 보면 그 자체로 특정 특성이 있습니다.

하지만 우리는 아티팩트 비즈니스를 하고 있습니다. 그렇죠? 우리는 소스 코드를 공개하지 않으며, 사용자가 소스 코드를 보고 "아, 정말 멋지다"라고 말하지도 않습니다. 그렇죠? 안 그래요? 사용자는 소프트웨어를 실행하고 오랜 기간 동안 실행합니다. 그리고 시간이 지남에 따라 소프트웨어에 더 많은 기능이 추가됩니다. 이 모든 것, 실행, 성능, 변경 기능은 모두 원래의 구조가 아니라 인공물의 속성입니다.

하지만 여기서도 우리는 여전히 구조체 사용에 대한 경험에 너무 집중하고 있습니다. 보세요, 16자만 입력했네요. 와우! 대단하네요. 세미콜론이나 그런 것들도 없네요. 프로그래머의 편의성이라는 이 모든 개념은 우리에게 도움이 되지 않는데도 우리는 그것에 열광하고 있습니다.

So, what's one critical area where we have to distinguish these two things and look at them from a perspective of them being easy and being simple? It has to do with constructs and artifacts. Right? We program with constructs. We have programming languages. We use particular libraries, and those things, in and of themselves, when we look at them, like when we look at the code we write, have certain characteristics in and of themselves.

But we're in a business of artifacts. Right? We don't ship source code, and the user doesn't look at our source code and say, "Ah, that's so pleasant." Right? No? They run our software, and they run it for a long period of time. And, over time, we keep glomming more stuff on our software. All of that stuff, the running of it, the performance of it, the ability to change it all is an attribute of the artifact, not the original construct.

But again, here we still focus so much on our experience of the use of the construct. Oh, look; I only had to type 16 characters. Wow! That's great. No semicolons or things like that. This whole notion of sort of programmer convenience, again, we are infatuated with it, not to our benefit.

그 반대편에서는 상황이 더욱 악화됩니다. 우리 고용주들도 이 문제에 열광하고 있습니다. 그렇죠? '쉽다'의 앞 두 가지 의미는 무슨 뜻일까요? 안 그래요? 다른 프로그래머를 데려올 수 있다면요? 그리고 그들은 소스 코드를 보고 익숙하다고 생각하겠죠? 그리고 이미 툴킷을 알고 있겠죠? 그래서 바로 손에 닿는 거죠. 그들은 항상 툴킷에 동일한 도구를 가지고 있습니다. 그들은 그것을 읽을 수 있습니다. 제가 대신할 수 있어요. 특히 세 번째 개념인 '누구나 코드를 이해할 수 있느냐 없느냐'를 무시하면 정말 쉬운 일입니다. 그들은 단지 누군가가 내 자리에 앉아서 타이핑을 시작할 수 있는 것만 중요하게 생각합니다.

따라서 일종의 비즈니스 소유자로서 프로그래머를 대체할 수 있기 때문에 처음 두 가지 측면에 초점을 맞추는 것과 같은 종류의 초점이 있습니다. 그래서 우리는 이것을 장기 사용의 영향과 대조해 보겠습니다. 그렇죠? 장기적으로 사용한다는 것은 무엇을 의미할까요? 그리고 무엇이 있을까요? 거기에는 모든 고기가 있습니다. 그렇죠?

소프트웨어가 제대로 작동하나요? 품질이 좋은가요? 소프트웨어가 제대로 작동하는 것을 신뢰할 수 있나요? 문제가 발생했을 때 해결할 수 있나요? 새로운 요구 사항이 주어지면 변경할 수 있나요? 이러한 것들은 우리가 입력한 구조와는 전혀 관련이 없거나 거의 관련이 없으며, 아티팩트의 속성과 많은 관련이 있습니다. 입력하는 경험의 모양과 느낌이나 문화적 측면이 아니라 아티팩트를 중심으로 구조를 평가하기 시작해야 합니다.

On the flipside it gets even worse. Our employers are also infatuated with it. Right? Those first two meanings of easy, what do they mean? Right? If I can get another programmer in here, right? And they look at your source code, and they think it's familiar, right? And they already know the toolkit, right? So it's near at hand. They've always had the same tool in their toolkit. They can read it. I can replace you. It's a breeze, especially if I ignore the third notion of easy, right, which is whether or not anybody can understand your code, right, because they don't actually care about that. They just care that somebody can go sit in your seat, start typing.

So again, as sort of business owners, there's sort of, again, the same kind of focus on those first two aspects of easy because it makes programmers replaceable. So we're going to contrast this with the impacts of long-term use. Right? What does it mean to use this long term? And what's there? What's there is all the meat. Right?

Does the software do what it's supposed to do? Is it of high quality? Can we rely on it doing what it's supposed to do? Can we fix problems when they arise? And if we're given a new requirement, can we change it? These things have nothing to do with the construct, as we typed it in, or very little to do with it, and have a lot to do with the attributes of the artifact. We have to start assessing our constructs based around the artifacts, not around the look and feel of the experience of typing it in or the cultural aspects of that.

# Limits

00:12:14 Limits

이제 한계에 대해 조금 이야기해 보겠습니다. 봐요, 움직이네요. 이것은 제가 말하는 모든 것이 사실처럼 보이는 상태로 여러분을 진정시키기 위한 것입니다.

[청중 웃음]

모나드는 그렇게 할 수 없으니까요.

[청중 웃음]

이건 아주 간단한 논리잖아요? 우리가 이해하지 못하는 것을 어떻게 신뢰할 수 있는 것으로 만들 수 있을까요? 매우, 매우 어렵습니다. 서스만 교수님이 훌륭한 지적을 해주셨는데요, 이런 트레이드오프가 있을 거라고 생각하죠? 어떤 종류의 시스템에 대해 가능한 미래에서 더 유연하고 확장 가능하며 동적으로 만들면서, 우리는 그 행동을 이해하고 그것이 올바른지 확인하는 능력에서 절충을 하게 될 것입니다. 그러나 우리가 이해하고 정확성을 확인하고자 하는 것들에 대해서는 제한이 있을 것입니다. 우리는 우리의 이해에 제한을 받게 될 것입니다.

그리고 우리의 이해는 매우 제한적이지 않습니까? 한 번에 몇 개의 공을 공중에 띄울 수 있는지, 한 번에 몇 가지를 염두에 둘 수 있는지 같은 개념이 있죠? 한정된 숫자이고 아주 적은 숫자죠? 그래서 우리는 몇 가지만 고려할 수 있고, 여러 가지가 서로 얽혀 있으면 분리해서 생각할 수 있는 능력을 잃게 됩니다.

따라서 이해해야 할 소프트웨어의 새로운 부분을 꺼낼 때마다 그것이 다른 것과 연결되어 있다고 생각하면, 다른 것 없이는 하나를 생각할 수 없기 때문에 다른 것을 머릿속으로 끌어와야 합니다. 이것이 서로 얽혀 있는 것의 본질입니다. 따라서 서로 얽혀 있을 때마다 부담이 가중되고, 고려할 수 있는 것의 수에 대한 부담은 일종의 조합적 부담입니다. 따라서 근본적으로 이러한 복잡성, 즉 복잡성이란 사물이 서로 얽혀 있다는 것을 의미하므로 시스템을 이해하는 능력이 제한될 것입니다.

So let's talk a little bit about limits. Oh, look; it does move. This is just supposed to sort of lull you into this state where everything I say seems true.

[Audience laughter]

Because I can't use monads to do that.

[Audience laughter]

This stuff is pretty simple logic, right? How can we possibly make things that are reliable that we don't understand? It's very, very difficult. I think Professor Sussman made a great point saying there's going to be this tradeoff, right? As we make things more flexible and extensible and dynamic in some possible futures for some kinds of systems, we are going to make a tradeoff in our ability to understand their behavior and make sure that they're correct. But for the things that we want to understand and make sure are correct, we're going to be limited. We're going to be limited to our understanding.

And our understanding is very limited, right? There's the whole notion of, you know, how many balls can you keep in the air at the time, or how many things can you keep in mind at a time? It's a limited number, and it's a very small number, right? So we can only consider a few things and, when things are intertwined together, we lose the ability to take them in isolation.

So if every time I think I pull out a new part of the software I need to comprehend, and it's attached to another thing, I had to pull that other thing into my mind because I can't think about the one without the other. That's the nature of them being intertwined. So every intertwining is adding this burden, and the burden is kind of combinatorial as to the number of things that we can consider. So, fundamentally, this complexity, and by complexity I mean this braiding together of things, is going to limit our ability to understand our systems.

# Change

00:14:07 Change

그렇다면 소프트웨어를 어떻게 변경할까요? 오늘 강연에서 들었는데, 애자일 프로그래밍과 익스트림 프로그래밍은 리팩터링과 테스트를 통해 아무런 영향 없이 변경할 수 있다는 것을 보여주었습니다.

[청중 웃음]

그건 몰랐어요. 아직도 모르겠어요.

[청중 웃음]

사실 그건 알 수 있는 게 아니죠. 그건 말도 안 돼요.

[청중 웃음]

그렇죠? 소프트웨어를 변경하려면 소프트웨어가 무엇을 하는지를 분석하고 무엇을 해야 하는지 결정해야 합니다. 적어도 "이 잠재적인 변화가 어떤 영향을 미칠까요?"라는 질문은 해야 합니다. 그렇죠? "그리고 변화를 적용하려면 소프트웨어의 어떤 부분을 변경해야 할까요?"

XP를 사용하든 Agile을 사용하든 다른 것을 사용하든 상관없습니다. 프로그램에 대해 추론할 수 없다면 이러한 결정을 내릴 수 없다는 사실을 피할 수 없을 것입니다. 하지만 여기서 분명히 말씀드리고 싶은 것은, 많은 사람들이 추론이라는 단어를 듣자마자 "오, 세상에! 프로그램을 증명할 수 있어야 한다는 말인가요?"라고 묻습니다. 저는 그렇지 않습니다. 저는 그렇게 생각하지 않습니다. 그게 목적이 아니라고 생각해요. 저는 비공식적인 추론, 즉 우리가 매일 무엇을 할 것인지 결정할 때 사용하는 것과 같은 종류의 추론에 대해 이야기하고 있을 뿐입니다. 우리는 범주 이론을 꺼내서 "우"라고 말하지 않습니다. 실제로 범주 이론 없이도 추론할 수 있습니다. 다행이네요.

So how do we change our software? Apparently, I heard in a talk today, that Agile and Extreme Programming have shown that refactoring and tests allow us to make change with zero impact.

[Audience laughter]

I never knew that. I still do not know that.

[Audience laughter]

That's not actually a knowable thing. That's phooey.

[Audience laughter]

Right? If you're going to change software, you're going to need to analyze what it does and make decisions about what it ought to do. You know, I mean, at least you're going to have to go and say, "What is the impact of this potential change?" Right? "And what parts of the software do I need to go to to effect the change?"

You know, I don't care if you're using XP or Agile or anything else. You're not going to get around the fact that if you can't reason about your program, you can't make these decisions. But I do want to make clear here because a lot of people, as soon as they hear the words reason about, they're like, "Oh, my God! Are you saying that you have to be able to prove programs?" I am not. I don't believe in that. I don't think that's an objective. I'm just talking about informal reasoning, the same kind of reasoning we use every day to decide what we're going to do. We do not take out category theory and say, "Woo," you know. We actually can reason without it. Thank goodness.

# Debugging

00:15:32 Debugging

그렇다면 다른 쪽은 어떨까요? 그렇죠? 소프트웨어의 미래를 위해 할 수 있는 일은 두 가지가 있습니다. 하나는 새로운 기능을 추가하는 것입니다. 다른 하나는 제대로 작동하지 않는 기능을 수정하는 것입니다.

저는 이런 질문을 하고 싶습니다: 현장에서 발견되는 모든 버그의 원인이 무엇인가요?

[청중 답변: 누가 만들었나요?] [청중 답변: 작성되었습니다.]

누군가 작성했군요. 그렇습니다. 더 흥미로운 사실은 무엇인가요? 이 글은 형식 검사기를 통과했습니다.

[청중 웃음]

또 어떻게 되었나요?

[청중 대답: (알 수 없음)]

모든 테스트를 통과했습니다. 좋아요, 이제 어떻게 하나요? 그렇죠? 가드레일 프로그래밍이라고 부르고 싶은 이 세상에 우리가 살고 있는 것 같아요. 그렇죠? 정말 슬픈 일이죠 우린 테스트가 있기 때문에 변화를 만들 수 있어요. 누가 그렇게 하나요? 차를 몰고 가드레일을 쾅쾅 치면서 "우와! 이 가드레일이 있어서 다행이야, 제시간에 공연에 못 갈 것 같아"라고 말하죠.

[청중 웃음]

그렇죠? 그리고 가드레일이 목적지에 도착하는 데 도움이 되나요? 가드레일이 목적지를 안내해 주나요? 아니요, 가드레일은 어디에나 있습니다. 가드레일은 특정 방향으로 차를 가리키지 않습니다. 그래서 다시 한 번 우리 프로그램에 대해 생각할 수 있어야 합니다. 매우 중요할 겁니다. 모든 가드레일이 우리를 실패하게 할 것입니다. 우리는 이 문제를 겪게 될 것입니다. 우리 프로그램에 대해 추론할 수 있어야 합니다. "음, 있잖아요? 너무 복잡하지 않다면 일반적인 논리로는 프로그램의 이 부분에 있을 수 없다고 말할 수 있을 것입니다. 저 부분에 있을 거야, 내가 먼저 가서 찾아볼게"라고 말할 수 있기 때문입니다.

So what about the other side? Right? There are two things you do with the future of your software. One is, you add new capabilities. The other thing is you fix the ones you didn't get, you know, done so well.

And I like to ask this question: What's true of every bug found in the field?

[Audience reply: Someone wrote it?] [Audience reply: It got written.]

It got written. Yes. What's a more interesting fact about it? It passed the type checker.

[Audience laughter]

What else did it do?

[Audience reply: (Indiscernible)]

It passed all the tests. Okay. So now what do you do? Right? I think we're in this world I'd like to call guardrail programming. Right? It's really sad. We're like: I can make change because I have tests. Who does that? Who drives their car around banging against the guardrail saying, "Whoa! I'm glad I've got these guardrails because I'd never make it to the show on time."

[Audience laughter]

Right? And - and do the guardrails help you get to where you want to go? Like, do guardrails guide you places? No. There are guardrails everywhere. They don't point your car in any particular direction. So again, we're going to need to be able to think about our program. It's going to be critical. All of our guardrails will have failed us. We're going to have this problem. We're going to need to be able to reason about our program. Say, "Well, you know what? I think," because maybe if it's not too complex, I'll be able to say, "I know, through ordinary logic, it couldn't be in this part of the program. It must be in that part, and let me go look there first," things like that.

# Development Speed

00:17:14 Development Speed

물론 이제 모든 사람들이 "하지만 저는 이 모든 속도를 가지고 있습니다. 난 민첩해. 난 빠르다고요. 이렇게 쉬운 일들이 내 인생을 좋게 만드는 건 속도가 빠르기 때문이죠."

어떤 선수가 레이스 시작부터 최대한 빨리 달릴 수 있을까요?

[청중 답변: 단거리 선수]

네, 정말 짧은 레이스를 뛰는 사람만 가능하겠죠?

[청중 웃음]

하지만 물론 우리는 프로그래머이고, 달리기 선수보다 더 똑똑하기 때문에 문제를 해결하는 방법을 알고 있죠? 우리는 100야드마다 출발 권총을 발사하고 새로운 스프린트라고 부릅니다.

[청중 웃음과 박수]

왜 그들이 그걸 알아내지 못했는지 모르겠지만... 맞아요. 제 경험에 비추어 볼 때 복잡성을 무시하면 속도가 느려진다는 것이 제 주장입니다. 장기적으로 보면 항상 속도가 느려집니다.

물론 단기간에 끝낼 수 있는 일이라면 이런 것들은 필요 없습니다. 그냥 1과 0으로 써도 되니까요. 그리고 이것은 정말 과학적인 그래프입니다. 축에 숫자가 없는 것을 보시면 아시겠지만, 제가 완전히 지어낸 것이기 때문에 숫자가 없습니다.

[청중 웃음]

이 그래프는 경험적 그래프이며, 이 그래프가 보여주는 것은 용이성에 초점을 맞추고 단순성을 무시할 때 나타나는 것이므로 두 가지를 모두 시도할 수 없다는 말은 아닙니다. 그렇게 하면 좋겠죠. 하지만 편의성에 집중한다면 레이스 초반부터 최대한 빨리 달릴 수 있을 것입니다. 하지만 어떤 기술을 사용하든, 스프린트를 하든, 권총을 쏘든, 그 어떤 것을 사용하든, 복잡성은 결국 여러분을 죽일 것입니다. 복잡한 기술은 모든 스프린트의 성취도를 떨어뜨리는 방식으로 당신을 죽일 것입니다. 대부분의 스프린트는 이미 해왔던 일을 완전히 다시 하는 것입니다. 그 결과 중요한 방식으로 앞으로 나아가지 못합니다.

단순성에 초점을 맞춰 시작한다면 처음부터 최대한 빨리 진행할 수 없는 이유는 무엇일까요? 간단한 도구도 실제로는 그렇지 않은 도구만큼 사용하기 쉽기 때문입니다. 그렇다면 왜 그렇게 빨리 갈 수 없나요?

[청중 응답: 생각해야 합니다.]

생각해야 합니다. 시작하기 전에 실제로 문제에 단순화 작업을 적용해야 하며, 이를 통해 속도를 높일 수 있습니다.

Now, of course, everybody is going to start moaning, "But I have all this speed. I'm agile. I'm fast. You know, this easy stuff is making my life good because I have a lot of speed."

What kind of runner can run as fast as they possibly can from the very start of a race?

[Audience reply: Sprinter]

Right, only somebody who runs really short races, okay?

[Audience laughter]

But of course, we are programmers, and we are smarter than runners, apparently, because we know how to fix that problem, right? We just fire the starting pistol every hundred yards and call it a new sprint.

[Audience laughter and applause]

I don't know why they haven't figured that out, but -- right. It's my contention, based on experience, that if you ignore complexity, you will slow down. You will invariably slow down over the long haul.

Of course, if you are doing something that's really short term, you don't need any of this. You could write it, you know, in ones and zeros. And this is my really scientific graph. You notice how none of the axis are -- there's no numbers on it because I just completely made it up.

[Audience laughter]

It's an experiential graph, and what it shows is if you focus on ease and ignore simplicity, so I'm not saying you can't try to do both. That would be great. But if you focus on ease, you will be able to go as fast as possible from the beginning of the race. But no matter what technology you use, or sprints or firing pistols, or whatever, the complexity will eventually kill you. It will kill you in a way that will make every sprint accomplish less. Most sprints be about completely redoing things you've already done. And the net effect is you're not moving forward in any significant way.

Now if you start by focusing on simplicity, why can't you go as fast as possible right at the beginning? Right, because some tools that are simple are actually as easy to use as some tools that are not. Why can't you go as fast then?

[Audience response: You have to think.]

You have to think. You have to actually apply some simplicity work to the problem before you start, and that's going to give you this ramp up.

# Easy Yet Complex?

00:19:36 Easy Yet Complex?

제가 생각하는 문제 중 하나는 쉬워 보이는 일들이 실제로는 복잡하다는 수수께끼입니다. 예를 들어 보겠습니다. 매우 간결하게 설명된 복잡한 아티팩트를 가진 구조가 많이 있습니다. 그렇죠? 사용하기에 정말 위험한 것들 중 일부는 설명하기가 너무 간단합니다. 엄청나게 친숙하죠? 객체 지향에서 왔다면 복잡한 것들에 익숙할 것입니다. 아주 많이 사용할 수 있습니다. 그렇죠?

그리고 사용하기 쉽습니다. 사실, 모든 척도, 기존의 척도로 보면 이것이 쉽다고 말할 수 있습니다. 그렇죠? 하지만 저희는 그런 것에는 신경 쓰지 않습니다. 그렇죠? 다시 말하지만, 사용자는 소프트웨어를 보는 것이 아니며, 우리가 소프트웨어를 개발할 때 얼마나 좋은 시간을 보냈는지에 대해서는 별로 신경 쓰지 않습니다. 그렇죠? 사용자가 관심을 갖는 것은 프로그램이 무엇을 하는가이며, 프로그램이 잘 작동한다면 그 결과물이 단순했는지 여부와 관련이 있을 것입니다. 다시 말해, 어떤 복잡성을 초래했느냐는 것입니다.

복잡성이 있는 경우 이를 부수적 복잡성이라고 부릅니다. 그렇죠? 사용자가 요청한 작업의 일부가 아니었습니다. 우리는 도구를 선택했습니다. 그 도구에는 내재된 복잡성이 있었습니다. 문제에 부수적인 것이죠. 여기에 정의를 넣지는 않았지만 부수적이란 라틴어로 부수적이라는 뜻입니다.

[청중 웃음]

그렇기 때문에 여러분은 정말 스스로에게 물어봐야 할 필요가 있습니다. 정말 즐거운 시간을 보내고 있잖아요. 셔틀을 앞뒤로 던지고 있잖아요. 그런데 반대편에서 나오는 것은 엉망진창인 매듭입니다. 예쁘게 보일지 몰라도 문제가 있잖아요. 그렇죠? 뭐가 문제죠? 문제는 니트 캐슬 문제입니다. 안 그래요?

One of the problems I think we have is this conundrum that some things that are easy actually are complex. So let's look. There are a bunch of constructs that have complex artifacts that are very succinctly described. Right? Some of the things that are really dangerous to use are like so simple to describe. They're incredibly familiar, right? If you're coming from object-orientation, you're familiar with a lot of complex things. They're very much available. Right?

And they're easy to use. In fact, by all measures, conventional measures, you would look at them and say this is easy. Right? But we don't care about that. Right? Again, the user is not looking at our software, and they don't actually care very much about how good a time we had when we were writing it. Right? What they care about is what the program does, and if it works well, it will be related to whether or not the output of those constructs were simple. In other words, what complexity did they yield?

When there is complexity there, we're going to call that incidental complexity. Right? It wasn't part of what the user asked us to do. We chose a tool. It had some inherent complexity in it. It's incidental to the problem. I didn't put the definition in here, but incidental is Latin for your fault.

[Audience laughter]

And it is, and I think you really have to ask yourself, you know, are you programming with a loom? You know, you're having a great time. You're throwing that shuttle back and forth. And what's coming out the other side is this knotted, you know, mess. I mean it may look pretty, but you have this problem. Right? What is the problem? The problem is the knitted castle problem. Right?

# Benefits of Simplicity

00:21:30 Benefits of Simplicity

니트 성을 원하시나요? 단순함을 통해 얻을 수 있는 이점은 무엇일까요? 이해하기 쉬워지겠죠? 그건 일종의 정의입니다. 저는 변경이 쉽고 디버깅이 쉬워진다고 주장합니다. 부차적으로 얻을 수 있는 다른 이점은 유연성 향상입니다. 모듈화 및 세분화에 대해 더 자세히 이야기하면 어떤 이점이 있는지 알 수 있을 것입니다. 정책을 변경하거나 물건을 옮길 수 있는 기능 같은 것이죠? 일을 더 단순하게 만들면 의사 결정이 끼어들지 않기 때문에 더 독립적으로 위치를 결정할 수 있습니다. 이는 성과 결정과 직교합니다.

테스트 스위트와 리팩토링 도구가 있으면 니트 성을 바꾸는 것이 레고 성을 바꾸는 것보다 더 빠를까요? 절대 아닙니다. 전혀 관련이 없습니다.

Do you want a knitted castle? What benefits do we get from simplicity? We get ease of understanding, right? That's sort of definitional. I contend we get ease of change and easier debugging. Other benefits that come out of it that are sort of on a secondary level are increased flexibility. And when we talk more about modularity and breaking things apart, we'll see where that falls. Like the ability to change policies or move things around, right? As we make things simpler, we get more independence of decisions because they're not interleaved, so I can make a location decision. It's orthogonal from a performance decision.

And I really do want to, you know, ask the question, agilest or whatever: Is having a test suite and refactoring tools going to make changing the knitted castle faster than changing the Lego castle? No way. Completely unrelated.

# Making Things Easy

00:22:35 Making Things Easy

그럼 어떻게 하면 일을 쉽게 할 수 있을까요? 아마도 여기서 말하는 목적은 소프트웨어 위기를 한탄만 하는 것이 아니겠죠? 그렇다면 어떻게 하면 일을 더 쉽게 할 수 있을까요? 이제 다시 한 번 이러한 부분, 즉 편의성의 측면을 살펴보겠습니다. 위치 측면이 있습니다. 무언가를 만들어서 툴킷에 넣는 것은 비교적 간단합니다. 그렇죠? 설치만 하면 되죠. 하지만 누군가가 사용해도 좋다는 허락을 받아야 하기 때문에 조금 더 어려울 수도 있습니다.

그런 다음 어떻게 하면 친숙하게 만들 수 있을지에 대한 측면이 있습니다. 전에는 이런 것을 본 적이 없을 수도 있습니다. 그건 학습 연습입니다. 책을 구해서 튜토리얼을 듣고 누군가에게 설명을 들어야 하죠. 한번 해봐야죠. 그렇죠? 이 두 가지 모두 우리가 운전하고 있습니다. 운전하고 있어요 설치하고 배우고. 전적으로 우리 손에 달려 있습니다.

하지만 정신적 능력이라는 또 다른 부분이 있습니다. 정신적 능력은 항상 이야기하기 어려운 부분인데, 사실 우리는 더 많은 것을 배울 수 있기 때문입니다. 사실 우리는 더 똑똑해질 수 없습니다. 우리는 움직이지 않을 것입니다. 우리의 두뇌를 복잡성에 더 가깝게 만들지 않을 것입니다. 우리는 사물을 단순화하여 가까이 만들어야 합니다.

하지만 여기서 진실은 저글링의 비유가 매우 비슷하기 때문에 저글링을 잘하는 사람들이 놀라운 일을 할 수 있는 매우 똑똑한 사람들이고 다른 사람들은 모두 막혀 있다는 것이 아닙니다. 그렇죠? 평균적인 저글러는 공 세 개를 던질 수 있습니다. 세계에서 가장 놀라운 저글러는 9개의 공이나 12개의 공 같은 것을 할 수 있습니다. 그들은 20개나 100개를 할 수 없습니다. 우리 모두는 매우 제한적입니다. 우리가 만들어낼 수 있는 복잡성에 비해 통계적으로 우리 모두는 그것을 이해하는 능력에서 같은 지점에 있으며, 이는 그다지 좋지 않습니다. 그래서 우리는 사물을 우리에게로 가져와야 합니다.

그리고 우리는 많은 공만 저글링할 수 있기 때문에 결정을 내려야 합니다. 그 공 중 몇 개를 부수적인 복잡성으로, 몇 개를 문제 복잡성으로 만들까요? 여분의 공은 몇 개로 할까요? 여기에 통합해야 하는 공을 누군가 던져주길 원하시나요? 오, 이 도구를 사용하세요. 그러면 공이 더 많아지는 거죠. 그렇게 하고 싶은 사람?

Okay. So how do we make things easy? Presumably, you know, the objective here is not to just bemoan their software crisis, right? So what can we do to make things easier? So we'll look at those parts, those aspects of being easy again. There's a location aspect. Making something at hand, putting it in our toolkit, that's relatively simple. Right? We just install it. Maybe it's a little bit harder because we have to get somebody to say it's okay to use it.

Then there's the aspect of how do I make it familiar, right? I may not have ever seen this before. That's a learning exercise. I've got to go get a book, go take a tutorial, have somebody explain it to me. Maybe try it out. Right? Both these things we're driving. We're driving. We install. We learn. It's totally in our hands.

Then we have this other part though, which is the mental capability part. And that's the part that's always hard to talk about, the mental capability part because, the fact is, we can learn more things. We actually can't get much smarter. We're not going to move; we're not going to move our brain closer to the complexity. We have to make things near by simplifying them.

But the truth here is not that they're these super, bright people who can do these amazing things and everybody else is stuck because the juggling analogy is pretty close. Right? The average juggler can do three balls. The most amazing juggler in the world can do, like, 9 balls or 12 or something like that. They can't do 20 or 100. We're all very limited. Compared to the complexity we can create, we're all statistically at the same point in our ability to understand it, which is not very good. So we're going to have to bring things towards us.

And because we can only juggle so many balls, you have to make a decision. How many of those balls do you want to be incidental complexity and how many do you want to be problem complexity? How many extra balls? Do you want to have somebody throwing you balls that you have to try to incorporate in here? Oh, use this tool. And you're like, whoa! You know, more stuff. Who wants to do that?

# Parens are Hard!

00:24:48 Parens are Hard!

좋아요, 사실 하나만 말씀드리죠.

[청중 웃음]

저는 이 불만의 반대편에 서 본 적이 있습니다. 왜냐하면 이 분석은 사용량과는 아무런 관련이 없기 때문입니다. 이 복잡성 분석은 프로그래머 경험에 관한 것입니다. 그래서 부모들은 힘들죠. 그렇죠? 사용해 보지 않은 대부분의 사람들에게는 쉽게 이해되지 않습니다.

그게 무슨 뜻일까요? 예를 들어, 부모를 일치시키거나 구조적으로 이동하는 방법을 아는 편집기가 없거나 편집기가 있어도 이를 가능하게 하는 모드를 로드해 본 적이 없다는 뜻입니다. 완전히 주어진 거죠? 손에 잡히지도 않고 익숙하지도 않죠. 누구나 괄호를 본 적은 있지만 그 반대쪽에서 괄호를 본 적은 없으니까요.

[청중 웃음]

제 말은 [웃음] 그건 정말 미친 짓이에요!

[청중 웃음]

하지만 사용자로서, 잠재적 사용자로서 이 두 가지를 고치는 것은 여러분의 책임이라고 생각합니다. 여러분은 이 일을 해야 합니다. 하지만 더 깊이 파고들 수 있습니다. 세 번째를 살펴봅시다. 정말 간단한 것을 주셨나요? 부모님으로 만들어진 언어가 모두 단순할까요? 제가 말씀드린 경우라면, 인터리빙과 브레이딩이 없는 언어일까요? 대답은 '아니요'입니다. 그렇죠?

일반적인 LISP와 Scheme은 괄호 사용으로 인해 과부하가 걸리기 때문에 이러한 의미에서 파렌스를 사용하는 언어가 단순하지 않습니다. 부모는 호출을 감싸줍니다. 그룹화를 래핑합니다. 데이터 구조를 감싸기도 합니다. 그리고 이러한 과부하는 제가 말씀드린 정의에 따라 복잡성의 한 형태입니다. 그렇죠?

따라서 실제로 편집기를 설정하고 괄호가 동사의 반대편에 있다는 사실을 알게 되었다면 이는 여전히 유효한 불만입니다. 물론 모든 사람들이 쉽게, 어렵고, 복잡하다고 말하면서 이 단어들을 정말 약하게 사용하고 있었습니다. 그렇죠? 하지만 언어 디자이너의 잘못으로 과부하가 걸린다는 몇 가지 이유 때문에 어렵고, 언어 디자이너의 잘못으로 단순하지 않았습니다. 그리고 우리는 그것을 고칠 수 있습니다. 그렇죠? 다른 데이터 구조를 추가하면 됩니다.

데이터 구조가 더 많다고 해서 LISP가 LISP가 아닌 것은 아닙니다. 그렇죠? 여전히 자체 데이터 구조로 정의된 언어이기 때문입니다. 하지만 데이터 구조가 더 많다는 것은 이 경우 과부하를 제거할 수 있다는 의미이며, 이는 다시 단순성이 구조로 돌아오고 익숙해져서 스스로 해결할 수 있는 문제이기 때문에 다시 사용자의 잘못이 됩니다.

All right, so let's look at a fact.

[Audience laughter]

I've been on the other side of this complaint, and I like it. We can look at it really quickly only because it's not -- this analysis has nothing to do with the usage. This complexity analysis is just about the programmer experience. So parens are hard. Right? They're not at hand for most people who haven't otherwise used it.

And what does that mean? It means that, like, they don't have an editor that knows how to do, you know, paren matching or move stuff around structurally, or they have one and they've never loaded the mode that makes that happen. Totally given, right? It's not at hand, nor is it familiar. I mean, everybody has seen parentheses, but they haven't seen them on that side of the method.

[Audience laughter]

I mean [laughter] that is just crazy!

[Audience laughter]

But, you know, I think this is your responsibility, right, to fix these two things, as a user, as a potential user. You've got to do this. But we could dig deeper. Let's look at the third thing. Did you actually give me something that was simple? Is a language built all out of parens simple? In the case I'm saying, right, is it free of interleaving and braiding? And the answer is no. Right?

Common LISP and Scheme are not simple in this sense, in their use of parens because the use of parentheses in those languages is overloaded. Parens wrap calls. They wrap grouping. They wrap data structures. And that overloading is a form of complexity by the definition, you know, I gave you. Right?

And so, if you actually bothered to get your editor set up and learn that the parentheses goes on the other side of the verb, this was still a valid complaint. Now, of course, everybody was saying easy, and it's hard, it's complex, and they were using these words really weakly. Right? But it was hard for a couple reasons you could solve, and it was not simple for a reason that was the fault of the language designer, which was that there was overloading there. And we can fix that. Right? We can just add another data structure.

It doesn't make LISP not LISP to have more data structures. Right? It's still a language defined in terms of its own data structures. But having more data structures in play means that we can get rid of this overloading in this case, which then makes it your fault again because the simplicity is back in the construct, and it's just a familiarity thing, which you can solve for yourself.

# Alan Perlis quote

00:27:33 Alan Perlis quote

좋아요. 이것은 LISP 프로그래머에 대한 오래된 발굴이었습니다. 무슨 말인지 잘 모르겠어요. 성능과 관련된 것이었던 것 같아요. LISP 프로그래머들은 모든 기억을 동원해 모든 평가를 했는데, 그건 돼지였어요. 당시의 LISP 프로그래머는... 당시의 LISP 프로그램은 하드웨어에 비해 완전한 돼지였습니다. 그래서 그들은 이러한 모든 구조의 가치, 즉 동적 특성을 잘 알고 있었습니다. 이런 것들은 모두 훌륭합니다. 모두 가치가 있지만 성능 비용이 발생했습니다.

저는 이 문구 전체를 떼어내서 지금 우리 모두에게 적용하고 싶습니다. 프로그래머로서 우리는 모든 종류의 것을 보고 있고, 저는 그냥 보고 있습니다. 해커 뉴스 같은 걸 읽으면서요. 이걸 보면 이런 이점이 있네요. 오, 좋아요. 그렇게 할게요. 아, 하지만 이건 이런 장점이 있네요. 오, 멋지네요. 오, 그거 멋지네요 그게 더 짧아요. 이런 토론에서는 절대로 볼 수 없는 장단점이 있나요? 단점은 없나요? 나쁜 점은 없나요? 전혀요. 전혀요.

우리가 모두 이점을 찾는 것과 같습니다. 프로그래머로서 우리는 이점에만 집중할 뿐 부산물에 대해서는 충분히 주의 깊게 살펴보지 않는 것 같아요.

Okay. This was an old dig at LISP programmers. I'm not totally sure what he was talking about. I believe it was a performance related thing. The LISPers, they consed up all this memory, and they did all this evaluation, and it was a pig. LISP programmers at that time were -- LISP programs at that time were complete pigs relative to the hardware. So, you know, they knew the value of all these constructs, right, this dynamic nature. These things are all great. They are valuable, but there was this performance cost.

I'd like to lift this whole phrase and apply it to all of us right now. As programmers, we are looking at all kinds of things, and I just see it. You know, read Hacker News or whatever. It's like, oh, look; this thing has this benefit. Oh, great. I'm going to do that. Oh, but this has this benefit. Oh, that's cool. Oh, that's awesome. You know, that's shorter. You never see in these discussions: was there a tradeoff? Is there any downside? You know, is there anything bad that comes along with this? Never. Nothing.

It's just like we look all for benefits. So as programmers now, I think we're looking all for benefits, and we're not looking carefully enough at the byproducts.

# What's in your Toolkit?

00:28:50 What's in your Toolkit?

툴킷에는 무엇이 있나요? 두 개의 열이 있습니다. 하나는 복잡성, 다른 하나는 단순성이에요. 단순성 열은 더 단순하다는 뜻입니다. 저기 있는 것들이 순전히 단순하다는 뜻은 아닙니다. 저는 이런 것들을 나쁘고 좋은 것으로 분류하지 않았습니다. 여러분 마음속에 맡기겠습니다.

[청중 웃음]

그렇다면 어떤 것들이 복잡하고 어떤 것들이 간단하게 대체될 수 있을까요? 자세한 설명은 하지 않겠습니다만, 객체는 복잡하고 값은 단순하며 많은 경우에 이를 대체할 수 있다고 말씀드리겠습니다. 메서드는 복잡하고 함수는 단순하다고 말씀드리겠습니다. 그리고 네임스페이스는 단순합니다. 메서드가 있는 이유는 메서드의 공간인 클래스나 그 무엇이든 미니 네임스페이스인 경우가 많기 때문입니다.

변수는 복잡하고 변수도 복잡합니다. 관리 참조도 복잡하지만 더 간단합니다. 상속, 스위치 문, 패턴 매칭은 모두 복잡하고 단품 다형성은 단순합니다. 이제 단순의 의미를 기억하세요. 단순하다는 의미는 다른 것과 뒤엉켜 있지 않고 얽히지 않았다는 뜻입니다. 단순하다고 해서 이미 그 의미를 알고 있다는 뜻은 아닙니다. 단순하다고 해서 이미 그 의미를 알고 있다는 뜻은 아닙니다.

구문은 복잡합니다. 데이터는 단순합니다. 명령형 루프, 폴드 이븐은 다소 고차원적으로 보이지만 여전히 두 가지를 하나로 묶는 함축적인 의미가 있는 반면 집합 함수는 더 단순합니다. 액터는 복잡하고 큐는 더 간단합니다. ORM은 복잡하고 선언적 데이터 조작은 더 간단합니다. Eric도 강연에서 그렇게 말했습니다. 마지막에 정말 빠르게 말했죠.

[청중 웃음]

네, 그리고 최종적인 일관성은 프로그래머에게 정말 어려운 문제입니다. 조건문은 흥미로운 방식으로 복잡하고 규칙은 더 간단할 수 있습니다. 그리고 불일치는 매우 복잡합니다. 일관성이 있다는 것은 함께 서 있다는 뜻이고, 일관성이 없다는 것은 따로 서 있다는 뜻이기 때문에 거의 정의적으로 복잡합니다. 즉, 서로 떨어져 있는 여러 가지를 동시에 생각해야 한다는 뜻입니다. 그렇게 하는 것은 본질적으로 복잡합니다. 결국 일관성 있는 시스템을 사용해 본 사람이라면 누구나 알고 있는 사실입니다.

So, what's in your toolkit? I have, you know, I have these two columns. One says complexity and one says simplicity. The simplicity column just means simpler. It doesn't mean that the things over there are purely simple. Now I didn't label these things bad and good. I'm leaving your minds to do that.

[Audience laughter]

So what things are complex and what are the simple replacements? I'm going to dig into the details on these, so I won't actually explain why they're complex, but I'm going to state and objects are complex, and values are simple and can replace them in many cases. I'm going to say methods are complex, and functions are simple. And namespaces are simple. The reason why methods are there are because often the space of methods, the class or whatever, is also a mini, very poor namespace.

Vars are complex and variables are complex. Managed references are also complex, but they're simpler. Inheritance, switch statements, pattern matching are all complex, and polymorphism a la carte is simple. Now remember the meaning of simple. The meaning of simple means unentangled, not twisted together with something else. It doesn't mean I already know what it means. Simple does not mean I already know what it means.

Okay. Syntax is complex. Data is simple. Imperative loops, fold even, which seems kind of higher level, still has some implications that tie two things together, whereas set functions are simpler. Actors are complex, and queues are simpler. ORM is complex, and declarative data manipulation is simpler. Even Eric said that in his talk. He said it really fast near the end.

[Audience laughter]

Oh, yeah, and eventual consistency is really hard for programmers. Conditionals are complex in interesting ways, and rules can be simpler. And inconsistency is very complex. It's almost definitionally complex because consistent means to stand together, so inconsistent means to stand apart. That means taking a set of things that are standing apart and trying to think about them all at the same time. It's inherently complex to do that. And anybody who has tried to use a system that's eventually consistent knows that.

# Complect

00:31:36 Complect

좋아요, '컴플렉트(complect)'라는 멋진 단어가 있네요. 제가 찾았어요.

[청중 웃음]

정말 마음에 들어요. 엮다, 얽다, 땋다라는 뜻이죠. 알겠죠? 저는 우리가 소프트웨어를 나쁘게 만드는 것에 대해 이야기하고 싶습니다. 브레이드(braid)나 인튜바인(entwine)은 컴플렉트처럼 좋은 의미나 나쁜 의미가 없기 때문에 사용하고 싶지 않아요. 컴플렉트는 분명히 나쁘죠. 그렇죠?

[청중 웃음]

구식 단어이긴 하지만 다시 사용하지 말라는 규칙은 없으니 남은 강연에서 이 단어를 사용하겠습니다. 컴플렉트에 대해 무엇을 알고 계신가요? 나쁘죠. 하지 마세요. 그렇죠? 컴플렉트는 바로 여기서 복잡성이 비롯됩니다. 아주 간단합니다.

[청중 웃음]

특히 애초에 피하고 싶은 것이 바로 복잡성입니다. 이 다이어그램을 보세요. 첫 번째를 보세요. 마지막을 보세요. 그렇죠? 두 다이어그램 모두 똑같은 내용입니다. 같은 스트립이에요 어떻게 된 거죠? 합쳐졌어요.

[청중 웃음]

이제 아래쪽 다이어그램과 위쪽 다이어그램을 구분하기는 어렵지만 같은 내용입니다. 여러분은 항상 이런 일을 하고 있죠. 프로그램을 만드는 방법은 수백 가지가 있습니다. 그 중 일부는 그냥 거기 매달려 있습니다. 모두 똑같아요. 보세요. 이 프로그램은 네 줄로 되어 있죠? 그렇죠? 그러면 다른 언어나 다른 구조로 네 줄을 입력하면 매듭이 생기므로 이를 처리해야 합니다.

Okay. So there's this really cool word called complect. I found it.

[Audience laughter]

I love it. It means to interleave or entwine or braid. Okay? I want to start talking about what we do to our software that makes it bad. And I don't want to say braid or entwine because it doesn't really have the good/bad connotation that complect has. Complect is obviously bad. Right?

[Audience laughter]

It happens to be an archaic word, but there are no rules that say you can't start using them again, so I'm going to use them for the rest of the talk. So what do you know about complect? It's bad. Don't do it. Right? This is where complexity comes from: complecting. It's very simple.

[Audience laughter]

In particular, it's something that you want to avoid in the first place. Look at this diagram. Look at the first one. Look at the last one. Right? It's the same stuff in both those diagrams, the exact. It's the same strips. What happened? They got complected.

[Audience laughter]

And now it's hard to understand the bottom diagram from the top one, but it's the same stuff. You're doing this all the time. You can make a program a hundred different ways. Some of them, it's just hanging there. It's all straight. You look at it. You say, I see it's four lines, this program. Right? Then you could type in four lines in another language or with a different construct, and you end up with this knot, so we've got to take care of that.

# Compose

00:33:07 Compose

따라서 컴플렉트(complect)는 실제로 함께 땋는다는 뜻입니다. 그리고 컴포지션(compose)은 함께 배치한다는 뜻입니다. 우리도 알고 있죠? 모두가 우리에게 계속 말하죠. 우리가 하고 싶은 것은 컴포저블(함께 배치할수 있) 시스템을 만드는 것입니다. 우리는 단지 함께 배치하고 싶을 뿐이며, 이는 훌륭하고 이견이 없다고 생각합니다. 그렇죠? 그런 점에서 단순한 구성 요소를 간단하게 구성하는 것이 바로 강력한 소프트웨어를 작성하는 방법입니다.

So complect actually means to braid together. And compose means to place together. And we know that, right? Everybody keeps telling us. What we want to do is make composable systems. We just want to place things together, which is great, and I think there's no disagreement. Right? Composing simple components, simple in that same respect, is the way we write robust software.

# Modularity and Simplicity

00:33:35 Modularity and Simplicity

간단하죠? 우리가 해야 할 일은... 모두가 알고 있는 사실입니다. 저는 여러분들이 알고 있는 내용을 말씀드리는 것뿐입니다. 모듈화하면 간단한 시스템을 만들 수 있죠? 다 끝났어요 제 얘기의 절반은 끝났어요. 끝낼 수 있을지도 모르겠어요. 너무 간단해요. 바로 이거예요. 이게 열쇠에요.

아니요, 분명히 열쇠가 아닙니다. 이런 특징을 가진 컴포넌트를 본 사람 있나요? 손을 드는 사람이 적어서 두 번만 손을 들겠습니다. 말도 안 되죠? 어떻게 될까요? 모든 종류의 상호 연결이 가능한 모듈형 소프트웨어를 작성할 수 있습니다. 서로를 호출하지 않을 수도 있지만 완전히 포괄됩니다.

So it's simple, right? All we need to do is -- everybody knows this. I'm up here just telling you stuff you know. We can make simple systems by making them modular, right? We're done. I'm like halfway through my talk. I don't even know if I'm going to finish. It's so simple. This is it. This is the key.

No, it's obviously not the key. Who has seen components that have this kind of characteristic? I'll raise my hand twice because not enough people are raising their hands. It's ridiculous, right? What happens? You can write modular software with all kinds of interconnections between them. They may not call each other, but they're completely complected.

# Modularity and Simplicity - build slide

00:34:19 Modularity and Simplicity - build slide

그리고 우리는 이 문제를 해결하는 방법을 알고 있습니다. 두 가지가 있다는 사실과는 아무 상관이 없습니다. 정말 의인화하려면 이 두 가지를 어떻게 생각해야 하는지와 관련이 있습니다.

And we know how to solve this. It has nothing to do with the fact that there are two things. It has to do with what those two things are allowed to think about, if you want to really anthropomorphize.

00:34:31 Modularity and Simplicity - build slide

그리고 어떤 것만 생각하도록 허용하고 싶을까요? 약간의 추상화요. 그게 잘 나오는지 모르겠어요. 레고 윗부분을 흰색 점선으로 표시한 거죠. 이제 파란색 사람은 노란색 사람에 대해 아무것도 모르고 노란색 사람은 파란색 사람에 대해 아무것도 모르며 둘 다 단순해졌기 때문에 그것으로 제한하고 싶습니다.

따라서 단순성을 파티셔닝 및 계층화와 연관시키지 않는 것이 매우 중요합니다. 단순성은 파티셔닝과 계층화를 암시하지 않습니다. 그것들은 그것에 의해 활성화됩니다. 단순한 컴포넌트를 만들면 수평적으로 분리할 수 있고 수직적으로 계층화할 수 있습니다. 그렇죠? 하지만 복잡한 컴포넌트로도 그렇게 할 수 있지만 아무런 이점을 얻을 수 없습니다.

따라서 코드 구성에 속지 않도록 특히 주의하시기 바랍니다. 라이브러리에는 수많은 클래스가 있고 각기 다른 클래스가 있습니다. 이런 멋진 방식으로 서로를 호출하죠? 그런데 막상 현장에 나가면 세상에! 저건 숫자 17을 절대 반환하지 않는다고 가정합니다. 저게 뭐죠?

And what do we want to make things allowed to think about, and only these things? Some abstractions. I don't know if that's coming out that well. That's a dashed white version of the top of a Lego. That's all we want to limit things to because now the blue guy doesn't really know anything about the yellow guy, and the yellow guy doesn't really know anything about the blue guy, and they've both become simple.

So it's very important that you don't associate simplicity with partitioning and stratification. They don't imply it. They are enabled by it. If you make simple components, you can horizontally separate them, and you can vertically stratify them. Right? But you can also do that with complex things, and you're going to get no benefits.

And so I would encourage you to be particularly careful not to be fooled by code organization. There are tons of libraries that look, oh, look, there's different classes; there's separate classes. They call each other in sort of these nice ways, right? Then you get out in the field and you're like, oh, my God! This thing presumes that that thing never returns the number 17. What is that?

# State is Never Simple

00:35:38 State is Never Simple

좋아요, 여기 와서 주정부가 멋지다고 말하진 않겠습니다. 전 주를 좋아해요. 저는 기능적인 사람이 아니니까요. 대신 이렇게 말할게요 저는 이 일을 해봤는데 형편없었어요. 몇 년 동안 해봤어요: C++, 히맨, 상태 저장 프로그래밍을 해봤어요. 정말 재미없어요. 좋지 않죠. 결코 간단하지 않죠.

프로그램에서 상태를 갖는다는 것은 결코 간단하지 않은데, 그 이유는 그 아티팩트에 근본적인 컴포짓이 있기 때문입니다. 그것은 가치와 시간을 수집합니다. 시간과 무관한 가치를 얻을 수 있는 능력은 없습니다. 때로는 적절한 의미의 가치를 얻을 수 있는 능력이 전혀 없을 수도 있습니다. 하지만 다시 말하지만, 이것은 좋은 예입니다. 이것은 쉽습니다. 완전히 친숙합니다. 우리 가까이에 있습니다. 모든 프로그래밍 언어에 있습니다. 정말 쉽습니다. 이 복잡성은 너무 쉽습니다.

그리고 당신은 그것을 제거 할 수 없습니다. 모든 것에는 모듈성이 있습니다. 할당 문은 메서드 안에 있습니다. 동일한 인수로 메서드를 호출할 때마다 다른 결과를 얻을 수 있다면 어떻게 될까요? 그 복잡성이 바로 밖으로 새어 나갔을 것입니다. 변수를 볼 수 없다는 것은 중요하지 않습니다. 변수를 감싸고 있는 것이 상태 저장소이고 변수를 감싸고 있는 것이 여전히 상태 저장소인 경우, 다시 말해 같은 질문을 할 때마다 다른 대답을 얻는다면, 이 복잡성은 독약과 같습니다.

마치 꽃병에 어두운 액체를 떨어뜨리는 것과 같습니다. 결국 여기저기 흩어지게 되죠. 이러한 복잡성을 제거할 수 있는 유일한 방법은 외부에 기능적인 인터페이스를 제공할 수 있는, 즉 동일한 입력과 동일한 출력이라는 진정한 기능적인 인터페이스를 제공할 수 있는 무언가에 넣는 것입니다. 일반적인 코드 정리를 통해서는 이 문제를 완화할 수 없습니다.

특히 여기서 동시성에 대해 이야기하지 않았다는 점에 유의하세요. 이것은 동시성에 관한 것이 아닙니다. 동시성과는 아무 상관이 없습니다. 여러분의 프로그램을 이해하는 능력에 관한 것입니다.

여러분의 프로그램은 저 밖에 있습니다. 싱글 스레드입니다. 작동하지 않았어요. 모든 테스트는 통과했습니다. 유형 검사기를 통과했어요. 무슨 일이 있었는지 알아내세요. 변수로 가득 차 있다면 어떻게 해야 할까요? 문제가 발생했을 때 클라이언트에서 발생했던 상태를 다시 만들어 보세요. 그게 쉬울까요? 절대 아닙니다!

Okay. I'm not going to get up here and tell you state is awesome. I like state. I'm not a functional whatever guy, whatever. I'm going to say instead: I did this, and it sucked. I did years and years: C++, you know, He-Man, stateful programming. It's really not fun. It's not good. It's never simple.

Having state in your program is never simple because it has a fundamental complecting that goes on in its artifacts. It complects value and time. You don't have the ability to get a value independent of time. And sometimes not an ability to get a value in any proper sense at all. But again, it's a great example. This is easy. It's totally familiar. It's at hand. It's in all the programming languages. This is so easy. This complexity is so easy.

And you can't get rid of it. Everything -- I have modularity. That assignment statement is inside a method. Well, if every time you call that method with the same arguments, you can get a different result, guess what happened? That complexity just leaked right out of there. It doesn't matter that you can't see the variable. If the thing that's wrapping it is stateful and the thing that's wrapping that is still stateful, in other words by stateful I mean every time you ask it the same question you get a different answer, you have this complexity and it's like poison.

It's like dropping some dark liquid into a vase. It's just going to end up all over the place. The only time you can really, you know, get rid of it is when you put it inside something that's able to present a functional interface on the outside, a true functional interface: same input, same output. You can't mitigate it through the ordinary code organization things.

And note in particular, I didn't talk about concurrency here. This is not about concurrency. This has nothing to do with concurrency. It's about your ability to understand your program.

Your program was out there. It's single threaded. It didn't work. All the tests passed. It made it through the type checker. Figure out what happened. If it's full of variables, where are you going to need to try to do? Recreate the state that was happening at the client when it went bad. Is that going to be easy? No!

# Not all refs/vars are Equal

00:38:00 Not all refs/vars are Equal

하지만 우리가 고칠 수 있죠? 여러분의 언어, 여러분의 새롭고 반짝이는 언어에는 var라는 것이 있거나 참조나 참조가 있을 수 있습니다. 이러한 구조 중 어느 것도 상태를 단순하게 만들지 못합니다. 이것이 가장 중요한 첫 번째 문제입니다. 저는 클로저의 구조체조차도 그렇게 말하고 싶지 않습니다. 제가 말하는 단순함의 본질에서 상태를 단순하게 만들지 않습니다. 그러나 그들은 동일하지 않습니다.

모두 상태가 있을 때 경고를 하긴 하는데, 이는 좋은 점입니다. 가변성이 기본값이 아니고 이를 얻기 위해 노력해야 하는 언어를 사용하는 대부분의 사람들은 애초에 다른 모든 상태가 필요하지 않았기 때문에 결국 작성하는 프로그램이 다른 경우보다 훨씬 적은 상태를 가지고 있다는 것을 알게 됩니다. 정말 대단하죠.

하지만 저는 값과 시간을 구성하기 때문에 이 문제를 처리하는 데 있어 특히 Clojure와 Haskell의 참조가 우수하다고 말씀드리고 싶습니다. 실제로 두 가지를 수행하는 작은 구조체가 있습니다. 시간에 따른 추상화와 값을 추출할 수 있는 기능이 있습니다. 이는 단순함으로 돌아가는 길이기 때문에 매우 중요합니다. 이 구조에서 벗어나 값을 추출할 수 있는 방법이 있다면 프로그램을 계속 진행할 수 있습니다. 변수를 다른 사람에게 전달하거나 매번 변수를 찾을 수 있는 참조를 변수를 통해 전달해야 한다면 시스템의 나머지 부분을 오염시키는 것입니다. 따라서 해당 언어의 변수를 살펴보고 동일한 기능을 수행하는지 확인하세요.

But we fix this, right? Your language, your new, shiny language has something called var, or maybe it has refs or references. None of these constructs make state simple. That's the first, primary thing. I don't want to say that even of Clojure's constructs. They do not make state simple in the case I'm talking about, in the nature of simple I'm talking about. But they're not the same.

They all do warn you when you have state, and that's great. Most people who are using a language where mutability is not the default and you have to go out of your way to get it, finds that the programs you end up writing have dramatically, like orders of magnitude, less state than they would otherwise because they never needed all the other state in the first place. So that's really great.

But I will call out Clojure and Haskell's references as being particularly superior in dealing with this because they compose values and time. There are actually little constructs that do two things. They have some abstraction over time and the ability to extract a value. That's really important because that's your path back to simplicity. If I have a way to get out of this thing and get a value out, I can continue with my program. If I have to pass that variable to somebody else or a reference to something that's going to find the variable every time through the varying thing, I'm poisoning the rest of my system. So look at the var in your language and ask if it does the same thing.

# The Complexity Toolkit

00:39:28 The Complexity Toolkit

자, 왜 상황이 복잡한지 살펴봅시다. 이미 이야기한 상태입니다. 상태는 닿는 모든 것을 포괄합니다. 객체는 상태, 신원, 가치를 포함합니다. 객체에는 이 세 가지가 섞여 있어서 부품을 분리할 수 없습니다.

메서드는 보통 기능과 상태를 포함하죠? 또한 일부 언어에서는 네임스페이스를 포함하기도 합니다. Java에서 두 가지에서 파생되고 이름이 같은 메서드와 [폭발과 같은 소리가 나는 손 제스처]가 있습니다. 작동하지 않습니다.

구문은 흥미롭게도 매우 단방향적인 방식으로 의미와 순서를 구성하는 경우가 많습니다. 서스만 교수는 데이터와 구문에 대해 훌륭한 지적을 했고, 이는 매우 사실입니다. 여러분이 좋아하는 언어의 구문을 얼마나 좋아하든 상관없습니다. 모든 면에서 데이터보다 열등합니다.

상속은 유형을 수집합니다. 이 두 가지 유형이 수집됩니다. 이것이 바로 상속, 컴포짓의 의미입니다. 정의적입니다.

스위칭과 매칭은 누가 어떤 일을 하고 어떤 일이 일어날지에 대한 여러 쌍을 수집하며, 이 모든 것을 폐쇄적인 방식으로 한곳에서 수행합니다. 이는 매우 나쁜 방식입니다.

변수와 변수 역시 가치와 시간을 포함하며, 종종 분리할 수 없는 방식으로 결합되기 때문에 값을 얻을 수 없습니다. 어제 기조연설에서 주소를 참조 해제하고 객체를 가져올 수 있는 놀라운 메모리의 그림을 보았습니다. 저런 컴퓨터를 하나 갖고 싶어요. 그런 컴퓨터를 사용해 본 적이 있나요? 구할 수가 없어요. 애플에 전화했더니 안 된다고 하더군요.

메모리 주소에서 얻을 수 있는 건 단어나 스칼라 같은 것뿐이라고 하더군요. 주소에서 복합 객체를 복구하는 것은 컴퓨터가 할 수 있는 일이 아니며, 우리가 가진 컴퓨터도 없습니다. 따라서 변수도 같은 문제가 있습니다. 복합 가변 객체는 한 번의 참조 제거로 복구할 수 없습니다.

루프와 폴드: 루프는 무엇을 어떻게 할 것인가를 명확하게 보여줍니다. 폴드는 다른 사람이 처리하는 것처럼 보이기 때문에 조금 더 미묘합니다. 하지만 왼쪽에서 오른쪽으로 이동하는 순서에 대한 함축적인 의미가 있습니다.

배우들은 무엇을 할 것인지, 누가 할 것인지를 고려합니다.

All right, let's see why things are complex. State, we already talked about. It complects everything it touches. Objects complect state, identity, and value. They mix these three things up in a way that you cannot extricate the parts.

Methods complect function and state, ordinarily, right? In addition, in some languages, they complect namespaces. Derive from two things in Java and have the same name method, and [hand gesture with sounds like explosion]. It doesn't work.

Syntax, interestingly, complects meaning and order often in a very unidirectional way. Professor Sussman made the great point about data versus syntax, and it's super true. I don't care how many you really love the syntax of your favorite language. It's inferior to data in every way.

Inheritance complects types. These two types are complected. That's what it means: inheritance, complecting. It's definitional.

Switching and matching, they complect multiple pairs of who's going to do something and what happens, and they do it all in one place in a closed way. That's very bad.

Vars and variables, again, complect value and time, often in an inextricable way, so you can't obtain a value. We saw a picture during a keynote yesterday of this amazing memory where you could de-reference an address and get an object out. I want to get one of those computers. Have you ever used one of those computers? I can't get one. I called Apple, and they were like, pff, no.

The only thing you can ever get out of a memory address is a word, a scalar, the thing that was all derided. Recovering a composite object from an address is not something computers do, none of the ones that we have. So variables have the same problem. You cannot recover a composite mutable thing with one de-reference.

Loops and fold: loops are pretty obviously complecting what you're doing and how to do it. Fold is a little bit more subtle because it seems like this nice, somebody else is taking care of it. But it does have this implication about the order of things, this left to right bit.

Actors complect what's going to be done and who is going to do it.

[청중 웃음]

서스만 교수는 모든 강연에 두문자어가 있고 제 슬라이드를 제때 수정할 수 없어서 객체 관계형 매핑은 정말 엄청난 양의 컴파일을 해야 한다고 말했습니다. 얼마나 끔찍한지 말로 표현할 수도 없죠? 그리고 이중화를 할 거라면 이중 가치란 무엇일까요? 공동 가치인가요? 공동 가치란 무엇인가요? 일관성이 없는 거죠. 누가 그걸 원하겠어요?

조건부는 흥미롭다고 생각합니다. 이것은 일종의 최첨단 영역입니다. 우리 프로그램에는 프로그램이 해야 할 일에 대한 일종의 규칙이 많이 있습니다. 프로그램 전체에 흩어져 있죠. 프로그램 구조와 프로그램 구성에 반영되어 있기 때문에 이를 수정할 수 있을까요?

[Audience laughter]

Now Professor Sussman said all these talks have acronyms, and I couldn't actually modify my slides in time, so object relational mapping has oh, my God complecting going on. You can't even begin to talk about how bad it is, right? And, you know, if you're going to do, like, duals, what's the dual of value? Is it co-value? What's a co-value? It's an inconsistent thing. Who wants that?

Conditionals, I think, are interesting. This is sort of more cutting edge area. We have a bunch of sort of rules about what our programs are supposed to do. It's strewn all throughout the program. Can we fix that, because that's complected with the structure of the program and the organization of the program?

# The Simplicity Toolkit

00:42:55 The Simplicity Toolkit

이 강연에서 두 가지를 제외한다면 하나는 단순함과 쉬움이라는 단어의 차이일 것입니다. 다른 하나는 복잡한 도구로 지금 만들고 있는 것과 똑같은 프로그램을 훨씬 더 간단한 도구로 만들 수 있다는 사실입니다. 저는 C++를 오랫동안 사용했습니다. Java도 해봤고요. C#도 해봤죠. 저는 이러한 언어로 대규모 시스템을 만드는 방법을 알고 있으며, 여러분에게 그러한 복잡성이 필요하지 않다고 전적으로 믿습니다. 훨씬 더 간단한 도구로도 정교한 시스템을 작성할 수 있으며, 이는 사용 중인 구조에서 떨어지는 모든 잡동사니 대신 시스템과 시스템이 수행해야 하는 작업에 집중할 수 있다는 것을 의미합니다.

그래서 저는 더 단순한 삶을 위한 첫 번째 단계는 더 단순한 것을 선택하는 것이라고 말하고 싶습니다. 그렇죠? 값을 원한다면 보통은 값을 얻을 수 있습니다. 대부분의 언어에는 값과 같은 것이 있습니다. 파이널이나 밸은 어떤 것을 불변하는 것으로 선언하는 것입니다. 많은 언어에서 값인 집합을 얻는 것이 가장 어렵기 때문에 영구 컬렉션을 찾아야 합니다. 이를 위해 좋은 라이브러리를 찾거나 기본값이 있는 언어를 사용해야 합니다.

[청중 웃음]

함수는 대부분의 언어에 있습니다. 다행이네요. 함수가 무엇인지 모른다면 상태 없는 메서드와 비슷합니다.

[청중 웃음]

네임스페이스는 언어가 여러분을 위해 정말 필요로 하는 기능이지만, 안타깝게도 많은 곳에서 잘 활용되지 않고 있습니다. 데이터입니다: 제발요! 저희는 프로그래머입니다. 데이터 처리 프로그램을 작성해야 하잖아요. 데이터가 없는 프로그램은 항상 존재합니다. 그 프로그램에는 우리가 데이터 위에 얹어놓은 모든 구조가 있습니다.

데이터는 사실 정말 간단합니다. 데이터의 본질적인 특성에는 엄청난 수의 변형이 존재하지 않습니다. 지도가 있습니다. 집합이 있습니다. 선형적이고 순차적인 것들이 있습니다. 데이터의 다른 개념적 범주는 그리 많지 않습니다. 우리는 데이터의 본질과 상관없는 수십만 가지의 변형을 만들어내고, 데이터의 본질을 조작하는 프로그램을 작성하기 어렵게 만듭니다. 데이터의 본질만 조작하면 됩니다. 어렵지 않습니다. 더 간단합니다.

커뮤니케이션도 마찬가지입니다. 우리 모두 웹에서 유닉스 통신 방식을 사용하지 않아서 다행이라고 생각하지 않나요? 그렇지 않나요? 임의의 명령 문자열이 프로그램의 인수 목록이 될 수 있고, 임의의 문자 집합이 다른 쪽 끝에서 나올 수 있습니다. 우리 모두 파서를 작성해 봅시다.

All right, so if you take away two things from this talk, one would be the difference between the words simple and easy. The other, I would hope, would be the fact that we can create precisely the same programs we're creating right now with these tools of complexity with dramatically drastically simpler tools. I did C++ for a long time. I did Java. I did C#. I know how to make big systems in those languages, and I completely believe you do not need all that complexity. You can write as sophisticated a system with dramatically simpler tools, which means you're going to be focusing on the system, what it's supposed to do, instead of all the gook that falls out of the constructs you're using.

So I'd love to say the first step in getting a simpler life is to just choose simpler stuff. Right? So if you want values, usually you can get it. Most languages have something like values. Final or val, you know, let's you, like, declare something as being immutable. You do want to find some persistent collections because the harder thing in a lot of languages is getting aggregates that are values. You've got to find a good library for that or use a language where there's the default.

[Audience laughter]

Functions, most languages have them. Thank goodness. If you don't know what they are, they're like stateless methods.

[Audience laughter]

Namespaces is something you really need the language to do for you and, unfortunately, it's not done very well in a lot of places. Data: Please! We're programmers. We're supposedly write data processing programs. There are always programs that don't have any data in them. They have all these constructs we put around it and globbed on top of data.

Data is actually really simple. There are not a tremendous number of variations in the essential nature of data. There are maps. There are sets. There are linear, sequential things. There are not a lot of other conceptual categories of data. We create hundreds of thousands of variations that have nothing to do with the essence of this stuff and make it hard to write programs that manipulate the essence of the stuff. We should just manipulate the essence of the stuff. It's not hard. It's simpler.

Also, the same thing for communications. Are we all not glad we don't use the Unix method of communicating on the Web? Right? Any arbitrary command string can be the argument list for your program, and any arbitrary set of characters can come out the other end. Let's all write parsers.

[Audience laughter]

아니요, 문제가 있다는 뜻입니다. 복잡성의 원인이죠. 그래서 우리는 그것을 제거할 수 있습니다. 데이터를 활용하면 됩니다.

가장 바람직한 것, 가장 난해한 것, 가장 얻기 힘든 것, 하지만 이걸 얻으면 삶이 완전히, 완전히 달라지는 것은 단품 다형성입니다. 클로저 프로토콜과 하스켈 타입 클래스 및 구조체 같은 것들 말이죠. 데이터 구조가 있고, 함수 집합의 정의가 있고, 그것들을 서로 연결할 수 있다고 독립적으로 말할 수 있는 기능을 제공하면 세 가지 독립적인 작업이 가능합니다. 다시 말해, 일반성은 특별히 어떤 것에 묶여 있지 않습니다. 단품으로 사용할 수 있습니다. 이 기능이 없는 언어용 라이브러리 솔루션은 많지 않은 것으로 알고 있습니다.

참조 관리와 참조를 얻는 방법에 대해 이미 이야기했습니다. 다른 Java 언어의 클로저를 사용할 수도 있습니다.

집합 함수는 라이브러리에서 얻을 수 있습니다. 큐는 라이브러리에서 얻을 수 있습니다. 특별한 통신 언어가 필요하지 않습니다.

마지막으로 SQL을 사용하거나 SQL을 배우면 선언적 데이터 조작을 할 수 있습니다. 아니면 LINQ나 Datalog 같은 것을 사용할 수도 있습니다.

저는 이 마지막 두 가지가 더 어렵다고 생각합니다. 현재로서는 우리 언어와 잘 통합되어 이 작업을 수행할 수 있는 방법이 많지 않다고 생각합니다. LINQ는 이를 위한 노력입니다.

규칙, 선언적 규칙 시스템은 모든 의사 결정 시점에 원시 언어에 수많은 조건문을 삽입하는 대신, 그런 것들을 모아서 다른 곳에 배치하는 것이 좋습니다. 라이브러리에서 규칙 시스템을 구할 수도 있고, 프롤로그와 같은 언어를 사용할 수도 있습니다. 일관성을 원한다면 트랜잭션을 사용해야 하고 값을 사용해야 합니다. 이 목록에서 벗어나야 하는 이유가 있을 수 있지만, 이 목록에서 시작하지 못할 이유는 없습니다.

No, I mean it's a problem. It's a source of complexity. So we can get rid of that. Just use data.

The biggest thing, I think, the most desirable thing, the most esoteric, this is tough to get, but boy when you have it your life is completely, totally different thing is polymorphism a la carte. Clojure protocols and Haskell-type classes and constructs like that. Give you the ability to independently say I have data structures, I have definitions of sets of functions, and I can connect them together, and those are three independent operations. In other words, the genericity is not tied to anything in particular. It's available a la carte. I don't know of a lot of library solutions for languages that don't have it.

I already talked about manage references and how to get them. Maybe you can use closures from different Java languages.

Set functions, you can get from libraries. Queues, you can get from libraries. You don't need special communication language.

You can get declarative data manipulation by using SQL or learning SQL, finally. Or something like LINQ or something like Datalog.

I think these last couple of things are harder. We don't have a lot of ways to do this well integrated with our languages, I think, currently. LINQ is an effort to do that.

Rules, declarative rule systems, instead of embedding a bunch of conditionals in our raw language at every point of decision, it's nice to sort of gather that stuff and put it over someplace else. You can get rule systems in libraries, or you can use languages like Prolog. If you want consistency, you need to use transactions, and you need to use values. There are reasons why you might have to get off of this list, but, boy, there's no reason why you shouldn't start with it.

# Environmental Complexity

00:47:21 Environmental Complexity

알겠어요. 여러분의 잘못이 아니라 정말 다루기 어려운 복잡성의 원인이 있습니다. 저는 이를 환경적 복잡성이라고 부릅니다. 우리 프로그램은 컴퓨터에서 다른 프로그램 옆에서, 다른 부분 옆에서 실행되며 메모리, CPU 주기 등 여러 가지를 놓고 경쟁합니다.

모두가 경쟁하고 있는 것이죠. 이것이 바로 내재적 복잡성입니다. 내재적이란 라틴어로 당신의 잘못이 아니라는 뜻입니다. 구현 공간에서, 아니, 이것은 문제의 일부가 아니라 구현의 일부입니다. 고객에게 돌아가서 GC 문제가 있어서 원하는 것이 좋지 않다고 말할 수는 없습니다. 하지만 GC 문제와 그런 것들이 작용합니다.

훌륭한 솔루션은 많지 않습니다. 세분화를 할 수 있습니다. 이쪽은 메모리, 이쪽은 메모리, 이쪽은 메모리, 이쪽은 CPU, CPU라고 말할 수 있습니다. 하지만 미리 할당하기 때문에 엄청난 낭비가 발생합니다. 모든 것을 사용하지 않죠. 일종의 동적 특성이 없죠.

하지만 현재 우리가 직면하고 있다고 생각하지만 현재로서는 해결책이 없는 문제는 이러한 문제에 대한 정책이 일관성이 없다는 것입니다. 모든 사람이 "내 스레드 풀의 크기를 그 수만큼만 늘리겠습니다."라고 말한다면, 물론 그렇겠죠. 한 프로그램에서 몇 번이나 그렇게 할 수 있을까요? 많지 않은데도 여전히 잘 작동합니다.

안타깝게도 이러한 작업을 분할하여 개별적으로 결정하는 것은 실제로 일을 더 단순하게 만드는 것이 아닙니다. 더 나은 정보를 가진 사람이 결정해야 하기 때문에 일을 복잡하게 만들고 있습니다. 그리고 이러한 결정을 시스템의 한 곳에 정리할 수 있는 좋은 자료가 많지 않다고 생각합니다.

Okay. There's a source of complexity that's really difficult to deal with, and not your fault. I call it environmental complexity. Our programs end up running on machines next to other programs, next to other parts of themselves, and they contend; they contend for stuff: memory, CPU cycles, and things like that.

Everybody is contending for it. This is an inherent complexity. Inherent is Latin for not your fault. In the implementation space and, no, this is not part of the problem, but it is part of implementation. You can't go back to the customer and say the thing you wanted is not good because I have GC problems. But the GC problems and stuff like that, they come into play.

There are not a lot of great solutions. You can do segmentation. You can say this is your memory, this is your memory, this is your memory, this is your CPU and your CPU. But there's tremendous waste in that, right, because you pre-allocate. You don't use everything. You don't have sort of dynamic nature.

But the problem I think we're facing, and it's not one for which I have a solution at the moment, is that the policies around this stuff don't compose. If everybody says, "I'll just size my thread pool to be the number of," you know, of course. How many times can you do that in one program? Not a lot and have it still work out.

So, unfortunately, a lot of things like that, splitting that stuff up and making it an individual decision, is not actually making things simpler. It's making things complex because that's a decision that needs to be made by someone who has better information. And I don't think we have a lot of good sources for organizing those decisions in single places in our systems.

# Edsger W. Dijkstra quote

00:49:03 Edsger W. Dijkstra quote

굉장히 긴 인용문입니다. 기본적으로 프로그래밍은 키보드로 타이핑하는 제스처와 같은 타이핑이 아니라고 말합니다. 프로그래밍은 사고에 관한 것입니다.

This is a hugely long quote. Basically, it says programming is not about typing, like this [gestures of typing on a keyboard]. It's about thinking.

# Abstraction for Simplicity

00:49:20 Abstraction for Simplicity

그렇다면 다음 단계로 넘어가서 조금 더 빠르게 진행해야 하는데요, 어떻게 우리만의 단순한 것을 디자인할 수 있을까요? 단순하게 만드는 첫 번째 단계는 단순한 아티팩트가 있는 구성을 선택하는 것입니다. 하지만 때로는 직접 구조를 작성해야 할 때도 있는데, 단순화를 위해 어떻게 추상화할 수 있을까요? 추상화는 지어낸 것이 아니라 실제 정의가 있습니다. 추상화란 무언가를 그려낸다는 뜻입니다. 특히 어떤 것의 물리적 본질에서 멀어지는 것을 의미합니다.

가끔 사람들이 이 용어를 단순히 무언가를 숨긴다는 의미로 심하게 사용하는 것과는 구별하고 싶습니다. 추상화란 그런 것이 아니며 이 공간에서는 도움이 되지 않습니다.

두 가지가 있습니다... 이 작업이 어떻게 이루어지는지 완전히 설명할 수는 없습니다. 하지만 한 가지 접근 방식은 누가, 무엇을, 언제, 어디서, 왜, 어떻게 할 것인가를 결정하는 것입니다. 이러한 것들을 살펴보고 결정한 모든 것을 살펴보고 "이 작업의 누가 측면은 무엇입니까? 무엇의 측면은 무엇일까?"라고 생각해보세요. 이렇게 하면 물건을 분해하는 데 도움이 될 수 있습니다.

또 다른 한 가지는 "모르겠어, 알고 싶지 않아"라는 접근 방식을 유지하는 것입니다. 제가 가르치던 C++ 강좌에서 학생 중 한 명이 제게 셔츠를 만들어 주면서 자주 했던 말입니다. 부크 다이어그램이었는데, 당시에는 지금처럼 통합된 다이어그램이 없었기 때문입니다. 모든 줄에 그렇게 적혀 있었죠. 그게 바로 당신이 하고 싶은 일이죠. 정말 알고 싶지 않은 거죠.

So the next phase here--I've got to move a little bit quicker--is how do we design simple things of our own? So the first part of making things simple is just to choose constructs that have simple artifacts. But we have to write our own constructs sometimes, so how do we abstract for simplicity? An abstract, again, here's an actual definition, not made up one. It means to draw something away. And, in particular, it means to draw away from the physical nature of something.

I do want to distinguish this from, that sometimes people use this term really grossly to just mean hiding stuff. That is not what abstraction is, and that's not going to help you in this space.

There are two -- you know, I can't totally explain how this is done. It's really the job of designing, but one approach you can take is just to do who, what, when, where, why, and how. If you just go through those things and sort of look at everything you're deciding to do and say, "What is the who aspect of this? What is the what aspect of it?" This can help you take stuff apart.

The other thing is to maintain this approach that says, "I don't know; I don't want to know." I once said that so often during a C++ course I was teaching that one of the students made me a shirt. It was a Booch diagram because we didn't have whatever it is now, the unified one. And every line just said that. That's what you want to do. You really just don't want to know.

# What

00:50:39 What

좋아요, 그럼 뭐가 뭔가요? 작전이란 무엇인가요. 우리가 달성하고자 하는 것은 무엇인가요. 함수, 특히 함수 집합을 취해 이름을 붙임으로써 추상화를 형성할 것입니다. 특히 언어가 허용하는 모든 것을 사용할 것입니다. 인터페이스만 있다면 인터페이스를 사용하면 됩니다. 프로토콜이나 타입 클래스가 있다면 그것들을 사용할 것입니다. 이러한 모든 것은 추상화가 될 함수 집합을 만드는 데 사용하는 것들의 범주에 속합니다. 그리고 그것들은 실제로 함수의 사양 집합입니다.

제가 오늘 말씀드리고 싶은 요점은 이러한 것들이 우리가 일반적으로 보는 것보다 훨씬 작아야 한다는 것입니다. 자바 인터페이스가 거대한 이유는 자바에는 유니온 타입이 없기 때문에 이 함수가 이것도 하고 저것도 하고 저것도 하는 함수를 취한다고 말하는 것이 불편하기 때문입니다. 이것도 하고 저것도 하고 저것도 하는 인터페이스를 만들어야 하므로 거대한 인터페이스를 보게 됩니다. 그리고 이러한 거대한 인터페이스는 프로그램을 분해하기가 훨씬 더 어렵기 때문에 다형성 구조로 표현하게 됩니다.

이것들은 사양이죠? 실제로는 구현이 아닙니다. 정의에는 값과 기타 추상화만 사용해야 합니다. 따라서 인터페이스나 타입 클래스를 정의하고, 인터페이스와 타입 클래스 또는 값만 받아서 반환하는 인터페이스를 정의할 것입니다.

이 부분을 디자인할 때 가장 큰 문제는 이것을 어떻게 컴포짓(조합)하는가 하는 것입니다. 여기에는 인터페이스 대신 구체적인 함수가 있다거나 여기에는 인터페이스 대신 구체적인 클래스가 있다거나 하는 식으로 어떻게와 함께 컴포짓할 수 있습니다. 함수의 의미론이 어떻게 수행되는지에 대한 함축적인 의미를 부여함으로써 어떻게를 더 미묘하게 포함시킬 수도 있습니다. Fold가 그 예입니다.

'무엇'과 '어떻게'를 엄격하게 분리하는 것이 다른 사람의 문제를 만드는 열쇠입니다. 이 작업을 정말 잘 수행했다면 어떻게 작업을 다른 사람에게 넘겨버릴 수(pawn off) 있습니다. 에를 들어, 데이터베이스 엔진이 이 작업을 수행하는 방법을 알아내거나, 로직 엔진은 이 검색 방법을 알아낼 수 있습니다. 내 자신은 알 필요가 없습니다.

All right, so what is what? What is the operations. What is what we want to accomplish. We're going to form abstractions by taking functions and, more particularly, sets of functions and giving them names. In particular -- and you're going to use whatever your language lets you use. If you only have interfaces, you'll use that. If you have protocols or type classes, you'll use those. All those things are in the category of the things you use to make sets of functions that are going to be abstractions. And they're really sets of specifications of functions.

The point I'd like to get across today is just that they should be really small, much smaller than what we typically see. Java interfaces are huge, and the reason why they are huge is because Java doesn't have union types, so it's inconvenient to say this function takes, you know, something that does this and that and that. You have to make a this and that and that interface, so we see these giant interfaces. And the thing with those giant interfaces is that it's a lot harder to break up those programs, so you're going to represent them with your polymorphism constructs.

They are specifications, right? They're not actually the implementations. They should only use values and other abstractions in their definitions. So you're going to define interfaces or whatever, type classes, that only take interfaces and type classes or values and return them.

And the biggest problem you have when you're doing this part of design is if you complect this with how. You can complect it with how by jamming them together and saying here is just a concrete function instead of having an interface, or here's a concrete class instead of having an interface. You can also complect it with how more subtly by having some implication of the semantics of the function dictate how it is done. Fold is an example of that.

Strictly separating what from how is the key to making how somebody else's problem. If you've done this really well, you can pawn off the work of how on somebody else. You can say database engine, you figure out how to do this thing or, logic engine, you figure out how to search for this. I don't need to know.

# Who

00:52:41 Who

데이터 또는 엔티티에 관한 것입니다. 이러한 것들은 기술 작동 방식에 따라 추상화가 결국 연결될 것입니다. 일종의 직접 주입 방식으로 하위 컴포넌트에서 컴포넌트를 구축하려고 할 수 있습니다. 하위 컴포넌트가 무엇인지 하드 와이어링하고 싶지 않을 것입니다. 가능한 한 인자로 사용하는 것이 좋으며, 그래야 빌드 방식에서 프로그래밍 유연성을 높일 수 있기 때문입니다.

하위 컴포넌트가 현재보다 훨씬 더 많아야 하므로 현재보다 훨씬 작은 인터페이스를 원하고, 일반적으로는 하위 컴포넌트가 없는 경우가 많으므로 일반적으로 사용하는 것보다 더 많은 하위 컴포넌트를 원할 것입니다. 그런 다음 정책을 팜아웃해야 한다고 결정할 때 하나가 있을 수도 있습니다. 누가, 무엇을, 언제, 어디서, 왜 했는지, 그리고 5가지 구성 요소를 찾았다고 말하면서 들어가면 나쁘게 생각하지 마세요. 대단한 일이죠. 그렇게 하면 큰 성공을 거두는 것이니까요. 정책을 세분화하고 그런 식으로요. 하위 구성 요소에서 사물을 정의할 때 주의해야 할 점은 노란색이 파란색에 대해 생각하고 파란색이 노란색에 대해 생각하는 것과 같은 숨겨진 세부 종속성이 있으므로 이를 피해야 한다는 것입니다.

Who is about, like, data or entities. These are the things that our abstractions are going to be connected to eventually depending on how your technology works. You want to build components up from subcomponents in a sort of direct injection style. You don't want to, like, hardwire what the subcomponents are. You want to, as much as possible, take them as arguments because that's going to give you more programmatic flexibility in how you build things.

You should have probably many more subcomponents than you have, so you want really much smaller interfaces than you have, and you want to have more subcomponents than you probably are typically having because usually you have none. And then maybe you have one when you decide, oh, I need to farm out policy. If you go in saying this is a job, and I've done who, what, when, where, why, and I found five components, don't feel bad. That's great. You're winning massively by doing that. You know, split out policy and stuff like that. And the thing that you have to be aware of when you're building, you know, the definition of a thing from subcomponents is any of those kind of, you know, yellow thinking about blue, blue thinking about yellow kind of hidden detail dependencies, so you want to avoid that.

# How

00:53:45 How

일이 어떻게 일어나는지, 이것이 실제 구현 코드이며 작업을 수행하는 작업입니다. 이러한 다형성 구조를 사용하여 이러한 것들을 엄격하게 연결하고 싶을 것입니다. 이것이 가장 강력한 기능입니다. 네, 스위치 문을 사용할 수 있습니다. 패턴 매칭을 사용할 수도 있습니다. 하지만 이 모든 것을 하나로 묶어버립니다.

이러한 시스템 중 하나를 사용하면 개방형 다형성 정책을 사용할 수 있으며, 특히 런타임 개방형인 경우 매우 강력합니다. 하지만 그렇지 않더라도 없는 것보다는 낫습니다. 그리고 다시 한 번 말하지만, 미묘한 방식으로 방법을 지시하는 추상화에 주의하세요. 그렇게 하면 실제로 구현을 수행해야 하는 사람의 손발을 묶는 것이기 때문입니다. 그들의 손을 묶는 것이죠. 따라서 선언적일수록 더 잘 작동하고 더 잘 작동합니다. 그리고 제 말은... 일종의 바닥이 어떻게 되는 거죠? 이걸 다른 것과 혼동하지 마세요. 이러한 모든 구현은 가능한 한 섬이어야 합니다.

How things happen, this is the actual implementation code, the work of doing the job. You strictly want to connect these things together using those polymorphism constructs. That's the most powerful thing. Yeah, you can use a switch statement. You could use pattern matching. But it's glomming all this stuff together.

If you use one of these systems, you have an open polymorphism policy, and that is really powerful, especially if it's runtime open. But even if it's not, it's better than nothing. And again, beware of abstractions that dictate how in some subtle way because, when you do that, you're really, you're nailing the person down the line who has to do the implementation. You're tying their hands. So the more declarative things are, the better, the better things work. And the thing that -- I mean, how is sort of the bottom, right? Don't mix this up with anything else. All these implementations should be islands as much as possible.

# When, Where

00:54:40 When, Where

언제, 어디서, 이것은 매우 간단합니다. 다른 어떤 것과도 섞이지 않도록 철저하게 피해야 합니다. 저는 주로 사람들이 직접 연결된 객체가 있는 시스템을 설계할 때 실수로 이 문제가 발생하는 것을 봅니다. 즉, 이 객체가 입력을 처리한 다음 이 객체가 다음 작업을 수행하도록 프로그램이 설계되어 있다는 것을 알고 있다면요. A라는 객체가 B라는 객체를 호출하면 방금 컴파일한 것이죠. 그렇죠? 이제 언제, 어디서 호출할지 결정해야 하는데, A가 B를 호출하려면 B가 어디에 있는지 알아야 하고, 그 시기는 A가 호출할 때마다 결정됩니다.

거기에 대기열을 넣으세요. 큐는 이 문제를 해결할 수 있는 방법입니다. 큐를 광범위하게 사용하지 않는다면 큐를 사용해야 합니다. 이 강연이 끝난 직후부터 바로 시작해야 합니다.

[청중 웃음]

When and where, this is pretty simple. I think you just have to strenuously avoid complecting this with anything. I see it accidentally coming in, mostly when people design systems with directly connected objects. So if you know your program is architected such that this thing deals with the input and then this thing has to do the next part of the job. Well, if thing A calls thing B, you just complected it. Right? And now you have a when and where thing because now A has to know where B is in order to call B, and when that happens is whenever A does it.

Stick a queue in there. Queues are the way to just get rid of this problem. If you're not using queues extensively, you should be. You should start right away, like right after this talk.

[Audience laughter]

# Why

00:55:34 Why

그리고 '왜'라는 부분이 있습니다. 이것은 일종의 정책과 규칙입니다. 이것은... 저희에게는 어려운 부분이라고 생각합니다. 우리는 일반적으로 애플리케이션 전체에 이러한 내용을 넣습니다. 이제 애플리케이션의 기능에 대해 고객과 이야기해야 하는 경우, 고객과 함께 소스 코드를 보면서 설명하기가 정말 어렵습니다.

고객이 볼 수 있도록 영어 문자열을 작성할 수 있는 테스트 시스템 중 하나가 있다면 이는 어리석은 일입니다. 누군가가 볼 수 있는 작업을 수행하는 코드가 있어야 합니다. 즉, 이 코드를 외부 어딘가에 넣어야 한다는 뜻입니다. 이 작업을 수행할 수 있는 선언적 시스템이나 규칙 시스템을 찾아보세요.

And then there's the why part. This is sort of the policy and rules. This is -- I think this is hard for us. We typically put this stuff all over our application. Now if you ever have to talk to a customer about what the application does, it's really difficult to sit with them in source code and look at it.

Now, if you have one of these pretend testing systems that lets you write English strings so the customer can look at that, that's just silly. You should have code that does the work that somebody can look at, which means to try to, you know, put this stuff someplace outside. Try to find a declarative system or a rule system that lets you do this work.

# Information is Simple

00:56:10 Information is Simple

마지막으로, 이 영역에서는 정보는, 그것이 간단하다는 것입니다. 정보로 할 수 있는 유일한 일은 정보를 망치는 것뿐입니다.

[청중 웃음]

하지 마세요! 그렇죠? 이런 건 하지 마세요. 객체가 있잖아요. 오브젝트는 IO 장치를 캡슐화하기 위해 만들어졌기 때문에 화면이 있지만 화면을 만질 수 없으므로 오브젝트가 있습니다. 그렇죠? 마우스가 있죠. 마우스를 만질 수 없으니 객체가 있죠. 그렇죠? 그게 전부예요. 정보에 적용하면 안 되는 거였어요. 그리고 우리는 잘못된 정보에 적용합니다.

잘못된 거죠. 하지만 이제 저는 그것이 잘못된 이유가 있다고 말할 수 있습니다. 복잡하기 때문에 잘못된 것입니다. 특히 일반적인 데이터 조작을 구축하는 능력을 망칩니다. 데이터를 그대로 두면 데이터를 조작하는 무언가를 한 번 만들면 모든 곳에서 재사용할 수 있고, 한 번만 맞으면 끝이라는 것을 알 수 있습니다.

ORM에도 적용되는 또 다른 장점은 로직을 표현하는 것에 연결하여 다시 연결하고, 종합하고, 서로 얽히게 한다는 것입니다. 따라서 데이터를 표현하는 것이 곧 데이터입니다. 맵과 집합을 직접 사용해 보세요. 새로운 정보가 생겼기 때문에 지금 당장 클래스를 작성해야 한다고 생각하지 마세요. 그건 어리석은 생각입니다.

Finally, in this area, information: it is simple. The only thing you can possibly do with information is ruin it.

[Audience laughter]

Don't do it! Right? Don't do this stuff. I mean, we've got objects. Objects were made to, like, encapsulate IO devices, so there's a screen, but I can't, like, touch the screen, so I have the object. Right? There's a mouse. I can't touch the mouse, so there's an object. Right? That's all they're good for. They were never supposed to be applied to information. And we apply them to information that's just wrong.

It's wrong. But I can now say it's wrong for a reason. It's wrong because it's complex. In particular, it ruins your ability to build generic data manipulation things. If you leave data alone, you can build things once that manipulate data, and you can reuse them all over the place, and you know they're right once and you're done.

The other thing about it, which also applies to ORM is that it will tie your logic to representational things, which again tying, complecting, intertwining. So represent data is data. Please start using maps and sets directly. Don't feel like I have to write a class now because I have a new piece of information. That's just silly.

00:57:20 Constantin Brancusi quote

# Simplifying

00:57:24 Simplifying

마지막 측면은 바로 간단한 도구를 선택하는 것입니다. 우리는 간단한 것을 작성합니다. 그리고 때로는 다른 사람의 것을 단순화해야 할 때도 있습니다. 특히 다른 사람이 작성한 문제 공간이나 코드를 단순화해야 할 수도 있습니다. 이 이야기는 지금 여기서 다루지 않겠습니다. 하지만 이 작업은 본질적으로 얽힌 것을 풀어내는 작업 중 하나죠? 우리는 무엇이 복잡한지 알고 있습니다. 얽혀 있죠. 그럼 어떻게 해야 할까요? 어떻게든 풀어야 합니다.

당신은 이것을 얻을 것입니다. 먼저 어디로 가는지 파악해야 합니다. 물건을 따라다니면서 결국에는 모든 것에 라벨을 붙여야 합니다. 이것이 시작입니다. 이것이 대략적인 과정입니다. 하지만 단순화에 대해 이야기하는 것은 완전히 별개의 이야기입니다.

So the final aspect, right, so we choose simple tools. We write simple stuff. And then sometimes we have to simplify other people's stuff. In particular, we may have to simplify the problem space or some code that somebody else wrote. This is a whole separate talk I'm not going to get into right now. But the job is essentially one of disentangling, right? We know what's complex. It's entangled. So what do we need to do? We need to somehow disentangle it.

You're going to get this. You're going to need to first sort of figure out where it's going. You're going to have to follow stuff around and eventually label everything. This is the start. This is roughly what the process is like. But again, it's a whole separate talk to try to talk about simplification.

# Simplicity is a Choice

00:58:14 Simplicity is a Choice

자, 이제 몇 개의 슬라이드를 마무리하겠습니다. 결론은 단순성은 선택입니다. 단순한 시스템을 갖추지 않은 것은 여러분의 잘못입니다. 그리고 우리에게는 복잡한 문화가 있다고 생각합니다. 우리 모두가 복잡한 결과물이 나오는 도구를 계속 사용하는 한, 우리는 매너리즘에 빠져 있습니다. 우리는 자기 강화만 하고 있습니다. 그리고 우리는 그 틀에서 벗어나야 합니다. 하지만 다시 한 번 말씀드리지만, 여러분이 이미 "나는 이것을 알고 있습니다. 난 당신을 믿어요. 나는 이미 더 나은 것을 사용하고 있어요. 나는 이미 오른쪽 열을 모두 사용했습니다."라고 말하고 있다면, 이 강연이 여러분을 믿지 않는 다른 사람과 대화할 수 있는 기초가 되기를 바랍니다.

단순성과 복잡성에 대해 이야기합니다. 그러나 그것은 선택입니다. 끊임없는 경계가 필요합니다. 우리는 이미 가드레일이 단순함을 가져다주지 않는다는 것을 보았습니다. 가드레일은 우리에게 도움이 되지 않습니다.

감성과 주의가 필요합니다. 단순함이 사용 편의성과 같다는 생각은 잘못된 것입니다. 그냥 잘못된 생각입니다. 그렇죠? 단순함과 용이함의 정의를 살펴봤습니다. 완전히 다른 개념입니다. 쉬운 것은 단순하지 않습니다.

얽힘에 대한 감성을 개발하기 시작해야 합니다. 즉, 얽힘에 대한 레이더가 있어야 합니다. 어떤 소프트웨어를 보고 '어! 사용한 이름이나 코드의 모양이 마음에 들지 않거나 세미콜론이 있는 것은 아닙니다. 그것도 중요합니다. 하지만 여러분은 수집을 보기 시작하고 싶을 겁니다. 독립적일 수 있는 것들 사이의 상호 연결을 보기 시작하고 싶을 것입니다. 여기서 가장 큰 힘을 얻을 수 있습니다.

여러분이 가지고 있는 모든 신뢰성 도구는 단순성에 관한 것이 아니기 때문에 모두 부차적인 것입니다. 이 문제의 핵심을 건드리지 못합니다. 안전망은 있지만 그 이상은 아닙니다.

All right, I'm going to wrap up a couple of slides. The bottom line is simplicity is a choice. It's your fault if you don't have a simple system. And I think we have a culture of complexity. To the extent we all continue to use these tools that have complex outputs, we're just in a rut. We're just self-reinforcing. And we have to get out of that rut. But again, like I said, if you're already saying, "I know this. I believe you. I already use something better. I've already used that whole right column," then hopefully this talk will give you the basis for talking with somebody else who doesn't believe you.

Talk about simplicity versus complexity. But it is a choice. It requires constant vigilance. We already saw that guardrails don't yield simplicity. They don't really help us here.

It requires sensibilities and care. Your sensibilities about simplicity being equal to ease of use are wrong. They're just simply wrong. Right? We saw the definitions of simple and easy. They're completely different things. Easy is not simple.

You have to start developing sensibilities around entanglement. That's what you have to -- you have to have entanglement radar. You want to look at some software and say, uh! You know, not that I don't like the names you used or the shape of the code or there was a semicolon. That's also important too. But you want to start seeing complecting. You want to start seeing interconnections between things that could be independent. That's where you're going to get the most power.

All the reliability tools you have, right, since they're not about simplicity, they're all secondary. They just do not touch the core of this problem. They're safety nets, but they're nothing more than that.

# Simplicity Made Easy

00:59:53 Simplicity Made Easy

그렇다면 어떻게 하면 단순함을 쉽게 만들 수 있을까요? 그렇죠? 더 단순한 아티팩트(결과물)를 가진 구조를 선택하고 복잡한 아티팩트를 가진 구조는 피해야 합니다. 아티팩트입니다. 저작이 아니라 아티팩트입니다. 누군가와 논쟁을 벌이다가 '우리는 이걸 사용해야 한다'고 말한다면, 그들이 입력하는 코드의 모양에 대해 어떻게 생각하든 이것과는 별개의 문제이므로 그 문제를 해결해야 합니다.

우리는 단순성을 기본으로 하는 추상화를 만들려고 노력할 것입니다. 시작하기 전에 먼저 약간의 시간을 할애하여 단순화하는 데 시간을 할애하겠습니다. 그리고 일을 단순화하면 더 많은 일을 하게 되는 경우가 많다는 것을 인식하세요. 단순함은 숫자를 세는 것이 아닙니다. 저는 몇 가지 물건이 매듭으로 묶여 있는 것보다 더 많은 물건이 꼬이지 않고 똑바로 늘어져 있는 것이 더 좋습니다. 그리고 그것들을 분리하는 것의 아름다운 점은 그것을 바꿀 수 있는 능력이 훨씬 더 많아진다는 것입니다. 그래서 저는 이것이 큰 문제라고 생각하며, 모든 사람들이 이를 실천에 옮기거나 다른 사람을 설득하는 도구로 사용할 수 있기를 바랍니다.

So, how do we make simplicity easy? Right? We're going to choose constructs with simpler artifacts and avoid constructs that have complex artifacts. It's the artifacts. It's not the authoring. As soon as you get in an argument with somebody about, oh, we should be using whatever, get that sorted out because, however they feel about the shape of the code they type in is independent from this and this is the thing you have to live with.

We're going to try to create abstractions that have simplicity as a basis. We're going to spend a little time upfront simplifying things before we get started. And recognize that when you simplify things, you often end up with more things. Simplicity is not about counting. I'd rather have more things hanging nice, straight down, not twisted together, than just a couple of things tied in a knot. And the beautiful thing about making them separate is you'll have a lot more ability to change it, which is where I think the benefits lie. So I think this is a big deal, and I hope everybody is able to bring it into practice or use this as a tool for convincing somebody else to do that.

01:01:13 Leonardo da Vinci quote

(화면) 단순함은 궁극의 정교함입니다. Simplicity is the ultimate sophistication.

그래서 저는 이 말만 남기겠습니다. 누군가 정교한 타이핑 시스템을 팔려고 할 때 이렇게 말하세요.

[청중 웃음]

감사합니다.

[청중 박수]

So I'll leave you with this. This is what you say when somebody tries to sell you a sophisticated type system.

[Audience laughter]

Thank you.

[Audience applause]