- Flix là một ngôn ngữ đột phá kết hợp lập trình hàm với mô hình định hướng hiệu ứng
- Ngôn ngữ này giúp mô hình hóa các quy tắc logic và phụ thuộc dữ liệu một cách dễ dàng, đồng thời có thế mạnh ở việc biểu diễn tri thức theo hướng khai báo
- Có thể viết mã ngắn gọn để mô tả quan hệ phụ thuộc phức tạp và luồng quy trình
- Cách tiếp cận này mang lại hiệu quả cho các tác vụ thiết kế thuật toán và suy luận
- Thông qua tính năng truy vấn, có thể khám phá dữ liệu nền tảng tri thức một cách dễ dàng
Tổng quan về ngôn ngữ Flix
- Flix là một ngôn ngữ hàm mới giới thiệu mô hình lập trình định hướng hiệu ứng
- Lập trình viên có thể mô tả hệ thống xoay quanh các quan hệ và quy tắc logic, thay vì mã thủ tục
- Bằng các quy tắc logic (được khai báo trong
#{}), có thể biểu diễn ngắn gọn các kịch bản sản xuất phức tạp như thành phần, phụ thuộc, thời gian lắp ráp, thời hạn giao hàng
Quy tắc khai báo và mô hình dữ liệu
- Trong ví dụ mã, các sự kiện và quy tắc như PartDepends, AssemblyTime, DeliveryDate, ReadyDate được sử dụng
- Định nghĩa quan hệ phụ thuộc giữa các sản phẩm như
PartDepends("Car", "Chassis")
- Thiết lập thời gian lắp ráp theo từng bộ phận như
AssemblyTime("Engine", 2)
- Đồng thời chỉ rõ thời hạn giao hàng của bộ phận như
DeliveryDate("Piston"; 1)
- Thông qua quy tắc logic ReadyDate, có thể tính ra ngày sẵn sàng cuối cùng của các bộ phận có ngày giao hàng xác định hoặc các bộ phận dạng lắp ráp
- Nói cách khác, có thể suy luận đơn giản về chu kỳ cung ứng và lắp ráp của từng bộ phận
Suy luận định hướng hiệu ứng và truy vấn
- Bộ máy quy tắc logic của Flix kết hợp định hướng hiệu ứng với tính trong suốt tham chiếu, từ đó thúc đẩy thiết kế chương trình trực quan hơn và ít lỗi hơn
- Sử dụng cú pháp truy vấn để dễ dàng rút ra ngày sẵn sàng của mọi bộ phận tương ứng với ReadyDate
- Cách làm này có thể được ứng dụng trong nhiều lĩnh vực như sản xuất, quản lý chuỗi cung ứng, tự động hóa dựa trên suy luận
Tổng kết và ưu điểm
- Flix kết hợp Effects với suy luận dựa trên quy tắc logic để mô hình hóa ngắn gọn mối quan hệ giữa các thành phần và quy trình trong những hệ thống phức tạp
- So với các ngôn ngữ hiện có, nó có những ưu điểm khác biệt về độ rõ ràng logic và tính ngắn gọn của mã
- Có thể cung cấp lời giải phù hợp cho nhiều bài toán phần mềm hiện đại như đồ thị tri thức, workflow engine, suy luận dữ liệu
1 bình luận
Ý kiến trên Hacker News
Tôi thực sự ấn tượng với chiều sâu và độ rộng của ngôn ngữ này
Các tính năng thiết yếu như kiểu dữ liệu đại số, lập trình logic, tính biến đổi đều đã được tích hợp ngay từ đầu
Điều tôi thích nhất khi nhìn vào bảng so sánh là một tệp thực thi duy nhất đảm nhiệm luôn vai trò package manager, LSP và compiler
Với Haskell, LSP phải tái triển khai khá nhiều thứ giữa ghc và các tệp cabal, lại còn có cả stack được dùng nên tính “chính thống” của package manager cũng hơi mơ hồ
Không phải tôi định chê Haskell, đó thực sự là một ngôn ngữ tuyệt vời
Nhưng thật tiếc là những tính năng tốt nhất của nó dường như hơi bị ẩn đi
Tôi tò mò không biết Flix tích hợp với Java và các ngôn ngữ khác trên JVM thuận tiện đến mức nào
Vì compiler JVM xóa bỏ phần lớn thông tin kiểu, nên tôi thấy tích cực ở chỗ khái niệm
regionscủa Flix hỗ trợ tương tác mệnh lệnh như một công dân hạng nhấtDùng JVM là một lợi thế cực lớn vì có thể dễ dàng tận dụng các thư viện chuẩn chất lượng cao trị giá hàng chục tỷ đô la
Vì thế tôi nghĩ JVM hay .net core là lựa chọn hợp lý nhất cho hơn 90% dự án
Có vẻ F# là ngôn ngữ duy nhất đáng đem ra so sánh
Sẽ thật tuyệt nếu có một tài liệu tổng hợp các giới hạn trong khả năng tương tác giữa Flix và JVM
Nhân tiện, có thông tin liên quan ở đây
Về cơ bản, các giá trị Flix/Java đi qua quá trình boxing/unboxing
Ngoài ra, Record cũng là công dân hạng nhất
Nếu bạn thích việc package manager, LSP và compiler đều là một tệp thực thi duy nhất, có lẽ bạn cũng sẽ rất thích Unison
Phần lập trình logic và datalog có cảm giác hơi được thêm vào
Những tính năng khác thì rõ ràng giúp tăng tính an toàn kiểu của codebase, còn lập trình logic lại khá là tính năng dành cho số ít, nên tôi nghĩ có lẽ tốt hơn nếu nó tồn tại tách biệt với bản thân ngôn ngữ
Nói rằng compiler JVM xóa toàn bộ thông tin kiểu thì không hoàn toàn đúng đâu (với lớp ẩn danh thì tham số kiểu vẫn được giữ lại)
Cũng có nhiều cách lách khác nhau
Và thật ra từ góc nhìn của compiler thì đây không phải vấn đề lớn
Chỉ cần ngẫu nhiên hóa tên lớp đã áp dụng type constructor rồi render nó như lớp bình thường là được
F# (vẫn) chưa hỗ trợ type class nên có khá nhiều hạn chế với lập trình dựa trên monad
Nếu F# bỏ qua monad kiểu Haskell và nhảy thẳng sang algebraic effects thì theo tôi điều đó sẽ hợp hơn với triết lý của F#
Phần
StringBuilderhơi khiến tôi thất vọngỞ khía cạnh này có vẻ nó nghiêng về phía Java hơn một chút nên tôi chưa thực sự bị thuyết phục
Còn những phần khác thì nhìn qua thấy khá ổn
Xét từ góc độ ngữ nghĩa ngôn ngữ, có vẻ ngữ nghĩa mở rộng/hạn chế của record đa hình đang đi theo cách scoped label của Leijen (liên kết bài báo)
Ví dụ nếu có record
r1 = { color = "yellow" }thì có thể mở rộng thànhr2 = { +color = "red" | r1 }r2#colorsẽ cho ra"red", rồi nếu lại bỏ trường"color"đi thìr3 = { -color | r2 }r3#colorsẽ cho ra giá trị gốc là"yellow"Tôi nghĩ cách này hợp lý hơn nhiều so với kiểu cũ, tức là dùng một hệ kiểu cực kỳ phức tạp chỉ để cấm thêm cùng một label field hai lần
Tôi tò mò vì sao Aarhus (đặc biệt là trường đại học/tech hub ở đó) lại có ảnh hưởng mạnh đến nghiên cứu ngôn ngữ lập trình như vậy
C++, C#/Typescript, Dart đều có gốc rễ rất mạnh ở khu vực nhỏ bé này của Đan Mạch
Nó không phải kiểu trường danh tiếng Ivy League hay Oxbridge điển hình như Delft hay INRIA
Điều gì đã khiến nơi đó trở nên đặc biệt như vậy? Chỉ là tò mò vu vơ thôi, do nước chăng, hay vì lý do nào khác?
Nhắc một chút thì C# do Anders Hejlsberg tạo ra và ông ấy học ở DTU (Copenhagen)
Turbo Pascal cũng do ông ấy làm, còn Borland là công ty do một người Đan Mạch sáng lập
Nhìn chung Đan Mạch rất mạnh về lý thuyết ngôn ngữ lập trình
Ví dụ, giáo trình cao học tiêu chuẩn trong lĩnh vực phân tích chương trình tĩnh (của Nielson & Nielson) cũng do người Đan Mạch viết
Mads Tofte có đóng góp lớn cho Standard ML
Aarhus có thể không ở đẳng cấp Ivy League hay Oxbridge, nhưng vẫn là một trường đại học xuất sắc
Ở châu Âu có hàng chục trường kiểu như vậy: danh tiếng không quá lớn nhưng chất lượng giảng dạy và nghiên cứu rất cao
Aarhus có truyền thống rất mạnh trong logic, type theory, và các ngôn ngữ hàm/hướng đối tượng
Nhiều nhà nghiên cứu có ảnh hưởng trong lĩnh vực này đều xuất thân từ Aarhus
Ngoài ra, tôi cũng cảm thấy nghiên cứu ngôn ngữ lập trình trên toàn cầu bị lệch về phía Mỹ khá mạnh
Những tổ chức như Aarhus thường rất ít làm marketing hay tự PR, và thiên về tập trung vào nghiên cứu tốt
Không hẳn là tốt hơn hay kém hơn, nhưng điều đó khiến họ khó nhận được sự chú ý trên phạm vi toàn cầu hơn
Flix tiếp tục gây ấn tượng như ngôn ngữ được thiết kế chỉn chu nhất trong họ ML mà tôi từng thấy
Sự kết hợp giữa các mô hình hàm, mệnh lệnh, logic cùng với hệ kiểu & hiệu ứng đa hình và cả các ràng buộc Datalog như công dân hạng nhất là điều thực sự độc đáo
Việc phân tách nghiêm ngặt mã thuần/không thuần ở cấp kiểu mang lại cảm giác mới mẻ như một lựa chọn thay thế monad nhưng dễ suy luận hiệu ứng hơn
Triết lý “một ngôn ngữ, không cần cờ” và việc chỉ hướng đến lỗi ở thời điểm biên dịch cũng đơn giản, dễ đoán và rất đáng thích
Dù bản thân JVM không hỗ trợ loại bỏ đệ quy đuôi một cách native, việc Flix vẫn triển khai được loại bỏ lời gọi đuôi hoàn chỉnh là một thành tựu kỹ thuật đáng chú ý
Tôi rất muốn nghe trải nghiệm từ những ai đang dùng Flix trong môi trường production hoặc nghiên cứu
Đặc biệt là khi dùng trong lập trình logic hay đồng thời, mọi người đã gặp khó khăn gì với “closed-world assumption”, việc không hỗ trợ exception, hay sự khác biệt giữa tích hợp Datalog và các ngôn ngữ logic khác như Prolog?
Hồi trước tôi từng xem qua Flix và thấy rất thú vị, đến mức còn viết một bài có tiêu đề “Flix for Java Programmers”
Giờ nó hơi cũ nên chắc cần cập nhật lại một chút...
Nếu ai quan tâm thì có thể xem ở đây
Bài blog thật sự rất hay
Nếu được phép thì sẽ rất tuyệt nếu thêm nó vào tuyển tập blog chính thức của Flix (liên kết)
Từ sau bài đó, ngôn ngữ Flix đã phát triển khá nhiều
Đặc biệt là hệ hiệu ứng đã được mở rộng mạnh, khả năng tương tác Java được cải thiện và cú pháp cũng đã được cập nhật
Blog đúng là như một kho báu
Nó giống như phiên bản tinh tế hơn của những suy nghĩ đã làm tôi bận tâm suốt thời gian dài
Tôi rất háo hức đọc hết tất cả
Hỗ trợ cả HKT nên rất tuyệt
Nhưng tôi không thấy giải thích gì về typeclass nên khá tò mò
Nếu chỉ cần hỗ trợ thêm typeclass và macro kiểu Scala thì tôi có thể sẽ thử chuyển các thư viện tôi viết (distage, izumi-reflect, BIO) sang Flix, và nghiêm túc cân nhắc chuyển từ Scala sang Flix
Sau đó tôi phát hiện ra rằng về sau họ gọi typeclass là traits
Tôi cũng tò mò macro thì sao
Ngoài ra tôi thấy hơi tiếc là Flix cũng không hỗ trợ nominal inheritance tường minh
Thành ra ngay cả dạng trait vô hại nhất của Scala cũng không được phép
Tôi cảm thấy typeclass không thể thay thế interface, và nếu không có lớp trừu tượng đó thì rất nhiều thứ hữu ích либо không thể triển khai được, либо mã sẽ trở nên xấu xí
Trait cũng có thể cung cấp triển khai mặc định cho hàm, nhưng instance có thể override
Flix hoàn toàn không có inheritance
Trait chỉ được dùng ở thời điểm biên dịch và đi qua quá trình monomorphization nên không có chi phí runtime
Trình inliner của Flix cũng tối ưu cả bên trong trait, đến mức tích cực loại bỏ luôn closure
Ví dụ các hàm bậc cao hay pipeline ở mức bytecode sẽ biến thành các vòng lặp bình thường, không còn allocation cho closure hay gián tiếp tham chiếu gì cả
Flix hiện vẫn chưa hỗ trợ macro
Có lẽ vì kinh nghiệm (bị lạm dụng) ở các ngôn ngữ khác nên họ ngại đưa vào
Bọn tôi đang tìm thêm tác giả thư viện mới, nên nếu hứng thú thì mong bạn ghé qua kênh Gitter
Liên quan đến mục “các tính năng Flix không hỗ trợ” trong tài liệu chính thức
Có một mục là
No Code Before MainNhưng phần mô tả thực tế lại là “Flix không chạy bất kỳ đoạn mã nào trước
main, hoàn toàn không có static initializer hay thứ tương tự”Tôi nghĩ tên tính năng nên đổi thành
Code Before Mainthì sẽ chính xác hơnTôi tò mò vì sao trong Flix lại bắt buộc phải đánh dấu tường minh việc một hàm là thuần
Gần như trong mọi trường hợp, có vẻ phân tích tĩnh là đủ để suy luận, nên tôi muốn biết lý do là gì
Theo tôi biết thì nếu bạn đánh dấu tính thuần cho hàm, compiler sẽ đảm bảo điều đó cho bạn
Khi nhìn vào câu “Flix tracks the purity of every expression in the program exactly”, cùng với ví dụ định nghĩa hàm không có ký hiệu thuần/không thuần
thì có vẻ trong đa số trường hợp compiler hoàn toàn có thể tự suy luận tính thuần
nên tôi có cảm giác việc đánh dấu thuần/không thuần có thể chỉ là tùy chọn
FAQ của Flix (liên kết) mở đầu khá bình thường nhưng càng đọc càng buồn cười
Một vài ví dụ hài hước:
Tôi tò mò liệu các code agent tương thích với ngôn ngữ này có hoạt động tốt không, hay vẫn là tình huống phải tự mình vắt óc
Nói đùa vậy thôi, nhưng thật sự nhìn ngôn ngữ này rất hay nên cũng thấy buồn
LLM có lẽ sẽ càng cản trở việc chấp nhận các ngôn ngữ mới, và tôi tự hỏi vấn đề này sẽ được giải như thế nào
Tôi lại có trực giác rằng LLM sẽ làm giảm rào cản tiếp nhận ngôn ngữ mới
Mã của thư viện chuẩn là đủ để LLM học cú pháp mới, mà kể cả không đủ thì agent vẫn có thể quan sát đầu ra compiler để học dần
Bản thân việc chuyển mã không phải loại công việc đòi hỏi sáng tạo cao, mà là một việc được xác định khá rõ, nên nó sẽ là một trong những lĩnh vực tự động hóa đầu tiên của LLM
Về sau, tôi nghĩ phần chúng ta thật sự phải dùng đầu óc nghiêm túc suy nghĩ sẽ là “vì sao ta làm việc này” và “nó tạo ra tác động gì lên thế giới”
Tôi nhận được kết quả khá ổn khi ghi rõ trong prompt rằng bắt buộc phải dùng index/dependent types của Idris
(nếu không có chỉ dẫn kiểu đó thì thường cùng lắm chỉ ra được GADT)