bgl gwyng

@bgl@hackers.pub · 63 following · 64 followers

슈티를 함께 만들 팀을 만들고 있습니다. 관심 있으신 분, 또는 잘 모르겠지만 이야기를 나눠보고 싶은 분도 bgl@gwyng.com으로 편하게 연락주세요.

GitHub
@bglgwyng
shootee
www.shootee.io

bgl gwyng replied to the below article:

셸 언어는 때로 추하길 요구 받는다

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

명령줄 인터페이스(CLI)는 컴퓨터와 상호작용하는 가장 오래된 방식 중 하나다. 그리고 이 인터페이스를 지배하는 것은 셸 언어다. 그런데 흥미로운 점은 셸 언어가 일반적인 프로그래밍 언어들과는 상당히 다른 설계 철학을 따른다는 것이다. 한 마디로 요약하자면, 셸 언어는 때로 “추함”을 받아들여야 한다.

간결함의 미학

Bash나 zsh와 같은 전통적인 셸을 보자. grep -r "error" /var/log | wc -l와 같은 명령은 암호처럼 보일 수 있지만, 타이핑하는 데 몇 초밖에 걸리지 않는다. 이러한 간결함은 우연히 생긴 것이 아니다. 셸 환경에서는 사용자가 빠르게 입력하고, 결과를 확인하고, 다시 명령을 수정하는 반복적인 워크플로우가 일반적이다. 여기서 핵심은 “대화형” 경험이다.

PowerShell의 딜레마

PowerShell은 마이크로소프트가 셸의 개념을 재정의하려 한 야심찬 시도였다. 객체 지향적 파이프라인, 일관된 동사–명사 구문, 그리고 자세한 매개변수 이름 등은 모두 코드의 가독성과 유지보수성을 높이기 위한 설계였다.

그러나 다음 명령을 비교해보자:

Bash:

find . -name "*.log" -mtime -7 \
  | xargs grep "error" \
  | sort \
  | uniq -c

PowerShell:

Get-ChildItem -Path . -Filter *.log `
  | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-7)} `
  | ForEach-Object {Select-String -Path $_.FullName -Pattern "error"} `
  | Sort-Object `
  | Group-Object `
  | Select-Object Name,Count

PowerShell의 명령은 더 명확하고 자기 설명적이지만, 대화형 셸에서 빠르게 실험하고 반복하기에는 너무 장황하다. PowerShell 설계자들은 “추함”을 견디지 못하고 너무 많은 “다림질”을 해버린 것이다.

균형점 찾기

흥미롭게도 최근의 Nushell 같은 현대적인 셸은 이 교훈을 받아들이고 있다. 구조화된 데이터 처리와 같은 PowerShell의 장점을 가져오면서도, 대화형 사용에 필요한 간결함을 유지하려 노력한다.

셸 언어의 진정한 성공은 “아름다운 코드”와 “효율적인 상호작용” 사이의 균형에 달려 있다. 이는 때로 완벽한 문법이나 일관성보다는 실용적인 “추함”을 수용해야 함을 의미한다.

결론

프로그래밍 언어의 세계에서는 우아함과 일관성이 미덕이다. 그러나 셸의 세계에서는 타이핑 효율성, 속도, 그리고 대화형 적합성이 우선시된다. 이것이 바로 셸 언어가 때로 “추함”을 요구받는 이유다. PowerShell의 제한적인 성공은 이 기본적인 진실을 간과한 데서 비롯된 것일지도 모른다.

그리고 어쩌면 이것은 소프트웨어 설계 전반에 걸친 더 깊은 교훈을 담고 있다: 모든 도구는 그 사용 맥락에 맞게 설계되어야 한다는 것이다. 셸 언어에서는 그 맥락이 바로 키보드와 사용자 사이의 빠른 대화다.

Read more →
0
0
0
0

실용적인 프로그램을 만들 수는 없겠지만, Maude와 같은 정형 명세 언어도 재미있습니다. 저는 실제 코드를 쓰기 전에 데이터 흐름을 정리하고 추상화 하여 스펙을 명확히 하는데 사용합니다. 단점은 GitHub에서 무슨 언어인지 몰라서 통계가 안 잡힙니다.

0

bgl gwyng shared the below article:

셸 언어는 때로 추하길 요구 받는다

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

명령줄 인터페이스(CLI)는 컴퓨터와 상호작용하는 가장 오래된 방식 중 하나다. 그리고 이 인터페이스를 지배하는 것은 셸 언어다. 그런데 흥미로운 점은 셸 언어가 일반적인 프로그래밍 언어들과는 상당히 다른 설계 철학을 따른다는 것이다. 한 마디로 요약하자면, 셸 언어는 때로 “추함”을 받아들여야 한다.

간결함의 미학

Bash나 zsh와 같은 전통적인 셸을 보자. grep -r "error" /var/log | wc -l와 같은 명령은 암호처럼 보일 수 있지만, 타이핑하는 데 몇 초밖에 걸리지 않는다. 이러한 간결함은 우연히 생긴 것이 아니다. 셸 환경에서는 사용자가 빠르게 입력하고, 결과를 확인하고, 다시 명령을 수정하는 반복적인 워크플로우가 일반적이다. 여기서 핵심은 “대화형” 경험이다.

PowerShell의 딜레마

PowerShell은 마이크로소프트가 셸의 개념을 재정의하려 한 야심찬 시도였다. 객체 지향적 파이프라인, 일관된 동사–명사 구문, 그리고 자세한 매개변수 이름 등은 모두 코드의 가독성과 유지보수성을 높이기 위한 설계였다.

그러나 다음 명령을 비교해보자:

Bash:

find . -name "*.log" -mtime -7 \
  | xargs grep "error" \
  | sort \
  | uniq -c

PowerShell:

Get-ChildItem -Path . -Filter *.log `
  | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-7)} `
  | ForEach-Object {Select-String -Path $_.FullName -Pattern "error"} `
  | Sort-Object `
  | Group-Object `
  | Select-Object Name,Count

