Về Ngôn Ngữ Forth - nói dối e blog

Về Ngôn Ngữ Forth

Tối nay tiếp tục đọc cuốn Masterminds of Programming, lại không kiềm chế được mà dịch tiếp nửa chương phỏng vấn cha đẻ của Forth - Charles Moore. Trước đây tôi từng đọc vài bài phỏng vấn ông ấy từ thời kỳ đầu, hiểu sơ qua quan điểm của ông. Hồi nhỏ tôi đặc biệt say mê Forth. Ông cụ này quả thật rất kỳ thú!

Tôi chưa tham khảo bản dịch gốc nào khác, chỉ tự mình dịch chương 4 theo cách hiểu riêng. Có lẽ tôi cũng thuộc dạng yêu Forth sâu sắc, hiểu rõ cả những thuật ngữ như ITC (Indirected-threaded code), nhưng dù vậy vẫn thấy việc dịch thuật khá vất vả.
Dành cho các bạn cùng đam mê Forth, xin mời đọc bản dịch này như một tài liệu

Thiết kế ngôn ngữ Forth

Ông định nghĩa Forth thế nào?
Chunk: Forth là một ngôn ngữ lập trình máy tính với cú pháp tối giản đến mức gần như triệt để. Đặc điểm nổi bật nhất là việc tách riêng ngăn xếp tham số, giúp việc gọi chương trình con cực kỳ hiệu quả. Vì thế, ngôn ngữ này dùng biểu thức hậu tố (viết tham số trước, toán tử sau), khuyến khích phong cách chia nhỏ chương trình thành hàng loạt hàm con cực ngắn, chia sẻ tham số qua ngăn xếp.

Tôi từng đọc giải thích về tên Forth, hình như liên quan đến “thế hệ thứ tư” của phần mềm. Ông có thể nói rõ hơn?
Chunk: Từ “Forth” bắt nguồn từ chữ “Fourth” (thứ tư), ám chỉ thế hệ thứ tư của ngôn ngữ máy tính. Theo ký ức của tôi, tôi đã nhảy qua một thế hệ. Thế hệ thứ nhất là FORTRAN/COBOL; thế hệ thứ hai là Algol/Lisp, đều tập trung vào cú pháp. Cú pháp càng phức tạp, càng dễ phát hiện lỗi, nhưng đa số lỗi lại chính là lỗi cú pháp. Tôi quyết định giảm thiểu yếu tố cú pháp, tập trung vào ngữ nghĩa. Trong Forth, mỗi từ (word) khi được nạp vào bộ nhớ đều trực tiếp biểu lộ ý nghĩa của nó.

Ông coi Forth như một bộ công cụ ngôn ngữ. Tôi hiểu theo nghĩa: cú pháp đơn giản hơn các ngôn ngữ khác, cho phép tạo từ vựng bằng những từ ngắn hơn. Tôi có bỏ sót điều gì không?
Chunk Moore: Chính xác như vậy. Chìa khóa nằm ở việc phân tách triệt để. Một chương trình Forth gồm hàng loạt từ nhỏ. So với chương trình C cùng chức năng, số lượng từ ít hơn hẳn, nhưng mỗi từ lại phức tạp hơn nhiều.

Tôi gọi từ nhỏ là những từ có thể được định nghĩa trong một dòng mã nguồn duy nhất. Bạn dùng từ vừa định nghĩa để tiếp tục xây dựng từ mới, tích lũy dần thành hàng nghìn định nghĩa, tạo nên ngôn ngữ riêng. Thách thức nằm ở hai điểm: 1) Xác định từ nào thực sự hữu ích; 2) Nhớ được toàn bộ hệ thống từ. Hiện tôi đang làm dự án có hơn nghìn từ, nên đành viết một công cụ tìm kiếm, nhưng bạn phải nhớ tên từ và cách viết tương đối chính xác mới tìm được.

