Juntai Park

@arkjun@hackers.pub · 47 following · 44 followers

中年(중년)中小企業(중소기업) 開發者(개발자), 90年代(년대) Console Gamer(콘솔 게이머). 좋은 하루를 繼續(계속)해 나아간다. 좋은 하루가 모이면 좋은 人生(인생)이 된다.

韓国人のプログラマー、40代、小学生の息子とゲームするのが幸せ😃💕龍が如く 、ゼルダの伝説、マリオ、ピクミン好き

「いい1日を続ける」
いい1日を続けていけば、いい人生になる!

threads
@rkjun
x
@rkJun
uri.life
@arkjun@uri.life
GitHub
@arkjun

높은 목표를 가진 개발자라도 결국엔 아주 사소한 동기로 움직이는거 같다.

나같은 경우엔, 완벽한 프로그래밍 언어를 만드는 것이 목표인데(가능한지는 차치하고), 완벽하다는건 나말고 다른 누군가가 같은 문제 의식을 가진다면 똑같이 그곳에 다다를 거란걸 의미한다. 그 프로그래밍 언어의 설계에서 내 마음대로 결정할수 있는 부분은 없을 것이다. 설계에서 최적의 선택지만을 택해야 완벽할테니까 말이다. 그때가선 그 선택들이 너무 자명해서, 내겐 처음부터 선택의 여지가 없었다고 느낄것이다.

그럼에도 내가 결정할 수 있을 부분이 있기는한데, 그 언어의 이름에 뜬금없이 우리집 강아지 이름을 붙인다던가 하는 것이다. 이게 그 사소한 동기다.

0

安寧(안녕)하세요, 저는 서울에 살고 있는 30() 後半(후반) 오픈 소스 소프트웨어 엔지니어이며, 自由(자유)·오픈 소스 소프트웨어와 聯合宇宙(연합우주)(fediverse)의 熱烈(열렬)支持者(지지자)입니다.

저는 TypeScript() ActivityPub 서버 프레임워크인 @fedifyFedify: an ActivityPub server framework 프로젝트와 싱글 유저() ActivityPub 마이크로블로그인 @holloHollo :hollo: 프로젝트와 ActivityPub 봇 프레임워크인 @botkitBotKit by Fedify :botkit: 프로젝트의 製作者(제작자)이기도 합니다.

저는 ()아시아 言語(언어)(이른바 )와 유니코드에도 關心(관심)이 많습니다. 聯合宇宙(연합우주)에서는 國漢文混用體(국한문 혼용체)를 쓰고 있어요! 제게 韓國語(한국어)英語(영어), 日本語(일본어)로 말을 걸어주세요. (아니면, 漢文(한문)으로도!)

こんにちは、私はソウルに住んでいる30代後半のオープンソースソフトウェアエンジニアで、自由・オープンソースソフトウェアとフェディバースの熱烈な支持者です。名前は洪 民憙ホン・ミンヒです。

私はTypeScript用のActivityPubサーバーフレームワークである「@fedifyFedify: an ActivityPub server framework」と、ActivityPubをサポートする1人用マイクロブログである 「@holloHollo :hollo:」と、ActivityPubのボットを作成する為のシンプルなフレームワークである「@botkitBotKit by Fedify :botkit:」の作者でもあります。

私は東アジア言語(いわゆるCJK)とUnicodeにも興味が多いです。日本語、英語、韓国語で話しかけてください。(または、漢文でも!)

0

Hello, I'm an open source software engineer in my late 30s living in , , and an avid advocate of and the .

I'm the creator of @fedifyFedify: an ActivityPub server framework, an server framework in , @holloHollo :hollo:, an ActivityPub-enabled microblogging software for single users, and @botkitBotKit by Fedify :botkit:, a simple ActivityPub bot framework.

I'm also very interested in East Asian languages (so-called ) and . Feel free to talk to me in , (), or (), or even in Literary Chinese (, )!

安寧(안녕)하세요, 저는 서울에 살고 있는 30() 後半(후반) 오픈 소스 소프트웨어 엔지니어이며, 自由(자유)·오픈 소스 소프트웨어와 聯合宇宙(연합우주)(fediverse)의 熱烈(열렬)支持者(지지자)입니다.

