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

어제랑 오늘 오전은 주로 버그 수정만 했다.

  • 비공개 게시물은 공유 못 하게 막음
  • Markdown 렌더링에서 GitHub 스타일 콜아웃 버그 고침
  • AUTHORIZED_FETCH 적용된 인스턴스로부터 노트 객체 요청 받았을 때 무조건 401 떨어지던 버그 수정 (Fedify까지 덩달아 수정…)
  • 각주 링크 작동 안 하던 버그 고침
  • 다른 사람 DM이 타임라인에 뜨던 버그 고침
  • 파비콘 추가
0

昨日と今朝は主にバグ修正だけだった。

  • 非公開の投稿は共有を出来なくした
  • Markdown のレンダリングで GitHub スタイルのコールアウトのバグを修正
  • AUTHORIZED_FETCHが適用されたインスタンスからノートオブジェクトのリクエストを受けた時、無条件に401が出るバグ修正(Fedifyまでまとめて修正…)
  • 脚注リンクが動かないバグ修正
  • 他の人のDMがタイムラインに表示されるバグを修正
  • ファビコン追加
0

어제랑 오늘 오전은 주로 버그 수정만 했다.

  • 비공개 게시물은 공유 못 하게 막음
  • Markdown 렌더링에서 GitHub 스타일 콜아웃 버그 고침
  • AUTHORIZED_FETCH 적용된 인스턴스로부터 노트 객체 요청 받았을 때 무조건 401 떨어지던 버그 수정 (Fedify까지 덩달아 수정…)
  • 각주 링크 작동 안 하던 버그 고침
  • 다른 사람 DM이 타임라인에 뜨던 버그 고침
  • 파비콘 추가
0
0

궁금해 하실 분들이 계실지 모르겠지만, Hackers' Pub은 아래의 기술로 만들어지고 있습니다.


  1. 2025년 3월 현재 Fresh 2.0은 정식 버전이 릴리스되지 않은 상태인데, 무시하고 불안정 버전을 그대로 쓰고 있습니다. Fresh 1.0 → 2.0에서 많은 게 바뀌기 때문에 굳이 Fresh 1.0을 쓰고 싶지 않았습니다. ↩︎

気になる方がいるか分かりませんが、Hackers' Pubは下記の技術で作られています。

  • バックエンドのJavaScriptランタイムとしてDeno(Node.jsは使わない)
  • データベースとしてPostgreSQL
  • ウェブフレームワークとしてFresh 2.0[1]
  • ORMとしてDrizzle ORM
  • キャッシュストレージとしてRedis
  • ActivityPub連合の為のFedify
  • ロギングライブラリとしてLogTape
  • WebフロントエンドフレームワークとしてPreact
  • スタイリングにTailwind CSS
  • 国際化にi18next

  1. 2025年3月現在Fresh 2.0は正式版がリリースされていない状態ですが、無視して不安定なバージョンを使っています。Fresh 1.0→2.0で色々変わったので、あえてFresh 1.0を使いたくなかったです。 ↩︎

1

궁금해 하실 분들이 계실지 모르겠지만, Hackers' Pub은 아래의 기술로 만들어지고 있습니다.


  1. 2025년 3월 현재 Fresh 2.0은 정식 버전이 릴리스되지 않은 상태인데, 무시하고 불안정 버전을 그대로 쓰고 있습니다. Fresh 1.0 → 2.0에서 많은 게 바뀌기 때문에 굳이 Fresh 1.0을 쓰고 싶지 않았습니다. ↩︎

0

Hackers' Pub 쓰고 계신 분들 중에서, 자신의 Hackers' Pub 계정을 연합우주(fediverse)뿐만 아니라 Bluesky에도 노출하고 그쪽 사람들과 교류하고 싶으신 분이 있다면, 상단 검색창에 @bsky.brid.gy@bsky.brid.gy을 검색하셔서 나오는 프로필을 팔로해 보세요. 그리고 1분 정도 뒤에 Bluesky에서 본인ID.hackers.pub.ap.brid.gy로 검색하면 본인의 Hackers' Pub 계정이 Bluesky에서도 보이는 걸 확인하실 수 있을 겁니다.

0
0
0
0
0
0
0
0