PowerShell의 명령은 더 명확하고 자기 설명적이지만, 대화형 셸에서 빠르게 실험하고 반복하기에는 너무 장황하다. PowerShell 설계자들은 “추함”을 견디지 못하고 너무 많은 “다림질”을 해버린 것이다.

균형점 찾기

흥미롭게도 최근의 Nushell 같은 현대적인 셸은 이 교훈을 받아들이고 있다. 구조화된 데이터 처리와 같은 PowerShell의 장점을 가져오면서도, 대화형 사용에 필요한 간결함을 유지하려 노력한다.

셸 언어의 진정한 성공은 “아름다운 코드”와 “효율적인 상호작용” 사이의 균형에 달려 있다. 이는 때로 완벽한 문법이나 일관성보다는 실용적인 “추함”을 수용해야 함을 의미한다.

결론

프로그래밍 언어의 세계에서는 우아함과 일관성이 미덕이다. 그러나 셸의 세계에서는 타이핑 효율성, 속도, 그리고 대화형 적합성이 우선시된다. 이것이 바로 셸 언어가 때로 “추함”을 요구받는 이유다. PowerShell의 제한적인 성공은 이 기본적인 진실을 간과한 데서 비롯된 것일지도 모른다.

그리고 어쩌면 이것은 소프트웨어 설계 전반에 걸친 더 깊은 교훈을 담고 있다: 모든 도구는 그 사용 맥락에 맞게 설계되어야 한다는 것이다. 셸 언어에서는 그 맥락이 바로 키보드와 사용자 사이의 빠른 대화다.

Read more →
0
0
0
0

역시 모든 것들은 직접 데여봐야 는다... React의 useContext가 뭐하려고 쓰는지 실감이 잘 안났었는데, prop drilling하지 않고 디펜던시를 주입하고 싶을때 유용한듯.

특히, 어떤 특정한 데이터를 다루는 복잡한 컴포넌트를 다룬다고 가정하면 요렇게 프로바이더에 넘겨주면 되고 하위 컴포넌트에서는 useContext에서 그 값을 가져오면 코드도 굉장히 깔끔해지게 되는 듯

  <PostContext.Provider value={{ currentUser }}>
     <Post.Title post={post} />
     <Post.Comments>
       {comments.map(comment =>
          <Post.Comment  comment={comment} />
        )}
     </Post.Comments>
  <PostContext.Provider>

이런 글도 있다.

https://testdouble.com/insights/react-context-for-dependency-injection-not-state-management

0

Hackers' Pub에 이제 알림 기능이 생겼습니다. 우상단 프로필 사진 바로 왼쪽에 알림 아이콘이 추가되었고, 이제 읽지 않은 알림이 있을 경우 그 위에 빨간 동그라미가 표시됩니다. 알림의 종류는 현재 다음 다섯 가지입니다:

  • 누가 날 팔로했을 때
  • 누가 날 언급했을 때
  • 누가 내 글에 답글을 달았을 때
  • 누가 내 글을 인용했을 때
  • 누가 내 글을 공유했을 때
Hackers' Pub의 우상단에 표시되는 아이콘들. 왼쪽부터 새 게시글 아이콘, 읽지 않은 알림 아이콘, 프로필 사진.
0

소수의견: 프로그래밍 언어의 identifier에서 그냥 소문자만 남기고 대문자를 아예 금지시켜야한다. 그리고 하이픈이나 언더바 둘중에 하나만 허용한다. 둘다 허용하면 취향에 따라 섞어쓰게된다. 진작에 이렇게 했으면 뭐시기 case 논쟁으로 시간낭비 안 했을것이다.

그리고 남은 대문자를 identifier와 충돌할 걱정없이 자유롭게 keyword에 쓰면 된다. 내가 생각하는 멋진 응용으로는, 객체 생성에 대표적으로 쓰이는 new 대신에 A를 쓰는 것이다. x = A user, 쏘쿨하지 않습니까.

0
0

@hongminhee洪 民憙 (Hong Minhee) @curry박준규 제가 Rust 유저한테 하스켈을 영업해본적은 없지만, Rust 유저들은 하스켈을 고를수 있는 선택지에서 이미 결정을 내리고 지나온 사람들이라고 생각했거든요. HKT, 모나드? 그런거보다 포인터 직접 만지고 최적화하는게 좋아.

근데 생각해보니 Rust가 언어덕후들이 파던 언어였던것도 이미 오래전 얘기고, 이제는 하스켈 등의 옵션을 고려하지 않은채로 Rust를 써야할 환경에 놓인 사람들도 많겠다 싶네요.

0

해커스 펍에 남기는 첫 글로 진.짜. 술을 파는 해커스 펍을 소개하겠습니다… 도쿄 히가시나카노에 위치한ハッカーズバー(hackers bar)에 가시면 바텐더 분의 라이브코딩을 구경하며 블루스크린, 커널 패닉 등의 이름이 붙여진 칵테일을 마실 수 있어요… 모두가 각자의 랩탑을 들고 와서 자유롭게 코딩하고 이야기 나누는 분위기! 도쿄에서 손에 꼽게 인상적이었던 바였습니다. 도쿄에서 술도 마시고 코딩도 하고 싶으신 분들은 한 번 들러보심이~~!

