Flix – 강력한 효과 지향 프로그래밍 언어
(flix.dev)- Flix는 함수형 프로그래밍과 효과 지향 모델을 결합한 혁신적인 언어임
- 논리 규칙과 데이터 종속성 모델링이 용이하며, 선언적인 지식 표현이 강점임
- 복잡한 의존 관계 및 프로세스 흐름을 간결하게 코드로 작성할 수 있음
- 이런 접근 방식은 알고리듬 설계와 추론 작업에 효율성을 제공함
- 쿼리 기능을 통해 지식 기반 데이터를 손쉽게 탐색할 수 있음
Flix 언어 개요
- Flix는 효과 지향적 프로그래밍 패러다임을 도입한 새로운 함수형 언어임
- 프로그래머는 절차적 코드가 아니라, 논리적 관계와 규칙 중심으로 시스템을 기술할 수 있음
- 논리 규칙(#{} 내에 선언)으로 구성요소, 의존성, 조립 시간, 납기일 등 복잡한 제조 시나리오를 간결하게 표현 가능함
선언적 규칙 및 데이터 모델링
- 예시 코드에서는 PartDepends, AssemblyTime, DeliveryDate, ReadyDate와 같은 사실과 규칙이 사용됨
- PartDepends("Car", "Chassis")와 같이 제품 간 의존 관계를 정의함
- AssemblyTime("Engine", 2)처럼 부품별 조립 시간을 설정함
- DeliveryDate("Piston"; 1)와 같이 부품 납기일도 명시함
- ReadyDate라는 논리 규칙을 통해 납기일이 정의된 부품 혹은 조립식 부품의 최종 준비일 산출 가능함
- 즉, 개별 부품의 공급 및 조립 주기를 단순하게 추론 가능함
효과 지향적 추론 및 쿼리
- Flix의 논리적 규칙 엔진은 효과 지향과 참조 투명성을 결합해, 직관적이면서도 오류가 적은 프로그램 설계를 유도함
- 쿼리 구문을 이용해 ReadyDate에 해당하는 모든 부품별 준비일을 손쉽게 도출함
- 이러한 방식은 제조, 공급망 관리, 추론 기반 자동화 등 다양한 분야에서 응용 가능함
종합 및 장점
- Flix는 효과(Effects)와 논리 규칙 기반 추론을 결합해, 복잡한 시스템의 구성요소와 프로세스 간 관계를 간결하게 모델링함
- 기존 언어 대비 논리적 명확성과 코드 간결성 면에서 차별화된 장점이 있음
- 지식 그래프, 워크플로우 엔진, 데이터 추론 등 다양한 현대 소프트웨어 문제에 적합한 솔루션 제공 가능함
Hacker News 의견
-
이 언어의 깊이와 폭에 깊은 감명을 받음
대수적 데이터 타입, 논리 프로그래밍, 변이성 등 필수 기능들이 모두 첫 단계부터 포함되어 있음
비교 표를 보며 가장 마음에 들었던 부분은 단일 실행 파일이 패키지 매니저, LSP, 컴파일러 역할까지 모두 담당하는 점임
Haskell의 경우 LSP가 ghc와 cabal 파일 사이에서 많은 작업을 다시 구현해야 했고, stack도 쓰이는 등 패키지 매니저의 공식성이 애매했음
Haskell을 비판하려는 의도는 아니며, 정말 훌륭한 언어임
하지만 최고의 기능은 조금 숨겨져 있는 것 같아 아쉬움
Flix가 JVM 상에서 Java 등과 얼마나 편하게 통합되는지 궁금함
JVM 컴파일러가 타입 정보를 대부분 지워버리기 때문에, Flix의 'regions' 컨셉이 명령형 상호작용을 1등급 시민으로 지원하는 점은 긍정적임
JVM을 사용하면 수십억 달러 가치의, 고품질 표준 라이브러리를 손쉽게 쓸 수 있으니 엄청난 장점임
그래서 JVM이나 .net core가 프로젝트의 90% 이상에서는 가장 합리적인 선택이라고 생각함
F#만이 유일한 비교 대상 언어로 보임
Flix와 JVM 간 상호운용성에서의 한계점들을 정리한 문서가 있으면 정말 좋겠음
참고로, 관련 정보가 여기 있음
기본적으로 Flix/Java 값은 boxing/unboxing 과정을 거침
또, Record가 1등급 시민임-
패키지 매니저, LSP, 컴파일러가 모두 하나의 실행 파일이라는 점이 마음에 든다면 Unison도 정말 좋아할 거라는 생각임
-
논리 프로그래밍과 datalog 부분은 좀 추가적인 느낌임
다른 기능들은 확실하게 코드베이스의 타입 안전성을 높이는 것이 보이지만, 논리 프로그래밍은 상당히 마니아층 기능이라 오히려 언어와 별개로 존재하는 게 더 낫지 않을까 생각함 -
JVM 컴파일러가 타입 정보를 모두 지운다는 것은 완전히 맞지는 않음 (익명 클래스의 경우 타입 파라미터를 유지함)
여러가지 우회 방법도 존재함
그리고 사실 컴파일러 입장에서는 큰 문제가 아님
타입 생성자를 적용한 클래스명을 난수화해서 일반 클래스처럼 렌더링하면 됨 -
F#은 (아직) 타입 클래스를 지원하지 않기 때문에 monad 기반 프로그래밍에 제한이 많음
만약 F#이 Haskell 스타일 monad를 생략하고 바로 대수효과(algebraic effects)로 점프한다면, 그게 F# 철학엔 더 잘 맞을 거라고 생각함 -
"StringBuilder" 부분은 약간 아쉬움
이 면에서는 Java 쪽에 좀 더 기울어 있는 것 같아서 확신이 서지 않음
다른 부분은 얼핏 보면 괜찮아 보임
-
-
언어 의미론 측면에서 볼 때, 다형적 레코드의 확장/제한 의미론이 Leijen의 scoped label 방식(논문 링크)을 따르는 것 같음
예를 들어 r1 = { color = "yellow" }라는 레코드가 있으면, r2 = { +color = "red" | r1 }로 확장할 수 있음
r2#color는 "red"가 나오고, 다시 "color" 필드를 없애면 r3 = { -color | r2 }가 되고
r3#color는 원래 값인 "yellow"가 나옴
이렇게 하는 게 이전 스타일(동일한 label 필드를 두 번 추가불가하도록 극도로 복잡한 타입 시스템을 사용하는 방향)보다 훨씬 합리적이라고 생각함 -
Aarhus(특히 대학/테크허브)가 프로그래밍 언어 연구에서 강력한 영향력을 갖는 이유가 궁금함
C++, C#/Typescript, Dart 등 모두 이 덴마크의 작은 지역에서 강한 뿌리를 갖고 있음
Delft, INRIA같은 곳처럼 전형적 Ivy League나 Oxbridge의 명문대는 아님
뭐가 그렇게 특별하게 만든 걸까? 물 때문인가, 아니면 다른 이유가 있나 하는 단순한 궁금증임-
한 가지 짚자면, C#은 Anders Hejlsberg가 만들었고 그는 DTU(코펜하겐)에서 공부했음
Turbo Pascal도 그가 만들었고, Borland도 덴마크인이 창업한 회사임
전반적으로 덴마크는 프로그래밍 언어 이론이 강함
예를 들어, 정적 프로그램 분석 분야 표준 대학원 교재(저자 Nielson & Nielson)도 덴마크 출신임
Mads Tofte는 Standard ML에 큰 기여를 함
Aarhus가 Ivy League, Oxbridge 급은 아니지만 훌륭한 대학임
유럽에는 이런 식으로 명성은 작지만 교육, 연구의 질이 뛰어난 대학들이 수십 군데 이상 존재함 -
Aarhus는 논리, 타입 이론, 함수형/객체지향 언어 분야에서 전통이 강함
이 분야에서 영향력을 끼친 많은 연구자들이 Aarhus 출신임
또, 프로그래밍 언어 연구는 전 세계적으로 미국 편향이 심하게 작용하는 것처럼 느껴짐
Aarhus 같은 기관은 마케팅이나 자기 PR에 현저하게 인색하고, 좋은 연구에 집중하는 편임
특별히 더 낫거나 덜 나은 건 아니고, 글로벌 주목을 받기가 어렵게 만드는 점이 있음
-
-
Flix는 ML 계열 언어들 중에서 가장 세심하게 설계된 언어로 계속 인상적임
함수형, 명령형, 논리형 패러다임의 조합과 다형적 타입&이펙트 시스템, Datalog 제약까지 1등급 시민으로 지원하는 점이 정말 독특함
타입 레벨에서 순수/비순수 코드를 엄격히 구분하는 점이 Monad 대신 효과를 추론하기 더 쉬운 대안이라 신선함
"하나의 언어, 플래그 필요 없음" 철학과 오직 컴파일 타임 에러만 추구하는 점도 단순하고 예측 가능해서 좋음
JVM 자체가 꼬리 재귀 제거를 네이티브로 지원하지 않는데도 Flix는 완전한 꼬리 호출 제거를 구현했다는 것은 주목할 만한 기술적 성취임
실제로 생산 환경이나 연구에서 Flix를 사용하는 분들의 경험이 궁금함
특히 논리 프로그래밍이나 동시성 분야에서 사용하면서 '폐쇄 세계 가정(closed-world assumption)'이나 예외 미지원 등에서 겪은 어려움, Prolog 등 다른 논리 언어와 Datalog 통합의 차이점에 대해 듣고 싶음 -
예전에 Flix를 살펴봤을 때 정말 흥미로워서 "Java 프로그래머를 위한 Flix"라는 제목으로 글까지 썼음
지금은 조금 오래되어 업데이트가 필요하긴 하겠지만...
혹시 관심 있다면 여기에서 볼 수 있음-
블로그 글이 정말 멋짐
허락만 한다면 Flix 공식 블로그 모음(링크)에 추가하면 좋겠음
그 글 이후로 Flix 언어가 많이 발전함
특히 이펙트 시스템이 크게 확장됐고, Java 상호운용성 개선, 문법 업데이트가 있었음 -
블로그가 정말 보물 창고 같음
오랫동안 나를 괴롭혀온 생각들을 정리해준 더 고급스러운 버전이라 느낌
전부 읽어볼 생각에 기대감이 큼
-
-
HKTs도 지원해서 멋짐
그런데 typeclass에 대한 설명이 안 보여서 궁금함
typeclass와 Scala 스타일 매크로만 지원해주면 내가 만든 라이브러리(distage, izumi-reflect, BIO)도 Flix로 옮겨보고 싶고 Scala에서 Flix로 넘어가는 것도 진지하게 고민할 듯
추후에 typeclass를 traits로 부르고 있음을 발견함
매크로는 어떤지 궁금함
또, Flix에서 명시적 이름 기반 상속(nominal inheritance)도 지원하지 않다는 게 아쉬움
Scala의 trait 중 가장 무해한 형태조차 허용 안 되니까
typeclass는 interface를 대체할 수 없는데, 그 추상화가 없으면 많은 유용한 기능을 아예 구현 못 하거나 코드가 보기 싫어질 수 있다고 느꼈음- Flix는 typeclass(여기서는 trait이라고 부름)를 HKT, associated type, associated effect와 함께 지원함
trait이 함수 기본 구현도 제공하지만, 인스턴스에서 오버라이드 가능함
Flix는 상속(inheritance)은 아예 없음
trait이 오직 컴파일 타임에만 사용되고 monomorphization 처리를 거쳐 런타임 오버헤드가 없음
Flix 인라이너가 trait 내부도 최적화 처리해서 closure까지 적극적으로 제거함
예를 들어 고차함수나 파이프라인이 바이트코드 수준에서는 평범한 루프로 바뀌고 closure 할당이나 간접 참조가 아예 없어짐
Flix는 아직 매크로를 지원하지 않음
다른 언어에서의 (남용)경험 때문인지 도입을 두려워하고 있음
새로운 라이브러리 작성자를 모시고 있으니 혹시 관심 있으면 Gitter 채널에 들러줬으면 좋겠음
- Flix는 typeclass(여기서는 trait이라고 부름)를 HKT, associated type, associated effect와 함께 지원함
-
Flix 공식 문서 중 'Flix에서 지원하지 않는 기능' 섹션 관련
"No Code Before Main"라는 항목이 있는데
실제 설명은 "Flix는 main 이전에 아무 코드도 실행되지 않으며 정적 이니셜라이저 같은 건 전혀 없음"이라고 되어 있음
기능명은 "Code Before Main"으로 바꾸는 것이 더 정확하다고 생각함 -
Flix에서 함수가 순수함을 반드시 명시적으로 표시하게 하는 이유가 궁금함
거의 모든 경우 정적 분석으로 충분히 추론할 수 있을 것 같은데 왜 그런지 알고 싶음-
내가 알기로 함수에 순수성을 표시하면, 컴파일러가 이를 보장해줌
-
"Flix는 프로그램 내 모든 표현식의 순수성을 정확히 추적한다"라는 문장과, 순수/비순수 표기가 없는 함수 정의 예시를 보면
대다수 경우에는 컴파일러가 순수성을 자동 추론하는 게 가능한 것으로 보여서
순수/비순수 표시는 옵션일 수도 있다는 인상을 받음
-
-
Flix FAQ(링크)는 평범하게 시작하다가 점점 재미있어짐
몇 가지 웃긴 예시들:- Q: 0으로 나누면 진짜 결과가 0임?<br> A: 네. 근데 이 부분만 신경 쓰는 건 마치 우주선 좌석 색깔만 따지는 것과 같음
- Q: "이 사이트는 JavaScript 필요"<br> A: JavaScript 사용을 비판한 사람들: [1],[2],[3],[4],[5], 실질적으로 HTML로 리팩토링을 돕겠다고 한 사람: 0명
- Q: 내가 좋아하는 기능 Y 대신 X라는 기능이 들어 있어서 실망임<br> A: 유감임
- Q: 지금까지 본 함수형 언어 중 최악의 문법임. 세미콜론, 중괄호, 심볼 난장판이 만났음. 마치 Scala, Java, Haskell이 체르노빌 한가운데서 원나잇한 것 같음<br> A: 오히려 대단한 성취 아닌가?
-
이 언어와 호환되는 코드 에이전트(agent)가 잘 작동하는지, 아니면 머리를 직접 써야 하는 상황인지 궁금함
농담처럼 얘기하지만, 실제로 언어가 멋져 보여서 슬픔
LLM이 오히려 신규 언어 채택을 저해할 텐데, 이 문제를 어떻게 풀 수 있을지 의문이 있음-
나는 오히려 LLM이 새로운 언어 채택 장벽을 낮추는 역할을 할 거라는 직감임
표준 라이브러리 코드는 LLM이 새로운 문법을 학습하기에 충분하고, 아니더라도 에이전트가 컴파일러 출력을 관찰하며 배우는 것도 가능함
코드 포팅 작업 자체는 고도의 창의성이 별로 필요 없는, 정의가 명확한 일이라서 LLM의 자동화 1호 영역이 될 것임
앞으로는 우리가 '왜 이걸 하는지'와 '세상에 어떤 영향을 주는지'를 두뇌로 진지하게 고민해야 한다고 봄 -
프롬프트에 Idris의 인덱스/의존 타입을 반드시 사용하도록 지시해두니 괜찮은 결과를 얻음
(이런 지시가 없으면 GADT 정도가 한계)
-