2024. 06. 16., 경북 포항시 남구 효자동길10번길 32.

맑은가 싶다가도 이내 흐려져서

일어난 것은 8시였습니다. 엄마는 나에게 샐러드를 내어줬고 나는 다소 인상 쓴 표정을 취할 수 밖에 없었습니다. 엄마는 기억하지 못하는 것 같았습니다. 양상추와 닭가슴살을 그릭 요거트로 비벼낸 같은 모양의 샐러드를 먹고 급성 장염으로 응급실에 갔었던 적이 있었다는 사실을요. 이번에는 그러지 않을 것이라는 것을 알면서도 혹시라도 포항으로 올라가는 버스에서 고통스러운 시간을 보내게 될 수도 있지 않을까 걱정했습니다.

캐리어 하나가 있다는 핑계로 지하철 대신 택시를 택했고 나는 꽤나 여유롭게 나갈 준비를 할 수 있었습니다. 포항에 가는 버스를 기다리며 몇 가지 메시지를 처리했습니다. 교수님께 미팅 시간을 제안해두었어요. 카이스트 쪽에서 제안한 수정 사항을 출근하면 처리할 것이라고 말해두었어요. 출근을 두 세시 께에나 하게 될 것이라고는 말하지 않았습니다.

버스에서 웹툰만 뒤적거리던 찰나에 이제는 진짜 미궁을 개발하기 시작해야겠다는 생각이 들었습니다. 남은 시간만 두고 보면 꽤나 여유로운 편이었지만 나에게 주어진 작업들이 여유를 허락해주지는 않은 터였습니다. 이번주 내로 기능을 완성해서 최소 한 두달간은 신경쓰지 않아도 되는 상태로 만들어놓기로 다짐했습니다.

이번에는 Kysely를 써보려고 합니다. ORM에 있어서 극렬히 Prisma를 선호하는 사람이지마는 크게 만족하지 못한 탓에 늘 새로운 ORM을 찾고 있었습니다. 처음 고려한 대상은 Drizzle이었습니다만 몇 번의 검색을 통해 타입 지원이 시원찮다는 사실을 알 수 있었고— 더 나아가 Kysely를 추천하는 사람들을 몇몇 볼 수 있었습니다. Kysely는 ORM이 아니라 타입 시스템에 기대는 쿼리 빌더입니다만 나는 그 부분이 마음에 들었습니다. 데이터베이스 쿼리부터 오브젝트의 구성까지 책임지는 ORM과 달리 쿼리를 내가 직접 구성하면 실행 결과로 타입이 잡힌 오브젝트를 반환하는 구조였습니다. ORM 라이브러리에 비해 현저히 작은 라이브러리의 책임과 더 좋은 타입 지원은 나를 유혹하기에 충분했어요.

Kysely를 이용하기로 결정한 이후로 시작한 일은 SQL 라이브러리를 찾는 일이었습니다. Kysely는 태생이 쿼리 빌더이다보니 SQL 라이브러리가 필요했습니다. 이번 포카전 미궁은 모두 클라이언트 사이드에서 동작할 수 있도록 만들 작정이었기에 나는 브라우저에서 인메모리로 실행시킬 수 있는 SQLite 라이브러리를 찾아나섰습니다. Sql.js가 그 적임자로 나타났으나 그를 Kysely와 연결짓기 위한 dialect 라이브러리가 없음에 한숨을 내쉬었습니다.

생각과 검색이 여기까지 다다랐을 때 나는 버스에서 내렸어야만 했습니다.

2024. 06. 10., 경북 포항시 남구 청암로 77.

짐을 정리하면서 나는 꽤나 많은 가을 옷들을 발견할 수 있었습니다. 분명 이번에 본가에 가면서 다 챙겼다고 생각했는데. 이 참에 옷 정리를 다시 시작했습니다. 더워진 날씨에 절대로 입지 않을 것 같은 옷들은 박스에 넣었어요. 박스에 넣으면서 남은 공간에는 옷장 밖에 걸어둔 여름 옷들을 옮겨두었습니다. 청바지들을 모두 말아서 옷장에 넣었습니다. 대책없이 건조대에 널려있던 수많은 옷들을 옷장에 넣을 수 있었고 방이 훨씬 쾌적해보일 수 있었습니다.

포항에 도착하자마자 연구실에 출근할 작정이었으나 정리를 하고 보니 3시였습니다. 카이스트에서 요청한 수정 사항을 반영해서 푸시하고 교수님과의 미팅에 들어갔습니다. 과제 프로포절에 관련한 미팅이었지만 그 과정이 그렇게 순조롭지는 않았습니다.