긴 술 잔에 파란색 술이 담겨있다.술집 천장에 달린 세개의 모니터를 사람들이 보고 있다.
0
0
2
0

bgl gwyng shared the below article:

함수형 프로그래머한테 닉스 패키지 매니저의 derivation 소개하는 글

lionhairdino @lionhairdino@hackers.pub

닉스의 derivation은 코드 모양으로만 보면, 단순히 빌드에 필요한 속성의 집합이다. 별 거 아닌 것 같지만, 이 개념이 닉스의 핵심 아이디어다. 패키지를 빌드할 때 개입하는 널리고 널린 이펙트들을 깡그리 무시하고, 순수한 척 하는 derivation만으로 의존 관계를 표현한다. 만일, 패키지A가 패키지B에 의존한다면, A의 derivation이 B의 derivation에 의존한다고 표시해 둔다. 이렇게 derivation만 엮어서 패키지 빌드 명세서를 완성해 두고, 진짜 패키지가 필요한 순간이 오면, 그때서야 realize란 동작으로, 미뤄 놨던 이펙트들의 영향을 받게 된다. 모나드들의 runner처럼 말이다.

진짜 귀찮게 굴러야 하는 이펙트들은 나몰라라 하고, 고귀한 척 동작의 선언적인 명세서derivation만 조합해서 최종 결과 패키지를 위한 명세서를 작성하니 선언형 패키지 매니저라 부른다.

어떤 이펙트가 방해할지는 나중 문제고, 최종 패키지 명세서 자체는 순수한 derivation 조합으로만 구성해 놓고, 이들 이름에, 내용을 기반으로 계산한 해시까지 붙여 놓으니 절대 같은 이름, 다른 내용의 derivation이 생기지 않는다. 그래서 이들을 캐싱하기에도 좋고, 재현성도 올라간다고 한다.

다만, derivation에서 해시 베이스가 되는 필드의 점하나만 달라져도 해시값이 달라지니 다른 패키지가 되어버려, 디스크 용량이 좀 과하게 필요하고, 빌드 시간이 좀 과하게 걸리는 단점이 있다. 덕분에 쉴 시간이 자주 생긴다!

※ Nixpkgs를 보면 derivation이 아닌, derivation을 생성하는 표현식 .nix들의 모음으로 되어 있다.

(닉스 공부한지 몇 달 안된 사람의 노트입니다. 생각이 틀렸다면 알려주세요. 저는 혼자 공부한 내용들을 요약해서 블로그 혹은 닉스 NixOS.kr 디코에 올리고 제대로 길을 가고 있는지 검증 받곤 합니다.)

Read more →
0
0
0

Hackers' Pub 행동 강령을 관통하는 큰 키워드가, 존중배려라고 느꼈고, 그래서 더욱 Hackers' Pub 을 응원하고 있는데, 오랜 시간이 흘러도 추구하는 가치에 흔들림이 없으면 좋겠고, 여기에 더해 긍정적이고 밝은 에너지가 가득한 공간이 되기를 소망한다.

한가지만 더 첨언하자면, 개발자의 소소한 일상 얘기들도 많이 공유되었으면 좋겠다. (우선 나부터도 해야겠지만)

0

bgl gwyng shared the below article:

deno-task-hooks: Git 훅을 Deno 태스크로 쉽게 관리하기

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

안녕하세요! 오늘은 제가 개발한 deno-task-hooks 패키지를 소개해 드리려고 합니다. 이 도구는 Deno 태스크를 Git 훅으로 사용할 수 있게 해주는 간단하면서도 유용한 패키지입니다.

어떤 문제를 해결하나요?

Git을 사용하는 개발 팀에서는 코드 품질 유지를 위해 커밋이나 푸시 전에 린트, 테스트 등의 검증 작업을 실행하는 것이 일반적입니다. 이러한 작업은 Git 훅을 통해 자동화할 수 있지만, 기존 방식에는 몇 가지 문제가 있었습니다:

  • Git 훅 스크립트를 팀원들과 공유하기 어려움 (.git 디렉토리는 보통 버전 관리에서 제외됨)
  • 각 개발자가 로컬에서 훅을 직접 설정해야 하는 번거로움
  • 훅 스크립트의 일관성 유지가 어려움

deno-task-hooks는 이러한 문제를 해결하기 위해 Deno의 태스크 러너를 활용합니다. Deno 태스크는 deno.json 파일에 정의되어 버전 관리가 가능하므로, 팀 전체가 동일한 Git 훅을 쉽게 공유할 수 있습니다.

어떻게 작동하나요?

deno-task-hooks의 작동 방식은 간단합니다:

  1. deno.json 파일에 Git 훅으로 사용할 Deno 태스크를 정의합니다.
  2. hooks:install 태스크를 실행하면, 정의된 태스크들이 자동으로 .git/hooks/ 디렉토리에 설치됩니다.
  3. 이후 Git 작업 시 해당 훅이 트리거되면 연결된 Deno 태스크가 실행됩니다.

설치 및 사용 방법

1. hooks:install 태스크 추가하기

먼저 deno.json 파일에 hooks:install 태스크를 추가합니다:

{
  "tasks": {
    "hooks:install": "deno run --allow-read=deno.json,.git/hooks/ --allow-write=.git/hooks/ jsr:@hongminhee/deno-task-hooks"
  }
}

2. Git 훅 정의하기

Git 훅은 hooks: 접두사 다음에 훅 이름(케밥 케이스)을 붙여 정의합니다. 예를 들어, pre-commit 훅을 정의하려면:

{
  "tasks": {
    "hooks:pre-commit": "deno check *.ts && deno lint"
  }
}

3. 훅 설치하기

