Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save coleea/9dde4715c22ed10c1807c8a8aa4159c2 to your computer and use it in GitHub Desktop.
Save coleea/9dde4715c22ed10c1807c8a8aa4159c2 to your computer and use it in GitHub Desktop.
진행자 - 브루스 에클 (00:00)
Happy Path Programming에 오신 것을 환영합니다. 저는 브루스 에클이고, 저는 제임스 워드입니다. 자, 여러분 모두 환영합니다. 잠시 휴식기를 가진 후 다시 돌아왔습니다. 여러모로 좀 정신없었죠.
진행자 - 제임스 워드 (00:18)
맞아요. 그리고 저희 규칙은...
진행자 - 브루스 에클 (00:22)
규칙은 없어요. 그냥 즐기세요.
진행자 - 제임스 워드 (00:24)
팟캐스트를 제대로 하려면 매주 해야 하고, 그렇지 않으면 청취자들이 실망한다고 하죠. 하지만...
진행자 - 브루스 에클 (00:31)
인생이라는 게 있잖아요.
진행자 - 제임스 워드 (00:33)
인생이라는 게 있죠.
진행자 - 브루스 에클 (00:34)
브루스와 제가 살고 있는 콜로라도, 크레스티드 뷰트에서 곧 있을 흥미로운 소식을 발표하려고 합니다. 브루스는 이런 개발자 리트릿을 몇 번 진행했었죠. 개발자 리트릿이 뭔가요?
진행자 - 제임스 워드 (00:46)
개발자 리트릿은 가능한 가장 편안한 모임입니다. 우리는 함께 모여서 무언가를 하고, 쓰고, 하고 싶은 건 무엇이든 하죠.
진행자 - 브루스 에클 (00:59)
하이킹도 가고...
진행자 - 제임스 워드 (01:00)
보통은 그렇죠. 네, 우리는 일반적으로 주제를 정하지만 주제는 필수가 아닙니다. 와서 하고 싶은 일을 해도 괜찮습니다. 기본적으로 저는 성인 프로그래머를 위한 유치원 같은 거라고 생각했습니다. 마치 공간이 있고 우리는 어울리고, 원하는 건 무엇이든 하는 거죠. 종종 야외 활동 같은 것도 포함되고요. 놀라운 점은...
진행자 - 제임스 워드 (01:35)
압박감을 없애면 얼마나 많은 기술적인 것들을 하게 되는지입니다. 압박감도 없고, 일정도 없고, 아무것도 없지만 즐거운 시간을 보낸다는 게 핵심입니다.
진행자 - 브루스 에클 (01:49)
아름다운 곳에 괴짜들을 모아 놓으면 멋진 일이 일어나죠.
진행자 - 제임스 워드 (01:52)
맞아요. 그리고 첫 번째 리트릿은 7월 17일에 열리는데, 꽤 촉박해서 사람들이 여기까지 올 수 있을지 모르겠네요.
진행자 - 브루스 에클 (02:04)
그리고 숙박 시설을 찾는 것도 문제겠죠.
진행자 - 제임스 워드 (02:05)
네, 몇 가지 방법이 있습니다. 캠핑도 있고, 이제는 사람들 마당에 캠핑하는 것도 합법이라고 알고 있습니다. 아직 케이트와 이야기해보지 않았지만, 한 블록 떨어진 곳에 그녀의 집이 있으니... 아무튼 첫 번째 리트릿은 동시성에 관한 내용입니다. 제가...
진행자 - 브루스 에클 (02:27)
7월 첫째 주에...
진행자 - 제임스 워드 (02:28)
7월 17일, 네, 그 주 전체입니다. 그리고 다시 말하지만, 사람들은 때때로 짧게 또는 길게 참여합니다. 그들이 얼마나 시간을 낼 수 있는지에 따라 다르죠. 그리고 동시성은 제가 계속 작업해 왔고, 다음 책의 주제이기도 하기 때문에...
진행자 - 브루스 에클 (02:50)
동시성에 대해 알고 싶다면 개발자 리트릿이 도움이 될 수 있겠네요.
진행자 - 제임스 워드 (02:55)
네, 맞습니다. 그리고 두 번째 리트릿은 8월 14일에 열리는데, 많은 관심을 받고 있는 Rust 언어에 관한 것입니다. 저는...
진행자 - 브루스 에클 (03:07)
어려운 부분을 맡고 있고, 당신은...
진행자 - 제임스 워드 (03:09)
네, 거의 모든 Rust 예제 코드를 보고 이해할 수 있을 정도로 몰두해 왔습니다. 그래서...
진행자 - 브루스 에클 (03:22)
대단하네요. 저는 Scala를 10년 정도 했는데도 아직 이해하지 못하는 코드를 보거든요.
진행자 - 제임스 워드 (03:27)
저는... Rust가 저에게 매력적인 이유 중 하나는, 즉 Rust가 놀라운 일을 하지만, 저는 그... 아무튼, 이 리트릿은...
진행자 - 브루스 에클 (03:44)
네, 여기까지 오고 숙박하는 비용 외에는...
진행자 - 제임스 워드 (03:46)
네, 어디에 머물지 알아내는 것 외에는 비용이 들지 않습니다. 관심 있는 분들은 Wintertech Forum으로 가보세요. Wintertech Forum com에 슬랙 채널 가입 안내가 있습니다. 네, 아무튼 슬랙 채널에 들어가면 질문을 할 수 있습니다. 보통 몇 명만 참석합니다. Rust 리트릿은...
진행자 - 제임스 워드 (04:13)
배리 호킨스가 올 것 같습니다. 그리고 관심을 표명한 다른 사람들도 있었고요. 그래서...
진행자 - 브루스 에클 (04:22)
네, 크레스티드에 오시는 분들을 환영합니다.
진행자 - 제임스 워드 (04:27)
어떻게 될지 지켜보죠. 네, 꽤 흥미로운 경험이 될 겁니다. 네.
진행자 - 브루스 에클 (04:32)
좋습니다. 자, 이제 게스트를 소개하겠습니다. 마이크 아날디, 당신은 Scala ZIO 관련 작업을 하고 있었죠. 예전에 몇 번 마주친 적이 있는데, 지금은 ZIO에서 영감을 받은 TypeScript 이펙트 시스템을 이끌고 있다고 들었습니다. 잠시 후에 자세히 이야기해 보죠. 아무튼, 그게 배경 이야기입니다. 오늘은 함수형 프로그래밍, 이펙트, TypeScript 등에 대해 이야기해 보겠습니다. 마이크, 함께 해주셔서 반갑습니다.
마이클 아날디 (05:07)
초대해 주셔서 감사합니다. 여기 와서 기쁩니다.
진행자 - 제임스 워드 (05:11)
이탈리아에서 오셨죠?
마이클 아날디 (05:14)
네, 이탈리아에서 왔습니다. 현재는 여름 동안 이탈리아에 있습니다.
진행자 - 브루스 에클 (05:20)
멋지네요. 당신에 대해, 그리고 당신의 경력과 지금 하고 있는 일에 대해 간략하게 소개해 주시겠어요?
마이클 아날디 (05:30)
네, 물론입니다. 제가 어떻게 TypeScript용 이펙트 시스템을 만들게 되었는지와 연관 지어 설명할 수 있을 것 같습니다. 저는 항상 스타트업에 열정을 가지고 있었고, 상당한 기간 동안 금융에도 관심이 많았습니다. 그래서 21살 때 예산도 없이 고도로 규제된 일을 하려는 회사에 자금을 지원하게 되었습니다. 저의 배경은...
마이클 아날디 (06:08)
대기업에 속해 있고 프로젝트에 예산이 할당된 많은 일반적인 배경과는 반대입니다. 저에게는 그런 이야기가 놀랍게 들립니다. 제 현실은 항상 5명 정도의 인원으로 은행을 만들고, 모든 종류의 규제와 싸우고, 실제로 일을 제대로 해야 한다는 것이었습니다. 그런 경험이 제가 최근에 내린 많은 결정에 영향을 미쳤습니다. 이제...
진행자 - 브루스 에클 (06:36)
효율성, 낮은 비용으로 높은 효율성을 추구하는 것이죠. 그 방정식을 어떻게 최적화하나요?
마이클 아날디 (06:43)
실제로 제품을 만들고 시간이 지남에 따라 제품을 변형할 수 있도록 어떻게 최적화하나요? 제품을 뒷받침하는 프로그램을 만들어 본 사람이라면 누구나 그 프로그램의 유지 관리 가능성을 고려해야 한다는 것을 알 것입니다. 처음부터 완벽하게 만들 수는 없습니다.
진행자 - 브루스 에클 (07:09)
실제로 해보기 전까지는 모든 것을 알 수 없죠.
마이클 아날디 (07:12)
첫째, 해보기 전까지는 모든 것을 알 수 없습니다. 둘째, 시장이 무엇을 원하는지 알 수 없습니다. 즉, 시장에 진출하더라도 제품을 100번은 바꿔야 할 것입니다. 그리고 일을 하는 방법은 여러 가지가 있습니다. 많은 사람들이 망가뜨리고 빠르게 움직이는 길을 선택했습니다. 안타깝게도 많은 산업에서 그것은 선택 사항이 아닙니다. 망가뜨릴 수 없습니다.
진행자 - 브루스 에클 (07:34)
네, 은행 거래 시스템을 망가뜨리면 사람들이 좀 화낼 겁니다. 그런 건 망가뜨릴 수 없는 부분이죠.
마이클 아날디 (07:44)
투자를 관리할 때는 내가 얼마나 많은 돈을 가지고 있는지 확인하고 싶어 합니다. 제대로 보고되어야 하죠. 1초 늦게 표시되더라도 크게 달라지지는 않습니다. 그리고 그것도 방정식의 매우 중요한 부분입니다. 우리는 극도로 데이터 집약적인 고빈도 도메인에 대해 이야기하는 것이 아닙니다. 우리는 말 그대로 작업의 스마트 스케줄링에 대해 이야기하고 있습니다.
마이클 아날디 (08:10)
이런 방식으로 더 많이 접근해야 하는 주제입니다. 여러분은 일을 조율하고 있으며, 그 일이 제대로 이루어지도록 신경 쓰고 있습니다. 네, 조심해야 합니다.
진행자 - 브루스 에클 (08:22)
빠르게 움직이고 망가뜨리지 말아야죠.
마이클 아날디 (08:26)
확실히 빠르게 움직이되 망가뜨리지 않아야 합니다.
진행자 - 브루스 에클 (08:28)
하지만 정확해야 하기도 합니다.
마이클 아날디 (08:31)
저는 그것을 아무것도 망가뜨리지 않고 충분히 빠르게 움직이는 것으로 생각하고 싶습니다.
진행자 - 브루스 에클 (08:39)
네. 그런 배경에서 함수형 프로그래밍을...
마이클 아날디 (08:48)
그런 배경에서 저는 유휴 프로그램을 실행하는 데 매달 3,000파운드의 인프라 비용을 지불하는 상황에 처하게 되었습니다. 이 프로그램들은 주로 JVM에서 Kotlin과 같은 다양한 기술을 사용하여 구축되었지만, ZIO는 아직 나오지 않았습니다. 저는 그런 문제를 해결하는 데 ZIO를 사용하고 싶었지만, 단순히 존재하지 않았습니다. 비용이 많이 들었던 이유는 제가 설명했듯이 그런 유형의 작업이...
마이클 아날디 (09:28)
실제로 데이터 집약적이지 않았기 때문입니다. 즉, 이 프로그램들은 대부분의 시간 동안 유휴 상태였고 초당 100건 정도의 트랜잭션을 처리했습니다. 단일 CPU로도 충분히 처리할 수 있는 수준이었습니다. 로켓 과학이 아니죠.
진행자 - 브루스 에클 (09:42)
대규모가 아니었죠.
마이클 아날디 (09:43)
대규모도 아니었고, 숫자상으로는 대규모일 수 있지만, 하나의 트랜잭션이 크고 밀리초 단위의 변화가 전체 방정식에 아무런 영향을 미치지 않습니다. 그리고 네트워크에 접속하는 모든 유형의 문제는 이 범주에 속합니다. 왜냐하면 빛의 속도라는 한계가 있기 때문에 다른 모든 것은 더 빨라질 수밖에 없기 때문입니다. 네트워크에 접속하는 순간 밀리초 단위의 범위에 들어가게 됩니다. 그래서...
마이클 아날디 (10:23)
극단적인 확장성을 최적화하려는 것이 아니라 정확성과 유지 관리 및 개발의 용이성을 최적화하려는 것입니다.
진행자 - 브루스 에클 (10:35)
그렇다면 인프라 비용이 중요한 요소였나요? 비용의 상당 부분이 낭비되는 인프라에 쓰이고 있었기 때문에 그것이...
마이클 아날디 (10:49)
최적화하려는 목표 중 하나였죠. 그리고 그 인프라는 주로 개발 인프라였습니다. 따라서 실제 운영 환경에 적용되었다면 비용이 적어도 두 배는 늘었을 것입니다. JVM을 사용하더라도, 그리고 기술 유형을 따지지 않더라도 훨씬 더 적은 비용으로 최적화할 수 있었을 것입니다. 하지만 또 다른 요소는 그런 유형의 기술을 다루는 개발자가 매우 비싸다는 것입니다. 반면에 TypeScript 개발자는 많이 찾을 수 있습니다. 그리고 그 당시 ZIO가 등장하고 있었고...
마이클 아날디 (11:26)
저는 '좋아, TypeScript로도 할 수 있겠다'라고 생각했습니다. 소프트웨어 개발에서 흔히 그렇듯이, 우리는 쉬워서가 아니라 쉬울 거라고 생각했기 때문에 이런 일을 합니다. 항상 그렇게 시작하죠. 그래서 제가 TypeScript로 이펙트 시스템을 만들기 시작한 이유입니다. 솔직히 말해서, 같은 개발자들이 처음부터 생산성을 유지했고 시스템 비용이 몇 백 달러밖에 들지 않았기 때문에 매우 잘 진행되었습니다.
마이클 아날디 (12:01)
큰 차이죠.
진행자 - 브루스 에클 (12:05)
Scala JVM 관련 작업을 하면서 ZIO가 어떻게 되어가는지 보기 시작했고, 그러다가 '같은 일을 TypeScript로 해야겠다'라고 생각했군요.
마이클 아날디 (12:19)
저는 '가볍게 해야겠다'라고 생각했습니다. 그리고 저는 JavaScript 생태계의 어떤 기술도 좋아하지 않았습니다. 저는 은행 거래를 관리해야 했습니다. JavaScript로는 그렇게 할 수 없었습니다. 그래서 타협점을 찾아야 했습니다.
진행자 - 제임스 워드 (12:37)
Elm은 살펴봤나요?
마이클 아날디 (12:39)
네, 하지만 주요 목적 중 하나는 주류 언어를 사용하는 것이었습니다. 그리고 TypeScript의 또 다른 중요한 점은, 우선 TypeScript는 JavaScript라는 것을 이해해야 합니다. 타입을 제거하면 유효한 JavaScript 코드가 됩니다. 런타임에 아무것도 추가하지 않습니다. 타입 주석이 있는 스마트 린터 같은 것입니다. 따라서 TypeScript로 컴파일하면 다른 언어가 되는 것이 아닙니다.
마이클 아날디 (13:09)
JavaScript에서 사용할 수 있습니다. JavaScript로 작성한 코드는 TypeScript에서 사용할 수 있습니다. 실제로 많은 라이브러리가 JavaScript로 작성되었고 별도의 타입 정의를 가지고 있으며 완벽하게 사용할 수 있습니다. 그것은 아마도 장점이지만, 다른 언어는 아닙니다. 그래서 지금 TypeScript에 대해 이야기할 때 TypeScript와 JavaScript를 구분하기는 매우 어렵습니다.
마이클 아날디 (13:34)
JavaScript 관련 툴의 약 90%가 TypeScript를 사용하여 구축되었습니다. 따라서 TypeScript를 직접 사용하지 않는 프로젝트라도 TypeScript로 구동되는 IDE를 사용하고 있습니다. 그래서 우리는 아마도 상위 3, 4위 안에 드는 언어에 대해 이야기하고 있습니다. 저는 통계에 크게 신경 쓰지 않지만, 주류 언어라는 것은 분명합니다.
진행자 - 제임스 워드 (13:59)
Python이 타입 주석을 추가한 방식에 대해 알고 있나요?
마이클 아날디 (14:05)
어느 정도는 알고 있습니다. 저는 Python 전문가는 아닙니다.
진행자 - 제임스 워드 (14:08)
네, TypeScript가 그와 비슷한 일을 한 것 같습니다. 타입 주석이 추가되었지만 JavaScript는 무시할 수 있습니다. 그렇게 작동하나요?
마이클 아날디 (14:22)
아니요, 일종의 정적 컴파일러입니다. 타입 주석을 추가하지만 정적 컴파일러는 모든 것의 무결성을 검사하고 컴파일 단계에서 해당 타입 주석을 제거하여 JavaScript로 동일한 코드를 생성합니다. 예를 들어, const foo: string = "bar"와 같은 코드가 있다면 : string을 제거합니다. 문자 그대로 코드에서 토큰으로 제거합니다. 따라서 런타임에 아무런 영향을 미치지 않습니다.
진행자 - 브루스 에클 (15:00)
'더블 포인트'라는 용어는 처음 들어봤습니다. 콜론을 말하는 거죠? Scala와 같은...
마이클 아날디 (15:07)
네, 그렇습니다.
진행자 - 제임스 워드 (15:11)
실제로 Python이 사용하는 모델과 매우 유사합니다. Python 컴파일러는 타입 주석을 무시하도록 수정되었고 별도의 타입 검사기가 있습니다. 하지만 TypeScript의 경우에는 검사하는 동안 타입 주석을 제거합니다.
진행자 - 브루스 에클 (15:29)
구체화된 타입과 같습니다. 전체 타입 시스템을 가져와서 구체화하는 것과 같습니다.
마이클 아날디 (15:36)
솔직히 말해서, 정적으로 타입이 지정되지 않은 언어에 사후적으로 타입 시스템을 적용하는 것은 매우 인상적입니다. TypeScript가 매우 인기를 얻은 이유는 Microsoft가 실제로 그런 종류의 일을 잘하기 때문이라고 생각합니다. 툴링이 정말 훌륭하고 세부 수준이 놀랍습니다. 거의 농담처럼 시작했는데... 저는...
마이클 아날디 (16:07)
Scala 개발자였고, JVM 개발자였고, 그 전에는 네이티브 개발자였습니다. 그래서 처음에는 TypeScript를 진지하게 받아들이기 어려웠지만, 점차 JavaScript가 서버에서 실행되기 시작했습니다. 이제는 브라우저에서 시작하여 람다를 실행하는 전용 런타임과 전 세계 인프라의 절반을 차지하는 엄청나게 방대한 생태계를 가진 언어가 되었습니다. 그것이 옳은지 그른지에 대해서는 논쟁하지 않겠습니다. 그것은 저의 영역을 벗어납니다.
마이클 아날디 (16:43)
저의 영역을 벗어나고, 저는 툴링과 다른 언어에 열정적입니다. 그래서 짐작하시겠지만, JavaScript가 그런 많은 상황에서 승리하게 되어 그렇게 행복하지는 않습니다.
진행자 - 브루스 에클 (16:59)
하지만 그게 우리가 가진 세상이죠.
진행자 - 제임스 워드 (17:01)
그게 우리가 가진 세상이고, 우리가...
마이클 아날디 (17:03)
우리가 받아야 할 벌이지만, 저는 그것을 조금 더 좋게 만들려고 노력하고 있습니다. 그게 목표이고, 주류 언어는 중요했습니다.
진행자 - 브루스 에클 (17:14)
저는 TypeScript의 기원에 대한 이야기를 들었는데, 사실인지 아닌지는 모르겠지만, Microsoft가 VS Code를 만들기 시작했고 JavaScript로 만들고 있었는데 수십만 줄의 코드에 도달했을 때 더 이상 진전을 이룰 수 없다는 것을 깨달았다고 합니다. 왜냐하면...
진행자 - 브루스 에클 (17:39)
대규모 코드베이스에서 JavaScript를 리팩토링하는 것은 많은 회귀 없이 정확성을 유지하면서 불가능하기 때문입니다. 물론 테스트가 그 문제를 해결할 수 있다고 말할 수 있지만, 리팩토링 과정에서 발생할 수 있는 모든 사소한 문제를 포착할 만큼 충분한 테스트를 가진 사람이 실제로 있을까요?
마이클 아날디 (17:57)
그리고 많은 라이브러리 코드베이스와 애플리케이션 코드베이스를 봤는데, 애플리케이션 코드베이스에서 100% 커버리지 단위 테스트를 하는 것이 얼마나 현명한지 모르겠습니다. 저는 그것에서 많은 것을 얻지 못했습니다.
진행자 - 브루스 에클 (18:19)
시간 낭비죠. 네.
마이클 아날디 (18:21)
아마도 시간 낭비일 겁니다. 시간을 낭비하고 싶어 하는 사람들을 존중합니다. 다른 기술을 비판하려는 것은 아니지만, 저는 직접 하지는 않을 것입니다. 저는 IDE 내에서 즉각적인 피드백을 원합니다. 그것이 실제로 TypeScript가...
진행자 - 브루스 에클 (18:38)
네.
마이클 아날디 (18:39)
제공하는 것 중 하나이고, 꽤 괜찮은 오류 메시지를 제공합니다. 물론 더 개선될 수 있겠죠.
진행자 - 브루스 에클 (18:47)
좋은 IDE 코드 힌트와 같은 오류 메시지를 얻으려면 타입이 필요합니다. 기원 이야기로 돌아가서, Microsoft가 VS Code를 모두 JavaScript로 만들 때 더 이상 진전을 이룰 수 없는 지점에 도달했고...
진행자 - 제임스 워드 (19:11)
게다가 CoffeeScript와 같은 예시가 있었죠.
진행자 - 브루스 에클 (19:18)
네, JavaScript를 가져와서...
진행자 - 제임스 워드 (19:23)
그 위에 무언가를 만들고 더 좋게 만드는 데 영감을 주었죠. 그래서...
마이클 아날디 (19:26)
JavaScript가 나쁜 언어라는 결함이 있었기 때문에 처음부터 다른 언어를 JavaScript로 컴파일하려고 했습니다. 직접 작성하기에는 너무 고통스러웠기 때문입니다. 따라서 JavaScript를 빌드하고 변환하는 툴체인은 실제로 매우 오래되었습니다. 그래서 툴체인에 경쟁 요소를 도입했을 때 큰 마찰을 겪지 않았습니다. ECMAScript 6가 등장하던 시기였습니다.
마이클 아날디 (20:01)
사람들은 ECMAScript 6를 작성하고 싶었지만 브라우저가 ECMAScript 5와 호환되기 때문에 그럴 수 없었습니다.
진행자 - 브루스 에클 (20:07)
맞아요, 이미 트랜스파일링을 하고 있었죠. 트랜스파일링을 해야 한다면 타입 주석을 추가하고 그 모든 이점을 얻는 것이 좋겠죠.
진행자 - 제임스 워드 (20:17)
안데르스 헤일스버그가 시작했나요? 네, 제 생각에는 그랬던 것 같습니다.
마이클 아날디 (20:21)
네, C#의 개발자이기도 하죠.
진행자 - 제임스 워드 (20:27)
닷넷도요. 네, 그래서 그들은...
마이클 아날디 (20:30)
타입에 대한 영감을 주었죠.
진행자 - 제임스 워드 (20:31)
네, 그는 매우 똑똑한 사람입니다.
진행자 - 브루스 에클 (20:33)
물론 JavaScript 영역에 있던 사람이라면 누구나, 아니, 어쩌면 모두는 아니겠지만, JavaScript로 된 대규모 코드베이스를 가진 대부분의 사람들은 JavaScript 위에 타입 언어를 사용하여 리팩토링, 코드 편집, 컴파일러 오류 메시지, 정확성 등 모든 이점을 얻는 것이 당연하다고 생각했을 것입니다.
진행자 - 브루스 에클 (21:02)
그래서 이것이 어떻게 발전했는지 이해가 됩니다. 그리고 이제 JavaScript를 대상으로 하려는 사람이라면 TypeScript가 거의 기본값이 되었다고 생각합니다.
마이클 아날디 (21:14)
이상하게도 저는 친구에게 기본 사항을 가르치고 있었는데, '좋아, IDE를 열고 JavaScript의 기본 사항을 배우자'라고 했습니다. 그리고 '맙소사, 기본적인 메서드 이름조차 기억나지 않아'라고 생각했습니다. '아니, 이건 배우는 올바른 방법이 아니야. 왜냐하면...' 언어를 배우는 방법은 예전에 종이에 언어를 배우고...
마이클 아날디 (21:46)
C 명세를 공부하고 모든 것이 매우 천천히 움직이던 시절과는 다릅니다. 우리는 엄청나게 큰 코드베이스를 가지고 있지 않았습니다. 프로세스가 달랐습니다. 이제는 몇 가지 타입 주석만 있으면 모든 메서드와 모든 것을 알려주는 IDE가 있습니다. 그리고 타입은 가장 중요한 개념 중 하나입니다. 왜냐하면 현실 세계의 문제를 표현할 때마다 도메인이 있기 때문입니다. 마치 언어 안의 언어와 같습니다.
마이클 아날디 (22:20)
사람에게 같은 문제를 설명하는 것과 비슷하게 읽히는 코드를 작성해야 합니다. 그렇지 않으면 단절이 발생합니다. 코드를 읽는 사람은 사람이고, 그 코드는 기계에 명령을 내립니다. 하지만 기계에 대한 명령은 번역된 요소입니다. 직접 코드를 읽고 도움 없이 추론해야 하는 유일한 존재는 인간입니다. 그것은 매우 중요합니다.
진행자 - 브루스 에클 (22:55)
타입이 매우 도움이 됩니다.
마이클 아날디 (22:56)
타입은 그 부분에서 매우 도움이 됩니다. 사용자라는 변수를 보고 사용자가 무엇인지 모르고, 사용자에게 이름이라는 필드가 있는지 모르면 매우 빠르게 복잡해집니다.
진행자 - 브루스 에클 (23:13)
따라서 타입은 개발자를 위해 존재해야 합니다. 기계를 위해 존재하는 것이 아닙니다. 기계는 타입에 신경 쓰지 않습니다. 하지만 개발자는...
마이클 아날디 (23:22)
ZIO는 실제로 그것을 잘 해냈습니다. 왜냐하면 ZIO의 타입을 관리하는 것이 매우 쉽고 기본 사항만 알면 되기 때문입니다. ZIO에 확장 기능을 작성하려면 적절한 Scala를 알아야 하지만, 사용하려면 기본 구현과 몇 가지 메서드가 있는 케이스 클래스를 작성하면 됩니다. 그러면 함수형 프로그래밍의 모든 이점을 얻을 수 있습니다. 하지만 예를 들어, Effect의 목표는 함수형 프로그래밍을 대중화하는 것이 아니라 실제로 애플리케이션을 구축하는 것이었습니다. 그리고 그것은...
마이클 아날디 (23:58)
코드를 유지 관리 가능하게 하고 코드를 효율적으로 실행하고 더 많은 사람들이 작업할 수 있도록 하는 방법이었습니다.
진행자 - 브루스 에클 (24:07)
ZIO가 하는 일을 보고 TypeScript에서도 ZIO와 같은 이점을 얻고 싶었군요. 그 여정에 대해 자세히 말씀해 주시겠어요?
마이클 아날디 (24:24)
그래서 저는 다른 사람들처럼 애플리케이션 코드에서 작게 시작했습니다. 기본적인 아이디어를 가지고 시작했죠. 하지만 첫 번째 질문은 '전체 컨텍스트, 환경, 매개변수, 전체 오류, 그 변형, 그리고 그것들이 어떻게 혼합되는지 표현할 수 있을까?'였습니다. 시간이 좀 걸렸지만 가장 어려운 부분은 아니었습니다. 그리고 저는 처음부터 TypeScript가 실제로 매우 유연하고 유연한 타입 연산을 가지고 있으며 교집합과 합집합을 포함한다는 것을 깨달았습니다.
마이클 아날디 (25:13)
처음에 저에게 가장 자연스러운 것은 서비스를 교집합 타입으로 표현하고 오류 채널을 합집합 타입으로 표현하는 것이었습니다. 그것이 Scala에서도 해결책이 되었습니다. 왜냐하면 그것이 변형이 혼합되는 방식이기 때문입니다. 타입 시그니처는 조금 다르게 보이지만...
진행자 - 제임스 워드 (25:40)
교집합 타입이라고 하셨는데, 합 타입을 말하는 건가요?
마이클 아날디 (25:48)
AND 타입입니다. A & B & C & D & E와 같습니다.
진행자 - 브루스 에클 (25:59)
네, 대수적 데이터 타입, 하위 타입, 곱 타입, 그리고 교집합 사이에는 미묘한 차이점이 있습니다.
마이클 아날디 (26:08)
곱 타입은 다릅니다. 교집합 타입은 다르지 않습니다. 여러 인터페이스를 가진 동일한 값과 같습니다. 합집합과 같다고 볼 수 있습니다. 합집합은 값이 해당 인터페이스 중 하나인 것이고, 교집합은 값이 해당 인터페이스 모두인 것입니다. 네.
진행자 - 브루스 에클 (26:32)
서비스가 교집합인 이유는 데이터베이스 커넥터 등이 필요한 서비스가 있을 수 있기 때문이죠.
마이클 아날디 (26:41)
실행하려면 데이터베이스가 필요하고 연결 풀이 필요하고 사용자 서비스가 필요하고 캐시가 필요한 프로그램이 있습니다. 실행하려면 이 모든 것이 제공되어야 합니다. Scala에서는...
진행자 - 브루스 에클 (27:02)
환경 타입으로...
마이클 아날디 (27:04)
ZIO의 환경 부분으로 끝났습니다. 그것은 has의 필요성을 제거했습니다. 1.0에서는 hasZero, hasOne, hasTwo와 같이 조금 더 복잡했습니다. 이제는 팬텀 타입이라고 하는 가짜 타입입니다. 아무것도 매핑되지 않습니다. TypeScript에서는 조금 다르게 작동합니다. 왜냐하면 TypeScript는 구조적이기 때문입니다. 따라서 동일하게 보이는 두 타입이 있다면 TypeScript에서는 동일한 타입입니다.
마이클 아날디 (27:42)
따라서 교집합 타입에서 한 타입에 다른 타입과 충돌하는 필드가 있으면 전체가 never가 됩니다. TypeScript는 '이봐, 그런 값은 존재할 수 없어. 이름 필드가 숫자이면서 문자열인 값은 가질 수 없어.'라고 말할 만큼 똑똑하기 때문입니다. 숫자이면서 문자열인 값은 없습니다. 그래서 전체가 never가 됩니다.
마이클 아날디 (28:10)
저희에게는 그렇게 좋지 않습니다. 합집합 타입으로는 괜찮습니다. 그래서 TypeScript에서는 실제로 둘 다 합집합 타입을 사용합니다. 약간의 차이점이 있지만 개념적으로는 같은 것을 표현하려는 것이고 TypeScript는 그것을 할 수 있을 만큼 강력합니다. 처음에는 저에게도 놀라운 일이었습니다. 그리고 적응의 여정은 하루 만에 끝나지 않았습니다. 배우고, 배우고, 배우고, 실패하고, 실패하고, 실패했습니다. 모든 기술이 그렇듯이.
마이클 아날디 (28:47)
그래서 Scala와 ZIO의 개념을 TypeScript에 적용하려고 했군요. 그리고 몇 가지 변경해야 할 사항이 있었고...
진행자 - 브루스 에클 (28:50)
네, Scala와 ZIO의 개념을 TypeScript에 매핑하려고 했고, 그 과정에서 몇 가지 변경해야 할 사항이 있었군요.
마이클 아날디 (29:01)
그리고 '언어의 어떤 기능을 활용하여 더 좋게 만들 수 있을까?' 그리고 '어떤 것을 타협해야 할까?'라는 질문이 생깁니다. 왜냐하면 어떤 것은 표현할 수 없기 때문입니다. 반대의 경우도 마찬가지입니다. 예를 들어, ZIO 1.0에서는 잔여 타입을 수동으로 지정하지 않고도 타입을 부분적으로 지우기 위해 단일 컨텍스트 매개변수를 제공할 방법이 없었습니다. TypeScript에서는 처음부터 가능했습니다. 전혀 문제가 없었습니다. 따라서 언어에서 활용할 수 있는 것들이 있습니다.
마이클 아날디 (29:43)
좋게 만들 수 있는 것들이 있고, 타협해야 하는 것들이 있습니다. 예를 들어, TypeScript에 암시적 변환이 있으면 좋겠지만, 아니면 Kotlin과 다른 언어에서 점점 더 많이 사용되는 컨텍스트 함수가 있으면 좋겠지만, 안타깝게도 그런 일은 일어나지 않을 거라는 것을 알고 있습니다.
진행자 - 브루스 에클 (30:01)
흥미롭네요. 런타임 측면은 어떤가요? ZIO의 마법 중 일부는 이펙트 정의를 가져와서 런타임에서 해당 정의를 효율적으로 실행하고 실제 스레드에 매핑하는 방식에서 발생한다고 생각합니다. 이펙트 런타임 부분을 만드는 데 어려움이 있었나요?
마이클 아날디 (30:29)
놀랍게도 매우 유사합니다. ZIO에서도 런타임이 무엇을 의미하는지에 대한 여러 번의 반복 작업을 거쳤습니다. 재미있게도 런타임을 TypeScript로 변환하면서 Scala의 원래 런타임에서 버그를 발견했습니다. 원칙과 개념이 너무 비슷해서 TypeScript에서 컴파일되지 않으면 Scala에서도 컴파일되지 않았습니다. 아니면 Scala에서 오류가 발생하거나...
마이클 아날디 (31:07)
TypeScript에서 뭔가 다르게 하고 있었고 뭔가 잘못되었을 수도 있습니다. 양쪽 모두에서 발생했습니다. 따라서 런타임은 매우 유사합니다. 유일한 차이점은 여러 스레드를 할당하는 문제에 대해 신경 쓰지 않아도 된다는 것입니다. 스레드 풀을 관리하지 않고 하나의 스레드를 사용합니다. 네, 같은 스레드에서 이펙트를 엮어야 합니다. 성능 측면에서는 최선이 아닐 수도 있습니다. 하지만 다시 말하지만, TypeScript에서는 조정 코드를 관리하고 있습니다.
마이클 아날디 (31:47)
따라서 백엔드에서도 작업을 조정할 때 아무도 TypeScript로 데이터 요소를 처리하지 않을 것입니다. API를 호출하고 데이터베이스를 호출할 것입니다. 그리고 오해 중 하나는 Node.js가 완전히 단일 스레드라는 것입니다. 조정을 위한 스레드는 하나지만 HTTP 요청을 예약하면 다른 스레드에서 처리됩니다. 스레드를 차단하지 않습니다. JavaScript는 비동기 작업을 매우 잘 실행하는 하나의 코디네이터와 같습니다.
마이클 아날디 (32:18)
ZIO는 그런 비동기 작업을 설명하는 데 매우 탁월합니다. 둘을 합치면 매우 효과적입니다. 제 생각에는요.
진행자 - 브루스 에클 (32:32)
이펙트 시스템에 대해 잠깐 이야기해 보죠. 이펙트 시스템의 가치는 무엇이라고 생각하시나요?
마이클 아날디 (32:44)
다시 말하지만, 저는 실제로 코드를 테스트해야 했고 코드를 안정적으로 만들어야 했습니다. 그래서 저에게는 두 줄의 코드로 지수 백오프 재시도 정책을 표현할 수 있다는 것이 놀라운 일이었습니다. 그것이 놀라운 일이라는 것을 깨달은 이유는 일반적으로 수백 줄의 코드를 작성하고 테스트하고 디버깅해야 했고, 제대로 작동하는지조차 알 수 없었기 때문입니다. 안정성을 위해 변경하는 것도 어려웠습니다. 또 다른 측면입니다.
마이클 아날디 (33:16)
사람들은 모킹을 통해 안정성을 확보하는 것을 좋아합니다. 저는 모킹을 싫어합니다. 저는 테스트 환경에서 실제 데이터베이스를 실행하는 테스트 컨테이너를 좋아합니다. 당신도 좋아한다는 것을 알고 있습니다. 왜냐하면 제가 봤거든요.
진행자 - 브루스 에클 (33:31)
네, 서비스 종속성에는 최고죠.
마이클 아날디 (33:34)
네, 저는 테스트에 레이어를 두는 것을 좋아합니다. 테스트 컨테이너를 통해 인프라를 생성하고 네트워크 구성, 데이터베이스 구성 등을 추출하고 로컬 서비스를 구성하고 로컬 서비스에 데이터베이스 연결을 제공하고 실제 API를 실행하는 레이어가 있습니다. 실제 상황을 테스트하는 레이어가 있습니다. 이펙트 시스템 없이 그렇게 해 보세요. 정말 재미있을 겁니다. 정말로요. 하지 마세요.
마이클 아날디 (34:07)
저는 처음부터 이펙트 시스템을 통해 표현할 수 있는 추상화 수준과 시간이 지남에 따라 얻을 수 있는 모듈성과 구성 가능성이 결국에는 승리할 것이라는 것을 깨달았습니다. 왜냐하면 필요한 것은 올바른 기본 요소를 구축하는 것뿐이기 때문입니다. 네, 적절한 데이터베이스 클라이언트를 만들고 데이터베이스 풀링 등을 파악하는 데는 시간이 많이 걸립니다. 하지만 일단 만들고 나면 두 번 다시 만들 필요가 없습니다. 코드 내에서 사용하기만 하면 됩니다. 그리고 그냥 작동합니다.
마이클 아날디 (34:46)
다른 데이터베이스로 변경한다고 해도 TypeScript에서는 문자 그대로 차이점뿐입니다. 우리는 RPC 시스템을 구축하는 지점에 도달했습니다. 다음 단계는 Saga와 분산 워크플로우를 개발하는 것입니다. 그것은 우리가 트위터에서 이야기해 왔던 또 다른 주제이지만, 전체적인 아이디어는 '네, 우리는 작업을 조정하고 있습니다. 우리는 그 작업을 현명하게 정의해야 합니다. 모든 작업에 동일한 요구 사항이 있는 것은 아닙니다.'입니다.
마이클 아날디 (35:17)
예를 들어, 세 개의 API를 순차적으로 호출해야 한다면 일반적인 프로그래밍 기능이 필요하지 않을 것입니다. 람다에서 실행자로 트랜잭션을 전달할 수 있는 ZIO의 flow와 같은 것이면 충분합니다. 실행자는 실제로 그 작업을 처리합니다. 따라서 작업을 다른 곳으로 보내고 있습니다. 데이터를 이동하는 것뿐만 아니라 계산을 이동하고 있습니다. 따라서 우리는 전체 인프라에 구성 가능성을 가져오고 싶습니다. 그리고...
마이클 아날디 (35:55)
저는 이펙트 시스템이 올바른 기본 요소라고 생각합니다. 그렇지 않으면 어떻게 이러한 모든 솔루션을 실제로 사용할 수 있는 방식으로 구성할 수 있을까요?
진행자 - 브루스 에클 (36:07)
네, 네, '아, 함수형 프로그래밍은 구성 가능성에 정말 좋구나'라고 생각했고, 그다음에는 '이펙트는 부수 효과가 있는 것들의 구성 가능성에 정말 좋구나'라고 생각했습니다. 그리고 저는 이펙트를 사용하여 부수 효과가 있는 것들의 구성 가능성을 관리하는 것보다 더 좋은 모델을 본 적이 없습니다. 하지만 당신이 말하는 것은 이것의 다음 단계는 분산 시스템이 구성 가능성이 절대적으로 끔찍했던 마지막 개척지라는 것입니다.
진행자 - 브루스 에클 (36:48)
그리고 분산 시스템 수준에 더 나은 구성 가능성 모델을 어떻게 가져올 수 있을까요?
마이클 아날디 (36:55)
그것은 일종의 필수 사항입니다. 왜냐하면 이제 제가 이 말을 하면 보통 사람들이 저를 이상하게 쳐다보는데... 브라우저는 분산 시스템입니다. 브라우저가 왜 분산 시스템일까요? 제 머리 속에서요. 내 컴퓨터에서 실행되는데 왜 분산 시스템일까요? 네, 당신의 컴퓨터에서 실행되지만 단일 JavaScript 엔진은 워커를 가질 수 있고 메시지를 통해 통신하고 실패할 수 있습니다. 메모리를 공유하지 않고 두 워커 간에 객체를 전달할 수 없습니다. 마치 HTTP 호출을 하는 것과 같습니다.
마이클 아날디 (37:36)
브라우저 내에서 동일한 네트워크 오류 시나리오를 가지고 있습니다. 지연 시간만 다를 뿐입니다. 하지만 분산 시스템을 구축하고 있으며 브라우저 내에서 프로그래밍하고 있습니다. WebAssembly를 추가하고 다른 요소를 추가합니다. 엄청납니다. 매우 빠르게 복잡해질 것입니다. 그리고 저는...
진행자 - 브루스 에클 (37:57)
Effect 프로젝트의 얼마나 많은 부분이 브라우저 애플리케이션을 대상으로 하고 있고 얼마나 많은 부분이 서버 측 애플리케이션을 대상으로 하고 있나요? 사람들이 서버에서 사용하든 브라우저에서 사용하든 상관없다고 생각하지만 브라우저 측에서 더 많이 사용되나요? 서버 측에서 더 많이 사용되나요? 어떻게 보시나요?
마이클 아날디 (38:17)
커뮤니티 측면에서는 50 대 50이라고 생각합니다. 제가 처음에 Effect를 만든 이유는 백엔드와 더 관련이 있었습니다. 저는 분산 워크플로우를 조정하기 위해 TypeScript를 사용할 계획이었습니다. 예를 들어, 트랜잭션 청산과 같은 프로세스는 몇 주가 걸릴 수 있고 수동 개입이 필요할 수도 있고 부분적으로 자동화되어야 하고 감사 가능해야 하고 고도로 규제되어야 합니다. 그게 제 영역이었습니다.
마이클 아날디 (38:52)
하지만 시스템은 매우 작게 만들어졌고, 다시 말하지만 브라우저도 서버와 많은 문제를 공유한다는 것을 깨달았습니다. 그리고 이 시점에서 저는 50 대 50의 사람들이 있다고 생각합니다. 그중 일부는 Effect 내에서 렌더링 스택이 어떻게 보일지 생각하고 있습니다. 이제 그것은...
진행자 - 브루스 에클 (39:20)
Effect 위에 Elm 아키텍처와 같은 것을 만들어 주세요.
마이클 아날디 (39:27)
로컬에서 그렇게 하고 있는 사람들이 있습니다. 저는 프런트엔드 개발자가 아니지만, 좋은 아이디어가 떠오르면... 요점은 너무 방대하다는 것입니다. 이 질문에 답하기 어려운 이유는 너무 방대해서 프런트엔드 사용에 대한 좋은 아이디어가 떠오르면 모든 곳에서 사용하기에 완벽한 작은 런타임을 가지고 있습니다. 런타임은 압축하면 10킬로바이트 정도입니다.
진행자 - 브루스 에클 (40:00)
10킬로바이트요?
마이클 아날디 (40:02)
압축하면요.
진행자 - 브루스 에클 (40:03)
네, 그래서 모든 종류의 사용에 적합합니다.
마이클 아날디 (40:05)
모든 종류의 사용에 적합합니다. 물론, 예를 들어 제 친구 중 한 명이 최근에 로컬 우선 앱을 만들었습니다. Effect 회사의 팀원인 요하네스 세틀링입니다. 그는 브라우저에서 SQLite를 실행하고 로컬 SQLite에 쿼리와 모든 것을 작성하고 네트워크를 통해 복제하는 로컬 우선 앱을 가지고 있습니다. 조금 다른 유형의 아키텍처이고 그는 코드의 많은 부분에 Effect를 사용하고 있습니다.
마이클 아날디 (40:46)
그리고 우리는 그의 번들을 확인하고 있었는데, '친구야, Effect 라이브러리 코드를 150킬로바이트나 사용하고 있다는 걸 알고 있니?'라고 했습니다. 저는 그 150킬로바이트의 코드 없이 이 앱이 얼마나 커질지 상상도 할 수 없습니다. 최소 15킬로바이트부터 시작하지만 너무 많은 것들이 있습니다. 아마도 같은 앱이라면 이러한 고도로 구성 가능한 블록을 사용하지 않으면 최소 3, 4메가바이트가 될 것입니다. 제가 확인했을 때...
진행자 - 브루스 에클 (41:24)
중복이 많고 관리해야 할 미묘한 차이점이 많습니다.
마이클 아날디 (41:28)
네, 그리고 스트리밍과 같은 기본적인 것조차도 매우 효율적입니다. 채널 파이버 또는 채널의 실제 구현은 그렇게 크지 않고 엄청난 이점을 제공합니다. 처음에는 프런트엔드에서의 사용을 잠시 동안 무시했습니다. 사용하지 말라고 권장했지만 실제로 프런트엔드 친구들이 '아니, 사용하지 말라고 권장해서는 안 돼. 왜냐하면 우리는 당신의 조언을 무시하고 1년 반 동안 사용해 왔고 아무 문제 없이 잘 되고 있거든. 그리고 실제로 훌륭해.'라고 말했습니다.
진행자 - 브루스 에클 (42:06)
음, 아직 적절한 단어가 있는지 모르겠지만 이펙트 시스템을 통해 무엇이든 추가할 수 있는 기능은 프런트엔드에서도 매우 가치가 있을 것입니다. 따라서 무언가를 재시도해야 할 때 .retry를 사용하고, 무언가에 시간 제한을 설정해야 할 때 .timeout을 사용합니다. 이러한 기능의 보편성, 프로그램의 모든 수준에서 적용할 수 있다는 것은...
마이클 아날디 (42:33)
그리고 최근에 오랫동안 조사해 왔고 ZIO Query 프로젝트에 매우 관심이 많았습니다. Scala에서 데이터 가져오기의 배칭, 캐싱, 최적화를 수행하는 프로젝트입니다. 어느 시점에 저는 '이것을 파이버 내부에 직접 구현하여 anyRef 또는 ZIO 용어로 anyEffect를 캐시 가능하고 배치 가능하게 만들 수 있을까?'라고 생각했습니다.
마이클 아날디 (43:08)
그래서 이제 Effect에서는 코드를 전혀 변경하지 않고도 이펙트를 요청으로 선언할 수 있고 해당 요청은 코드를 변경하지 않고도 백그라운드에서 배치되고 캐시될 수 있습니다. 실행 중인 프로그램으로 해석되는 순수한 프로그램 설명 없이는 이러한 기능을 사용할 수 없습니다. 설명이 없으면 이러한 종류의 기능을 수행할 방법이 없습니다.
마이클 아날디 (43:44)
당신이 언급한 것과 같은 개념이라고 생각합니다. 설명이 없다면 프로그램을 가지고 '100번 재시도해 주세요'라고 말할 방법이 없습니다. 배칭, 캐싱에도 같은 개념이 적용됩니다. 제 생각에는 지속성, 네트워크 상호 작용, 분산 트랜잭션 실행에도 적용될 것입니다. 그리고 점차적으로 서로 구성되는 추상화를 구축하는 데 도움이 될 것입니다.
진행자 - 브루스 에클 (44:23)
그 기반에는 이펙트 시스템이 필요합니다. 왜냐하면 이펙트 시스템이 리소스를 관리할 수 있는 기능을 제공하기 때문입니다.
마이클 아날디 (44:31)
보편적인 구성을 보장해야 합니다. 그렇지 않으면 망칠 것입니다.
진행자 - 브루스 에클 (44:39)
캡슐화해야 합니다.
마이클 아날디 (44:41)
캡슐화하는 단일 방법이 없다면 시간문제일 뿐입니다. 서로 통신하지 않는 두 가지가 생길 것입니다. 단일 기반을 가지고 있어야 합니다.
진행자 - 제임스 워드 (44:51)
그렇다면 구성 가능성이 함수형 프로그래밍의 전체 이유라고 말씀하시겠습니까?
마이클 아날디 (44:59)
저는 함수형 프로그래밍의 전체 이유는 처음부터 매우 명확했고 프로그램을 합리적으로 추론할 수 있는 능력이라고 생각합니다. 즉, 프로그램을 읽고 일반적인... 정신적으로 변환할 수는 없습니다. 방정식을 가져와서 한 조각을 잘라내어 다음 줄로 옮겨도 방정식은 전혀 변하지 않습니다.
마이클 아날디 (45:34)
코드도 같은 속성을 가져야 합니다. 저는 그것이 함수형 프로그래밍의 목표였다고 생각합니다. 하지만 저는 오랫동안 우리가 하려는 '무엇'과 '어떻게'를 혼동해 왔다고 생각합니다. 우리는 모두가 이해할 수 있는 소프트웨어를 작성하려고 노력하고 있고 유지 관리하기에 너무 복잡하지 않은 소프트웨어를 작성하려고 노력하고 있습니다. 왜냐하면 우리는 소프트웨어를 좋아하고 제품을 만드는 것을 좋아하고 고객이 원하는 것에 집중하고 싶기 때문입니다.
마이클 아날디 (46:14)
'데이터베이스를 어떻게 호출해야 할까?' '왜 아직도 PostgreSQL 연결 문자열을 수동으로 작성해야 할까?' '지난 4년 동안 우리는 무엇을 해야 할지 대신에 어떻게 해야 할지 작성하는 데 시간을 낭비했을까?'라고 생각합니다. 프로그래머는 '무엇'을 작성하고 싶어 하고 우리는...
진행자 - 브루스 에클 (46:41)
배관 작업, 리소스 관리, 오류 처리 또는 무시에 갇혀 있습니다.
마이클 아날디 (46:46)
그것은 업계의 관점이고 연구 관점에서는 '네, 모나드는 순차적 계산을 표현하는 좋은 방법입니다. 좋은 수학적 결과입니다.'입니다. 저는 수학자입니다. 저는 이론적인 결과를 좋아하지만 실제로 그것은 한 가지 방법일 뿐입니다. 그리고 네, 모나드는 매우 똑똑한 것이지만 모나드의 구성은 수학적 이론에서 주어진 것이 아닙니다. 구성하는 방법은 여러 가지가 있습니다.
마이클 아날디 (47:24)
그리고 우리가 집중해야 할 것은 언어 내에서 어떻게 가장 잘 할 수 있느냐입니다. 그래서 저는 누군가가 '타입 클래스가 절대적으로 최고야. 왜냐하면 Haskell에서는 절대적으로 최고니까.'라고 말하는 것을 좋아하지 않습니다. 네, Haskell을 작성한다면 타입 클래스가 최고입니다. Scala에서는 암시적 변환이 최고일 수도 있습니다. TypeScript에서는 절대 아닙니다. 분명한 차이점이 있습니다. 그리고 저는 Haskell의 아버지조차도 이제 다른 방법을 모색하고 있다고 생각합니다. 다른 함수형 언어가 등장하고 있습니다.
마이클 아날디 (48:09)
Epic Games의 연구처럼 다른 접근 방식을 취하는 언어가 있습니다. 저는 주요 목표가 프로그램을 쉽게 작성하는 것이고 구성은 그냥 무료로 따라오는 좋은 것이기를 바랍니다. 제대로 한다면, ZIO 프로그램이나 Effect 프로그램을 작성하면 구성될 것입니다. 네, 구성되지 않도록 만드는 것은 꽤 어렵습니다. ZIO나 Effect에서 구성되지 않는 것을 만들려면 똑똑해야 합니다. 저는 이 세상의 모든 언어가 어느 정도는 불안정하다고 장담할 수 있습니다. 최고의 ZIO 앱이나 Effect 앱, 최고의 컴파일러를 포함해서요. 모든 것은 어느 정도는 망쳐져 있습니다.
진행자 - 브루스 에클 (49:10)
해피 패스가 구성 가능하도록 하려고 노력하는 과정에서요.
마이클 아날디 (49:15)
네, 해피 패스가 구성 가능하도록 하고 사용자가 언해피 패스가 존재하고 언해피 패스를 처리하는 방법을 알 수 있도록 해야 합니다. 저는 계산을 작성하고 싶지만... ZIO에서 처음부터 정말 좋아했던 원칙 중 하나는 ZIO에는 세 가지 매개변수가 있다는 것입니다. 이 세 가지 매개변수는 세 가지를 나타냅니다. 이 세 가지는 프로그램의 출력입니다.
마이클 아날디 (49:52)
프로그램에서 발생할 수 있는 오류 케이스와 프로그램을 실행하는 데 필요한 종속성입니다. 저는 이 세상의 모든 코드가 이 세 가지 속성을 가지고 있다고 주장합니다. 어쩌면 그중 일부는 never, none, any이거나 퇴화된 케이스일 수도 있습니다. 하지만 컨텍스트가 필요하지 않고 예측 가능한 이유로 실패할 수 없으며 숫자를 반환하는 이펙트라고 말하는 프로그램이 있다면...
마이클 아날디 (50:32)
언해피 패스에서 관리할 것이 없다는 것을 알고 있습니다. 실패할 수 없다는 뜻은 아닙니다. 폭발하면 실패할 수 있지만 디스크 오류를 복구하고 싶지는 않습니다. 프로그램이 충돌하고 디스크 오류가 발생했다고 알려주고 끝나기를 바랍니다. 완전히 예측 가능하고 5초 이내에 지수적으로 재시도해도 괜찮은 네트워크 오류 케이스에서 복구하고 싶습니다. 1분 후에 끝나면... 네, ZIO 용어로 다시 죽고 에스컬레이션되기를 바랍니다.
마이클 아날디 (51:06)
이러한 타입은 모든 코드, 적어도 제가 본 모든 애플리케이션 코드에 의미가 있습니다. 그 개념을 명확히 하는 것은 제 생각에는 절대적인 게임 체인저였습니다.
진행자 - 브루스 에클 (51:22)
브루스와 저는 최근에 액터에 대해 이야기하고 있었는데, 브루스는 제가 액터를 왜 싫어하는지 물었습니다. 그리고 제가 계속해서 떠올린 것 중 하나는 액터가 바로 그 세 가지에 대해 명확하지 않다는 것입니다. 필요한 종속성, 발생 가능한 오류, 또는 출력에 대해 명확하지 않습니다. 그리고 제가 ZIO를 좋아하는 이유 중 하나는 그 세 가지에 대해 명확해야 하기 때문입니다. 타입 정의에 있습니다. 그리고 그 명확성은...
진행자 - 브루스 에클 (51:58)
더 정확하고 구성 가능하도록 도와줍니다. 왜냐하면 명시적으로 명시해야 했기 때문입니다. 반면에 액터 세계에서는...
진행자 - 제임스 워드 (52:08)
메뉴에도 없습니다. 우리는 그런 것들에 대해 생각하지 않습니다. 네.
진행자 - 브루스 에클 (52:15)
하지만 액터에게 메시지를 보낼 때 분명히 종속성이 있고 실패할 수 있는 방법이 있고 출력이 있습니다. 마이크가 말했듯이 여전히 존재하지만 명확하지 않습니다. 그냥 메시지를 보내고 무슨 일이 일어나는지 신경 쓰지 않습니다. 네, 매우 그렇습니다. 그래서 명확성이 저에게는 정말... '아, 이 명확성이 예상대로 정확하고 구성 가능하도록 해 주는구나'라고 생각했습니다.
마이클 아날디 (52:53)
그리고 명확성에 대해 두 가지 방식으로 접근할 수 있다고 생각합니다. '좋아, 그러면 내 프로그램이 내가 원하는 대로 정확히 작동하는군.'이라고 말하는 사람들이 있습니다. 그리고 저처럼 '프로그램이 완벽하게 작동하는지 신경 쓰지 않습니다. 우리가 신경 쓰는 것은 망가뜨리기 어렵다는 것입니다. 그리고 뭔가를 잊어버리면 IDE에서 0.02밀리초 이내에... 피드백을 받습니다.'라고 말하는 사람들이 있습니다. 그리고 이것이 바로 TypeScript가 다른 모든 것보다 뛰어난 부분이라고 생각합니다. 그냥 거기에 있습니다. 프로그래밍하는 동안 당신을 도와주는 친구와 같습니다.
진행자 - 브루스 에클 (53:42)
명확하게 했고 명확하게 하기 위해 노력했습니다.
마이클 아날디 (53:45)
'오류를 관리하고 싶어요. 어떤 오류를 관리해야 하는지 알려주세요.'라고 말합니다. '오류 1번을 관리하고 싶어요.' '좋아, 오류 1번은 이 오류야. 처리하면 그 오류만 오류 목록에서 제거될 거야.'와 같습니다. 계산에서 단일 오류만 추출하는 catchSome과 같은 함수가 있습니다. 그래서 '네트워크 오류, 데이터베이스 오류, 사용자 도메인 오류로 인해 실패할 수 있는 프로그램이 있습니다.
마이클 아날디 (54:15)
네트워크 오류에 대해서만 재시도하고 나머지는 무시하고 싶습니다.'라고 말할 수 있습니다. 그러면 결과에는 네트워크 오류가 더 이상 포함되지 않지만 다른 두 가지 오류는 여전히 포함됩니다. 마치 당신을 도와주는 친구와 같습니다. 방해가 되는 타이핑이 아닙니다. 이것은 '모든 타입을 선언해야 할까? 모든 타입을 추론해야 할까?'라는 두 가지 생각으로 이어집니다. 저는 강력하게 어떤 것을 제안하지는 않겠지만 추론 우선 방식이 매우 잘 작동한다는 것을 보았습니다.
마이클 아날디 (54:52)
실제로 무엇을 했는지 알 때만 주석을 추가합니다. Effect를 작성하거나 ZIO를 작성하거나... 저는 이 개념이 다른 언어로도 확산될 것이라고 생각합니다. 적어도 전체를 추론하고 '아, 데이터베이스 연결을 사용했으니 이 프로그램은 A 또는 B로 인해 실패할 수 있어.'라고 말하고 VS Code에서 키 바인딩을 사용하여 타입을 자동으로 작성하고 계속 진행하기를 바랍니다. 컴파일러를 적처럼 사용하는 것이 아니라 나중에...
마이클 아날디 (55:27)
작성한 내용을 확인하고 얼굴에 총을 쏘는 친구처럼 사용하는 것입니다. '아니, 틀렸어. 왜 이걸 타이핑하는지 말해주지 않았잖아?'라고 말합니다. 그러면 제가 틀린 것입니다. 저는 이 가벼운 툴체인에서 큰 이점을 봅니다.
진행자 - 브루스 에클 (55:44)
네. 모나드에 대해 언급하셨는데, Effect가 ZIO와 같은 종류의 모나드 모델을 사용한다고 가정했습니다. 맞나요?
마이클 아날디 (55:55)
네, IO 계산을 박싱한 표현입니다.
진행자 - 브루스 에클 (56:01)
그리고 제가 ZIO와 같은 다른 함수형 프로그래밍 시스템에 대해 듣는 불만 중 하나는 모나드를 배우기 어렵다는 것입니다. JavaScript/TypeScript 개발자들이 모나드와 flatMap 등을 이해하도록 하는 데 어려움이 있었나요?
마이클 아날디 (56:24)
이 주제에 대해 감사합니다. 잊고 있었던 주제이지만 매우 흥미로운 주제입니다. 재미있게도, 우리가 먼저 있었다고 말할 수 있는 경우 중 하나입니다. 그리고 저는 모나드 자체에 대해서는... 고전적인 의미에서 모나드에 대해 이야기할 필요는 없다고 생각합니다. async/await을 알고 있나요? 네, async/await을 알고 있다면 그걸로 충분합니다. 그것만 알면 됩니다.
진행자 - 브루스 에클 (57:01)
Scala의 for 내포와 같은 flatMap 체인을 노출하지 않고 다른 것을 사용하나요?
마이클 아날디 (57:12)
우리는 제너레이터 표기법을 사용합니다. 제너레이터 표기법은 async/await과 동일한 기능을 제공합니다. 즉, while을 사용하고 조건 자체에서 await을 사용하여 매번 변수를 변경하고 이펙트를 yield할 수 있으며 오류 타입과 환경 타입을 자동으로 추적하고 빌드합니다. 이제는 약간 장황하고 언젠가는 더 사용자 정의 DSL이나 다른 것으로 바꾸고 싶습니다.
마이클 아날디 (57:49)
하지만 말 그대로 VS Code에서 typegg로 스니펫을 설정하여 제너레이터를 작성하고 yy로 yield를 작성하면 됩니다. yield는 제너레이터 용어로 await과 같습니다. 그리고 Promise를 사용하는 것처럼, 다른 어떤 것을 사용하는 것처럼 프로그래밍할 수 있습니다. 데이터베이스를 호출하고 그다음에 이것을 하고 그다음에 이것을 하고 그다음에 전환합니다. 저는 명령형 프로그래밍을 즐깁니다. 물론 함수가 노출되어 있고 순수하게 절차적인 방식으로 할 수 있는 것은 제한적일 것입니다. 왜냐하면 함수는 고차 함수이기 때문입니다. 하지만 기본적인 것들은 일반적으로 할 수 있습니다. 그리고 저는 아무도 Effect.retry를 사용하고 5번 재시도하고 다른 이펙트를 전달하는 것을 두려워하지 않을 것이라고 생각합니다. flatMap에 대해 전혀 생각하지 않고도 핵심 로직을 작성할 수 있다면... 네, 저는 그것이 승리라고 생각하고 다른 언어들도 그렇게 변화하고 있다고 생각합니다.
마이클 아날디 (58:59)
그래서 저는 Scala가 기대되고 Kotlin이 기대됩니다. 왜냐하면 프로그래밍할 때...
진행자 - 브루스 에클 (59:05)
브루스와 저는 ZIO를 사용하여 이펙트 관련 책을 쓰고 있는데, 일반 ZIO로 시작했습니다. 그리고 몇 달 전에 'ZIO Direct가 정말 흥미로워 보이는데...'라고 생각했습니다. 왜냐하면 저희 책의 독자들이 모나드를 배우고 flatMap을 통해 모든 것을 하고 싶어 하지 않을 것이라고 생각했기 때문입니다. 그래서 ZIO 코드를 절차적으로 보이게 해 주는 ZIO Direct를 사용하기 시작했습니다. 그리고 코드를 ZIO Direct로 마이그레이션하기 시작했고 '언제쯤 '좋아, 이건 망했어. 이건 나쁜 생각이야.'라고 생각하게 될까? 언제쯤 벽에 부딪힐까?'라고 생각했습니다. 하지만 아직 벽에 부딪히지 않았습니다. 그리고 이 시점에서 저희는 거의 모든 책 코드와 실험을...
마이클 아날디 (1:00:01)
3년 안에...
**진행자 - 브루스 에클 (1:00:04)**
...듣게 되어 기쁩니다. 우리보다 먼저 그 여정을 시작했고, 이제 '모나드가 내부에 있다는 것은 좋지만, 모든 사람이 그것을 이해할 필요는 없을 수도 있습니다.'라고 생각하는 위치에 있다는 것을 듣게 되어 기쁩니다.
마이클 아날디 (1:00:24)
사람들은 모나드가 극도로 중요한 것처럼 생각합니다. 네, 이론적으로는 그렇습니다. 실제로 ZIO에서 세 가지 함수를 설명합니다. ZIO에는 약 1,000개의 함수가 있습니다. 네, 모나드에 대해 이야기한다면 실제로는 그 세 가지 함수에 대해 이야기하는 것입니다. 그 세 가지 함수의 조합입니다. 좋습니다. 저에게는 거기서 끝납니다. 가장 흥미로운 것은 실제로 읽을 수 있는 프로그램을 작성할 수 있느냐입니다. 함수형 프로그래밍 개발자들에게...
마이클 아날디 (1:01:04)
코드를 작성하는 방식에 대해 물어보면 재미있습니다. '관련된 데이터 구조, 타입 클래스, 모듈식 인프라가 이런 식으로 데이터베이스를 호출할 것입니다.'라고 말합니다. 그리고 저는 '좋아요, Facebook이 메시지를 어떻게 처리하는지 설명해 주시겠어요?'라고 묻습니다. 그러면 '이것을 하고, 저것을 하고, 이것을 하고, 저것을 하고...'라고 설명합니다. 명령형으로 설명했다는 것을 깨닫나요? 왜 다른 방식으로 작성하고 싶어 하나요?
마이클 아날디 (1:01:42)
50년 동안의 프로그래밍으로 인한 스톡홀름 증후군일까요? 저는 이것이 순수한 방식인지 모르겠습니다. 순수한 방식인지 신경 쓰지 않습니다. 이것이 제가 생각하는 방식입니다. 저는 코드에서도 같은 것을 보고 싶습니다. '이것을 하고, 저것을 하고, 이것이 이러면 이것을 하고, 아니면 저것을 하고...'와 같이요. 패턴 매칭이 있으면 좋겠습니다. 우리는 비슷한 근사치를 가지고 있지만 몇 가지 타협을 해야 합니다. 하지만 실제로 읽을 수 있는 코드를 작성합니다.
진행자 - 브루스 에클 (1:02:25)
네, 도메인 지향적인 것들을 처리하는 능력, 예를 들어 .retry를 추가하는 것처럼요. 물론 flatMap을 사용하고...
진행자 - 브루스 에클 (1:02:41)
...할 수도 있지만, .retry라고 말하는 것이 훨씬 더 도메인 지향적이고 해결하려는 문제를 읽을 수 있습니다. 그리고 네, retry는 flatMap을 기반으로 하고 있으며 flatMap이 내부에 존재하고 이 모든 것의 기반을 제공한다는 것은 좋습니다. 하지만 대부분의 사람들은 도메인 비즈니스 문제 수준에서 코드를 작성하고 있으므로 더 높은 수준의 추상화를 원합니다. 그리고 네, 모나드에 대해 생각할 필요가 없어야 합니다.
진행자 - 제임스 워드 (1:03:12)
저는 Rust가 한 방식이 마음에 듭니다. 왜냐하면 자세히 살펴보면 '아, 여기서 모나드를 사용하고 있고 모나드를 지원하고 있구나'라고 생각할 수 있지만, Rust 커뮤니티에서는 아무도 모나드라는 단어를 사용하지 않습니다.
진행자 - 브루스 에클 (1:03:28)
함수형 프로그래밍 커뮤니티는 모나드를 발견하고 모나드가 얼마나 놀라운지 깨닫는 과정을 거쳤다고 생각합니다. '모나드가 얼마나 놀라운지 알려줘야 해. 왜냐하면 모나드는 너무 놀랍거든.'이라고 생각합니다. 그리고 네, 모나드는 놀랍지만 모든 사람이 그것을 이해할 필요가 있을까요?
마이클 아날디 (1:03:49)
네, 그리고 솔직히 말해서 저는 수학적인 것에 대한 범주 이론적 표현을 좋아하지만, 범주 이론적으로는 의미가 없는 적용 함수와 같은 것들이 있습니다. 함수적 측면에서는 의미가 있지만, 오히려 모노이드적인 것입니다. 곱을 만드는 것입니다. 다른 함수에 적용하는 것이 아닙니다. 그것은 Haskell이 커리되어 있기 때문입니다. Haskell에서 장식된 값을 장식된 함수에 적용하는 방법입니다. 그것은 수학적 표현의 순수성과는 아무런 관련이 없습니다. 그것은 당신이 사용하는 언어를 위한 트릭일 뿐입니다. 우리는 TypeScript에서도 같은 트릭을 사용하고 있습니다. John과 그의 팀은 Scala에서 작동하도록 같은 트릭을 사용해 왔습니다. 저는 Kotlin의 함수형 프로그래밍 라이브러리 뒤에 있는 사람들도 같은 종류의 타협을 하고 있다고 생각합니다. 네, 우리는 모두 언어에 적응하려고 노력하고 있습니다. 말할 때조차도...
마이클 아날디 (1:05:03)
저는 때때로 사람들이 '철학을 하기에 완벽한 언어는 독일어야.'라고 말하는 것을 듣습니다. 특정 주제를 표현하기에 완벽한 언어가 있습니다. 하지만 우리는 모두 의사소통을 합니다. 우리가 사용하는 언어에 최대한 개념을 적용하고 있기 때문입니다. 프로그래밍 언어도 마찬가지입니다. 인간 언어와 크게 다르지 않아야 합니다.
진행자 - 브루스 에클 (1:05:29)
흠, 네, 좋습니다. 마이크, 오늘 정말 즐거웠고 Effect에 대한 통찰력과 노력에 감사드립니다. 이러한 개념을 완전히 다른 개발자 그룹이 접근할 수 있게 되어 기쁩니다. 왜냐하면 저는 당신처럼 이펙트가 개발자의 생산성을 높이고...
진행자 - 브루스 에클 (1:05:57)
더 좋고 안정적인 프로그램을 만드는 데 도움이 되는 좋은 방법이라고 생각하기 때문입니다. 그리고 그것이 세상에 나와서 기쁩니다. 그리고 수백만 명의 개발자들이 앞으로 나아갈 수 있도록 도와주는 훌륭한 일입니다.
마이클 아날디 (1:06:11)
다시 한번 초대해 주셔서 감사합니다. 즐거웠습니다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment