39 điểm bởi xguru 2022-12-12 | 7 bình luận | Chia sẻ qua WhatsApp

"Little Language" là gì?

  • "Ngôn ngữ nhỏ" là những ngôn ngữ được tạo ra với mục đích giải quyết một vấn đề cụ thể
    → SQL, RegEx, Dhall,..
    → Ngoài ra còn được gọi là DSL

Vì sao cần ngôn ngữ nhỏ?

  • Khi ứng dụng trở nên rất phức tạp thì mã nguồn cũng phình to, đồng thời ngày càng khó hiểu hơn
  • Việc onboarding nhân sự mới trở nên khó khăn, dễ phát sinh lỗi do thiếu hiểu biết về các phụ thuộc, và việc thay đổi mã cũng ngày càng khó quản lý hơn
  • Trong 10 năm qua, codebase đã tăng kích thước từ 100 đến 500 lần
    • Linux kernel bắt đầu với 10 nghìn dòng vào năm 1992, nhưng sau 20 năm đã đạt 30 triệu dòng
  • Những đoạn mã này không chỉ tăng lên vì "tính năng nhiều hơn". Đó còn là vì cách chúng ta xây dựng phần mềm đã thay đổi
    • Phần mềm cũng giống như việc xây kim tự tháp: để đặt được viên đá cuối cùng, cần rất nhiều viên đá bên dưới

Vượt qua xu hướng này

  • Để tạo ra một hệ điều hành hiện đại, có nhất thiết phải cần tới hàng triệu dòng mã không?
  • Alan Kay đã thách thức giả định này trong chương trình STEPS năm 2006
  • Chúng tôi cho rằng việc tạo ra một "ngôn ngữ" phù hợp với bài toán cần giải quyết sẽ khiến việc giải quyết vấn đề trở nên dễ dàng hơn, đồng thời làm cho lời giải dễ hiểu hơn và nhỏ gọn hơn

  • Trong STEPS, họ tạo ra một ngôn ngữ tên là Nile, và dùng nó để triển khai chức năng tương tự bộ dựng hình Cairo 44.000 dòng chỉ với khoảng 300 dòng mã

Vì sao ngôn ngữ bậc cao là chưa đủ?

  • Chẳng phải chỉ cần tạo ra một ngôn ngữ đa dụng ở mức trừu tượng cao hơn là được sao?
  • Cá nhân tôi cho rằng chúng ta đã chạm tới mức lợi ích giảm dần đối với sức biểu đạt của các ngôn ngữ đa dụng
  • Một ngôn ngữ còn cao hơn nữa sẽ trông như thế nào? Lấy Python làm ví dụ, nó đã ở mức quá cao đến mức nhìn gần như pseudo-code
  • Vấn đề của ngôn ngữ đa dụng là bạn phải dịch bài toán của mình thành thuật toán, rồi lại phải biểu đạt thuật toán đó bằng ngôn ngữ đích
    • Trong cuốn Programming Pearls năm 1986 của Jon Bentley, ông từng mời Donald Knuth và Doug McIlroy viết một chương trình đếm tần suất xuất hiện của từ; Don đã viết nó trên 10 trang bằng WEB, một biến thể của Pascal, cùng với các cấu trúc dữ liệu phức tạp
    • Còn Doug thì giải quyết bằng cú pháp Unix pipe chỉ trong 6 dòng, dùng tr, sort, uniq, sort, sed...