실험을 돌리는 틈을 타서 5월 가계부를 정리했습니다. 장학금 덕분에 마이너스를 가까스로 피했어요. 아껴 쓰는 습관이 없는 탓에 항상 적자에 시달리고 있습니다. 야식만 줄이면 돈도 아끼고 살도 뺄 수 있을텐데 나는 왜 그것을 하지 못하는지 모르겠습니다. 나에게 무슨 문제가 있는 것일까요.

이번주 세미나에서 다룰 페이퍼들도 찾아봤습니다. 한 번의 세미나에서 2개의 페이퍼를 다루는 탓에 페이퍼를 고르는 것부터 난관입니다. 교수님께서는 서로 연관이 있거나 반대되는 페이퍼를 고르기를 원하시지만 그렇게 서치하는게 보통 일이어야죠. 나는 여느 때와 같이 매력적인 제목의 논문 두 편을 골랐습니다. 그 중 하나가 어펜딕스에 있는 증명을 포함해서 42페이지 짜리인 줄 알았다면 고르지 않았을텐데 말이죠.

이번주 랩 청소에서 청소를 감독하는 담당이었지만 꽤나 나사가 빠진 상태였습니다. 우리 랩에서는 청소를 시작하기 전에 이번주 담당 사람들이 모두 왔는지 확인합니다. 하지만 오늘따라 많은 사람들이 보이지 않았고 나는 총 3명의 사람들을 확인할 수 없었습니다. 별도로 다시 확인하지 않고 무단 결근을 보고하였으나 그 중 2명의 사람들은 무고했음을 확인할 수 있었고 나는 약간의 부끄러움을 느낄 수 있었습니다.

퇴근을 하고서는 버스에서 하던 궁리를 이어나갔습니다. 클라이언트 사이드에서 돌리기를 포기해야하나? 그러면 그냥 프리즈마를 써야하나? 아닌가 Kysely에 psql 조합을 선택해야하나?

나는 최종적으로 Kysely를 위한 sql.js dialect를 직접 개발할 것을 결심할 수 있었습니다. Dialect가 어떻게 구성되는지 알아보기 위해 PostgreSQL dialect의 구현을 확인해보았고 크게 어렵지 않음을 깨달을 수 있었어요. 큰 노력 없이 sql.js dialect를 만들 수 있었습니다. 몇몇의 유닛 테스트를 구성한 이후에 NPM에도 kysely-sql-js라는 이름으로 퍼블리시를 했습니다. 내가 퍼블리시한 첫 패키지예요.

2024. 06. 10., 경북 포항시 남구 청암로.

정말 오래간만에 러닝을 했습니다. 8km를 뛰었고 태우는 중간에 스스로 낙오를 선택했습니다. 화장실 때문에. 나는 태우가 따라올 수 있도록 카카오맵으로 위치를 공유해둔 상태로 러닝을 계속했고 덕분에 우리는 중간에서 접선할 수 있었습니다.

학식을 먹고 연구실에 출근하자마자 동기에게 괜찮은 제안을 들을 수 있었습니다. 오늘 러닝을 같이 하자는 제안이었어요. 평소에 이런 러닝 약속을 잡지 않으면 밤에 계속 야식을 먹게 되는 탓에 나는 반갑게 제안을 수락했습니다.

주최 측에서 문제의 포맷을 바꿔서 새로 배포했습니다만 확인해보지 않은 채로 우리 팀에 내 시스템을 공유했습니다. 오늘에서야 불안함을 느낄 수 있었습니다. 바뀐 포맷 위에서도 잘 동작하는지 이제서야 확인해보았습니다. 역시나 제대로 작동하지 않았어요. 제대로 작동하게 만드는데 꽤나 많은 시간을 쏟아야만 했습니다.

세미나 슬라이드도 만들기 시작했습니다. 두 페이퍼 중에서 “CodeFusion: A Pre-trained Diffusion Model for Code Generation”에 대한 슬라이드를 먼저 만들기 시작했습니다. 분량이 여섯 쪽 밖에 되지 않았거든요. 선행 연구에 많이 기대고 있음을 페이퍼를 읽을 때에서야 확인할 수 있었고 나는 두번째 페이퍼로 선행 연구를 골랐어야했음을 직감했습니다.

2024. 06. 11., 경북 포항시 남구 청암로.