저는 TypeScript() ActivityPub 서버 프레임워크인 @fedifyFedify: an ActivityPub server framework 프로젝트와 싱글 유저() ActivityPub 마이크로블로그인 @holloHollo :hollo: 프로젝트와 ActivityPub 봇 프레임워크인 @botkitBotKit by Fedify :botkit: 프로젝트의 製作者(제작자)이기도 합니다.

저는 ()아시아 言語(언어)(이른바 )와 유니코드에도 關心(관심)이 많습니다. 聯合宇宙(연합우주)에서는 國漢文混用體(국한문 혼용체)를 쓰고 있어요! 제게 韓國語(한국어)英語(영어), 日本語(일본어)로 말을 걸어주세요. (아니면, 漢文(한문)으로도!)

0

Hello, I'm an open source software engineer in my late 30s living in , , and an avid advocate of and the .

I'm the creator of @fedifyFedify: an ActivityPub server framework, an server framework in , @holloHollo :hollo:, an ActivityPub-enabled microblogging software for single users, and @botkitBotKit by Fedify :botkit:, a simple ActivityPub bot framework.

I'm also very interested in East Asian languages (so-called ) and . Feel free to talk to me in , (), or (), or even in Literary Chinese (, )!

0
4
0

ActivityPub 구현들에서 인용을 하면 content 값에 자동으로 “RE: 인용된 글 링크” 또는 “QT: 인용된 글 링크 [参照]” 같은 식으로 덧붙이는 동작들을 하는데, 다행히 Akkoma나 Fedibird 등에서는 이를 .quote-inline이나 .reference-link-inline 같은 클래스로 묶어줘서 CSS로 그것들을 가리는 게 가능하다. 그런데, 오직 Misskey만 그런 처리를 안 해줘서 CSS만으로 가릴 방법이 없다…

0
0
0