다음 명령어를 실행하여 정의된 훅을 설치합니다:

deno task hooks:install

이제 Git 커밋을 실행할 때마다 pre-commit 훅이 자동으로 실행되어 TypeScript 파일을 검사하고 린트 검사를 수행합니다.

지원되는 Git 훅 종류

deno-task-hooks는 다음과 같은 모든 Git 훅 타입을 지원합니다:

  • applypatch-msg
  • commit-msg
  • fsmonitor-watchman
  • post-update
  • pre-applypatch
  • pre-commit
  • pre-merge-commit
  • pre-push
  • pre-rebase
  • pre-receive
  • prepare-commit-msg
  • push-to-checkout
  • sendemail-validate
  • update

이점

deno-task-hooks를 사용하면 다음과 같은 이점이 있습니다:

  1. 간편한 공유: Git 훅을 deno.json 파일에 정의하여 팀 전체가 동일한 훅을 사용할 수 있습니다.
  2. 설정 용이성: 새 팀원은 저장소를 클론한 후 한 번의 명령어로 모든 훅을 설치할 수 있습니다.
  3. 유지 관리 용이성: 훅 스크립트를 중앙에서 관리하므로 변경 사항을 쉽게 추적하고 적용할 수 있습니다.
  4. Deno의 안전성: Deno의 권한 모델을 활용하여 훅 스크립트의 보안을 강화할 수 있습니다.

마치며

deno-task-hooks는 작은 패키지이지만, Git과 Deno를 함께 사용하는 팀의 개발 경험을 크게 향상시킬 수 있습니다. 코드 품질 유지와 개발 워크플로우 자동화를 위해 한번 사용해 보세요!

패키지는 JSR에서 다운로드할 수 있으며, GitHub에서 소스 코드를 확인할 수 있습니다.

피드백과 기여는 언제나 환영합니다! 😊

Read more →
0
0

아잇 오늘 확인해보니까

  1. emacs native-comp 잘 쓰고 있던 메인 맥은 macOS 15.3
  2. 새로 세팅한 맥은 하필 어제 업데이트를 누르는 바람에, 하필 어제 릴리즈된 macOS 15.4를 깔아버린 것

어쩐지 이슈가 없더라

0
0

요즘 OTT에서 미드보다 보면(영드,한드 보다 특히 미드) 정말 질떨어지는 시나리오들이 많다. 제대로된 갈등 구조도 없이, 그냥 성질 더럽고 의사소통 못하는 캐릭터들을 다수 등장시켜 걔네들끼리 언성높이고 투닥거리는 걸로 시간을 다 보낸다.

0

@hongminhee洪 民憙 (Hong Minhee) 음 표현이 좀 잘못된거 같네요. 버전에 constraint들 명시하면 그거 resolve해서 설치하겠죠. 제가 말하려고 했던건 lock이 개별 패키지 별로 안남고 indexed-state로 스냅샷 시간을 명시하는 방식이 마음에 안든가 거였습니다. cabal.freeze 또한 암호해시가 안 남고요.

0
0

근데 cabal처럼 기본이 스냅샷 모드인건 별로 같다. cabal로 locking하려면 시간으로(스냅샷을 특정할) 해야한다;; npm같이 각 패키지 버전과 lock이 있는 편이, 일단 심리적으로 더 든든하고, 또 가장 원자적인 동작을 더 확실하게 만든단 점에서 좋다.

대신 그 위에서 스냅샷(이라고 해야하나, 다른 이름이 있던거 같기도한데)을 다시 구현할수 있다. Expo같은 경우에 expo 패키지에 따라 나머지 expo-* 들의 버전이 결정되도록 한다.

0

bgl gwyng replied to the below article:

스태키지 큐레이션이 성공할 수 있었던 것은 하스켈이라는 언어와 생태계의 특징도 컸습니다.

juxtapose @xt@hackers.pub

인용: https://hackers.pub/@bgl/0195f0eb-88dd-77e3-a864-f0371e85b270

스태키지(Stackage)는 하스켈이 (의외로) 성공하여 해키지(Hackage)가 거대해지자, 그 거대함 때문에 발생하는 불편을 해소하는 한 방책으로 고안되었습니다. 그런데 당시에 해키지만큼 거대한 생태계를 갖추고 있으면서 동시에 "컴파일이 성공한다면 실행도 아마 성공할 것"이라는 훌륭한 속성을 갖는 언어는 달리 없었죠. 러스트가 있지 않으냐? 스태키지가 처음 나온 게 2012년입니다. 러스트는 아직 crates.io 도 자리잡기 전이었죠. (사실 이 시점의 러스트는 지금과는 언어 자체가 많이 다른 언어였고요.)

하스켈의 패키지 버저닝 정책에 따르면, 후방호환성 깨지는 변경은 반드시 메이저 버전을 올려야 하고, 마이너 버전만 올리는 변경은 후방호환성 유지될 때에만 가능합니다. 이런 정책 당연히 좋지만, 사람이 내용을 잘 숙지하고 지켜야 의미가 있습니다. 후방호환성을 깨면서 마이너 버전만 올리는 실수는 어떤 개발자든 할 수 있죠.

그런데 하스켈의 경우, 인간이 실수해도 기계가 잡아 줄 여지가 처음부터 매우 큰 언어이고, 예를 들어 어떤 함수가 핵미사일을 발사할 수 있는지 아닌지를 함수 실행 없이도 식별할 수 있는 언어라고들 하죠. 하스켈의 마지막 표준이 2010년에 나왔으니 2010년을 기준으로 하면, 당시 하스켈이 제공하는 "컴파일 시간 보장"의 범위는 그야말로 독보적이었습니다. (하스켈보다 더 강한 보장을 제공하는 언어들은 있었지만, 그만한 라이브러리 에코시스템이 없었고요.)

