Hi, I'm who's behind Fedify, Hollo, BotKit, and this website, Hackers' Pub!

Fedify, Hollo, BotKit, 그리고 보고 계신 이 사이트 Hackers' Pub을 만들고 있습니다.

FedifyHolloBotKit、そしてこのサイト、Hackers' Pubを作っています。

嗨,我是 FedifyHolloBotKit 以及這個網站 Hackers' Pub 的開發者!

Website
hongminhee.org
GitHub
@dahlia
Hollo
@hongminhee@hollo.social
DEV
@hongminhee
velog
@hongminhee
Qiita
@hongminhee
Zenn
@hongminhee
Matrix
@hongminhee:matrix.org
X
@hongminhee
3
3

UI 개발을 어렵게 만드는 가장 큰 요인은 테스트 아닐까... 비즈니스 로직이나 상태에 대한 유닛 테스트는 UI 차원에서 커버리지가 너무 낮다. E2E 테스트는 사이클이 너무 크고, 스냅샷 테스트는 시각적인 차이까지 캐치하지는 못한다.

3
4

뒤늦은 서울숲하스켈 조교 후기: 왠지 모르겠는데, 다들 운동을 열심히 하시는지 몸이 굉장히 좋으셨다. 건강한 신체에 건강한 정신이 깃든다를 실천하고 계신 분들이었다.

...는 농담이고(근데 사실입니다), 커리큘럼이 내가 상상하던 방향이랑은 꽤 달라서 흥미로웠다.

마지막 회차에 하스켈로 웹서버를 띄우는 것을 목표로 진행중이었는데, 이를 위해 Monad Transformer(Monad는 진즉에 해치우고), Tagless Final, Lens를 모두 소개한 상태였다. 근데 저 개념들이 '왜 하스켈에선 이거 안 돼요? 왤케 불편해요?' 같은 질문을 회피하지 않으려면 꼭 가르쳐야 하는 부분들이긴 하다. 가령, 'Monad만 배우면 이제 하스켈에서 명령형 코딩 할수 있다'라는 이야기가 이론상은 맞는데, Monad Transformer나 Algebraic Effect 같은거 안쓰면 웹사이트등 실제로 쓸모있는 프로그램을 사실상 짤수가 없다. 그래서 가르치긴 해야한다.

문제는 저걸 다 가르치려면 상당히 빡셀테니, 나는 만약에 내가 하스켈 부트캠프를 한다면 일단은 저런걸 회피하고 하스켈의 멋진 부분에 집중하는 커리큘럼을 짜야겠다고 그동안 생각했었다. 근데 또 이건 어찌보면 기만이기도 하다. 그런데 서울숲하스켈에서는 어찌저찌 다들 따라오도록 구성을 잘하신것 같다 하스켈을 이질적인(긍정적으로든 부정적으로든) 프로그래밍 언어로 소개하는게 아니라, 언젠가 본인의 작업에 활용할 언어의 후보로 올리게끔 하려면 저런 내용들을 다 다뤘어야 할것이다.

암튼 그동안 수고많으셨습니다. @eunmin은민

7

"The Good, the Bad and the Ugly" is a good article by @dominikDominik Chrástecký - Blog

chrastecky.dev/technology/acti

The two mentioned examples in "The Bad" are long-time issues that were also discussed at . I just responded to one of them on the forum..

The Update(Note) quirk. socialhub.activitypub.rocks/t/

The other one is around Direct Messages which are a hack (a Note with special sauce). specifies ChatMessage object type here, which is the intended way to extend the protocol.

0

이번 변경으로 홈 화면에 추가로 해커즈펍을 설치하면 android, iOS 양쪽 모두, 단독 앱인 것 같은 느낌으로 쓸 수 있게됩니다. 다만, 이메일의 로그인 링크가 설치 된 쪽으로는 안열리는 문제가 있으니 미리 로그인 된 상태에서 설치를 하셔야 곤란하지 않습니다.

4