동기는 기숙사 1층 현관에서 기다리고 있었습니다. 나에게 거리를 물어보았고 나는 5km라고 답했어요. 마음 같아서는 8km를 달리고 싶었지만 어제 8km를 뛴 탓에 무리하지는 말자는 생각이 앞섰습니다. 평소에 5km를 뛸 때에는 530에서 545 정도의 페이스를 유지하는 편 입니다. 하지만 동기가 너무 힘들어해서 평소보다 훨씬 천천히 뛸 수 밖에 없었습니다. 분명 저번에 동기와 함께 8km를 뛸 때는 이렇게까지 힘들어하지 않았던 것 같은데.

2024. 06. 12., 경북 포항시 남구 청암로 77.

아침 미팅에 들어가서야 이번주에는 세미나를 쉰다는 사실을 알 수 있었습니다. 한 사이클을 돌고 한 주는 쉬기로 이전에 결정했었는데 내가 그 사이클의 시작임을 잊고 있었어요. 교수님께서는 이번주에 하나를 하거나 다음주에 두 개를 하는 것 중에 고를 수 있도록 제안해주셨고 나는 다음주에 두 개를 다루기로 결정했습니다.

미팅이 끝나자마자 후회했습니다. 어제 준비하던 슬라이드를 모두 완성할 수 있었거든요. 이번주에 한 개 하고 때울걸 그랬습니다.

랩에 신입생 분이 들어오셔서 점심 식사를 같이 하고 싶었는데 사라지셨어요. 동기 분들도 어디론가 각자 사라졌습니다. 나는 랩에 남아있는 한 명의 선배에게 식사를 제안했고 덕분에 함께 학식을 먹을 수 있었습니다.

가방을 매고 나서는 나에게 퇴근하는 거냐고 물어보셨어요. 늦잠을 자서 씻지 못한 탓에 내려간 김에 씻기도 할 것이라고 제 발 저리면서 대답했습니다.

2024. 06. 12., 경북 포항시 남구 효자동길10번길 25 2층.

점심 식사 후 퇴근을 하지 않았습니다만 그렇다고 연구실로 출근하지도 않았습니다. 티타에 출근했습니다. 나는 아이스 아메리카노와 함께 코코넛 젤라또를 주문했고 그 모습이 꽤나 더워보였는지 사장님께서는 덥냐고 물어봐주셨습니다.

포카전 미궁을 위한 라이브러리를 작성했습니다. 웹 어플리케이션 서버 없이 정적 파일로만 구워낼 작정이었고 나는 수학의 힘을 빌렸습니다. 미궁이라는 것이 사실 노드와 엣지로 구성된 유향 그래프임에서 착안했어요. 특정 노드에서 어떤 답을 맞추면 그 답에 상응하는 노드로 이동하는 구조입니다. 나는 이 과정이 서버 없이도 일어날 수 있도록 설계했습니다.

클라이언트는 미리 렌더링 해 둔 문제 페이지에 접근하게 됩니다. 그 페이지에는 (해시된 정답, 정답으로 암호화 된 다음 문제로의 링크)들이 기록되어 있어요. 사용자가 답을 입력하면 그 해시가 존재하는지 확인하고 존재한다면 정답으로 복호화해서 다음 문제로의 링크를 얻게 됩니다. 이를 통해 서버 없이 브라우저에서 정답을 검증할 수 있게 되는 것이죠.

이 시나리오를 구현하는 막바지에 사장님은 쇼케이스의 불을 끄고 계셨고 시간은 8시였습니다. 나는 동아리방으로 자리를 옮겨서 구현을 계속했습니다. 동방에 있던 와장에게 위 시나리오를 검증받았고 나는 블록체인 같다는 평가를 받을 수 있었습니다.

2024. 06. 12., 경북 포항시 남구 청암로 77. 2024. 06. 12., 경북 포항시 남구 청암로 77.

와장은 침착맨 방송을 보면서 페이퍼를 읽고 있었고 침착맨이 오래간만에 히오스를 하는 모습을 볼 수 있었습니다. 우리 둘 다 같은 생각이 들었어요. 이거 저격할 수 있겠다. 우리는 파티를 맺고 조합을 맞춰서 몇번의 시도를 감행했고 끝끝내 침착맨이 포함된 스트리머 4인큐와 함께 게임을 할 수 있었습니다. 이런 경험은 처음이라 당황스러우면서도 재밌었어요. 그 뒤로도 한번 더 같이 해볼거라고 밤 12시까지 몇 번 더 시도해보았고 그런 일이 다시는 벌어지진 않았습니다.

2024. 06. 13., 경북 포항시 남구 청암로 77.