그래서 스태키지라는 모형이 의미가 있었습니다. A라는 패키지의 새 마이너 버전이 해키지에 올라오면, 스태키지에서 자동으로 가져갑니다. 스태키지는 같은 큐레이션에 포함된 다른 패키지들 중 A에 의존하는 패키지들을 추리고, 얘네한테 A의 새 버전을 먹여도 빌드가 잘 되는지 검사합니다. 이들 중 하나라도 깨지면? A 패키지는 해키지에서는 버전이 올랐으나, 스태키지에서는 버전이 오르지 않게 됩니다. 그리고 A 패키지의 제공자에게 자동으로 깃허브 멘션 알림이 갑니다!

("패키지 저자"와 "패키지를 스태키지에 제공하는 제공자"가 같은 사람이 아니어도 된다는 점도, 노동력의 효과적 분담에 한몫했습니다.)

이 모든 과정이 자동화되어 있는데, 이것만으로도 99.99%의 호환성 문제가 사라지고, 그러면서도 웬만한 라이브러리들은 충분히 최신 버전으로 쓸 수 있습니다. LTS와 나이틀리가 구분되어 있는 것도, LTS가 GHC 버전에 대응하여 여러 버전이 유지되는 것도, 실제 개발에서 아주 편리하고요.

스태키지가 개쩌는 부분은 "버저닝 정책에 완벽하게 부합하는데도 현실적으로 후방호환성 파괴를 일으키는" 변경점들도 잡아낸다는 것입니다. 아주 단순한 예시로 "많이 쓰이는 이름"이 있습니다. 예를 들어 어떤 라이브러리가 아주 널리 쓰이는데, 제공하는 네임 바인딩은 몇 개 안 되고, 그래서 대부분의 사용자가 그걸 그냥 전역 네임스페이스에 다 반입해서 쓴다고 칩시다. 어느 날 이 라이브러리가 process 라든지 f 같은 새 네임을 추가 제공하기 시작하면? 정책 규범에 따르면, 이것도 마이너 버전만 올려도 되는 변경점이 맞습니다. 하지만 현실에서는 많은 패키지들을 박살내겠죠. 언어를 막론하고 있을 수 있는 일인데, 이런 것들까지 스태키지에서 아주 높은 확률로 다 잡힙니다.

그리고... 이런 게 잘 된다는 것은 언어 그 자체의 특성도 있지만, 생태계 전체의 문화적인 특성도 있는데요. 하스켈도 라이브러리 제작자가 충분히 악독하다면, 컴파일러에게 안 잡히면서 인류문명멸망시키는 코드 변경을 얼마든지 슬쩍 끼워넣을 수 있습니다. 악의가 아니더라도 부주의로 후방호환성을 깰 수 있고요. 그런데 하스켈은 대부분의 라이브러리 설계자들이 "되도록 많은 것을 컴파일 시간에 잡고 싶다"라는 명확한 욕망으로 설계를 하는 경향이 뚜렷합니다. 그래서 호환성 문제는 웬만하면 스태키지 선에서 잡히고, 스태키지 큐레이션은 지난 10년 동안 실무상 아주 유용한 도구로 기능해 온 것이죠.

어지간하면 큐레이션만 잘 고르고 잘 갱신하면 되고, 종속성 목록에는 mypkg >= 2.1.1 && < 2.1.2 이런 거 하나도 관리 안 하고 그냥 mypkg 라고만 써도 된다는 것이, 솔직히 개짱편합니다. 다행히 지난 10년 동안 "문제의 소지는 컴파일 시간에 검출하는 게 좋다"라는 생각이 더 널리 받아들여져서, 다른 언어들도 이런 접근을 더 시도할 여지가 생긴 것 같군요.

Read more →
2
0

bgl gwyng shared the below article:

스태키지 큐레이션이 성공할 수 있었던 것은 하스켈이라는 언어와 생태계의 특징도 컸습니다.

juxtapose @xt@hackers.pub

인용: https://hackers.pub/@bgl/0195f0eb-88dd-77e3-a864-f0371e85b270

스태키지(Stackage)는 하스켈이 (의외로) 성공하여 해키지(Hackage)가 거대해지자, 그 거대함 때문에 발생하는 불편을 해소하는 한 방책으로 고안되었습니다. 그런데 당시에 해키지만큼 거대한 생태계를 갖추고 있으면서 동시에 "컴파일이 성공한다면 실행도 아마 성공할 것"이라는 훌륭한 속성을 갖는 언어는 달리 없었죠. 러스트가 있지 않으냐? 스태키지가 처음 나온 게 2012년입니다. 러스트는 아직 crates.io 도 자리잡기 전이었죠. (사실 이 시점의 러스트는 지금과는 언어 자체가 많이 다른 언어였고요.)

하스켈의 패키지 버저닝 정책에 따르면, 후방호환성 깨지는 변경은 반드시 메이저 버전을 올려야 하고, 마이너 버전만 올리는 변경은 후방호환성 유지될 때에만 가능합니다. 이런 정책 당연히 좋지만, 사람이 내용을 잘 숙지하고 지켜야 의미가 있습니다. 후방호환성을 깨면서 마이너 버전만 올리는 실수는 어떤 개발자든 할 수 있죠.