저도 비슷한 생각인데, Haskell이나 Rust는 코너 케이스를 다루지 않고는 컴파일도 못 하게 금지하는 경우들이 꽤 많고 (그래서 좋은 언어지요), 빠르게 해피 패스만을 검증하고 싶을 때는 Python 같은 널널한 언어(복잡하고 규모가 큰 소프트웨어를 만들 때는 나쁜 언어가 되지요)가 쉽게 느껴질 수 있다고 생각합니다. 즉, Haskell이나 Rust가 어렵다고 말할 때의 어려움은 개념적 이해의 난도라기 보다는 시행착오의 커브의 경사를 얘기하는 것 같아요.

비슷한 측면에서 저는 Python의 들여쓰기를 강제하는 문법이 프로그래밍 초심자에게 좋은 습관을 처음부터 정착시키는 데에는 일조할 수 있겠지만, 결코 쉽지는 않다고 생각합니다.



RE: https://hackers.pub/@bgl/01967f97-67ab-7a98-a6e5-16cb3ef31856

@hongminhee洪 民憙 (Hong Minhee) 약간 딴 얘긴데, 저는 들여쓰기가 그냥 안좋은 문법요소 같습니다. 코드의 복붙을 unreliable하게 만들어버려서요. 반대로 space sensitive한 문법은 괜찮다고 생각합니다. 복붙시 문제가 생겨도 스페이스 한번 치면 해결되니까요. 들여쓰기 대신에 {} 쌍을 쓰게 만들되, 에디터에서 보여줄때 어떻게 알아서 예쁘게 보여주는게 낫다고 생각해요.

2

러스트가 어렵다는 이야기가 숙고없이 재생산 되는거 같긴 합니다. 제가 러스트를 별로 안써봐서 실제로 얼마나 어려운진 모르겠습니다.

그런데 말씀하신 모나드, 트레잇, 오너십 등의 개념들과 클래스는 좀 차이가 있다고 생각합니다. 그러니까 자바에서 클래스 때문에 어떤 코드를 못짜게 되진 않잖아요? 자바를 하면서 클래스를 제대로 쓰지않고도 뭔가 만들순 있습니다. 반면 전자의 개념들은 잘못된 코드를 짜는걸 막고, 초보자 입장에서 뭔가 하고싶은게 있는데 그게 금지되는 상황에서 어렵다는 느낌을 (필요이상으로 크게) 받을수 있다고 생각합니다.



RE: https://yuri.garden/notes/a75i1vf42f

5
0
2

https://moreal.dev/blog/review-learning-zig/

  • 요근래 안 하던 직접 메모리 할당 및 해제를 Zig하면서 해보니 Bun에서 왜 메모리 누수가 나는지 이해가 가는 부분이었다. (메모리 관리 잘 하기 어려운 것 같다)
  • 컴파일 타임 코드 작성하기 편한 것은 좋았다. (comptime)
  • 회고를 하며 내가 공부할 때 방황한 과정을 돌이켜 보는 것이 좋았다. "언어 철학 먼저보기"와 "표준 라이브러리에서 Write, Read 추상화하는 방식 참조하기" 정도를 먼저 하면 좋겠다는 교훈(?)을 얻었다.
  • 위 글에 애자일 이야기 글 링크할 때, 애자일 이야기 검색 가능하게 만든거 잘 써서 좋았다 :D
3
3
7
0
0
0
2

Rust로 작성한 JPEG XL 디코더, jxl-oxide의 버전 0.12.0을 릴리스했습니다. https://github.com/tirr-c/jxl-oxide/releases/tag/0.12.0

CMYK 프로파일 등 복잡한 ICC 프로파일을 지원하기 위해 기존에 사용하던 Little CMS 2 (lcms2) 에 더해, Rust로 작성된 색 관리 시스템인 moxcms 지원을 추가한 것이 주요 변경사항입니다. CLI 툴의 기본 CMS는 아직 lcms2이지만 --cms moxcms 옵션으로 moxcms를 사용할 수 있습니다.

1

Rust로 작성한 JPEG XL 디코더, jxl-oxide의 버전 0.12.0을 릴리스했습니다. https://github.com/tirr-c/jxl-oxide/releases/tag/0.12.0

CMYK 프로파일 등 복잡한 ICC 프로파일을 지원하기 위해 기존에 사용하던 Little CMS 2 (lcms2) 에 더해, Rust로 작성된 색 관리 시스템인 moxcms 지원을 추가한 것이 주요 변경사항입니다. CLI 툴의 기본 CMS는 아직 lcms2이지만 --cms moxcms 옵션으로 moxcms를 사용할 수 있습니다.