Càng ít càng tốt: Less is More

  • Các lệnh Unix ở trên cho thấy thêm một đặc điểm khác của ngôn ngữ nhỏ.
    "Ngôn ngữ kém quyền năng hơn, nhưng runtime mạnh hơn"
  • Gonzalez đã nói về xu hướng này trong "The end of history for programming"
    • Đẩy các vấn đề ở tầng người dùng sang cho runtime giải quyết
      • Khiến chương trình trở nên gần với biểu thức toán học thuần túy hơn, trong khi độ phức tạp của runtime tăng mạnh
  • RegEx và SQL lần lượt không thể biểu đạt gì ngoài tìm kiếm văn bản và thao tác cơ sở dữ liệu
  • Điều này đối lập với những ngôn ngữ như C, nơi gần như mọi thứ đều có thể biểu đạt được mà không có runtime kiểu đó
  • Ngôn ngữ nhỏ đứng ở cực đối diện trên phổ sức mạnh mà C sở hữu
    • Không chỉ trừu tượng hóa kiến trúc máy tính, chúng còn giới hạn loại chương trình có thể biểu đạt, nên theo thiết kế là Turing-incomplete
    • Nghe có vẻ rất hạn chế, nhưng lại mở ra những khả năng hoàn toàn mới cho tối ưu hóa và phân tích tĩnh

Phân tích tĩnh

  • Ngôn ngữ kém quyền năng hơn thì dễ suy luận hơn, và có thể cung cấp những bảo đảm mạnh hơn so với ngôn ngữ đa dụng
  • Ví dụ, Dhall là một "Total Functional Programming Language" để tạo ra các tệp cấu hình
    • Nói cách khác, để loại bỏ nguy cơ rơi vào vòng lặp vô hạn, chương trình Dhall được "bảo đảm" là "(1) không bị crash, (2) kết thúc trong thời gian hữu hạn"
    • (1) đạt được bằng cách không cho phép ném exception. Những thao tác có thể thất bại sẽ trả về kết quả Optional (có thể có hoặc không có giá trị)
    • (2) đạt được bằng cách không cho phép định nghĩa đệ quy
  • Trong các ngôn ngữ hàm khác, đệ quy là cách cơ bản để triển khai vòng lặp, nhưng Dhall phải dựa vào hàm fold dựng sẵn
  • Việc không có cấu trúc lặp tổng quát có nghĩa là Dhall không Turing-complete. Nhưng vì đây không phải ngôn ngữ đa dụng nên điều đó không cần thiết
  • Khi ngôn ngữ nhỏ, việc suy luận trở nên dễ hơn rất nhiều
    • Ví dụ, rất khó xác minh một chương trình Python có tác dụng phụ nào khác hay không, nhưng với SQL thì chỉ cần kiểm tra xem truy vấn có bắt đầu bằng SELECT hay không
  • Với Nile, nhóm STEPS đã cần một trình gỡ lỗi đồ họa nên tự xây dựng nó, và bạn có thể xem trực tiếp
    • Điều này khả thi vì Nile là một ngôn ngữ nhỏ, dễ suy luận

Nhu cầu về tốc độ

  • Ngôn ngữ lập trình càng quyền năng thì không chỉ làm tăng khả năng phát sinh lỗi, mà còn có thể gây hại cho hiệu năng
  • Ví dụ, nếu chương trình không được biểu đạt dưới dạng thuật toán, runtime có thể tự chọn thuật toán
    • Những biểu đạt chậm có thể được thay bằng cách nhanh hơn, miễn là chứng minh được cho cùng một kết quả
  • Chẳng hạn, truy vấn SQL không chỉ thị cách thực thi truy vấn
    • Database engine có thể tự do quyết định query plan nào là phù hợp
      • Dùng index, composite index, hay quét toàn bộ bảng DB, v.v.
    • Các database engine hiện đại còn thu thập thống kê về phân bố giá trị của từng cột, nên có thể chọn kế hoạch truy vấn tối ưu về mặt thống kê ngay tại chỗ
    • Nếu truy vấn được viết sẵn dưới dạng thuật toán thì điều đó sẽ không thể thực hiện được
  • Một trong những "bí quyết" giúp ngôn ngữ Nile cực kỳ cô đọng là "Jitblt", một trình biên dịch Just-in-Time cho dựng hình đồ họa
    • Qua thảo luận giữa STEPS và nhóm Cairo, họ nhận ra rằng rất nhiều mã Cairo được dùng để tối ưu thủ công công việc phối trộn pixel
    • Về lý thuyết, đây là công việc có thể được offload sang compiler
    • Dan Amelang của nhóm Cairo đã tình nguyện hiện thực hóa kiểu compiler này, và đó chính là Jitblt
    • Điều này cho thấy việc tối ưu hóa pipeline đồ họa có thể được tách khỏi phần mô tả toán học thuần túy về những gì cần render,
      nhờ đó Nile có thể chạy nhanh ngang với mã Cairo gốc đã được tối ưu thủ công