오늘의 일기

  • hackers.pub 첫 포스트!
  • 첫 수영 수업을 다녀왔다. 전날 밤에 악몽 꿀 정도로 긴장했는데 다행히 가서 음파음파 잘 하고 왔다. (..)
  • SNS 여러 개는 도저히 못 쓰겠다는 결론을 내리고 블루스카이 탈퇴.
  • 스마트폰 사용 시간을 줄이기 위해 디스플레이를 흑백으로 바꿨다.
  • 과연 올해야말로 블로그 대통합을 이룰 수 있을 것인가? 네이버 블로그에 쌓여 있는 글을 모두 나만의 정적 웹사이트로 옮기고 애매하게 둥둥 떠 있는 github pages 는 없애는 게 목표.
0
0

오늘의 일기

  • hackers.pub 첫 포스트!
  • 첫 수영 수업을 다녀왔다. 전날 밤에 악몽 꿀 정도로 긴장했는데 다행히 가서 음파음파 잘 하고 왔다. (..)
  • SNS 여러 개는 도저히 못 쓰겠다는 결론을 내리고 블루스카이 탈퇴.
  • 스마트폰 사용 시간을 줄이기 위해 디스플레이를 흑백으로 바꿨다.
  • 과연 올해야말로 블로그 대통합을 이룰 수 있을 것인가? 네이버 블로그에 쌓여 있는 글을 모두 나만의 정적 웹사이트로 옮기고 애매하게 둥둥 떠 있는 github pages 는 없애는 게 목표.
0

Got an interesting question today about 's outgoing design!

Some users noticed we create separate queue messages for each recipient inbox rather than queuing a single message and handling the splitting later. There's a good reason for this approach.

In the , server response times vary dramatically—some respond quickly, others slowly, and some might be temporarily down. If we processed deliveries in a single task, the entire batch would be held up by the slowest server in the group.

By creating individual queue items for each recipient:

  • Fast servers get messages delivered promptly
  • Slow servers don't delay delivery to others
  • Failed deliveries can be retried independently
  • Your UI remains responsive while deliveries happen in the background

It's a classic trade-off: we generate more queue messages, but gain better resilience and user experience in return.

This is particularly important in federated networks where server behavior is unpredictable and outside our control. We'd rather optimize for making sure your posts reach their destinations as quickly as possible!

What other aspects of Fedify's design would you like to hear about? Let us know!

A flowchart comparing two approaches to message queue design. The top half shows “Fedify's Current Approach” where a single sendActivity call creates separate messages for each recipient, which are individually queued and processed independently. This results in fast delivery to working recipients while slow servers only affect their own delivery. The bottom half shows an “Alternative Approach” where sendActivity creates a single message with multiple recipients, queued as one item, and processed sequentially. This results in all recipients waiting for each delivery to complete, with slow servers blocking everyone in the queue.
0
5
1
0
0
0
0
0
0

Monads: Beyond Simple Analogies—Reflections on Functional Programming Paradigms

洪 民憙 (Hong Minhee) @hongminhee@hackers.pub

While exploring functional programming languages, I've been reflecting on how different communities approach similar concepts. One pattern that seems particularly fascinating is how Haskell and OCaml communities differ in their embrace of monads as an abstraction tool.

The Elegant Power of Monads in Haskell

It's common to hear monads explained through analogies to concepts like JavaScript's Promise or jQuery chains. While these comparisons provide an entry point, they might miss what makes monads truly beautiful and powerful in Haskell's ecosystem.

The real strength appears to lie in the Monad typeclass itself. This elegant abstraction allows for creating generic functions and types that work with any type that shares the monad property. This seems to offer a profound unification of concepts that might initially appear unrelated:

  • You can write code once that works across many contexts (Maybe, [], IO, State, etc.)
  • Generic functions like sequence, mapM, and others become available across all monadic types
  • The same patterns and mental models apply consistently across different computational contexts

For example, a simple conditional function like this works beautifully in any monadic context:

whenM :: Monad m => m Bool -> m () -> m ()
whenM condition action = do
  result <- condition
  if result then action else return ()

Whether dealing with potentially missing values, asynchronous operations, or state transformations, the same function can be employed without modification. There's something genuinely satisfying about this level of abstraction and reuse.