9
4

Protected Route에 대해 좀 생각을 더 해봤는데, 난 처음엔 React Native Navigation에서만 쓰는 해괴한 방식인줄 알았다. 근데 좀더 생각해봐도 별로긴하다. 라우터란게 결국 전체 상태중에 path만 별도로 관리해주는 건데,

app :: State -> View
--- router 도입
app :: (Path, State) -> View
--- Protected Route
app :: State -> Path -> View

여기서 대충 말해서 Path -> View가 라우터라 할수 있겠다. Protected Route는 State로부터 라우팅 룰을 동적으로 바꿔버리는 방식이다. 근데 애초에, 라우팅 룰을 정적인 정보로 만들고(즉 ->가 아님) 활용할게 아니라면 라우터를 쓸 이유가 뭘까? 그냥 Path를 일반적인 다른 상태와 똑같이 취급해도 상관없을 것이다. 근데 react-router도 그렇고 애초에 라우팅 룰을 정적인 정보로 알수있는 설계로 되어있지가 않다. Tanstack Router는 예외다.

근데 이러면 그냥 XState 쓰면 되지 않나? 상태/전이에 대한 정적인 정보를 가지고 있고, 또 React Native에서의 라우팅에는 화면 전환이 단순한 Path 변경이 아닌 어떻게 화면을 전환 시킬지(애니메이션 등)도 기술해야하는데, 이 역시 XState 이벤트로 넣으면 된다.

2

논리와 저수준(Low-level) 자료 표현(Data representation)에 대한 글 2 편 중 첫째 편입니다. "논리적이 되는 두 가지 방법"이라는 부제로 논리적 증명을 하는 두 방법론에 대해서 다뤄보았습니다. 이 중 하나의 방법론이 둘째 편의 핵심이 될 예정입니다.



RE: https://hackers.pub/@ailrun/2025/%EB%85%BC%EB%A6%AC%EC%99%80-%EC%A0%80%EC%88%98%EC%A4%80-low-level-%EC%9E%90%EB%A3%8C-%ED%91%9C%ED%98%84-data-representation-1-%ED%8E%B8

4

洪 民憙 (Hong Minhee) shared the below article:

논리적이 되는 두 가지 방법 - 논리와 저수준(Low-level) 자료 표현(Data representation) (2 편 중 1 편)

Ailrun (UTC-5/-4) @ailrun@hackers.pub

이 글은 어떤 문장이 "논리적"이라고 할 수 있는지에 대한 심도 있는 탐구를 시작합니다. 일상적인 오용을 지적하며, 진정으로 논리적인 주장은 증명 가능성과 체계의 무모순성이라는 두 가지 핵심 조건을 충족해야 한다고 주장합니다. 특히, "좋은 가정 아래" 논리성을 증명하는 두 가지 방법, 즉 함수형 언어와 유사한 구조를 가진 자연 연역과, 약간의 "부정행위"를 통해 무모순성을 쉽게 보일 수 있는 논건 대수를 소개합니다. 글에서는 명제와 판단의 개념을 명확히 정의하고, 자연 연역을 통해 논리적 증명을 구축하는 방법을 상세히 설명합니다. 특히, 자연 연역과 함수형 언어 간의 놀라운 유사성, 즉 커리-하워드 대응을 통해 논리적 사고와 프로그래밍 언어 이해 사이의 연결고리를 제시합니다. 또한, 자연 연역의 한계를 극복하고 무모순성을 보다 쉽게 증명할 수 있는 논건 대수를 소개하며, 자연 연역과의 구조적 차이점을 강조합니다. 이 글은 논리적 사고의 깊이를 더하고, 프로그래밍 언어와 논리 간의 관계에 대한 흥미로운 통찰을 제공합니다. 특히, 커리-하워드 대응을 통해 논리와 프로그래밍이 어떻게 연결되는지 이해하고 싶은 독자에게 유익할 것입니다.

Read more →
11

https://hackers.pub/?filter=local

와 이제 여기는 순수 개발이야기만 하는 국산 개발 SNS가 되었네 ㅋㅋㅋㅋㅋㅋ
사람도 계속 들어오는거 보면 장난 아닌 듯

얘가 한국 페디버스(연합우주)의 새로운 바람인 듯

