- Cốt lõi của năng suất lập trình nằm ở hệ sinh thái thư viện phong phú hơn là bản thân ngôn ngữ
- Những framework tận dụng các tính năng cao cấp của ngôn ngữ như Ruby on Rails mang lại năng suất cao ngay cả cho người không chuyên
- Tuy nhiên, do những giới hạn mang tính cấu trúc của ngôn ngữ, rất khó triển khai một framework ở cấp độ Rails bằng Java hay C
- Thiết kế ngôn ngữ trực tiếp quyết định hình thức và độ phức tạp của các thư viện có thể được viết ra, và đó chính là mục đích cốt lõi của sự phát triển ngôn ngữ
- Từ góc nhìn này, ngôn ngữ Stanza cho thấy tầm quan trọng của thiết kế ngôn ngữ trong việc cho phép tạo ra các thư viện mạnh mẽ và dễ dùng
Mối quan hệ giữa ngôn ngữ lập trình và thư viện
- Hầu hết các ngôn ngữ lập trình đều có những thành phần cơ bản tương tự như biến, mảng, vòng lặp và hàm
- Một số ngôn ngữ cung cấp các tính năng nâng cao như hàm hạng nhất hoặc coroutine, nhưng người không chuyên thường không sử dụng tốt chúng
- Với nhiều nhà phát triển, yếu tố giúp tăng năng suất là thư viện hơn là ngôn ngữ
- Ví dụ, Ruby on Rails giúp xây dựng ứng dụng web dựa trên cơ sở dữ liệu một cách dễ dàng
- Nhờ Rails, mức độ ưa chuộng framework còn cao hơn cả bản thân ngôn ngữ Ruby
Sự tương tác giữa Ruby on Rails và các tính năng ngôn ngữ
- Rails tận dụng nhiều tính năng của Ruby như metaprogramming, đánh giá lúc chạy, hàm hạng nhất, garbage collection
- Ví dụ: ActiveRecords dùng metaprogramming, còn hệ thống template dùng đánh giá lúc chạy
- Xử lý sự kiện được triển khai bằng cách truyền hàm hạng nhất làm callback
- Trong Java hay C, do thiếu các tính năng này nên không thể triển khai một framework ở cấp độ Rails
- Metaprogramming của Java không đủ mạnh để triển khai ActiveRecords
- Vì vậy, Rails tồn tại được nhờ cấu trúc của ngôn ngữ Ruby, và thiết kế ngôn ngữ quyết định khả năng của thư viện
Thiết kế ngôn ngữ quyết định hình thức của thư viện
- Ngôn ngữ C chỉ hỗ trợ tái sử dụng thông qua khai báo và gọi hàm, nên phần lớn thư viện C có dạng tập hợp các hàm
- Ruby hỗ trợ hàm hạng nhất nên có thể diễn đạt ngắn gọn kiểu “hành động sẽ chạy khi nút được bấm”
- Ngược lại, trong Java phải định nghĩa lớp handler, nên mã trở nên phức tạp hơn
- Năng lực biểu đạt của ngôn ngữ trực tiếp quy định cấu trúc và tính dễ dùng của thư viện
Phần mềm tương tác và sự xuất hiện của framework có thể mở rộng
- Trong thời kỳ điện toán xử lý theo lô của thập niên 1970, thư viện xoay quanh hàm là đủ dùng
- Trong phần mềm tương tác hiện đại, cần đến thư viện có thể mở rộng
- Trong GUI hay hệ thống dựa trên sự kiện, cần một cấu trúc kiểu “khi người dùng bấm thì chạy mã của tôi”
- Java và C++ hỗ trợ mở rộng bằng kế thừa và ghi đè phương thức, và cấu trúc đó đã phát triển thành framework
Bối cảnh thiết kế Stanza và giới hạn của ngôn ngữ
- Động lực thiết kế Stanza bắt đầu từ khó khăn khi viết thư viện lập trình game dễ dùng trong Java
- Trong Java, tính đồng thời phải được biểu diễn như máy trạng thái (state machine)
- Scheme hỗ trợ continuation nên có thể triển khai trực quan hơn
- Tuy nhiên, Scheme không hỗ trợ kiểm tra kiểu tĩnh nên hiệu quả debug thấp
- Hiện nay, phần lớn ngôn ngữ vẫn không thể mở rộng hệ thống kiểu bằng thư viện
- Stanza cung cấp hệ thống kiểu tùy chọn, garbage collection, hệ thống đối tượng dựa trên multimethod
- Nhưng không thể viết mới hoàn toàn một hệ thống đối tượng do người dùng định nghĩa
Mục đích của ngôn ngữ và hướng nghiên cứu
- Mục tiêu của ngôn ngữ lập trình đa dụng là hỗ trợ tạo ra các thư viện mạnh mẽ và dễ dùng
- Ngôn ngữ càng mạnh thì việc dùng thư viện càng ngắn gọn
- Khi mã sử dụng một thư viện được thiết kế tốt, nó có sự tự nhiên như đang đọc một câu lệnh giao việc cho đồng nghiệp
- Racket, Shen và các nghiên cứu về meta object protocol đang khám phá hệ thống kiểu và hệ thống đối tượng có thể mở rộng
- Cuối cùng, các ngôn ngữ được phân biệt bởi “có thể dùng loại thư viện nào, và không thể dùng loại thư viện nào”
- Đằng sau một thư viện thanh lịch là hàng chục năm nghiên cứu và nỗ lực thiết kế ngôn ngữ
1 bình luận
Ý kiến trên Hacker News
Ví dụ điển hình nhất là Prolog. Nó thường được gọi là ngôn ngữ tiêu biểu của lập trình logic, nhưng thực ra về cơ bản chỉ là một tập hợp các thuật toán, và có thể được triển khai như thư viện trong từng ngôn ngữ. Tôi nghĩ chỉ cần cung cấp cách biểu đạt cú pháp của Prolog sao cho phù hợp với cú pháp của từng ngôn ngữ là đủ
Mười năm trước tôi là fan của Scala. Khái niệm “Scalable Language” rất hấp dẫn vì có thể tạo DSL bên trong hệ thống kiểu. Nhưng rồi tôi mất hứng khi cộng đồng bắt đầu dùng nó như một kiểu Haskell chạy trên JVM. Gần đây tôi kỳ vọng các công nghệ như WASM hay Graal sẽ tăng tính linh hoạt trong việc chọn ngôn ngữ. Nhiều trường hợp chỉ cần JS là đủ, nhưng thật tốt khi có thêm lựa chọn dùng ngôn ngữ cấp thấp như Rust lúc cần thiết
Sẽ thật tuyệt nếu có thể thay bash bằng một ngôn ngữ script có kiểu. Tôi đã thử viết một script parser JSON đơn giản bằng Elixir và thấy khá ổn
#!/usr/bin/env ocamllà được. Tuy nhiên, nó không có khả năng tự động cài dependency ngoài trong một file đơnNgôn ngữ và thư viện không loại trừ lẫn nhau. Có những thư viện thực chất hoạt động như một ngôn ngữ, và ngược lại cũng có ngôn ngữ được thiết kế để phục vụ một thư viện cụ thể. Ví dụ, Julia là một trường hợp cân bằng tốt giữa hiệu năng và tính tiện dụng. Bạn có thể viết trực tiếp code hiệu năng cao bằng Julia và nhận được việc thực thi tối ưu nhờ biên dịch chuyên biệt theo kiểu ở mức JIT. Mô hình gọi hàm nhìn thì đơn giản nhưng bên trong vận hành rất tinh vi
Raku được thiết kế theo cấu trúc kết hợp nhiều tiểu ngôn ngữ (slang). Ví dụ, regex, PEG, quoting, v.v. đều được xử lý như những mini-language riêng, và có thể dễ dàng thêm DSL của riêng mình bằng Slangify
Trước đây có một lập trình viên senior từng nói “cứ thấy Rails trong CV là tôi loại ngay”. Điều đó lại khiến tôi càng thấy rõ việc đánh giá con người qua ngôn ngữ là ngớ ngẩn đến mức nào
Ngôn ngữ hay thư viện cuối cùng đều là công cụ giao tiếp với cả máy lẫn con người. Máy giao tiếp bằng bit và điện áp, còn con người giao tiếp bằng ý định và khái niệm. Vì thế, nếu một ngôn ngữ hay thư viện giúp con người diễn đạt rõ ràng và nhanh chóng thì việc nó là ngôn ngữ hay thư viện không còn quan trọng. Rails hay Stanza đều vậy, miễn là phù hợp với mục tiêu và cả nhóm dễ hiểu thì đó là lựa chọn đúng
Tôi nghĩ “thư viện chính là ngôn ngữ cuối cùng”. Ví dụ, Ruby on Rails là một ngôn ngữ tuyệt vời để viết dịch vụ web dựa trên Ruby. Ruby và Rails đã cùng tiến hóa vì nhau. Rốt cuộc, tôi xem lập trình là một quá trình dịch liên tục giữa các ngôn ngữ
Câu “ngôn ngữ càng mạnh thì càng dễ dùng thư viện” là đúng. Ngày xưa với Java cũ thì khó mà tạo ra framework kiểu Express
Nếu nói về web framework cho ngôn ngữ C, chẳng phải đã có PHP rồi sao? ;)