효자시장에 도착했지만 한참을 서성였습니다. 어떤 카페에 가야할 지 정하지 못한 상태였어요. 티타가 무난하게 좋은 옵션입니다만 어제 이미 방문한 탓에 다시 방문하고 싶지는 않았습니다. 달팽이 책방도 내가 좋아하는 공간이지만 본질적으로는 책방이다보니 본격적으로 타이핑을 하기에는 부담스러워요. 바르벳은 코딩을 하기에 괜찮은 공간이지만 나는 이상하리만치 큰 카페에 대해 거부감이 있습니다. 결국 끝의 끝에 나는 커들러에 갈 것을 결심할 수 있었습니다. 들어서자마자 사장님은 나에게 돌아다니는 모습을 보았다며 말을 걸어주셨습니다.

커피를 주문하려고 했는데 원두가 없대요. 어제 주문했는데 아직 오지 않았다고 합니다. 사장님께서는 대신 아껴둔 볼레로를 내어주셨습니다. 메뉴판에서 없어져서 아예 없는 줄 알았는데 몇 개 남아있었대요.

어제 개발해둔 라이브러리를 리팩토링했습니다. 어제 와장에게 말로 설명을 하면서 느낀 부분들을 반영했어요. Edge 테이블에서 답을 나타내는 칼럼 이름을 proof로 변경했습니다. 출발 노드와 도착 노드를 각각 fromto로 명시해두었는데 명사가 아닌 점이 마음에 들지 않아서 각각을 sourcetarget으로 변경했어요. 이 외에도 구글 스프레드시트에서 데이터베이스를 구성할 수 있도록 하는 등 여러 기능을 추가했습니다.

2024. 06. 13., 경북 포항시 남구 효자동길10번길 18 1층 101호.

한참 코딩에 집중하고 있는 와중에 사장님께서 같이 보드게임을 하자며 환기를 시켜주셨고 나는 당장에 함께 했습니다. 처음에는 스플렌더를 했어요. 나는 스플렌더를 정말 못하는데 사장님께서는 정말 잘하십니다. 그래서 연습도 할 겸 한 판을 했고 나는 또 패배를 맛볼 수 밖에 없었습니다. 사장님께서 다음 게임으로 클루를 제안하셨습니다. 고등학교 수학여행 때 한 두 판 정도를 해본 이후로 해본 적이 없었기에 나는 호기심으로 제안을 수락했어요. 확실히 클루를 플레이할 때에는 4명 정도는 있어야겠다는 생각이 들었습니다. 2명에서 하니까 너무 쉬워져버리네요.

그러고서 나는 사장님에게 8월이 되면 장사를 접을 것이라는 소식을 들을 수 있었습니다. 오늘 볼레로를 결제할 때 내 말도 듣지 않고 포인트를 다 써버리시길래 이상하다고 생각했는데 그런 이유가 있었던 탓이었나봅니다.

보드게임이 끝나는대로 나서는 나에게 마시멜로 샌드쿠키를 쥐어주셨습니다.

2024. 06. 13., 경북 포항시 남구 효자동길6번길 25-1 1층.

베라보에 방문했습니다. 처음에는 저녁을 먹을 생각이 없었어요. 하지만 낮에 헤일리와 전화 통화를 하면서 베라보 이번 특선이 카레 라멘이라는 사실을 알 수 있었습니다. 카레라니. 꼭 방문해야겠다는 생각만이 나를 감쌌습니다. 방학이라 그런지 손님들이 많이 없었어요. 사장님들도 어딘가 차분한 분위기였습니다. 하지만 라멘은 카레만큼 정직한 맛을 선보였고 그 뒤에 비벼먹는 밥은 디저트로 충분했습니다.

동아리방에서 프리뷰를 위한 미궁 프론트엔드를 만들었습니다. 포준위 위원들이 손쉽게 미궁 문제들을 작성하기 위해서는 미리 볼 수 있는 기능이 있으면 좋겠다는 생각이 들었거든요. 프리뷰를 위한 기능은 모두 완성한 채로 UI를 구성하는 단계에 다다랐습니다. 사람들이 다들 @shadcn/ui를 찬양하길래 써보았는데 나에게는 잘 맞지 않았습니다. 복사 붙여넣기를 하면서 개발하는 경험이 나에게는 썩 좋은 DX로 여겨지지 않았어요. 몇번의 시도 끝에 나는 Radix를 대체제로 선택했습니다. Styled component를 정말 싫어하는 편인데 막상 써보니까 나쁘지 않은 것 같습니다.

느지막히 일어나 병원으로 향했고— 한 가지 결심을 한 탓에 항갈망제를 처방받을 수 있었습니다.