Đây là phong cách lập trình hoàn toàn khác biệt, đòi hỏi thời gian để thích nghi. Tôi thấy nhiều chương trình Forth hiện nay thực chất chỉ là bản dịch trực tiếp từ C sang, điều này không nên. Cách đúng đắn là xây dựng từ đầu. Một điểm thú vị khác: từ mới bạn định nghĩa không khác gì các từ trong nhân hệ thống, cả về hiệu suất lẫn chức năng - không có chi phí bổ sung nào.

Cấu trúc bề ngoài gồm nhiều từ nhỏ là hệ quả của cách triển khai Forth?
Chunk: Đúng là kết quả của chuỗi gọi chương trình con cực kỳ hiệu quả. Không có cơ chế truyền tham số phức tạp vì ngôn ngữ dựa trên ngăn xếp - chỉ cần gọi và trả về. Ngăn xếp hoàn toàn “cởi mở”, các từ được biên dịch thành lệnh callreturn trực tiếp. Bạn thậm chí có thể đi sâu đến cấp hợp ngữ, mỗi từ tương ứng một lệnh máy, không qua trung gian gọi hàm. Nhờ vậy, Forth có thể cạnh tranh về hiệu suất với mọi ngôn ngữ khác, thậm chí vượt trội hơn.

Không có chi phí như gọi hàm trong C?
Chunk: Chính xác! Điều này trao cho lập trình viên sự linh hoạt kinh ngạc. Nếu bạn phân rã vấn đề khéo léo, không chỉ giải quyết hiệu quả mà còn tạo ra mã dễ đọc đến bất ngờ.

Ngược lại, nếu bạn làm tệ, kết quả sẽ là mớ hỗn độn chỉ có bạn hiểu. Thậm chí quản lý cấp cao của bạn cũng không thể đọc nổi, biến mã nguồn thành “thiên thư”. Đây là lưỡi dao hai mặt: bạn có thể tạo ra kiệt tác, cũng có thể sản sinh hỗn mang.

Ông có thể đưa ví dụ nào khiến lập trình viên ngôn ngữ khác “yêu ngay từ cái nhìn đầu tiên” với Forth?
Chunk: Khó đấy! Những lập trình viên kỳ cựu đã đầu tư hàng đống thời gian vào hệ sinh thái ngôn ngữ họ đang dùng. Dù bạn nói Forth nhỏ hơn, nhanh hơn, đơn giản hơn, họ cũng không sẵn lòng viết lại toàn bộ. Người mới làm quen với lập trình, hoặc kỹ sư cần giải quyết vấn đề cụ thể, mới là đối tượng tiếp nhận dễ dàng. Hoặc như tôi hiện tại, đang phát triển chip đa nhân - yêu cầu hoàn toàn mới đòi hỏi tư duy đột phá.

Ông từng nói nhiều chương trình Forth giống C. Vậy ông thiết kế chương trình Forth tốt hơn thế nào?
Chunk: Từ dưới lên trên (bottom-up).
Đầu tiên, bạn xác định những tín hiệu I/O cần tạo ra, rồi viết mã điều khiển từng tín hiệu cụ thể. Cứ thế tích lũy dần lên những từ cấp cao. Giả sử bạn đặt tên từ cao nhất là go, chỉ cần gõ go, mọi thứ sẽ vận hành trơn tru.

Tôi không tin vào phương pháp phân tích hướng trên xuống (top-down), phân rã vấn đề theo logic trừu tượng thường dẫn đến những thành phần khó triển khai thực tế.

Phương pháp thiết kế hướng miền (Domain-Driven Design) nhấn mạnh dùng từ vựng khách hàng để mô tả logic kinh doanh. Mối liên hệ thế nào với việc xây dựng từ điển trong Forth?
Chunk: Quan trọng nhất là lập trình viên phải hiểu lĩnh vực mình đang giải quyết. Tôi luôn trao đổi trực tiếp với khách hàng, lắng nghe từ vựng họ sử dụng, cố

0%