그런데 하스켈의 경우, 인간이 실수해도 기계가 잡아 줄 여지가 처음부터 매우 큰 언어이고, 예를 들어 어떤 함수가 핵미사일을 발사할 수 있는지 아닌지를 함수 실행 없이도 식별할 수 있는 언어라고들 하죠. 하스켈의 마지막 표준이 2010년에 나왔으니 2010년을 기준으로 하면, 당시 하스켈이 제공하는 "컴파일 시간 보장"의 범위는 그야말로 독보적이었습니다. (하스켈보다 더 강한 보장을 제공하는 언어들은 있었지만, 그만한 라이브러리 에코시스템이 없었고요.)

그래서 스태키지라는 모형이 의미가 있었습니다. A라는 패키지의 새 마이너 버전이 해키지에 올라오면, 스태키지에서 자동으로 가져갑니다. 스태키지는 같은 큐레이션에 포함된 다른 패키지들 중 A에 의존하는 패키지들을 추리고, 얘네한테 A의 새 버전을 먹여도 빌드가 잘 되는지 검사합니다. 이들 중 하나라도 깨지면? A 패키지는 해키지에서는 버전이 올랐으나, 스태키지에서는 버전이 오르지 않게 됩니다. 그리고 A 패키지의 제공자에게 자동으로 깃허브 멘션 알림이 갑니다!

("패키지 저자"와 "패키지를 스태키지에 제공하는 제공자"가 같은 사람이 아니어도 된다는 점도, 노동력의 효과적 분담에 한몫했습니다.)

이 모든 과정이 자동화되어 있는데, 이것만으로도 99.99%의 호환성 문제가 사라지고, 그러면서도 웬만한 라이브러리들은 충분히 최신 버전으로 쓸 수 있습니다. LTS와 나이틀리가 구분되어 있는 것도, LTS가 GHC 버전에 대응하여 여러 버전이 유지되는 것도, 실제 개발에서 아주 편리하고요.

스태키지가 개쩌는 부분은 "버저닝 정책에 완벽하게 부합하는데도 현실적으로 후방호환성 파괴를 일으키는" 변경점들도 잡아낸다는 것입니다. 아주 단순한 예시로 "많이 쓰이는 이름"이 있습니다. 예를 들어 어떤 라이브러리가 아주 널리 쓰이는데, 제공하는 네임 바인딩은 몇 개 안 되고, 그래서 대부분의 사용자가 그걸 그냥 전역 네임스페이스에 다 반입해서 쓴다고 칩시다. 어느 날 이 라이브러리가 process 라든지 f 같은 새 네임을 추가 제공하기 시작하면? 정책 규범에 따르면, 이것도 마이너 버전만 올려도 되는 변경점이 맞습니다. 하지만 현실에서는 많은 패키지들을 박살내겠죠. 언어를 막론하고 있을 수 있는 일인데, 이런 것들까지 스태키지에서 아주 높은 확률로 다 잡힙니다.

그리고... 이런 게 잘 된다는 것은 언어 그 자체의 특성도 있지만, 생태계 전체의 문화적인 특성도 있는데요. 하스켈도 라이브러리 제작자가 충분히 악독하다면, 컴파일러에게 안 잡히면서 인류문명멸망시키는 코드 변경을 얼마든지 슬쩍 끼워넣을 수 있습니다. 악의가 아니더라도 부주의로 후방호환성을 깰 수 있고요. 그런데 하스켈은 대부분의 라이브러리 설계자들이 "되도록 많은 것을 컴파일 시간에 잡고 싶다"라는 명확한 욕망으로 설계를 하는 경향이 뚜렷합니다. 그래서 호환성 문제는 웬만하면 스태키지 선에서 잡히고, 스태키지 큐레이션은 지난 10년 동안 실무상 아주 유용한 도구로 기능해 온 것이죠.

어지간하면 큐레이션만 잘 고르고 잘 갱신하면 되고, 종속성 목록에는 mypkg >= 2.1.1 && < 2.1.2 이런 거 하나도 관리 안 하고 그냥 mypkg 라고만 써도 된다는 것이, 솔직히 개짱편합니다. 다행히 지난 10년 동안 "문제의 소지는 컴파일 시간에 검출하는 게 좋다"라는 생각이 더 널리 받아들여져서, 다른 언어들도 이런 접근을 더 시도할 여지가 생긴 것 같군요.

Read more →
2
0

스냅샷 방식이 이론적으로는 참 좋은데, 제대로 돌아가려면 사람들이 새로운 버전을 테스트하고 호환되는 버전을 업데이트하는 등의 잡다구리한 수고를 다 같이 해줘야 한다는 문제가 있(었)다. 하지만 요즘 잡다구리한 수고가 매우 저렴했으니 올바른 방법을 다시 밀고나갈수 있게되었다.



RE: https://hackers.pub/@hongminhee/0195f09a-a7d0-79aa-a819-bdcf97d6d830

0
0

@curry박준규 반클릭 상태가 제가 생각한 클릭이었습니다. 클릭, 더블클릭, 드래그 같은 동작이 반클릭 상태에서 일어납니다. 풀클릭은 대응하는 앱이 별로 없는 것 같은데 파인더에서는 스페이스를 누른 것과 같은 동작을 합니다. 여기저기서 눌러보고있어요.

0

"pub"의 외래어 표기법에 따른 표기는 ""이 아니라 "퍼브"입니다. 유성음으로 끝나는 단어라서 "ㅡ"를 붙입니다. 이것은

  • log: ""이 아니라 "로그"
    • blog: "블록"이 아니라 "블로그"
  • tag: ""이 아니라 "태그"
  • egg: ""이 아니라 "에그"
  • dog: ""이 아니라 "도그"
  • mug: ""이 아니라 "머그"
  • hub: ""이 아니라 "허브"
  • pad: ""이 아니라 "패드"
  • lid: "릿"이 아니라 "리드"
  • mud: ""이 아니라 "머드"