3
1
6
0
1
1

많은 파일을 대상으로 텍스트를 대량 치환해야 할 일이 꽤 있는데, 파일 탐색과 치환을 인터랙티브하게 수행할 수 있는 툴이 없어서 ised(interactive sed)를 만들었다. 월요일부터 개밥먹기 할 예정. github.com/parksb/ised

3
1
2
8

# Ask Hackers Pub : 이번 주말에 뭐 하시나요?

이번 주말에 뭘 하려고 계획 중인지 편하게 얘기해 보아요.
읽을 책, 가볼 곳, 해볼 것.. 어떤 것이든 좋습니다.
도움 요청이나 피드백 요청도 좋습니다.
물론! 아무것도 하지 않고 쉬는 것도 훌륭합니다.

* 지난 주말에 계획하셨던 일의 회고도 한 번 남겨보면 좋을 것 같아요.

0
  1. VimConf 제안서 작성
  2. PyCon KR CFP 자료 85퍼센트 정도 채워넣기 (바이브 코딩 관련)
  3. Fediverse 앱 개발
  4. 이력서 작성
  5. High Performance Browser Networking Part1 완주
  6. React 공식 문서 완주
4
4

Relay LSP의 Go to Definition 기능이 VSCode에선 잘 되는데 Zed에서만 안 먹길래 디버깅을 해 봤는데 TS 서버가 Go to Definition 요청을 가로채가고 있던 거여서 (...) 모든 언어 서버에 요청을 날리고 응답을 병합하는 식으로 동작하도록 수정해서 PR을 날려보았다 (VSCode도 동일하게 동작함)

8

전반적으로 말길을 잘 못 알아 듣네요. 전에 다른 모델에 영수증 OCR한 텍스트로 더치페이 계산 해달라고 했던 것을 똑같이 시켜보니까, 상품명에 “3개” 가 들어간 상품의 가격을 지 맘대로 3배한 가격으로 만들고, 더하기는 틀리지 않게 해놓고는, 사람수만큼 안나눠주고 어째서인지 상품별로 다시 가격 안내를 하고는 알아서 나눠 내라합니다.

1

Show GN: 나만의 연합우주(fediverse) 마이크로블로그 만들기
------------------------------
이 튜토리얼은 [Fedify] 라이브러리를 사용하여 [ActivityPub] 프로토콜 기반의 마이크로블로그 서비스를 구현하는 방법을 설명합니다. ActivityPub은 다양한 소셜 네트워크 서비스들이 서로 연동될 수 있게 해주는 분산형 소셜 네트워킹 프로토콜로, 이를 통해 [Mastodon], [Misskey] 같은 서비스와 상호작용할 수 있는 독…
------------------------------
https://news.hada.io/topic?id=20508&utm_source=googlechat&utm_medium=bot&utm_campaign=1834

0
1
0
0
3
0

거꾸로 상태 모나드로 강화 학습 하기 (1/2) 2편을 마저 써야하는데, 먼저 하스켈 세미나 시간에 전체 내용으로 동료들한테 발표를 했다. 근데 발표하면서 글에 해결해야하는 문제점이라고 써놓은게 되게 얼렁뚱땅이란걸 깨달았다. 실제로 코드를 짠지가 시간이 좀 되어서 정확히 뭐가 문제였는지 좀 까먹어서 실제로 쓰기가 힘들어서 중간에 좀 놨었다ㅋㅋ 암튼 발표를 해보는게 내용 점검에 도움이 많이 된단걸 알았다.

거꾸로 상태 모나드로 강화 학습 하기 (1/2)

