@hong_minhee洪 民憙 (Hong Minhee) '맞팔로'라는 레이블이 저는 좀 헷갈리는거 같습니다. 그동안 '맞팔로'라고 뜬 사람들이 '맞팔로'가 되어있는 상태인줄 알았습니다. 그래서 팔로를 안하고 있었는데요. 팔로/언팔로랑 달리 동작인지 상태인지가 헷갈리네요.

bgl gwyng
@bgl@hackers.pub · 87 following · 107 followers
슈티를 함께 만들 팀을 만들고 있습니다. 관심 있으신 분, 또는 잘 모르겠지만 이야기를 나눠보고 싶은 분도 bgl@gwyng.com으로 편하게 연락주세요.
GitHub
- @bglgwyng
shootee
- www.shootee.io
옛날에 만들어놓고 저 혼자는 잘쓰고 있는 React 폼 라이브러리 react-form-mozard를 소개합니다.
폼 중에서 Stepper 또는 Wizard라고 하는, 여러 개의 폼을 순차적으로 합친 형태를 다룰때 씁니다. 그래서 하나의 폼에 대해서는 react-hook-form 등 을 쓰고, 그걸 여러개 조합할땐 react-form-mozard를 활용하면 됩니다.
순차적으로 합친 에서 느낌이 오지요? 모나드가... 그대를 부릅니다...
폼 말고 CLI를 만들때를 잠깐 생각해보죠.
const name = prompt("이름이?")
const age = prompt(`{name} 님, 나이가?`)
if (Number(age) < 20) {
console.info("미성년자는 이용할 수 없습니다")
return
}
const gender = prompt(`{name} 님, 성별이?`)
뭐 이런 흐름을 생각해볼 수 있는데요. 보시면 먼저 받은 입력값에 따라 이후의 메시지나, 제어 흐름이 달라질 수 있습니다. 즉, 모나딕하죠. 근데 이런 평범한 로직을 Stepper/Wizard 에서 짜게되면 코드게 쉽게 더러워 지는걸 알수 있습니다.
react-form-mozard의 step
은 위 예제의 prompt
와 같은 역할을 합니다. 그리고 그걸 Generator 위에 얹으면 모나딕한 폼 합성이 가능해집니다.
단점이라면... 지금은 React랑 강결합 되어 있어, XState 등 다른 상태관리 라이브러리를 같이 쓴다면 연동이 깔끔하지 않을수 있습니다. 근데 평소에 쉽게 겪을 문제는 아니라고 보고, 또 추후에 설계를 수정해서 개선이 가능한 부분입니다.
다들 개발할때 '하느님 제게 왜 이딴 시련을 : 하느님 이런 흥미로운 문제를 풀 기회를 주셔서 감사합니다'의 비율이 어떻게 되시나요? 저는 근 몇달간은 거의 99:1에 육박하는거 같습니다
Nix 기반의 인프라 관리에 관심있으신 Go 고수분 계시다면 nix-snapshotter에 관심 가져보시는걸 추천드립니다. 지금 메인테이닝이 살짝 안되고있는데 기여자가 많아지면 좋겠네요.
얼굴인식 사진공유 카메라앱 슈티를 함께 만들 분을 찾습니다. 앱은 출시되어 있어 써보실수 있습니다. 이번달 내로 페디버스 연동을 끝내면 제가 생각한 MVP는 완성입니다. 앞으로도 개발해야할 부분들이 많고, 개중에 기술적으로 흥미로운 문제들도 다수 있습니다.
지금 2025년 상반기 투자유치를 목표로 팀 빌딩을 하고 있습니다. 관심 있으신 분, 또는 잘 모르겠지만 이야기를 나눠보고 싶은 분도 bgl@gwyng.com으로 편하게 연락주세요.
높은 목표를 가진 개발자라도 결국엔 아주 사소한 동기로 움직이는거 같다.
나같은 경우엔, 완벽한 프로그래밍 언어를 만드는 것이 목표인데(가능한지는 차치하고), 완벽하다는건 나말고 다른 누군가가 같은 문제 의식을 가진다면 똑같이 그곳에 다다를 거란걸 의미한다. 그 프로그래밍 언어의 설계에서 내 마음대로 결정할수 있는 부분은 없을 것이다. 설계에서 최적의 선택지만을 택해야 완벽할테니까 말이다. 그때가선 그 선택들이 너무 자명해서, 내겐 처음부터 선택의 여지가 없었다고 느낄것이다.
그럼에도 내가 결정할 수 있을 부분이 있기는한데, 그 언어의 이름에 뜬금없이 우리집 강아지 이름을 붙인다던가 하는 것이다. 이게 그 사소한 동기다.
그동안(10+년;;) git이 엄청 잘만든 물건 같지는 않다고 생각하며 대충 쓰고있었는데, 요즘 branch 개념 자체가 근본적인 실수란 생각이 들기 시작했다. branch 대신에 변경의 시작과 끝, 양 끝점을 가지는 interval을 쓰는게 맞는거 같다(카테고리 이론의 작은 교훈: primitive는 양 끝점을 가지는게 좋다).
git을 쓰면 히스토리 길어진다고 squash merge 등을 하는데, (나도 하지만) 사실 기껏 만들어놓은 히스토리를 뭉개버리는 말도 안되는 동작이다. 만약 interval을 쓴다면 히스토리는 그대로 남기고 UI 단에서 fold/unfold 등을 해줄수 있을 것이다.
Darcs 등이 interval에 기초하는데, 지금은 일이 너무 바빠서 시도할 여유가 없다. 한번 숨고를 시간이 주어지면 멀쩡한 VCS를 탐색하는 시간을 가질것이다.
uv2nix는 uv보다 구리고, cabal2nix는 cabal보다 구린데, Nix는 uv + cabal + ... 보다 낫다. Nix 커뮤니티를 키우려면, 후자를 이해시키고(쉬움) 전자에 대해 익스큐즈하도록 설득해야한다(어려움) .
시간이 좀 지나서 그런가, 이제 계엄자체는 그냥 또라이가 또라이짓했다 정도로 생각되는데, 그 이후 탄핵 과정에서 뭔 말같지도 않는 어거지를 부리는거 때문에 자꾸 스트레스받는다.
그동안 동료들한테 Cursor 쓰자고했는데 그들이 오소독스 Emacs 매니아들이란 문제가 있었다.
작년에 Nix로 nvidia gpu 지원까지 포함해서 구축해놓은 k3s 클러스터에다가, 오늘 아침에 1시간만에 aider로 쓸수있게 DeepSeek R1을 띄웠고 한번 써보자고 했다. 최근에 한 것 중 가장 가성비 좋은 작업인듯 하다.
@campanulaLuminα 저의 경우는 React Native라서 백엔드로 SQLite를 쓰고 있어서 괜찮습니다. 생각해보니 RxDB 등의 경우는 웹도 지원해야해서 join을 지원하는게 어려울거 같긴하네요.
JS로 짜여진, join이 되는 reactive한 로컬 DB가 필요한데요. RxDB, SignalDB는 join이 안 돼서 탈락입니다. join을 안하면 되지 않냐 할수 있는데 어떤 특이한 로직 때문에 꼭 필요합니다. 지금은 직접 sqlite 호출하는 누더기 코드로 돌아가고 있는데요.
그 코드를 리팩토링해서 제대로 된걸 만들까 말까 고민중인데, 사실 잘만들어진게 있으면 그걸 쓰고 싶습니다. 제 요구사항을 만족하는 라이브러리가 있을까요?
영어권 웹을 보다보면 autism이 한국어에서의 '자폐'보다 부정적인 늬앙스가 훨씬 덜하단 느낌을 받는다. STEM 너드들이 본인이 autistic하다고 하는 경우를 종종 보는데, 자조적인 느낌이 좀 있지만 완전 딥다크한거 같진않고, 이분법적이기보단 스펙트럼으로 보는거 같다.
https://snix.dev/ 저는 Rust를 못해서 기여를 못하지만 유망한 프로젝트라고 생각합니다. Rust 고수분들이 관심가져주시면 좋겠네요.
바둑에 '묘수 3번두면 바둑은 진다'라는 말이 있는데, 프로그래밍에 비슷한 말이 있을까요
Nix를 보며 알수있는건, 사람들이 메타프로그래밍을 하기 좋은 언어로 메타프로그래밍을 하는게 아니라, 런타임이 좋은 언어로 메타프로그래밍을 한다는 것이다.
Nix의 런타임이 좋다는건 일반적인 의미에서(성능이 빠르다거나) 좋다기보다는 '재현가능한 캐싱되는 빌드'라는 런타임이 아주 많은 동작을 커버하는데 Nix가 그걸 구현했다는 얘기다. 그러니까 사람들은 큰 프로그램을 쌓아올릴 대들보가 될만한 런타임이 있으면 거기서 부터 메타프로그래밍을 시작해버린다. Nix가 언어는 구리고(애초에 엄청 잘만들려고 한거같지도 않음) 메타프로그래밍을 잘하기위한 어떠한 장치도 없음에도 가장 아래에 위치할수있어서 그 역할이 맡겨져버린다.
그래서 유용한 런타임과 오브젝트 언어(또는 DSL)을 표현할 문법에 대한 좋은 아이디어가 있으면, 좀더 나은 메타프로그래밍을 하기위한 언어를 만들수 있을거라고 생각한다.
사실 알고보니 이것도, 저것도 모나드였다... 하는 예시는 많은데 Category
의 예시는 뭐가 있을까? 그럼 설명이 훨씬 편해질텐데 말이다.
좀 인위적이지만 쉬운 예시를 하나 만들어보자면, 어떤 함수의 실행에 비용을 부여하는 것이다.
data Costful a b = Costful (a -> IO b) Int
f :: Costful Int String
g :: Costful String Bool
요런 정의를 생각해볼때
f . g
는 f
와 g
의 동작은 합성하고, 비용은 +
한 것이 될것이다.
instance Category where
Costful f c1 . Costful g c2 = Costful (f . g) (c1 + c2)
요렇게 말이다.
이때 f . g
의 비용은 함수를 실행하기 전에도 알수있다.
반면 그냥 f
, g
를 모나딕한 함수로 정의하고 f >=> g
이런식으로 합성했을땐, 함수를 실제로 실행하기 전에는 비용을 알수 없다. >=>
또는 >>=
의 정의를 생각해보면 쉽게 알수 있다.
Category
인스턴스는 정적인 정보를 추가로 가지고 있는 함수, 또는 함수보다 표현력이 약한데 비스무리한거(그래서 정적인 정보가 더많은) 것을 다룰때 유용하다.
ActivityPub은 눈팅만 하고있었는데, 슈티에 피드를 넣기로 결정하고나니 ActivityPub를 써볼 기회가 생겼다. 따로 페디버스 서버를 팔지, 아니면 다른 방법을 쓸지(있긴 한가)를 고민해봐야한다.
쉘스크립트처럼 oci 컨테이너들을 조합하는 언어가 있으면 좋겠다.
컨테이너는 샌드박싱된 파일시스템을 입력으로 받아 출력으로 쓰고, 그런 컨테이너들을 (|
pipe operator로 stdin/stdout을 잇듯이) 조합하는 것이다. 그리고 이때 각 컨테이너가 필요로하는 입력 파일/디렉토리들에 대해 일종의 타입 체크를 해서 no such file or directory
가 뜨는것을 막아줄수 있을것이다.
사실 yaml등으로 작성하는 CI/CD 설정 파일들이 비슷한 기능을 하고있는데, 이걸 좀더 멀쩡한 언어로, 로컬에서도 쓸수있으면 좋겠다.
https://github.com/bglgwyng/semantic-lang-gen
I wrote(tbh, just packaged) a Haskell library that generates TreeSitter bindings and the corresponding AST type definition from TreeSitter language definition. Writing parsers using a parser combinator is fun, of course. However, with TreeSitter, you can eat free lunches of language tooling.
나는 모나드를 설명하기가 어려운게 그냥 대부분의 언어에서 (HKT의 부재로) Monad
를 정의를 못해서라고 생각한다.
Haskell에 대한 경험이 없는 친구들한테 모나드를 설명하면 잘 알아듣는다. 근데 끝나고 그게 그럼 클래스냐 디자인 패턴이냐 이런 질문이 이어진다.
자기가 쓰고있는 언어에서 어떻게 쓸수있는지를 묻는셈인데, 여기서 '굳이 따지면 디자인패턴 같은거다' 라고하면 실망하는게 느껴졌다.
같은 이유로, Haskell 사용자에게 카테고리 이론의 유용함을 설명하고싶다면 Category
인스턴스의 활용부터 시작하는게 맞다고 생각한다.
저는 얼굴인식 카메라 앱 슈티를 개발하고 있습니다 iOS 버전 링크, 안드로이드 버전 링크
세션 타입 좋습니다 여러분