등등, 유성음으로 끝나는 영어 단어에 일관적으로 적용되는 규칙입니다.

보통 외래어 표기법의 규칙이 무시되는 사례를 보면, 규칙이 모호성을 낳는다는 이유로 기피되는 경향이 있는데요. 예를 들어 "seat"와 "sheet"를 구분하려는 욕망으로 인해 /ʃiː/를 "시"로 표기하는 원칙을 깨고 후자를 "쉬트"로 적는 것이 있죠.

그런데 유성음으로 끝나면 "ㅡ"를 붙인다는 규칙은 원어의 유성 음가를 반영하는 동시에, 대체로 모호성을 해소하는 방향으로 표기를 만들어 주는 좋은 규칙입니다. 이 규칙이 없었으면 꼼짝없이

  • "dog"와 "dock"이 "독"이라는 동음이의어가 되고
  • "pig"와 "pick"도 "픽"이라는 동음이의어가 되고
  • "rug"와 "luck"도 "럭"이라는 동음이의어가 되고
  • "tag"와 "tack"도 "택"이라는 동음이의어가 되고

영 좋지 않았겠죠.

0

그거 아십니까? XCode 업데이트는 거부할수 없고, 수락하면 보통 기존의 React Native 빌드가 터진다는 사실을... 해괴한 cpp 에러 메시지와 함께요

0
0

난 요거 반대의 도구를 찾고 있는데, remote로 electron이나 tauri등을 띄운다음에 웹뷰를 브라우저로 볼수있게하는 것이다. 안그래도 지금 GitButler 깔았는데 remote 사용을 지원안해서 난감해졌다.

0
0

난 요거 반대의 도구를 찾고 있는데, remote로 electron이나 tauri등을 띄운다음에 웹뷰를 브라우저로 볼수있게하는 것이다. 안그래도 지금 GitButler 깔았는데 remote 사용을 지원안해서 난감해졌다.

난 요거 반대의 도구를 찾고 있는데, remote로 electron이나 tauri등을 띄운다음에 웹뷰를 브라우저로 볼수있게하는 것이다. 안그래도 지금 GitButler 깔았는데 remote 사용을 지원안해서 난감해졌다.

0

@bglbgl gwyng 깃버틀러는 변경사항을 가상의 브랜치로 나눠서 상하차하고 머지하려는 브랜치에 PR 날리는 워크플로우에요. 이미 머지가 되어있는 브랜치에서 다른 브랜치로 톡톡 떼고, 뭐뭐 머지 안했는지 체크리스트만드는게 제가 궁극적으로 원하는건데... 해결하려는 문제가 달랐어요. 이거만 해결되면 충성충성하고 쓸 것 같네요..

0
0

Vim/Neovim의 시대가 가고, Vibe Coding 내지는 LLM 에이전트의 도움을 얻는 시대가 왔다지만, 난 아직까지는 전적으로 동의하지는 않음(부분적으로는 동의한다는 의미) 아직까지는 수제로 직접 코드를 짜는 것도 의미가 있고, CLI 기반의 에디터도 저마다의 발전을 하고 있다고 자신있게 말할 수 있음.

내가 생각하는 요오즘 시대 개발의 장점도 언급하면서 CLI 기반의 에디터는 어떤 위치에 있는지도 얘기해보고자 한다.

  1. 신뢰구간이 넓지 않아도 되는 작업을 할때는 AI를 사용하는 코드가 분명 시간을 확 줄여주고 결과적으로 생산성을 향상시키는 경향은 있지만, "정확함"을 위해서 프롬프트를 넣어야 하는데 그 프롬프트를 넣는 작업이 품이 많이 들때(넣어야 하는 맥락이 너무 많을때) 그렇게 정확하지는 않을뿐더러 맥락을 넣는 시간 때문에 차라리 내가 직접 짜는게 나을때가 많음. 수제로 직접 짜기 vs AI한테 전적으로 맡겨버리기 두 세계를 적절하게 오가면서 작업하는게 베스트이지 않나 싶음.

  2. GUI 에디터 특유의 장점도 분명 있긴 있다. GUI 에디터가 올인원 기능을 갖추고 있는 경우도 많고 편의성 면에서 미니멀리즘을 추구하는 CLI 기반의 에디터보다 가진 기능이 많다. 남이 차려준 밥상이 그렇게 달달하지 않을 수 없다. 하지만, 그런 기능들을 제공하는 플러그인이나 자체 기능들의 내부 구현을 막상 까보면 CLI 도구에 의존하는 기능들이 많다. 특히, LSP/린터/포매터가 그렇다. 다만 추상화레이어를 어떻게 감쌌느냐 정도의 차이가 있는데, 그 추상화레이어를 커스터마이징하는데 있어서의 진입장벽은 CLI 기반의 에디터가 상대적으로 낮은 편이다. 왜냐면, 인고의 시간을 거쳐서 해온게 딱 그거라서(.....)

  3. 바이브 코딩은 분명 압도적인 속도로 코드가 짜여질 수 있게 하고, 단위시간당 코드가 짜여지는 양 자체도 어마어마하다. 특히, scaffolding을 할때 더더욱 빛을 발휘한다. 그렇기 때문에, 코드를 짜는건 기계/인공지능에 위임하고, 자세한 디테일을 채우는건 유저리서치를 하거나 와이어프레임을 그려서 기획을 더 보강하는 등 중요한 영역에 집중할 수 있게 된다. 코드를 짜는데 드는 시간은 최소한으로, 중요한 영역에 집중하기 위해 생각하는 시간을 더 많이 가지는 것은 분명 좋은 일이다. 관련해서는 이 글도 읽어보면 좋을 것 같다. https://two-wrongs.com/typing-fast-is-about-latency-not-throughput

