Gleam - Erlang 가상머신에서 타입 안전성을 제공하는 프로그래밍 언어
(gleam.run)- Gleam은 타입 안전성과 함수형 프로그래밍을 Erlang 런타임 위에 얹어, 대규모 동시성 시스템을 더 친숙한 문법으로 만들 수 있게 하는 언어임
- Erlang 가상 머신 기반이라 WhatsApp과 Ericsson 같은 대규모 시스템에 쓰인 BEAM 생태계의 동시성·내결함성 기반을 활용함
- 멀티코어 액터 모델, 수백만 개의 그린 스레드, 불변 데이터 구조, 전체 실행을 멈추지 않는 가비지 컬렉터를 내세움
- 컴파일러·빌드 도구·포매터·에디터 통합·패키지 매니저를 내장해
gleam new,gleam add,gleam test흐름으로 프로젝트와 패키지를 다룰 수 있음 - null 값과 예외가 없고 Erlang·Elixir와 상호 운용되며, JavaScript 컴파일과 TypeScript 정의 생성으로 브라우저와 JavaScript 실행 환경까지 지원함
타입 안전성과 함수형 문법
- Gleam은 타입 안전 시스템을 확장 가능하게 만들기 위한 친숙한 프로그래밍 언어임
- 타입 시스템의 강점, 함수형 프로그래밍의 표현력, 고동시성·내결함성을 갖춘 Erlang 런타임의 신뢰성을 결합함
- 기본 예시는
gleam/io를 가져와io.println("hello, friend!")를 실행하는 단순한 구조임
Erlang 가상 머신 기반 확장성
- Gleam은 Erlang 가상 머신 위에서 실행됨
- 이 런타임은 WhatsApp, Ericsson 같은 대규모 시스템을 구동한 기반임
- 다양한 규모의 워크로드에 대응할 수 있음을 강조함
- 동시성 모델은 멀티코어 액터 기반임
- 수백만 개의 동시 그린 스레드를 실행할 수 있음
- 빠른 불변 데이터 구조를 제공함
- 동시 가비지 컬렉터는 전체 실행을 멈추지 않음
- 예시 코드는
process.new_subject()로 메시지 수신 대상을 만들고,process.spawn으로 자식 그린 스레드를 띄운 뒤process.send와process.receive로 메시지를 주고받음
내장 개발 도구와 패키지 생태계
- Gleam은 개발에 필요한 도구 체인을 함께 제공함
- 컴파일러
- 빌드 도구
- 포매터
- 에디터 통합
- 패키지 매니저
- 새 프로젝트는
gleam new로 생성함 - 패키지 작업은
gleam add gleam_json으로 패키지를 추가하고gleam test로 테스트를 실행하는 흐름임- 예시 출력에서는
gleam_json v0.5.0이 추가됨 - 테스트 결과는
1 tests, 0 failures임
- 예시 출력에서는
- 더 넓은 BEAM 생태계의 일부로서, Gleam 프로그램은 Gleam·Erlang·Elixir로 작성된 공개 패키지 수천 개를 사용할 수 있음
오류 처리와 타입 시스템
- Gleam에는 null 값과 예외가 없음
- 실용적인 타입 시스템과 명확한 오류 메시지를 제공함
- 존재하지 않는 레코드 필드
alias에 접근하면 구체적인 오류가 표시됨- 오류 메시지는
Unknown record field를 표시함 - 접근 대상 타입이
User임을 보여줌 - 사용 가능한 필드
.name을 제시하고Did you mean name?형태로 수정 후보를 안내함
- 오류 메시지는
- 새 코드를 작성하거나 기존 코드를 유지보수할 때 작업을 더 즐겁고 스트레스 적게 만들도록 설계됨
Erlang·Elixir·JavaScript와의 상호 운용
- Gleam은 Erlang, Elixir 같은 다른 BEAM 언어로 작성된 코드를 쉽게 사용할 수 있게 함
- 이 상호 운용성 덕분에 Gleam 사용자는 수천 개의 오픈소스 라이브러리 생태계를 활용할 수 있음
@external(erlang, "Elixir.HPAX", "new")예시는 Erlang 쪽 외부 함수를 Gleam 함수로 연결하는 형태임- JavaScript 대상으로도 컴파일 가능함
- 브라우저에서 코드를 사용할 수 있음
- JavaScript가 실행되는 다른 환경에서도 사용할 수 있음
- TypeScript 정의를 생성해 외부에서 Gleam 코드와 상호작용할 때도 타입 정보를 활용할 수 있음
커뮤니티 원칙과 학습 경로
- Gleam 커뮤니티는 전 세계의 다양한 배경, 성별, 경험 수준의 사람들을 동등하게 환영하고 존중한다고 밝힘
- 커뮤니티 행동 강령을 제공함
- 언어 학습은 Language tour에서 시작할 수 있음
- 공식 링크로 문서, 패키지, Playground, Roadmap, Case studies, Discord, GitHub 코드 저장소 등이 제공됨
댓글과 토론
Hacker News 의견들
-
문법이 정말 인상적이고, 아직 마음에 안 드는 문법을 못 찾았음. 예를 들어 라벨 있는 인자는 아주 좋음
pub fn replace(
in string: String,
each pattern: String,
with replacement: String,
) {
// The variables \string`, `pattern`, and `replacement` are in scope here}replace(in: "A,B,C", each: ",", with: " ")`- 유일하게 거슬리는 부분은 파이프 연산자가 왼쪽 값을 호출의 첫 번째 인자로 쓸 수 있는지 먼저 확인한다는 점임. 예를 들어
a |> b(1, 2)가b(a, 1, 2)가 되는데,_하나 덜 치려고 명확성을 희생하는 건 나쁜 절충으로 보임 - Swift에도 이미 있는 방식이고 꽤 영리함. 문서화에 도움이 되고 리팩터링도 단순해져서, 상위 호출부 변경을 줄여주는 기능이라면 뭐든 환영함
- 개인적으로는 바로 그 부분의 문법이 마음에 안 들고, 가치도 잘 모르겠음
- 참고로 Swift가 몇 년 전에 이미 이렇게 했음
- 변수 이름을 바꾸면 이게 어떻게 동작하는지 궁금함. 모든 호출부가 깨지는 건가?
- 유일하게 거슬리는 부분은 파이프 연산자가 왼쪽 값을 호출의 첫 번째 인자로 쓸 수 있는지 먼저 확인한다는 점임. 예를 들어
-
관련 글들:
Things I like about Gleam's Syntax - https://news.ycombinator.com/item?id=38031342 - 2023년 10월
Gleam v0.29 – Gleam gets autocompletion - https://news.ycombinator.com/item?id=36044484 - 2023년 5월
V0.28 released of Gleam, a type safe Erlang-family language - https://news.ycombinator.com/item?id=35425855 - 2023년 4월
Gleam v0.25 – Introducing use expressions - https://news.ycombinator.com/item?id=33731871 - 2022년 11월
The Gleam Language Server - https://news.ycombinator.com/item?id=31143792 - 2022년 4월
Gleam v0.18 Released - https://news.ycombinator.com/item?id=29464307 - 2021년 12월
Gleam 0.16 compiles to JavaScript - https://news.ycombinator.com/item?id=27538919 - 2021년 6월
Gleam 0.15 - https://news.ycombinator.com/item?id=27061500 - 2021년 5월
Phantom Types in Gleam - https://news.ycombinator.com/item?id=26284976 - 2021년 2월
Gleam 0.14 – Type-safe language for the Erlang VM - https://news.ycombinator.com/item?id=26185690 - 2021년 2월
Lean HTTP Server for Gleam - https://news.ycombinator.com/item?id=24265936 - 2020년 8월
V0.10 of Gleam, a statically typed language for the Erlang VM, is out - https://news.ycombinator.com/item?id=23706211 - 2020년 7월
Gleam: A statically typed language for the Erlang VM - https://news.ycombinator.com/item?id=22902462 - 2020년 4월
Hello, Gleam - https://news.ycombinator.com/item?id=19686413 - 2019년 4월
An interview with the creator of Gleam - https://news.ycombinator.com/item?id=19547418 - 2019년 4월 -
괜찮아 보임. 이전 논의들을 거의 다 놓쳤던 것 같고, 프로덕션에서 쓰는 사람 이야기를 들어보고 싶음
BEAM에는 늘 관심이 있었지만, 프로덕션에서 돌리기엔 큰 블랙박스처럼 느껴져 편하지 않았음. .NET, Go, Node만큼 문제를 빠르게 진단할 수 있을지 자신이 없고, 왜 BEAM에 대해 그렇게 느끼는지는 잘 모르겠음- 오히려 다른 가상 머신보다 BEAM을 관찰하기 더 쉬울 수 있음. 훨씬 오래되고 안정적이며, 자체 관찰 기능도 많음
BEAM의 핵심을 보여주는 Sasa Juric의 The Soul of Erlang and Elixir 강연을 강력 추천함: https://youtu.be/JvBT4XBdoUE - 익숙하지 않아서 그런 것 아닐까. 거기에 “IBM을 선택해서 해고된 사람은 없다”식의 직장 내 보수성도 영향을 줄 수 있음
- 왜 그렇게 느끼는지는 잘 모르겠음. BEAM은 실행 중인 시스템을 런타임에 디버깅하고 탐색·수정하는 도구가 훌륭함. 물론 배워야 하지만, 다른 도구와 마찬가지임
- Gleam과 함께 Phoenix를 쓸 가능성에 대한 논의가 있음: https://news.ycombinator.com/item?id=38037082
- 단일 서버에서 모놀리스를 돌리는 비교라면 .NET이 문제 진단에 더 나을 수도 있지만 확실하진 않음
반대로 많은 마이크로서비스가 있는 분산 시스템을 작성한다면, 같은 시스템을 BEAM 네이티브로 짰을 때 BEAM 쪽이 디버깅하기 훨씬 쉬울 것임
- 오히려 다른 가상 머신보다 BEAM을 관찰하기 더 쉬울 수 있음. 훨씬 오래되고 안정적이며, 자체 관찰 기능도 많음
-
내 기준에는 딱 맞음. 좋은 타입 시스템, Erlang과 BEAM 기반, Phoenix LiveView 접근성까지 있으면서도 개인적으로 끔찍하다고 느끼는 Ruby 문법은 없음
- Ruby 문법을 좋아하는 입장에서, 어떤 부분이 마음에 안 드는지 꽤 궁금함
- Ruby 문법에 뭐가 문제임?
-
Hindley-Milner인지 궁금했는데, 이 인터뷰에 따르면 맞음: https://blog.lambdaclass.com/an-interview-with-the-creator-o...
-
문서를 훑어봤는데 OTP 언급을 못 찾았음. 놓쳤을 수도 있지만, BEAM 위 언어가 그 모듈들에 대한 네이티브 인터페이스가 없다면 이상함. supervision tree와 gen server 예제를 찾고 있었음
- OTP는 작업 중이며 gleam_otp 패키지로 제공되고, 더 저수준의 gleam_erlang이 보완함. 아니면 FFI로 OTP 기능을 직접 호출할 수도 있음
[0] https://hexdocs.pm/gleam_otp/index.html
[1] https://hexdocs.pm/gleam_erlang/index.html - OTP를 다시 작성하거나 감싼 것처럼 보이지만 아직 프로덕션 준비는 안 된 듯함: https://github.com/gleam-lang/otp
사람마다 다르겠지만, OTP 없는 BEAM 언어는 매력과 사용성이 크게 제한됨
- OTP는 작업 중이며 gleam_otp 패키지로 제공되고, 더 저수준의 gleam_erlang이 보완함. 아니면 FFI로 OTP 기능을 직접 호출할 수도 있음
-
Gleam이 성공하길 정말 바람. 타입 있는 스크립팅 선택지가 더 필요함
- Erlang은 스크립팅에 특히 잘 맞지는 않음. 배포 과정이 정교하고, 운영체제 인터페이스를 그다지 좋아하지 않으며 보통 대안을 제공하는데, 설계는 더 나을 때가 많아도 스크립팅 대상 시스템과 나 사이에 두꺼운 층이 생김
스크립트에서 타입이 도움이 되는지도 잘 모르겠음. Unix 셸에서 모든 것이 문자열인 건 매우 가치 있는 특성임. 대화형으로 타입을 일일이 써야 하면 삶이 괴로워짐
PowerShell은 매우 꼼꼼하지만 멍청한 군 관료와 대화하는 느낌임. 매번 단어를 새로 정의하고, 대화에 등장하는 모든 사람의 직함을 미리 선언해야 하며, 명백히 관련된 두 정보를 연결하지 못함
Erlang이나 다른 BEAM 언어는 인프라 자동화에는 훌륭할 수 있고, 조직이 클수록 더 좋아질 것임. 다만 BEAM 언어에 ML 스타일의 명시적 타입이 주는 이점은 잘 모르겠음
Flash 시절 AVM은 거의 매 명령마다 런타임 타입 검사를 해야 했고, Haxe처럼 타입을 정적으로 증명하면 더 촘촘한 바이트코드를 만들 수 있었음. BEAM은 그렇게 동작하지 않는 것 같아서, 정적 증명이 같은 종류의 이점을 주지는 않을 듯함 - 그 목적이라면 F# 을 쓸 수도 있음
- Erlang은 스크립팅에 특히 잘 맞지는 않음. 배포 과정이 정교하고, 운영체제 인터페이스를 그다지 좋아하지 않으며 보통 대안을 제공하는데, 설계는 더 나을 때가 많아도 스크립팅 대상 시스템과 나 사이에 두꺼운 층이 생김
-
관심이 생겼다면 이것도 흥미로울 수 있음: https://github.com/leostera/riot
-
Gleam은 Rust로 작성된 언어이고, Rust 자체 외에 Rust로 언어를 작성하면 어떤 모습인지 보여주는 좋은 예임. 내가 추적하는 목록(https://github.com/alilleybrinker/langs-in-rust) 기준으로도 Gleam은 Rust로 작성된 언어 중 가장 인기 있는 축에 들고, 기존 언어 재구현이 아닌 상위 언어 중 하나임
- 프로그래밍 언어 제작은 Rust가 흔히 언급되는 단점 없이 장점을 잘 활용할 수 있는 영역처럼 느껴짐. 표준 라이브러리 같은 걸 만드는 경우를 빼면 파일 시스템 API 외의 입출력이 거의 없어서 비동기 선택 문제를 피할 수 있고, 값 타입과 복사만으로도 성능 병목이 되기 어렵게 꽤 멀리 갈 수 있음
대부분의 언어 컴파일러는 동시성도 많이 쓰지 않음. Rust 자체도 Cargo가 크레이트별로 빌드를 병렬화하고, 각 컴파일 단위마다 rustc를 따로 호출함
물론 이 말을 듣고 OCaml이나 Haskell을 쓰면 된다고 결론낼 수도 있고, 둘 다 컴파일러에 정말 좋은 언어임. 그래도 개인적으로는 도구와 생태계 때문에 Rust가 더 매력적이고, Rust 생태계를 더 접근하기 쉽다고 느낄 사람도 많을 것 같음
- 프로그래밍 언어 제작은 Rust가 흔히 언급되는 단점 없이 장점을 잘 활용할 수 있는 영역처럼 느껴짐. 표준 라이브러리 같은 걸 만드는 경우를 빼면 파일 시스템 API 외의 입출력이 거의 없어서 비동기 선택 문제를 피할 수 있고, 값 타입과 복사만으로도 성능 병목이 되기 어렵게 꽤 멀리 갈 수 있음
-
요즘 새 언어가 많이 나오는 건 흥미롭고 긍정적임. 더 나은 해법으로 진화할 수 있다는 희망을 줌
다만 겉보기에는 문법과 키워드가 비슷한 경우가 많아서, 어떤 언어로 프로그래밍 중인지 헷갈릴 때가 있음. 일부 문법은 여러 언어 사이에 거의 그대로 옮겨지는 것처럼 보임
물론 차이는 있고, 그 차이가 깊기 때문에 생태계가 풍부해지지만 내 머리는 헷갈림- 빌드 의존성으로 검증 안 된 코드 수천 개를 내려받을 때, 어느 쪽을 신뢰하는지도 알 수 없음