기계 학습을 전혀 모르고 살면 안 되겠다 싶어, 얼마전부터 하스켈로 공부하기 시작했다. Hasktorch라고 하스켈용 Torch 바인딩을 사용한다. 이전에 도전했을땐 MNIST까지 하고 다음에 뭘 해야할지 모르겠어서 그만뒀는데, 이번엔 강화 학습으로 이어나가 보기로 했다. 강화 학습은 주어진 환경에서 보상을 최대화하는 에이전트를 학습시키는 것으로, 데이터가 필요없다는게 장점이다. 대신 환경을 만들어야 하는데, 간단한 게임도 환경이 될 수 있다. 게임 만들기는 데이터 모으기와 달리 즐거운 일이니 마다할 필요가 없다. 첫번째로 도전으로 스네이크 게임을 골랐는데, 다들 한번쯤은 해봤을 것이다. 뱀을 조종해 먹이를 최대한 많이 먹으면 되는데, 뱀의 머리가 벽이나 아니면 자기 몸통에 부딪히면 죽는다. 여차여차 학습시켜서 이정도까지 하는데에는 성공했다. 강화 학습 지식이 일천해서 게임을 클리어하는 수준까지는 못 만들겠다. 이 글은 학습을 잘 시키는 방법이 아니라, 강화학습 코드를 어떻게 잘 짜느냐에 대한 것이다.<일단 강화 학습이란걸 형식화 해보자. 앞서 언급한 환경과 에이전트란 단어를 어떻게 정의할수 있을까? 먼저 에이전트의 정의는 이렇다.type Agent = Observation -> Action<관측 Observation 에 따라 행동 Action 을 선택한다. 나는 눈앞에 콜라가 보이면 마신다. 환경은 에이전트를 실행하는 무언가이다. 일상적인 표현으로 쓰자면, 에이전트를 둘러싼 무언가이다.runAgent :: Agent -> [Action]<이 runAgent 함수가 환경의 역할을 수행한다. Agent를 인자로 받아 죽을 때까지 선택한 행동들을 반환한다. 그런데 이건 너무 외연적인 정의고, 환경과 에이전트가 보통 만족할만한 조건을 나열해보자면 이렇다.환경은 상태를 가지고 있고 시간이 지남에 따라 변경된다상태는 에이전트가 무엇을 관측할지를 결정한다에이전트의 행동은 다음 상태에 영향을 끼친다<이 조건들을 바탕으로 환경을 좀더 구체적으로 정의하면 다음과 같다.class Environment e where type State e type Observation e type Action e update :: (State e, Action e) -> State e -- 조건 1, 3 observe :: State e -> Observation e -- 조건 2<스네이크 게임에서 상태는 뱀의 모양과 먹이의 위치, 관측은 상태와 같고(플레이어는 전체 게임 화면을 볼 수 있다), 행동은 좌회전과 우회전이 된다. 그런데 뱀이 아무렇게나 좌회전 우회전 한다고 박수 쳐줄순 없고, 우리는 얘한테 바라는 게 있다. 죽지않고 더 많은 먹이를 먹어야 한다. 이를 위해 뱀이 제때 방향을 바꿔서 먹이를 지나치지 않고 먹으면 잘 했다고 보상을 주자. 그러면 뱀은 보상을 더 많이 받을 방법을 학습한다.type RewardFunction = (Observation, Action) -> Float<보상 함수는 관측와 행동에 따라 보상을 결정한다. 가령 뱀이 먹이 하나를 냠냠하면 보상을 1 주면 된다. 지나쳐버리면 0점이고, 죽었을 때는 -1점을 줄 수도 있다. 당근과 채찍이라 생각하고 정의하면 된다. 또, 보상은 더해서 누적이 되어야 하므로 대충 Float으로 고른다. 학습을 시키려면 보상을 계산해야하고, 그러기 위해 관측과 행동을 짝지어야한다.trainAgent :: Agent -> [(Observation, Action)]<runAgent와 달리 Observation도 포함되어 있다. 이때 [(Observation, Action)]을 에피소드 Episode 라고 한다. 에피소드로부터 보상을 구하자.rewards = fmap (uncurry rewardFn) (trainAgent agent)rewardFn :: RewardFunctionagent :: Agent<...해치웠나? 에피소드가 어떻게 기록될지를 살펴보자.0123456789행동→↓→↓←↑→↓←↓보상🍎🍎🍎💀<위의 rewards의 값이 이런 의미일거라고 보인다. 실제로 Float 값을 표시해보자.0123456789행동→↓→↓←↑→↓←↓보상0010011000<혹시 이상한 걸 찾으셨나요? 이런식으로 보상하는게 틀린 건 아니다. 다만 에이전트가 장기적인 계획을 세우도록 학습시키지 못한다. 먹이를 먹는 순간에만 보상을 받기 때문에, 멀리 떨어진 먹이를 향해 다가가게끔 유도할 수가 없다. 이를 해결하려면 보상을 뒤에서부터 누적시켜야 한다.0123456789행동→↓→↓←↑→↓←↓보상3332221000rewards = scanr (+) 0 (fmap (uncurry rewardFn) (trainAgent agent))<코딩 테스트용 코드를 짜야할것 같은 느낌이 들었는데, 다행히 scanr 함수 덕분에 쉽게 해결했다. 좀더 개선해볼까. 지금의 보상 체계에서 에이전트는 먼 미래를 고려하며 선택하는 것을 배울 수 있다. 그런데, 사실 뱀이 맨 처음에 좌회전을 하던 우회전을 하던, 죽기 전까지 먹이를 총 몇개 먹는지에 엄청난 영향을 끼칠거 같진 않다. 어떤 시점에서의 선택의 영향은 시간이 지날 수록 점점 희미해진다. 이 점을 반영해서 뱀이 잘못된 편견을 갖지 않도록 도와주자. 미래의 보상을 누적하되, 감쇠율 0.9를 적용하는 것이다.0123456789행동→↓→↓←↑→↓←↓보상1.932.152.391.541.711.901.000.000.000.00rewards = scanr (\x y -> x + 0.9 * y) 0 (fmap (uncurry rewardFn) (trainAgent agent))<이제 나머지는 GPU한테 맡기면 된다. 조금만 기다리면 위의 동영상에서처럼 움직이는 뱀을 볼 수 있다.<여기서 GPU를 100장 더 사서 뱀 대신에 좀더 우리 삶에 도움되는 에이전트를 학습시킨다면, 그걸 10년전에 했으면, 난 지금 부자가 되어있을지도 모르겠다. 하지만 기회는 이미 떠났고, 난 지금 돈은 없지만 대신 시간은 많다. 그 시간을, 지금의 그럭저럭 볼만한 코드를 쥐꼬리만큼 개선하는데 낭비해보려 한다. 지금 코드에서 뭐가 마음에 안드냐면,<보상이 사실 서로 다른 두 개를 가리킨다 먹이를 먹자마자 즉각적으로 주는 보상과, 그것을 누적한 보상, 이렇게 두 개가 있다. 실제로 학습에 사용하는 것은 후자이다. 그런데 막상 보상 함수의 정의는 전자에 대한 것이다. 이는 보상 함수를 계산할 때 미래에 어떤 일이 일어나는지 알수가 없어서 그렇다. 정의를 두 개로 나눈 이유가 의미를 명쾌하게 하기 위해서가 아니라, 그냥 한번에 계산을 할수 없기 때문이다.<환경의 정의 위에서 살펴본 runAgent의 정의가 일견 우아해보일 수 있다. 문제는 그 정의는 환경과 에이전트가 모두 순수 함수일 것을 강요한다는 것이다. Environment의 정의도 마찬가지다. 환경과 에이전트는 각자의 부수효과 Side effect 를 가질 수 있어야 한다. 가령 온라인 게임을 환경으로 삼는다면, 환경은 네트워킹을 할 수 있어야 한다. 또, 에이전트는 매번 똑같은 선택이 아닌 확률적 선택을 하고 싶을텐데, 이는 순수 함수로써는 불가능하다.<그러면 부수효과를 허용하면 되는거 아냐?<맞다. 나처럼 시간이 많다면 직접 해보는 것도 나쁘지 않다. 하지만 정의가 점점 지저분해지는 것을 보게될 것이고... 시간을 아껴주기 위해 정답을 알려주겠다. 환경은 에이전트가 실행될 수 있는 모나드여야 한다. 딱 거기까지여야 한다. 환경과 에이전트 사이에 그 이상의 관계는 부적절하다.<글이 생각했던 것보다 길어져버려서, 오늘은 여기까지 해야겠다. 이어지는 글에서 거꾸로 상태 모나드가 이걸 어떻게 해결하는지 소개한다. 사실 아까 환경이니 에이전트니 어쩌고 할때부터, 진작에 강화 학습을 마스터한 학생들이 이미 다 아는 내용에 지겨워 졸기 시작하는게 보였다. 다음 수업은 재밌을테니, 대신 그때까지 모나드를 배워오세요.

hackers.pub · Hackers' Pub

Link author: bgl gwyng@bgl@hackers.pub

8
1