물론, 코드를 짜는데 있어서 중요한 것은 리터러시이다. LLM이 코드베이스의 이해를 빠르게 할 수 있도록 도와주긴 하지만, 위에서 언급했듯 어느 정도 시점이 되면 결국엔 직접 짜고 직접 수정하는 일도 있어야 한다. 로컬 LLM이 발전한다 하더라도, LLM을 사용할 여력이 되지 않는 환경에서도 동일한 생산성을 유지할 수 있을까? 생산성이 일관적이지 않다면, 그렇지 않은 환경에 노출이 되었을때 어떻게 대응할 수 있을지가 중요한 포인트일 수 있다고 생각한다. 인자강, 즉, 사람 자체가 강해질 필요가 있다고 생각한다.


인공지능에 전적으로 의존하지 않고 수제로 직접 코드를 짜는 사람들이 기계/인공지능에 저항해서 어떻게 살아남을까를 생각해보면 인간공학에 기반해서 편집하는 테크닉이 더 연구될 필요가 있다.

GUI 기반의 에디터가 날이 갈수록 좋아지고 있는 상황 속에서 CLI 기반의 에디터가 살아남으려면 더더욱 CLI 기반의 도구와 궁합이 좋은 것을 내세워서 차별점을 내세울 필요가 있다. Neovim은 그런 관점에서 IDE와 유사한 경험을 제공하는 쪽으로 잘 발전되어 왔다고 보고 있다.

Vim/Neovim 생태계는 아직까지는 미래가 낙관적이라고 본다.

@kodingwarriorJaeyeol Lee 저는 VS Code를 오래 써서, Cursor든 Windsurf든 VS Code 포크들은 아무 비용없이 갈아탈수 있었는데요. 사실 저런 툴들의 진짜 강점은 API 요금제인거 같습니다. Claude Code 붙여서 종량제로 쓰면 그게 제일 퍼포먼스 좋겠지만 돈이 계속 나간다는게 상당한 압박인데, Windsurf 한달에 15달러 내면 그냥 채팅용으로도 쓸수있고, 개발자 입장에서 단 한개의 AI 구독이 되는게 가능해요. 그러니까 에디터 자체는 별로 안중요하고 그 뒤에 묶여있는 AI 상품이 매력적인 거죠.

Aider같은 걸로 비슷한 요금제를 구현하는게 가능할지 모르겠네요. 또는 로컬 LLM 성능이 궤도에 오르면 그때 또 많이 달라질거라 봅니다.

0
0
0
0
0
0
0
0

요즘 주의 깊게 보고 있는 두 언어:

  • Gleam: Erlang의 OTP 런타임에서 돌아간다는 점에서 Elixir와 비슷한데, 처음부터 정적 타입 언어로 설계되었다. 아, JavaScript 타깃도 지원한다. Haskell의 타입클래스(typeclass)나 Rust의 트레이트(trait)에 해당하는 기능이 없다는 게 개인적으로는 조금 아쉬운 점.

  • MoonBit: 중국 쪽에서 주도해서 만들고 있는 WebAssembly 타깃 언어로, 이지 모드 Rust에 가까워 보인다. 다만 개발 과정이 완전히 오픈 소스는 아니고, (오픈 소스 라이선스이긴 하지만) 소스만 공개하는 형태라 거버넌스 측면에서 아쉬움이 있다.

0

많은 분들이 인용 방법을 혼란스러워 하셔서, 인용 버튼을 추가했습니다. 게시글이나 단문 아래의 아이콘들 중에 왼쪽에서 세 번째 아이콘을 누르시면 해당 콘텐츠를 인용한 글들이 나열되고, 그 위에 인용 글 입력란이 뜨게 됩니다. 거기서 인용 글을 쓸 수 있습니다. 아, 종래의 인용 UI도 그대로 사용하실 수 있습니다.

참고로 인용 아이콘은 @xtjuxtapose 님께서 수고해 주셨습니다. 감사합니다.



RE: https://hackers.pub/@xt/0195eb06-9f50-763d-85c8-5600ec78c539

Hackers' Pub의 게시글이나 단문 아래에 표시되는 아이콘들. 인용 버튼이 강조되어 있다.
0

vim.kr 디스코드에도 물어보긴 했는데, 해커스펍에도 공개적으로 물어봅니다.

Git 관련 유틸리티 중에 이런거 없을까요?

개발된 기능들은 어지간하면 싹 다 Staging 브랜치에 합쳐서 개발망에 배포중인데, 개발망에 배포된 기능/버그픽스 중에 몇개 컨펌된 것만 프로덕션에 배포하고 싶어요. 커밋을 가능하면 잘게 쪼개서 하는 편이긴 한데, 컨펌된 것만 한땀한땀 골라서 체리픽하다보니까 관리하는게 여간 귀찮은게 아니네요. 오죽하면 스프레드시트로 관리할 정도입니다 -_-;;;

커밋 중 몇개는 서로 독립적이긴 한데, 몇개는 비엔나소세지마냥 줄줄이 의존성이 엮여있어요. 줄줄이 의존성이 엮여있긴해도, 가만히 보면 A기능 / B기능 잘개 쪼개져있긴 해서, 그걸 좀 더 보기좋게 시각화하고 싶어요. staging 브랜치에 PR 머지할때도 일부러 Squash and merge로 머지합니다.

한줄 요약

  • 의도적으로 커밋 간의 연결관계를 디펜던시 그래프 형태로 가시화할 수 있는 Git 유틸리티 추천받습니다.
0