GN⁺: 스크립트에서는 긴 옵션을 사용합시다
------------------------------
- 많은 명령줄 유틸리티는 짧은 형식 옵션(
-f)과 긴 형식 옵션(--force)을 지원함
- 짧은 형식은 대화형 사용을 위한 것임, 스크립트에서는 긴 형식을 사용할 것을 권장함
- 예를 들어, 터미널에서는
$ git switch -c my-new-branch라고 입력함.
- 릴리스 스크립트에서는 다음과 같이 작성함:
- `try …
------------------------------
https://news.hada.io/topic?id=19905&utm_source=googlechat&utm_medium=bot&utm_campaign=1834

0
0
0

디지털 가드닝에 관심이 많은 개발자입니다.
- 특히 위키 형식의 문서 관리, knowledge graph 구조의 시각화에 관심이 있어요.
- kodingwarrior.github.io/wiki

Neovim 이라는 텍스트 에디터에 굉장히 꽂혀있습니다.
- 과몰입한 나머지 플러그인까지 개발해본 경험이 있어요.
- 한국어권 개발자를 위한 Vim 디스코드를 운영중입니다 (vim.kr)

프로그래밍을 하는 행위 자체를 좋아합니다.
- 프로그래밍으로 퍼즐을 푸는 행위를 좋아했고, 비슷한 흔적을 가진 사람들에게 친밀감을 느낍니다.

0
0
0
0
0
0
0
0
0
0
0

그동안(10+년;;) git이 엄청 잘만든 물건 같지는 않다고 생각하며 대충 쓰고있었는데, 요즘 branch 개념 자체가 근본적인 실수란 생각이 들기 시작했다. branch 대신에 변경의 시작과 끝, 양 끝점을 가지는 interval을 쓰는게 맞는거 같다(카테고리 이론의 작은 교훈: primitive는 양 끝점을 가지는게 좋다).

git을 쓰면 히스토리 길어진다고 squash merge 등을 하는데, (나도 하지만) 사실 기껏 만들어놓은 히스토리를 뭉개버리는 말도 안되는 동작이다. 만약 interval을 쓴다면 히스토리는 그대로 남기고 UI 단에서 fold/unfold 등을 해줄수 있을 것이다.

Darcs 등이 interval에 기초하는데, 지금은 일이 너무 바빠서 시도할 여유가 없다. 한번 숨고를 시간이 주어지면 멀쩡한 VCS를 탐색하는 시간을 가질것이다.

0
0

해커펍은 퍼머링크로 아카이빙 참조하기 최적이라 생각해서 앞으로 기술을 다루며 기록 및 참조하는 용도로 잘 사용하려고 합니다.

트위터는 나중에 다른 사람에게 보여줄 참조용으로 쓰기에는 너무 정보 대비 소음이 많은 특성 때문에 잘 맞지 않는다고 생각합니다.

0

📢 Hackers' Pub 招待システムオープン!

Hackers' Pub に招待システムが適用されました。これで設定→招待ページから知人を招待できます。

主な内容:

  • 招待状3枚支給:既存会員の皆様には3枚の招待状が支給されました。
  • 招待方法:設定→招待ページで招待リンクを作成して共有するか、メールアドレスを入力して招待できます。
  • 追加招待:招待状は今後不定期に追加される予定です。
  • 自動フォロー:招待者と被招待者は自動的に相互フォローされます。(フォロー解除可能)

Hackers' Pub のクオリティを維持し、より豊かな技術議論のために慎重な招待をお願いいたします。

ご不明な点やご要望は、この投稿への返信としてお寄せください。

Hackers' Pub コミュニティの成長にご協力をお願いいたします!

Hackers' Pub ウェブサイトの設定メニューにある「招待 (3)」が選択された状態のスクリーンショットです。ページ上部には「友達を Hackers' Pub に招待しましょう。最大 3 人まで招待できます」というテキストが表示されています。その下には、「メールアドレス」とラベル付けされた入力フィールドがあり、「メールアドレスは招待状を受け取るだけでなく、アカウントへのログインにも使用されます」という説明文が続いています。さらに下には、「追加メッセージ」というラベルの付いたテキストエリアと、「友達は招待メールでこのメッセージを見ることができます」という説明があります。ページ下部には「招待状を送る」というボタンと、「招待者」というセクションがあり、「洪 民意 (Hong Minhee) (@hongminhee@hackers.pub)」という名前とユーザー名が表示されています。
0

📢 Hackers' Pub 초대 시스템 오픈!

Hackers' Pub에 초대 시스템이 적용되었습니다. 이제 설정초대 페이지에서 지인들을 초대할 수 있습니다.

주요 내용:

  • 초대장 3장 지급: 기존 회원분들께 3장의 초대장이 지급되었습니다.
  • 초대 방법: 설정 → 초대 페이지에서 초대 링크를 생성하여 공유하거나, 이메일 주소를 입력하여 초대할 수 있습니다.
  • 추가 초대: 초대장은 향후 비정기적으로 추가될 예정입니다.
  • 자동 팔로: 초대자와 피초대자는 자동으로 상호 팔로됩니다. (언팔로 가능.)

Hackers' Pub의 퀄리티를 유지하고, 더욱 풍성한 기술 논의를 위해 신중한 초대를 부탁드립니다.

궁금한 점이나 건의사항은 답글로 남겨주세요.

Hackers' Pub 커뮤니티 성장에 많은 참여 부탁드립니다!

Hackers' Pub 웹사이트의 설정 메뉴에서 “초대 (3)”이 선택된 화면입니다. 페이지 제목은 “Hackers' Pub에 친구를 초대하세요. 현재 3장의 초대장이 남아 있습니다”로 표시되어 있습니다. 아래에는 이메일 주소를 입력하는 필드와 “이메일 주소는 초대장을 받을 때 뿐만 아니라, 계정에 로그인 할 때도 사용됩니다”라는 안내 문구가 있습니다. 그 아래에는 “추가 메시지”라는 제목의 텍스트 영역과 “초대장을 받는 친구가 볼 수 있는 메시지입니다”라는 설명이 있습니다. 하단에는 “초대장 보내기” 버튼과 “초대한 사람” 목록이 표시되어 있으며, “洪 民意 (Hong Minhee) (@hongminhee@hackers.pub)”라는 이름과 아이디가 적혀 있습니다.

📢 Hackers' Pub 招待システムオープン!

Hackers' Pub に招待システムが適用されました。これで設定→招待ページから知人を招待できます。

主な内容:

  • 招待状3枚支給:既存会員の皆様には3枚の招待状が支給されました。
  • 招待方法:設定→招待ページで招待リンクを作成して共有するか、メールアドレスを入力して招待できます。
  • 追加招待:招待状は今後不定期に追加される予定です。
  • 自動フォロー:招待者と被招待者は自動的に相互フォローされます。(フォロー解除可能)

Hackers' Pub のクオリティを維持し、より豊かな技術議論のために慎重な招待をお願いいたします。

ご不明な点やご要望は、この投稿への返信としてお寄せください。

Hackers' Pub コミュニティの成長にご協力をお願いいたします!

Hackers' Pub ウェブサイトの設定メニューにある「招待 (3)」が選択された状態のスクリーンショットです。ページ上部には「友達を Hackers' Pub に招待しましょう。最大 3 人まで招待できます」というテキストが表示されています。その下には、「メールアドレス」とラベル付けされた入力フィールドがあり、「メールアドレスは招待状を受け取るだけでなく、アカウントへのログインにも使用されます」という説明文が続いています。さらに下には、「追加メッセージ」というラベルの付いたテキストエリアと、「友達は招待メールでこのメッセージを見ることができます」という説明があります。ページ下部には「招待状を送る」というボタンと、「招待者」というセクションがあり、「洪 民意 (Hong Minhee) (@hongminhee@hackers.pub)」という名前とユーザー名が表示されています。
0

📢 Hackers' Pub 초대 시스템 오픈!

Hackers' Pub에 초대 시스템이 적용되었습니다. 이제 설정초대 페이지에서 지인들을 초대할 수 있습니다.

주요 내용:

  • 초대장 3장 지급: 기존 회원분들께 3장의 초대장이 지급되었습니다.
  • 초대 방법: 설정 → 초대 페이지에서 초대 링크를 생성하여 공유하거나, 이메일 주소를 입력하여 초대할 수 있습니다.
  • 추가 초대: 초대장은 향후 비정기적으로 추가될 예정입니다.
  • 자동 팔로: 초대자와 피초대자는 자동으로 상호 팔로됩니다. (언팔로 가능.)

Hackers' Pub의 퀄리티를 유지하고, 더욱 풍성한 기술 논의를 위해 신중한 초대를 부탁드립니다.

궁금한 점이나 건의사항은 답글로 남겨주세요.

Hackers' Pub 커뮤니티 성장에 많은 참여 부탁드립니다!

Hackers' Pub 웹사이트의 설정 메뉴에서 “초대 (3)”이 선택된 화면입니다. 페이지 제목은 “Hackers' Pub에 친구를 초대하세요. 현재 3장의 초대장이 남아 있습니다”로 표시되어 있습니다. 아래에는 이메일 주소를 입력하는 필드와 “이메일 주소는 초대장을 받을 때 뿐만 아니라, 계정에 로그인 할 때도 사용됩니다”라는 안내 문구가 있습니다. 그 아래에는 “추가 메시지”라는 제목의 텍스트 영역과 “초대장을 받는 친구가 볼 수 있는 메시지입니다”라는 설명이 있습니다. 하단에는 “초대장 보내기” 버튼과 “초대한 사람” 목록이 표시되어 있으며, “洪 民意 (Hong Minhee) (@hongminhee@hackers.pub)”라는 이름과 아이디가 적혀 있습니다.
0

📢 Hackers' Pub 초대 시스템 오픈!

Hackers' Pub에 초대 시스템이 적용되었습니다. 이제 설정초대 페이지에서 지인들을 초대할 수 있습니다.

주요 내용:

  • 초대장 3장 지급: 기존 회원분들께 3장의 초대장이 지급되었습니다.
  • 초대 방법: 설정 → 초대 페이지에서 초대 링크를 생성하여 공유하거나, 이메일 주소를 입력하여 초대할 수 있습니다.
  • 추가 초대: 초대장은 향후 비정기적으로 추가될 예정입니다.
  • 자동 팔로: 초대자와 피초대자는 자동으로 상호 팔로됩니다. (언팔로 가능.)

Hackers' Pub의 퀄리티를 유지하고, 더욱 풍성한 기술 논의를 위해 신중한 초대를 부탁드립니다.

궁금한 점이나 건의사항은 답글로 남겨주세요.

Hackers' Pub 커뮤니티 성장에 많은 참여 부탁드립니다!

Hackers' Pub 웹사이트의 설정 메뉴에서 “초대 (3)”이 선택된 화면입니다. 페이지 제목은 “Hackers' Pub에 친구를 초대하세요. 현재 3장의 초대장이 남아 있습니다”로 표시되어 있습니다. 아래에는 이메일 주소를 입력하는 필드와 “이메일 주소는 초대장을 받을 때 뿐만 아니라, 계정에 로그인 할 때도 사용됩니다”라는 안내 문구가 있습니다. 그 아래에는 “추가 메시지”라는 제목의 텍스트 영역과 “초대장을 받는 친구가 볼 수 있는 메시지입니다”라는 설명이 있습니다. 하단에는 “초대장 보내기” 버튼과 “초대한 사람” 목록이 표시되어 있으며, “洪 民意 (Hong Minhee) (@hongminhee@hackers.pub)”라는 이름과 아이디가 적혀 있습니다.
0
0
0
0
0

Juntai Park shared the below article:

Revisiting Java's Checked Exceptions: An Underappreciated Type Safety Feature

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

Despite their bad reputation in the Java community, checked exceptions provide superior type safety comparable to Rust's Result<T, E> or Haskell's Either a b—we've been dismissing one of Java's best features all along.

Introduction

Few features in Java have been as consistently criticized as checked exceptions. Modern Java libraries and frameworks often go to great lengths to avoid them. Newer JVM languages like Kotlin have abandoned them entirely. Many experienced Java developers consider them a design mistake.

But what if this conventional wisdom is wrong? What if checked exceptions represent one of Java's most forward-thinking features?

In this post, I'll argue that Java's checked exceptions were ahead of their time, offering many of the same type safety benefits that are now celebrated in languages like Rust and Haskell. Rather than abandoning this feature, we should consider how to improve it to work better with modern Java's features.

Understanding Java's Exception Handling Model

To set the stage, let's review how Java's exception system works:

  • Unchecked exceptions (subclasses of RuntimeException or Error): These don't need to be declared or caught. They typically represent programming errors (NullPointerException, IndexOutOfBoundsException) or unrecoverable conditions (OutOfMemoryError).

  • Checked exceptions (subclasses of Exception but not RuntimeException): These must either be caught with try/catch blocks or declared in the method signature with throws. They represent recoverable conditions that are outside the normal flow of execution (IOException, SQLException).

Here's how this works in practice:

// Checked exception - compiler forces you to handle or declare it
public void readFile(String path) throws IOException {
    Files.readAllLines(Path.of(path));
}

// Unchecked exception - no compiler enforcement
public void processArray(int[] array) {
    int value = array[array.length + 1]; // May throw ArrayIndexOutOfBoundsException
}

The Type Safety Argument for Checked Exceptions

At their core, checked exceptions are a way of encoding potential failure modes into the type system via method signatures. This makes certain failure cases part of the API contract, forcing client code to explicitly handle these cases.

Consider this method signature:

public byte[] readFileContents(String filePath) throws IOException

The throws IOException clause tells us something critical: this method might fail in ways related to IO operations. The compiler ensures you can't simply ignore this fact. You must either:

  1. Handle the exception with a try-catch block
  2. Propagate it by declaring it in your own method signature

This type-level representation of potential failures aligns perfectly with principles of modern type-safe programming.

Automatic Propagation: A Hidden Advantage

One often overlooked advantage of Java's checked exceptions is their automatic propagation. Once you declare a method as throws IOException, any exception that occurs is automatically propagated to the caller without additional syntax.

Compare this with Rust, where you must use the ? operator every time you call a function that returns a Result:

// Rust requires explicit propagation with ? for each call
fn read_and_process(path: &str) -> Result<(), std::io::Error> {
    let content = std::fs::read_to_string(path)?;
    process_content(&content)?;
    Ok(())
}

// Java automatically propagates exceptions once declared
void readAndProcess(String path) throws IOException {
    String content = Files.readString(Path.of(path));
    processContent(content); // If this throws IOException, it's automatically propagated
}

In complex methods with many potential failure points, Java's approach leads to cleaner code by eliminating the need for repetitive error propagation markers.

Modern Parallels: Result Types in Rust and Haskell

The approach of encoding failure possibilities in the type system has been adopted by many modern languages, most notably Rust with its Result<T, E> type and Haskell with its Either a b type.

In Rust:

fn read_file_contents(file_path: &str) -> Result<Vec<u8>, std::io::Error> {
    std::fs::read(file_path)
}

When calling this function, you can't just ignore the potential for errors—you need to handle both the success case and the error case, often using the ? operator or pattern matching.

In Haskell:

readFileContents :: FilePath -> IO (Either IOException ByteString)
readFileContents path = try $ BS.readFile path

Again, the caller must explicitly deal with both possible outcomes.

This is fundamentally the same insight that motivated Java's checked exceptions: make failure handling explicit in the type system.

Valid Criticisms of Checked Exceptions

If checked exceptions are conceptually similar to these widely-praised error handling mechanisms, why have they fallen out of favor? There are several legitimate criticisms:

1. Excessive Boilerplate in the Call Chain

The most common complaint is the boilerplate required when propagating exceptions up the call stack:

void methodA() throws IOException {
    methodB();
}

void methodB() throws IOException {
    methodC();
}

void methodC() throws IOException {
    // Actual code that might throw IOException
}

Every method in the chain must declare the same exception, creating repetitive code. While automatic propagation works well within a method, the explicit declaration in method signatures creates overhead.

2. Poor Integration with Functional Programming

Java 8 introduced lambdas and streams, but checked exceptions don't play well with them:

// Won't compile because map doesn't expect functions that throw checked exceptions
List<String> fileContents = filePaths.stream()
    .map(path -> Files.readString(Path.of(path))) // Throws IOException
    .collect(Collectors.toList());

This forces developers to use awkward workarounds:

List<String> fileContents = filePaths.stream()
    .map(path -> {
        try {
            return Files.readString(Path.of(path));
        } catch (IOException e) {
            throw new UncheckedIOException(e); // Wrap in an unchecked exception
        }
    })
    .collect(Collectors.toList());

3. Interface Evolution Problems

Adding a checked exception to an existing method breaks all implementing classes and calling code. This makes evolving interfaces over time difficult, especially for widely-used libraries and frameworks.

4. Catch-and-Ignore Anti-Pattern

The strictness of checked exceptions can lead to the worst possible outcome—developers simply catching and ignoring exceptions to make the compiler happy:

try {
    // Code that might throw
} catch (Exception e) {
    // Do nothing or just log
}

This is worse than having no exception checking at all because it provides a false sense of security.

Improving Checked Exceptions Without Abandoning Them

Rather than abandoning checked exceptions entirely, Java could enhance the existing system to address these legitimate concerns. Here are some potential improvements that preserve the type safety benefits while addressing the practical problems:

1. Allow lambdas to declare checked exceptions

One of the biggest pain points with checked exceptions today is their incompatibility with functional interfaces. Consider how much cleaner this would be:

// Current approach - forced to handle or wrap exceptions inline
List<String> contents = filePaths.stream()
    .map(path -> {
        try {
            return Files.readString(Path.of(path));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    })
    .collect(Collectors.toList());

// Potential future approach - lambdas can declare exceptions
List<String> contents = filePaths.stream()
    .map((String path) throws IOException -> Files.readString(Path.of(path)))
    .collect(Collectors.toList());

This would require updating functional interfaces to support exception declarations:

@FunctionalInterface
public interface Function<T, R, E extends Exception> {
    R apply(T t) throws E;
}

2. Generic exception types in throws clauses

Another powerful enhancement would be allowing generic type parameters in throws clauses:

public <E extends Exception> void processWithException(Supplier<Void, E> supplier) throws E {
    supplier.get();
}

This would enable much more flexible composition of methods that work with different exception types, bringing some of the flexibility of Rust's Result<T, E> to Java's existing exception system.

3. Better support for exception handling in functional contexts

Unlike Rust which requires the ? operator for error propagation, Java already automatically propagates checked exceptions when declared in the method signature. What Java needs instead is better support for checked exceptions in functional contexts:

// Current approach for handling exceptions in streams
List<String> contents = filePaths.stream()
    .map(path -> {
        try {
            return Files.readString(Path.of(path));
        } catch (IOException e) {
            throw new RuntimeException(e); // Lose type information
        }
    })
    .collect(Collectors.toList());

// Hypothetical improved API
List<String> contents = filePaths.stream()
    .mapThrowing(path -> Files.readString(Path.of(path))) // Preserves checked exception
    .onException(IOException.class, e -> logError(e))
    .collect(Collectors.toList());

4. Integration with Optional<T> and Stream<T> APIs

The standard library could be enhanced to better support operations that might throw checked exceptions:

// Hypothetical API
Optional<String> content = Optional.ofThrowable(() -> Files.readString(Path.of("file.txt")));
content.ifPresentOrElse(
    this::processContent,
    exception -> log.error("Failed to read file", exception)
);

Comparison with Other Languages' Approaches

It's worth examining how other languages have addressed the error handling problem:

Rust's Result<T, E> and ? operator

Rust's approach using Result<T, E> and the ? operator shows how propagation can be made concise while keeping the type safety benefits. The ? operator automatically unwraps a successful result or returns the error to the caller, making propagation more elegant.

However, Rust's approach requires explicit propagation at each step, which can be more verbose than Java's automatic propagation in certain scenarios.

Kotlin's Approach

Kotlin made all exceptions unchecked but provides functional constructs like runCatching that bring back some type safety in a more modern way:

val result = runCatching {
    Files.readString(Path.of("file.txt"))
}

result.fold(
    onSuccess = { content -> processContent(content) },
    onFailure = { exception -> log.error("Failed to read file", exception) }
)

This approach works well with Kotlin's functional programming paradigm but lacks compile-time enforcement.

Scala's Try[T], Either[A, B], and Effect Systems

Scala offers Try[T], Either[A, B], and various effect systems that encode errors in the type system while integrating well with functional programming:

import scala.util.Try

val fileContent: Try[String] = Try {
  Source.fromFile("file.txt").mkString
}

fileContent match {
  case Success(content) => processContent(content)
  case Failure(exception) => log.error("Failed to read file", exception)
}

This approach preserves type safety while fitting well with Scala's functional paradigm.

Conclusion

Java's checked exceptions were a pioneering attempt to bring type safety to error handling. While the implementation has shortcomings, the core concept aligns with modern type-safe approaches to error handling in languages like Rust and Haskell.

Copying Rust's Result<T, E> might seem like the obvious solution, but it would represent a radical departure from Java's established paradigms. Instead, targeted enhancements to the existing checked exceptions system—like allowing lambdas to declare exceptions and supporting generic exception types—could preserve Java's unique approach while addressing its practical limitations.

The beauty of such improvements is that they'd maintain backward compatibility while making checked exceptions work seamlessly with modern Java features like lambdas and streams. They would acknowledge that the core concept of checked exceptions was sound—the problem was in the implementation details and their interaction with newer language features.

So rather than abandoning checked exceptions entirely, perhaps we should recognize them as a forward-thinking feature that was implemented before its time. As Java continues to evolve, we have an opportunity to refine this system rather than replace it.

In the meantime, next time you're tempted to disparage checked exceptions, remember: they're not just an annoying Java quirk—they're an early attempt at the same type safety paradigm that newer languages now implement with much celebration.

What do you think? Could these improvements make checked exceptions viable for modern Java development? Or is it too late to salvage this controversial feature? I'm interested in hearing your thoughts in the comments.

Read more →
0
0
3

자바의 체크드 예외 재고찰: 저평가된 타입 안전성 기능
------------------------------
## 주요 내용 요약

* 자바의 체크드 예외가 커뮤니티에서 널리 비판받는 기능임에도 타입 안전성 측면에서 뛰어난 장점 보유.
* Rust의
Result<T, E>나 Haskell의 Either a b와 개념적으로 유사한 타입 안전성 메커니즘 제공.
* 체크드 예외가 메서드 시그니처에 잠재적 실패 가능성을 명시적으로 표현하…
------------------------------
https://news.hada.io/topic?id=19877&utm_source=googlechat&utm_medium=bot&utm_campaign=1834

0

@arkjunJuntai Park 아… 그럼 Threads의 주제는 ActivityPub 상에서 마크업이 되진 않는 것 같네요. Threads 내부에서만 활용 가능한 기능인가 봅니다. 참고로 이찬진 님의 해당 글은 Activity Streams 객체로 아래와 같이 표현되고 있습니다:

{
  "id": "https://threads.net/ap/users/17841400639660143/post/17976118301827877/",
  "type": "Note",
  "content": "<p>이제 스레드의 &#039;주제(Topic)&#039; 기능을 &#039;해시태그&#039;라고 부를 수 없겠네요. <br /><br />게시물 작성 화면에서 &#039;해시태그&#039;를 의미하는 &#039;#&#039; 버튼이 없어졌고 대신 &#039;주제 추가&#039; 버튼이 들어갔습니다. <br /><br />물론 전에 &#039;해시태그&#039;와 비슷하게 보일 때에도<br /><br />- 게시물에 하나 밖에 쓸 수 없었고<br />- 태그에 스페이스를 쓸 수 있었고<br />- &#039;#&#039;이 없었으니<br /><br />정확하게 해시태그는 아니었지만 이제는 입력하는 방법도 그렇고 표시되는 위치도 그렇고 확실히 &#039;주제&#039; 기능이라고 불러야겠네요.<br />#스레드 개선</p>",
  "published": "2025-03-20T18:35:52-07:00",
  "contentMap": {
    "ko": "<p>이제 스레드의 &#039;주제(Topic)&#039; 기능을 &#039;해시태그&#039;라고 부를 수 없겠네요. <br /><br />게시물 작성 화면에서 &#039;해시태그&#039;를 의미하는 &#039;#&#039; 버튼이 없어졌고 대신 &#039;주제 추가&#039; 버튼이 들어갔습니다. <br /><br />물론 전에 &#039;해시태그&#039;와 비슷하게 보일 때에도<br /><br />- 게시물에 하나 밖에 쓸 수 없었고<br />- 태그에 스페이스를 쓸 수 있었고<br />- &#039;#&#039;이 없었으니<br /><br />정확하게 해시태그는 아니었지만 이제는 입력하는 방법도 그렇고 표시되는 위치도 그렇고 확실히 &#039;주제&#039; 기능이라고 불러야겠네요.<br />#스레드 개선</p>"
  },
  "attributedTo": "https://threads.net/ap/users/17841400639660143/",
  "url": "https://www.threads.net/@chanjin65/post/DHcXMcczYx6",
  "to": [
    "https://www.w3.org/ns/activitystreams#Public"
  ],
  "cc": [
    "https://threads.net/ap/users/17841400639660143/followers/"
  ],
  "@context": [
    "https://www.w3.org/ns/activitystreams"
  ],
  "tag": [],
  "attachment": [
    {
      "type": "Image",
      "url": "https://scontent-ssn1-1.cdninstagram.com/v/t51.75761-15/485651795_17904023592105580_5390283833466719793_n.jpg?stp=dst-jpg_e35_tt6&_nc_cat=104&ccb=1-7&_nc_sid=18de74&_nc_ohc=Ds02qFOIJUUQ7kNvgGjxYCA&_nc_oc=AdnVGfWmGdOHV2sZAvWtcv1M0iaLjV4A-RbC0lDI_hgvwYrnt69HjBGo_js8NkvX6T0&_nc_zt=23&_nc_ht=scontent-ssn1-1.cdninstagram.com&edm=AMJMky4EAAAA&_nc_gid=dudtlAu0RjYNhaifxVdB_Q&oh=00_AYG5YaNk9YbLpECGixfB74Lgi9-VSZhhYWByBvTi6lGBaw&oe=67E29C5A",
      "name": "Photo by 이차지 on March 20, 2025. 사람 1명, 화면 및 문구: '10:26 취소 새로운 스레드 베타 베타·페디버스에공유합니다. 페디버스메 공유합니 chanjin65 chanjin650>7 이>주제추7 스레드에추가 누구에게나답글및인용허용 인용허용 N ㅂ 2 天 世 3 C 4 ٦ 5 人 6 Η ㅔ ㅁ니ㅇ리ㅎ 2 ᄒ @ ١ ᄏ ㅏ E 天 ㅍ T AAA 123 간격 AH KIy'의 Twitter 스크린샷일 수 있음.",
      "width": 1125,
      "height": 2436
    }
  ]
}
0
0
0
0
0
0
  1. 처음 써 보는 조용한 공개. 조용한 공개는 일반 공개와 뭐가 다를까. 연합 우주에는 올라가지 않는 거려나?
  2. 블스 연동을 했는데 hackers.pub 프로필에 쓴 텍스트가 블스 프로필로는 다 옮겨지지 않는다. 글자 수 제한이 있는 걸까요.
  3. 앱 지면을 무슨 아마존처럼 탐험하며 여기도 광고 넣을 수 있겠다! 저기도! 하는 흐름에 현기증이 난다. 이게 우리 회사 임원인지 사모펀드인지⋯.
  4. 마라톤 행사만 끝나고 나면 이것저것 해 보고 싶은 게 많은데.
0
0
0
0
0
0
0

오픈소스 프로젝트를 시작하는 비법은 특별한게 아니다.

일정 주기(일, 주, 월, 년 등) 반복되는 동일한 수기 또는 수동 작업 -> 공통범주로 최대한 묶음 -> 적정한 수준의 자동화 계획 -> 코드로 구현 -> 오픈소스 라이선스 붙여서 공개

이게 곧 프로젝트가 되는거임.

0
0