OCaml's Different Approach

Interestingly, the OCaml community seems less enthusiastic about monads as a primary abstraction tool. This might stem from several factors related to language design:

Structural Differences

OCaml lacks built-in typeclass support, relying instead on its module system and functors. While powerful in its own right, this approach might not make monad abstractions feel as natural or convenient:

(* OCaml monad implementation requires more boilerplate *)
module type MONAD = sig
  type 'a t
  val return : 'a -> 'a t
  val bind : 'a t -> ('a -> 'b t) -> 'b t
end

module OptionMonad : MONAD with type 'a t = 'a option = struct
  type 'a t = 'a option
  let return x = Some x
  let bind m f = match m with
    | None -> None
    | Some x -> f x
end

OCaml also doesn't offer syntactic sugar like Haskell's do notation, which makes monadic code in Haskell considerably more readable and expressive:

-- Haskell's elegant do notation
userInfo = do
  name <- getLine
  age <- readLn
  return (name, age)

Compared to the more verbose OCaml equivalent:

let user_info =
  get_line >>= fun name ->
  read_ln >>= fun age ->
  return (name, age)

The readability difference becomes even more pronounced in more complex monadic operations.

Philosophical Differences

Beyond syntax, the languages differ in their fundamental approach to effects:

  • Haskell is purely functional, making monads essential for managing effects in a principled way
  • OCaml permits direct side effects, often making monadic abstractions optional

This allows OCaml programmers to write more direct code when appropriate:

(* Direct style in OCaml *)
let get_user_info () =
  print_string "Name: ";
  let name = read_line () in
  print_string "Age: ";
  let age = int_of_string (read_line ()) in
  (name, age)

OCaml's approach might favor pragmatism and directness in many cases, with programmers often preferring:

  • Direct use of option and result types
  • Module-level abstractions through functors
  • Continuation-passing style when needed

While this directness can be beneficial for immediate readability, it might come at the cost of some of the elegant uniformity that Haskell's monadic approach provides.

Reflections on Language Design

These differences highlight how programming language design shapes the idioms and patterns that emerge within their communities. Neither approach is objectively superior—they represent different philosophies about abstraction, explicitness, and the role of the type system.

Haskell's approach encourages a high level of abstraction and consistency across different computational contexts, which can feel particularly satisfying when working with complex, interconnected systems. There's something intellectually pleasing about solving a problem once and having that solution generalize across many contexts.

OCaml often favors more direct solutions that might be easier to reason about locally, though potentially at the cost of less uniformity across the codebase. This approach has its own virtues, particularly for systems where immediate comprehensibility is paramount.

After working with both paradigms, I find myself drawn to the consistent abstractions that Haskell's approach provides, while still appreciating the pragmatic clarity that OCaml can offer in certain situations. The typeclasses and syntactic support in Haskell seem to unlock a particularly elegant way of structuring code that, while perhaps requiring a steeper initial learning curve, offers a uniquely satisfying programming experience.

What patterns have you noticed in how different programming language communities approach similar problems? And have you found yourself drawn to the elegant abstractions of Haskell or the pragmatic approach of OCaml?

Read more →
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

앞으로 또 해야 할 것들… 뭐부터 해야 할까?

  • 좋아요 및 에모지 리액션: 좋아요와 에모지 리액션을 별개로 구현할지(Hollo 방식), 좋아요를 에모지 리액션의 한 종류로 구현할지(Misskey 방식) 고민중…
  • 인용 공유
  • 사용자 이름에도 커스텀 에모지 지원
  • 알고리즘 타임라인
  • 게시물 번역: 대충 프롬프트는 만들었는데, 어떤 모델을 쓸 지 고민중…
0

앞으로 또 해야 할 것들… 뭐부터 해야 할까?

  • 좋아요 및 에모지 리액션: 좋아요와 에모지 리액션을 별개로 구현할지(Hollo 방식), 좋아요를 에모지 리액션의 한 종류로 구현할지(Misskey 방식) 고민중…
  • 인용 공유
  • 사용자 이름에도 커스텀 에모지 지원
  • 알고리즘 타임라인
  • 게시물 번역: 대충 프롬프트는 만들었는데, 어떤 모델을 쓸 지 고민중…
0
0
0
0
0
0