
bgl gwyng
@bgl@hackers.pub · 95 following · 119 followers
GitHub
- @bglgwyng
새로운 한주를 시작하는 귀중한 월요일 아침 시간을 맥북에 커피 쏟은거 수습하는데 쓰고 말았다...
에디터에서의 undo/redo가 그냥 버전관리랑 통합됐으면 좋겠다. 그러니까 undo 한 다음, redo로 다시 돌아가지 않고 다른 수정을 하면, 그 끝점이 anonymous commit 같은 걸로 남는거지.
튜사에 왔는데 몰입형 공간이 꽉차서 더블 모니터를 못쓰는 관계로, 어쩔수없이 오늘은 하스켈을 좀 해야겠다...
1만 * 1만 = 1억 이 상식인줄 알았는데 아닌가 봅니다? 오늘만난 제 문과친구 두 명이 저걸 모르길래 뭐라했더니 저보고 별것도 아닌걸로 잘난척하지 말라고합니다. 상식... 아닌가요?
AI 도움 받아 글쓰기할때 주로 어떤 방식으로 하시나요?
- 클로드 웹. 모델은 좋은데 인터페이스가 글쓰기 최적화는 아닙니다.
- Cursor/Windsurf 등. 모델이 코딩 고문을 당해서 그런가 글을 잘 못씁니다.
내일도 튜링의 사과 출근해야지
1년전에 하스켈로 프론트엔드 개발을 했었다. 프론트엔드 개발의 70% 정도는 state + reactivity를 다루는 것이라고 생각한다. classic FRP를 구현한 하스켈의 Reflex 같은 라이브러리를 쓰면 이 문제를 우아하게 해결할 수 있다. 근데 문제는 많은 프론트엔드 앱이 어엄창나게 복잡한 state를 가지고 있진않고, 그래서 Reflex 없이도 어느정도 만족할만한 코드가 나온다. 아마 에디터나 게임 같은걸 짜면 Reflex의 우월함을 느낄수 있을것이다.
문제는 나머지 30%에 있다. SSR, CSS 등이 거기에 포함되는데, JS 진영에서는 babel 플러그인의 도움을 받는 반칙을 쓰면서 편리함을 제공하고 있다. 여기서 반칙이란건 "use client"
등의 directive와 Tailwind CSS처럼 babel 플러그인이 JS 코드로부터 CSS 클래스 사용을 추출하는 그런걸 의미한다. 반칙이라고 하는 이유는 사실 JS가 아니고 babel로 업그레이드한 JS++쯤 되는 언어를 쓰는셈이기 때문이다. 근데 반칙이고 자시고 암튼 엄청 편하다. 하스켈 쪽에서 근본있는 방법으로 같은 편리함을 달성하려면 매우 힘들고 그걸 사용하는 사람도 공부를 많이 해야할것이다.
오픈소스 레포에 Windsurf Agent로 짠 Swift 코드로된 PR을 날렸는데, 저자의 코드 리뷰를 복붙해서 그걸 그대로 다시 Windsurf Agent한테 전달하고 있다. 이게 머하는 짓이고...
오픈소스에 토큰으로 기여하는 방법을 제공하는 플랫폼이 있나? Buy me tokens?
XCode는 내가 잘 몰라서 못쓰는건지 그냥 구려서 쓰기힘든건지 아직도 모르겠다...
케데헌 히트치는거보고 문득 든 생각
약 20년 전부터, 한국 인터넷 커뮤니티에 '떡볶이 참 맛있는데 외국인들도 좋아하지 않을까?' 이런 의견이 종종 올라왔었다. 근데 그 질문이 올라오면, 얼마 지나지않아 누군가가 '엣헴...서양인들은 떡의 sticky한 texture를 좋아하지 않습니다ㅎㅎ'이라는 답변을 다는걸 볼수 있었다. 내가 이걸 한두번 본게 아님.
근데 그 답변자에게 궁금한건. 그... 님은 떡복이를 실제로 드셔보셨나요? 떡볶이는 약으로 치면 마약이고 SNS로 치면 틱톡입니다. 감자튀김만으로 300파운드까지 벌크업하는 미국인들이 떡볶이에 저항할수 있을거 같으십니까?
아무튼 결국 20년이 지난 지금, 김구 선생님이 바라던 문화 승리를 목전에 두고 있고 떡볶이도 덩달아 인기를 끌고있다. 그동안 떡뽁이를 수출못했던게 그 sticky texture가 결정적인 문제였던건 아닌것으로? 결론은 그래서 '가장 한국적인 것이 가장 세계적인 것이다'는 아니고
인터넷에는 자신의 '오감'을 속여서까지 아무 소리를 당당하게 하는 사람들이 존재한다는 것이다. 당장 '엣헴'을 한번 하기 위해 생각을 포기하고 스스로를 속인다.
언젠가 tuple이란 이름의 (,)
를 로고로 쓰는 서비스를 만들고싶다. 웃긴건 정작 뭐하는 서비스인지는 아직 생각을 안 해놓음;; 대충 사람들을 짝지어주는 데이팅 또는 커피챗 주선 서비스면 이름과 어울리지 않을까 싶은데...
JS에서 Promise는 await으로 값을 읽는 것 외에, 현재 pending 상태를 읽는 등의 동작을 허용하지 않는다. 이거 왜 안되냐고하면 Promise의 의미론과 배경 철학이 어쩌구저쩌구하는 대답이 돌아온다. 내 생각에 그건 틀렸다. 이유는
간단한 대답: 가능하면서 왜 안해줌?
약간더 복잡한 대답
그 제약 조건은 Promise가 callback과 같은 의미의 다른 표현일때는 성립한다. callback이 전달하는 값은 특정시점 = t
에 존재하는 것이다. t
이후에 그 값을 사용하기위해선 따로 저장을 해놓던가해서 값의 존재시기를 >= t
로 바꾸어야한다.
그런데 Promise는 await을 여러번 하는걸 허용한다. await x; await x;
이런식으로. 값이 없으면 기다리고, 값이 한번 들어오면 그걸 계속해서 돌려준다. 여기서 Promise가 callback이랑 다른게 드러난다. 그리고 실제로 callback과 다르게 동작하기위해 값의 여부 등을 내부 상태로 갖고있을수 밖에 없다.
요약하면, callback과 완전히 상호호환될때 정당화되는 제약을 callback이 아니면서 강요하니까 문제란 얘기다.
화제의 케데헌을 봤는데 재밌고 노래가 좋았다. 일종의 마법소녀물인데, 시간이 짧아서 그런지 마법소녀물의 전형적인 설정들을 '다들 대충 알쥐?' 정도로 빠르게 넘어간다. 그래서 오히려 다 보고나서 마법소녀물에 대해 잠깐 생각을 하게 되었는데.
마법소녀물에서는 소녀들에게 의무가 일찌감치 구체적으로 주어지고 소녀들은 그걸 순순히 받아들이고 이행한다.
소년만화에서는 보통 소년들에게 처음부터 의무가 주어지지 않고 그들 스스로 원피스를 찾겠다거나 호카게가 되겠다거나 하고 선언한다. 유유백서나 블리치처럼 의무가 주어지는 경우에도 약간 임시직의 형태로 주어지고, 주인공 쪽에서도 그걸 순순히 받아들이지 않고 반항한다.
마법소녀물이나 소년만화나 대충 각각 공주랑 왕자가 제자리를 찾는 이야기로 볼수 있다.
마법소녀물에서는 주인공에게 의무를 부여할때 공주의 지위도 같이 준다. 예쁜 드레스도 지어주고 집사도 배정해준다(귀여운 애완동물도 겸하는 경우가 많다).
반면 소년만화의 주인공은 결말에 가까워지기 전까지 반지의 제왕의 아라고른처럼 왕자의 신분을 잃어버린 채로 지낸다. 소년만화의 클리셰로 주인공의 존나쎈 아버지가 있는데, 이게 일종의 승계의 정당성을 부여하는 역할을 한다. 그리고 우리 소년 독자들은 그걸 너무너무 좋아한다.
많은 오픈월드 게임이 '정신을 차려보니 어떤 처음보는 공간에 있다가(감옥/실험실/다른 세계 등등) 결국 어찌저찌 세계를 구함' 이런 전개를 따른다. 근데 처음에 시작하는 곳에서 NPC들이랑 언어가 달라서 말이 안통하는 상황으로 시작하는 게임이 있던가? 여태 해본 게임에서는 말이 다 통했던거 같다.
양심고백: Git CLI 와 Gitkraken에 여전히 모르는 기능이 많아, GitHub 또한 일종의 Git GUI로 쓰고있다;;
토욜에 튜링의사과 남은 시간을 마저쓰러 갈듯합니다
아이폰을 쓴지 어언 10년째. 여전히 텍스트 인풋에서 커서를 이동하는 방법을 모른다;;
이미 늦은 제안같지만... 터미널에 뭔가를 보여주는 방법에, 그냥 stdout에다가 출력하는 거랑, TUI 프로그램들이 사용하는 ANSI Escape Sequences가 있다. 전자는 가장 간단하고 무식한 방법이고, 후자는 무제한의 자유도를 제공하는, 그래서 그위에 TUI를 구현할수 있는 방법이다.
나는 그사이에 적당히 구조화된 출력을 할수있는 방식이 있으면 좋겠다. JS에서 console.group
하듯이 말이다. 그래서 출력이 너무 길면 fold/unfold도 할수 있고? 지금 큰 코드베이스에다가 빌드돌렸다가 에러나면 무슨 맥락인지 파악하는데 한세월인데, 그런걸 잘 읽게해주는데 도움이 될것이다.
나는 첫 웹사이트 개발을 C로 했는데(진짜 HTTP 서버를 만듬;;), PHP를 살펴봤다가 너무 배워볼 마음이 안들어서 그때 알고있던 C로 짰다. PHP 해괴한걸 알아본건 잘했는데, 다른 대안을 찾아볼 생각도 안하고(그때도 Java도 있고 Python 웹 서버도 있었음) C로 쓸데없이 차력쇼한건 한심했다. 좀더 똑똑했으면 고생도 덜하기 진작에 좋은걸 많이 배웠을텐데 말이다. 벨 커브 밈이 떠오른다.
RxJS의 cold observable은 처음에 배울때 많이 헷갈린다. 하지만 쓰다보면 익숙해지고 오히려 우아해‘보이는’ 코드를 짤수 있게 된다.
근데 그 우아함이 거짓 우아함이란 생각이 든다. Cold observable은 subscribe
메소드를 이펙트풀하게 만든다. 아닌게 낫지않나? 내가 아는 모든 cold observable 사용은 명시적인 함수 호출(이펙트를 발생시키는)을 하나 추가하는 것으로 피할수 있다.
보통 러닝커브가 있는 기능이 오래 존속하고 있으면 고진감래의 미덕이 있는 법인데 얘는 좀 특이한 경우인듯.
React Native 및 앱 개발 생태계에 대해 욕하고 싶은 사람들이 모이는 연합우주 인스턴스가 있었으면 좋겠다...
요즘 트위터에 하스켈 관련 계정들보면 Go를 가장 싫어하는 언어로 꼽는 경우를 자주 본다. C/C++/Java 등은 역사적인 맥락을 고려해 예우해주고, Python/JS 등등의 이상한 기능은 뭘 몰라서 잘못 만들었다고 이해해주는 반면, Go는 하스켈러들이 중요하게 여기는 가치들을 일부러 다 무시하고 만들기 때문에 괘씸가중치 x10 정도를 적용받는 듯하다.
어제 Phanpy라는 마스토돈 클라를 알게됐고 감탄했다. 이상적인 타임라인 UI야...
잘 못만든 선언형 인터페이스보다는 잘 못만든 명령형 인터페이스가 낫다. 후자는 피똥싸면서 뭔가를 어찌저찌 해낼순 있는데, 전자는 아예 뭔가를 하는게 불가능한 경우가 많다.
내일 모각코가 매우 기대되는구만요
방금 또 빌드 캐시 삭제를 일찌감치 시도해보지 않는 오만함 때문에 1시간을 허비했다ㅠㅠ
하다하다 Prisma의 Rust PANIC도 다 보는구나
PANIC: called `Option::unwrap()` on a `None` value
억까 그만해!!!
그동안 멘토링하면서 느낀게, 나한테 암묵지가 별로 없다는 것이다. 전문가는 암묵지가 많다는데, 나는 내 스스로가 매우 간단한 휴리스틱으로 동작한다고 느낀다. 난 전문가가 아닌건가? 내가 그동안 쌓아온 것은 암묵지라기보단 어떤 특정한 사안에 대한 강한 믿음들인거 같다.
나는 리액트에서 성능 자체가 떨어지는 부분보다(제대로 체감한적 없음), 성능을 고려해서 컴포넌트를 일부러 나눠야하는 점이 더 맘에 안든다.
주말에 튜사 모각코하실분 있나요~
뭔가를 잘 설명하는 방법에 대해 생각해봤는데. 일단 내가 어떤 내용을 말하고 싶은 욕구를 참아내야다. 어떤 재치있는 비유를 꼭 써야겠다거나, 아니면 '통찰'을 전달하고 싶다거나.
대신 상대방의 무지에 공감해야한다. 그 무지란게, 많은 경우 진짜 멍청해서 그런게 아니라, 대충 얼개는 파악하고 있음에도 뜬금없는 부분에서 뜬금없는 오해를 하고 있어서 완전한 이해를 막는다거나 하는 경우가 많다. 그래서 그 귀여운 멍청을 함께 디버깅해야한다. 요게 지식뿐만 아니라 공감능력이 필요한 부분.
크롬 개발자 도구의 네트워크 디버거에, 특정 상황에서(제 경우엔 400 Bad Request 에러 발생) 응답 본문이 빈 문자열로 표시되는 버그가 있는거 같습니다???
역시 하스켈을 가르친 덕택일테지...
마지막 멘티가 취직에 성공해서 기분이 좋구만
코드에디터의 탐색기 동작을 이렇게 개선하면 좋겠다.
지금 큰 프로젝트에서 이파일 저파일 돌아다니다보면 너무 많은 디렉토리들이 expand되어서 필요한 디렉토리를 찾는게 어려워진다. 이때 expand되어 있는 디렉토리중에, 직접 탐색기안에서 찾아서 들어간 경우가 있고, Go to Definition나 방금 닫은 창 다시 열기 등의 간접적인 방법으로 expand된 경우가 있다. 후자의 간접적인 방식으로 열린 파일이 닫혔을때 이로 인해 열린 디렉토리 중 전자의 방식으로 열리지 않은 것을 자동으로 닫아줬으면 좋겠다. 일종의 가비지 컬렉트?
...인데 https://github.com/microsoft/vscode/issues/150869 똑같은 제안이 있었는데 업보트가 부족해서 나가리됐구나ㅠ
내가 Git 쓰다가 왕대빵 커밋 똥히스토리 남기는 전형적인 패턴이다.
- 간단한 기능 A를 추가하려고 한다.
- A를 추가하려면 기존의 설계 B를 고쳐야한단걸 깨닫는다.
- B를 고친다.
- A를 추가한다.
이렇게 3, 4의 변경이 한데 들어가 있는 무근본 커밋이 탄생한다. 2 -> 3 사이에 stash를 하면 간단히 해결되는 문젠데 매번 까먹고 실천을 못한다.
요즘 하스켈 LSP가 너무 느려서 코드 수정하고 저장해서 오토포매팅 기다리는동안(몇초 걸림) LLM이 먼저 나서서 포매팅해준다;;
크런치ㅠㅠ 너무 기대된다ㅠㅠ
Zed는 아직 쓰지도 않는데도 요즘 보기드문 장인정신이 느껴지는 소프트웨어라 호감이 간다. 지금 쓰고있는 Windsurf는 VS Code 포크떠서 AI 채팅만 추가했는데 하루에 3번 터져서 에디터를 재시작해야한다(AI 채팅 패널이 터지는거라 VS Code가 아닌 Windsurf 문제로 보임). 5조 투자받은건 어따썼니??
지금 GraphQL Client로 Altair를 쓰고있는데, 요즘 이런 류의 API 테스트 툴에 살짝 회의가 든다. 쓰다보면 일찌감치 스크립팅을 하고싶어지고 그건 그냥 JS로짜면 된다. API 테스트 환경도 그냥 개발 환경과 같이 관리하면 되서 오히려 더 편하다. Postman은 조금밖에 안써봐서 모르겠다.
오늘 개발은 ! 하나 빼먹은거 못찾아서 귀중한 2시간 날아가고 시작~
펑터를 지하철 노선으로 설명해도 좋을거 같다. 서울의 지하철 노선도를 외우고 있는거랑 서울의 지리에 대해 빠삭한 거랑은 거리가 멀다. 그리고 지하철만으로 서울의 모든 곳을 구석구석 돌아다닐수 없다. 중간에 내려서 걷거나 버스를 타야 한다. 하지만 효율적인 경로를 찾는데 큰 도움이 된다는 사실은 부정할수 없다.
F : 지하철 노선도 -> 서울
에서 F
는 지하철 노선도를 참고해 현실에서 실제로 지하철을 타는 행위가 된다. 우리는 서울의 지하를 돌아다니고 싶어서 지하철을 타는게 아니다. 서울을 돌아다니고 싶은데 여기에 지하철의 도움을 빌리는거다.
프로그래밍도 어떤 경로를 찾는것으로 이해할 수 있다. f : a -> b
란 함수를 구현하는 것은 a
에서 출발해서 b
에 도착하는 길을 찾는 것이다(도착만 한다고 장땡이 아니란 점에서(=타입만 맞는 쓸모없는 함수를 구현하기) 위에서 든 지하철 비유랑 갈라지기 시작한다).그런데 함수(경로)는 무수히 많고 그중에 내가 원하는걸 하나 찾아내는건 어려운 일이다. 이때 좀더 단순한 이해하기 쉬운 지도와(다른 카테고리), 그 지도를 따라서 움직이는 방법(펑터)를 알고있으면 도움이 된다. 펑터 F : C -> D
는 D
라는 넓은 영토를 돌아다닐때 C
라는 지도의 도움을 받는 방법으로 볼수있다.
한 2년전부터 XState 대충 알고 쓰면서 느끼는 점들.
-
처음부터 정의가 verbose하고 그걸 작성하는게 수고로운건 알고있었다. 하지만 LLM을 믿고 쓰기로 결정했는데, 지금 2025년에도 여전히 LLM이 상태머신 설계를 잘 못한다. 얘한테 설계를 맡겨놓으면 뭐랄까, 성의가 없다고까지 느껴진다. 왜 그런거지?
-
Snapshot은 subscribe할 수 있다. 근데 그 Snapshot을 유발한 Transition이 같이 전달이 안된다. 사실 이게 필요했던 핵심 기능이었어서 이게 안된다는걸 알고 매우 당황했다. Transition에 반응하는건 오로지 상태머신 내에 설계된 action을 통해서만 가능하고, 상태머신을 구독하는 쪽에서는 안된다. 왜 이렇지?
-
상태머신을 확장하는 방식이 제한적이다. 이미 정의해놓은 action, actor들을 다른걸로 override하는 방식을 제공하는데, 상속 비스무리하다는 점에서 한계가 느껴진다. 실제로 사용하면서도 그 한계를 느꼈다.
종합하면 아직까진 수지타산이 안 맞다.
요즘 '이건 잘못된 코드지만 당분간 고칠일이 없기를 기도하자'고 하며 넘어간 코드들에서 나온 버그들을 계속 고치는 중이다.
과거의 나의 정확한 안목에 뿌듯해하며 동시에 피눈물을 흘리고 있다.
데이터에 대한 modality, 가령 동기/비동기, 더 나아가 캐시됨, 캐시되었지만 stale됨 등에 대해 일반적인(polymorphic) 함수를 만드려면 HKT가 필요하다. Relay와 같은 현존하는 JS 상태관리 라이브러리들은 저런 modality를 한번에 다 지원하는 대신, 확장에 열려있지 않는 구조로 되어있다. 타입을 제대로 지원못한다고 해서 구현을 못하는건 아닐테니, HKT 없음이 주된 이유는 아니겠지만 말이다.
최근 TS 코딩중에 async/sync에 대해 polymorphic한 인터페이스를 제공하려하다보니 HKT의 필요성을 느끼게 되었다. 해결책은 그냥 synchronous만 제공하기로;;
라이브러리를 좀 대국적으로 만드십시오!!!