Small languages, Big Potential (Ngôn ngữ nhỏ, tiềm năng lớn)

  • Vậy rốt cuộc STEPS đã đi đến đâu? Họ có tạo ra được một hệ điều hành chạy bằng lượng mã đủ để in lên áo thun không?
  • Kết quả cuối cùng của STEPS là KSWorld
    • Một hệ điều hành hoàn chỉnh có tích hợp trình soạn thảo văn bản và bảng tính
    • 17.000 dòng mã
    • Hơi dài để in vừa lên áo thun, nhưng tôi cho rằng đó vẫn là một thành công
  • Sự ra đời của KSWorld cho thấy "ngôn ngữ nhỏ" có tiềm năng rất lớn
  • Nhưng vẫn còn nhiều câu hỏi chưa được trả lời
    • Những ngôn ngữ này sẽ giao tiếp với nhau như thế nào?
    • Có nên biên dịch về một biểu diễn trung gian chung không?
    • Hay nên để nhiều runtime khác nhau cùng tồn tại song song và giao tiếp qua các giao thức chuẩn như Unix pipe, TCP/IP?
    • Hoặc liệu mỗi ngôn ngữ có đủ nhỏ để có thể được tái hiện thực trên nhiều host language khác nhau?
    • Hay có lẽ hướng đi đúng là kết hợp tất cả những điều này?
  • Dù sao đi nữa, tôi tin rằng chúng ta cần nghĩ ra một cách khác để xây dựng phần mềm
    • Có thể "ngôn ngữ nhỏ" sẽ là một phần của câu chuyện đó
    • Điều quan trọng là đừng tiếp tục chồng thêm gạch lên trên từng lớp hiện có quá lâu đến mức chúng ta không còn đủ thời gian để nghĩ ra thứ tốt hơn

7 bình luận

 
ide127 2022-12-15

"
Chúng tôi cho rằng việc tạo ra một 'ngôn ngữ' phù hợp với vấn đề cần giải quyết sẽ giúp việc giải quyết vấn đề trở nên dễ hơn, đồng thời làm cho giải pháp dễ hiểu hơn và gọn nhỏ hơn.
"

Cảm nhận của tôi khi đọc đoạn này là, rốt cuộc cái gọi là 'ngôn ngữ nhỏ' có lẽ chẳng phải mang ý nghĩa tương tự như framework sao. Giống như trường hợp 'JavaScript -> React', nơi các hàm thường dùng và các design pattern được áp đặt để trở thành một dạng cú pháp hóa.

 
chicol 2022-12-14

Chủ đề này thật thú vị.

 
kunggom 2022-12-12

Nghĩ lại thì gần đây tôi phát hiện ra một công cụ tạo DSL tên là MPS(Meta Programming System) do JetBrains làm.
Hóa ra đây là một món khá lâu đời hơn tôi tưởng. Vì thấy hứng thú nên tôi định tìm hiểu kỹ hơn, nhưng cứ vì chuyện này chuyện kia mà trì hoãn; nếu ở đây có ai đã dùng thử thì tôi rất muốn được nghe cảm nhận hay đánh giá sử dụng.

 
uglyduck68 2022-12-12

Wow, cảm ơn bạn.

 
nicewook 2022-12-12

Cảm ơn, tôi đã đọc.

 
roxie 2022-12-12

Lisp hớn hở

 
xguru 2022-12-12

Tôi thấy đây là một câu chuyện thú vị nên xin chuyển lại.