포항의 버스 시간에도 점점 익숙해지고 있어요. 오지 않는 버스를 기다리며 버스 정류장에서 시간을 보내기보다 근처 올리브영이나 다이소에 들어가서 구경하는 쪽을 택하기로 했습니다. 이번에는 버스를 기다리면서 올리브영에서 시간을 보냈습니다.

데오드란트와 헤어 에센스를 샀어요. 원래 뿌려서 쓰는 헤어 에센스를 쓰고 있었는데 본디 용도와는 다르게 손에 뿌려서 머리에 바르고 있습니다. 마침 다 써 가겠다 같은 라인의 제품이지만 발라서 쓰는 쪽으로 제형을 바꿔보기로 했습니다.

2024. 06. 14., 경북 포항시 남구.

효자로 향하는 버스를 탔고 나는 버스 손잡이에 끼워져 있는 다섯개의 인형을 발견할 수 있었습니다. 예상치 못한 곳에 있는 인형들이 귀여웠어요.

2024. 06. 13., 경북 포항시 남구 효자동길10번길 25 2층.

티타에서 미궁 프론트엔드 작업을 티타에서 마저 했습니다. 어차피 tailwind를 쓸 심산이라면 @shadcn/ui가 더 낫겠다는 생각이 갑자기 들었어요. 당장에 Radix로 작성한 UI를 날리고 다시 작업을 시작했습니다. 더 괜찮은 결과물을 볼 수 있었고, 복사 붙여넣기를 이용하는 DX가 그렇게 나쁘지 않음을 깨달을 수 있었습니다.

2024. 06. 14., 경북 포항시 남구 청암로 77.

카페 마감 시간이 되어서 나는 동아리방으로 자리를 옮겼습니다. 카드 프로텍터를 장착하고 있는 부우와 와장을 발견할 수 있었어요. 정령섬이라는 보드게임의 DLC가 도착해서 준비를 하고 있는 것 같았습니다. 나는 룰북을 달라고 했지만 30페이지라는 두께에 압도되어 읽기를 포기하고 설명을 부탁했습니다. 초행에 잘 이해되지 않는 부분들도 있었지만 꽤나 재밌게 플레이할 수 있었고 우리는 3시간의 플레이 끝에 침략자들을 무찌를 수 있었습니다.

역시 협력하는 보드게임이 더 재밌는 것 같아요.

이번에 개발해둔 미궁을 내년에도 쓸 수 있도록 라이브러리 코드와 프론트엔드 코드를 분리해서 작성하고 있었는데 디렉토리 구조가 썩 마음에 들지 않았습니다. 프론트엔드 프로젝트 안의 디렉토리에 라이브러리가 있어서 재사용성을 염두에 두었다고 말하기에는 무리가 있었어요.

짧은 생각 끝에 모노레포로 구성하면 되겠다는 생각이 들었습니다. 마침 지금 사용 중인 자바스크립트 런타임인 bun에서 workspaces를 지원하기도 했고요. 그냥 단순히 코드를 옮기기만 하면 되겠거니 생각했는데 옮기면서 리팩토링을 하다보니 생각보다 많은 시간을 쓰게 되었습니다. 한 6시간 쓴 것 같아요.

그리고 나는 어떤 패키지에서 re-export한 타입을 다른 패키지에서 import 하면 타입이 any로 날아간다는 사실을 배울 수 있었습니다. 이렇게나 부자연스러울수가. 타입스크립트의 언어 규격은 정말 마음에 들지만 패키지 에코시스템에 불만이 많은 편입니다. tsconfig.json이나 package.json의 옵션에 따라 패키징 동작이 치명적으로 달라지는 편인데도 설명이 잘 되어있지 않아서 설정을 해야할 때마다 너무 고통스러워요. 혹시나 브라우저를 위한 라이브러리를 배포해야한다면 그 고통은 수십배로 증가합니다. 정말 이거 생태계 어떻게 안될까요.

2024. 06. 16., 경북 포항시 남구 청암로 77.

2024. 06. 16., 경북 포항시 남구 효자동길10번길 32.

맑은가 싶다가도 이내 흐려져서

먹구름이 금새 파랑을 몰아내고 비를 게워냈습니다. 무엇이 그렇게 서러운지 천둥과 번개를 울부짖더니 금방 또 멎었습니다. 솔직한 표현에 마음이 풀어진 탓이겠거니.

감정을 정직하게 표현하지 못하는 나의 모습에 기대어 약간의 비난을 던지고 싶었습니다. 질투의 감정이었음을 깨닫기 위해서는 생각이 필요했습니다.


권민재

WWW 사이버디지탈 COM