Bảy ngôn ngữ nguyên mẫu của lập trình (2022)
(madhadron.com)- Khác biệt giữa các cụm mẫu nền tảng quan trọng hơn ngữ pháp riêng lẻ, và các ngôn ngữ lập trình được chia thành bảy ngôn ngữ nguyên mẫu theo cách lặp, đệ quy và tổ chức chương trình
- ALGOL, Lisp, ML, Self, Forth, APL, Prolog là các nhóm phân loại cốt lõi; mỗi hệ lấy một ngôn ngữ tiêu biểu làm mẫu chuẩn để xác định phả hệ của các ngôn ngữ khác
- Một ngôn ngữ mới chia sẻ nguyên mẫu quen thuộc thì dễ học, nhưng khi chuyển sang nguyên mẫu xa lạ sẽ cần lối tư duy mới và khá nhiều thời gian học tập
- ALGOL nổi bật với việc tổ chức hàm xoay quanh phép gán, câu lệnh điều kiện và vòng lặp; Lisp với macro và mã dạng danh sách; ML với hàm hạng nhất và đệ quy; Self với đối tượng truyền thông điệp; Forth với cú pháp dựa trên ngăn xếp; APL với mảng n chiều; Prolog với cấu trúc sự kiện và tìm kiếm
- Với mọi lập trình viên, ưu tiên trước hết là thành thạo ngôn ngữ họ ALGOL, tiếp theo là học SQL, rồi sau đó đều đặn làm quen với các ngôn ngữ nguyên mẫu xa lạ để có lợi thế dài hạn
Bảy ngôn ngữ nguyên mẫu của lập trình
- Khi chọn ngôn ngữ lập trình, việc nắm vững các mẫu nền tảng quan trọng hơn khác biệt ngữ pháp riêng lẻ; giữa các ngôn ngữ cùng họ, những cấu trúc cơ bản như duyệt mảng hay duyệt tổ hợp thường có hình thức gần như giống nhau
- Các họ ngôn ngữ khác nhau có sự khác biệt lớn về cách lặp, đệ quy và tổ chức chương trình; chính những cụm mẫu nền tảng này tạo thành các ngôn ngữ nguyên mẫu khác nhau
- Học một ngôn ngữ mới cùng chia sẻ nguyên mẫu quen thuộc là sự chuyển đổi tương đối dễ, nhưng chuyển sang một nguyên mẫu xa lạ thì cần đáng kể thời gian và những lối tư duy mới
- Trong lĩnh vực phần mềm, có bảy ngôn ngữ nguyên mẫu được thừa nhận là ALGOL, Lisp, ML, Self, Forth, APL, Prolog
- Mỗi ngôn ngữ nguyên mẫu được phân loại quanh một ngôn ngữ đại diện cụ thể như một mẫu chuẩn, và các ngôn ngữ khác được xác định phả hệ bằng cách so sánh với mẫu đó
-
ALGOL
- Chương trình được cấu thành như một chuỗi phép gán, câu lệnh điều kiện, vòng lặp, và được tổ chức theo đơn vị hàm
- Nhiều ngôn ngữ bổ sung vào đây hệ thống module, cách định nghĩa kiểu dữ liệu mới, tính đa hình, và các cấu trúc luồng điều khiển thay thế như ngoại lệ hay coroutine
- Phần lớn các ngôn ngữ lập trình đang được dùng rộng rãi hiện nay thuộc về họ ngôn ngữ nguyên mẫu này
- Bản thân ALGOL bao gồm ALGOL 58, ALGOL 60, ALGOL W, ALGOL 68
- Assembly language, Fortran, C, C++, Python, Java, C#, Ruby, Pascal, JavaScript, Ada đều nối với hệ này
- Đây là ngôn ngữ nguyên mẫu lâu đời nhất, với dòng dõi có thể truy ngược đến việc Ada Lovelace hình thức hóa các chương trình cho máy phân tích của Babbage
- Mã máy và hợp ngữ của các máy tính kiến trúc Eckert-Mauchly nối tiếp từ EDVAC và Univac đời đầu, cùng các nỗ lực ngôn ngữ bậc cao ban đầu từ A-0 của Grace Hopper đến Fortran và COBOL, đều mang hình thức này
- Khi lập trình cấu trúc phát triển trong học giới vào thập niên 1960, các ngôn ngữ này trở nên dễ quản lý hơn; kết quả là ALGOL 60, và sau đó phần lớn thành viên của họ này đều phát sinh từ đây
- Theo thời gian, hệ này có xu hướng hấp thụ các tính năng từ những ngôn ngữ nguyên mẫu khác
- Trong thập niên 1980, các khái niệm của họ Self được đưa vào dưới dạng class để làm phương tiện định nghĩa kiểu dữ liệu và triển khai đa hình
- Từ sau năm 2010, các khái niệm của họ ML cũng bắt đầu xuất hiện
-
Lisp
- Cú pháp kết hợp giữa biểu thức tiền tố bọc trong ngoặc và biểu diễn danh sách
(+ 2 3)(defun square (x) (* x x))(* (square 3) 3)
- Biểu diễn danh sách với các mục phân tách bằng khoảng trắng và đặt trong ngoặc được tích hợp sẵn vào ngôn ngữ, nên bản thân mã cũng ở dạng danh sách
- Macro có thể nhận danh sách, sửa đổi nó rồi chuyển đoạn mã đã sửa cho trình biên dịch, tạo nên cấu trúc cho phép lập trình viên tái định nghĩa ngữ nghĩa của ngôn ngữ
- Trong phần lớn việc viết mã, nó có xu hướng hoạt động giống các ngôn ngữ nguyên mẫu khác, thường là ALGOL hoặc ML, nhưng hệ thống macro là điểm phân biệt
- Cú pháp
loopcủa Common Lisp cũng không phải tính năng tích hợp sẵn của ngôn ngữ mà được định nghĩa bằng macro - Dù có nhiều biến thể Lisp ban đầu, cộng đồng đã hình thành đồng thuận quanh Common Lisp
- Sussman và Steele khám phá xem có thể đi xa đến đâu chỉ với hàm, và tạo ra Scheme
- Cũng có các Lisp chuyên dụng như Lush cho tính toán số, AutoLISP là ngôn ngữ script của AutoCAD, và Emacs Lisp để hiện thực hành vi chỉnh sửa của Emacs
- Gần đây, Clojure nổi lên như nhánh lớn thứ ba của họ Lisp
- Ra đời muộn hơn Fortran khoảng một năm, đây là họ ngôn ngữ lâu đời thứ hai vẫn còn được dùng đến ngày nay
- Điểm khởi đầu là một câu hỏi toán học về cách ký hiệu hóa một cấu trúc toán học có thể đánh giá chính biểu thức của nó
- John McCarthy đã đưa ra câu trả lời vào năm 1958, rồi sau đó hiện thực nó trên máy tính
- Do nền tảng toán học, Lisp ban đầu không khớp tốt với phần cứng thời đó; các vấn đề như bộ nhớ và chu kỳ CPU không tồn tại trong toán học, nên cần đến các kỹ thuật như garbage collection
- Cuối thập niên 1970 và đầu thập niên 1980 từng tồn tại những cỗ máy được thiết kế từ đáy lên chỉ để chạy Lisp
- Nhiều yếu tố của môi trường phát triển tích hợp ngày nay được phát minh trên những cỗ máy đó
- Cùng thời kỳ đó, Lisp là công cụ chủ đạo của nghiên cứu trí tuệ nhân tạo; khi cơn sốt AI thập niên 1980 không đem lại kết quả, Lisp cũng cùng lĩnh vực này rơi vào AI Winter
- Dù vậy nó vẫn sống sót, và nhờ hiệu năng máy tính tăng lên cùng việc các ngôn ngữ khác tiếp nhận tính năng của nó, độ khó hiện thực đã giảm đi
- Cú pháp kết hợp giữa biểu thức tiền tố bọc trong ngoặc và biểu diễn danh sách
-
ML
- Hàm là giá trị hạng nhất, và ngôn ngữ có hệ kiểu họ Hindley-Milner có thể biểu diễn nhiều loại hàm và tagged union
- Mọi sự lặp đều được thực hiện bằng đệ quy
sum [] = 0sum (x:xs) = x + sum xs
- Cũng dùng cách định nghĩa các hàm đóng gói mẫu lặp, rồi nhận các hàm khác để hiện thực hành vi
map _ [] = []map f (x:xs) = (f x) : (map f xs)
- Một số ngôn ngữ như Miranda và Haskell mặc định dùng đánh giá lười
- Những ngôn ngữ khác mở rộng hệ kiểu theo nhiều hướng
- OCaml là nỗ lực kết hợp với các khái niệm của ngôn ngữ nguyên mẫu Self
- Agda và Idris áp dụng hệ kiểu phụ thuộc, trộn giá trị và kiểu lại với nhau
- 1ML kết hợp module và kiểu
- Từ ML phát sinh CaML, Standard ML, OCaml
- Các họ liên quan như Miranda, Haskell, Agda, Idris cũng tiếp nối từ đó
- ML ban đầu là meta-language của một chương trình chứng minh định lý được phát triển tại Cambridge, Anh, và cái tên cũng xuất phát từ đây
- Sau đó nó lan ra thành một ngôn ngữ độc lập ngoài bối cảnh đó, và đặc biệt được ưa chuộng ở châu Âu, nhất là tại Anh và Pháp
-
Self
- Chương trình được cấu thành từ một tập hợp đối tượng gửi thông điệp cho nhau, và mọi hành vi đều được hiện thực theo cách này
- Đối tượng mới được tạo ra bằng cách gửi thông điệp tới đối tượng hiện có
- Ngay cả câu lệnh điều kiện cũng được thực hiện thông qua một biến tham chiếu đến một trong hai đối tượng true hoặc false
- Hai đối tượng này nhận một thông điệp với tham số là hàm sẽ chạy khi đúng và hàm sẽ chạy khi sai
- Đối tượng true thực thi hàm thứ nhất, còn đối tượng false thực thi hàm thứ hai
- Mã gọi không biết đó là đối tượng nào, mà chỉ đơn giản gửi thông điệp
- Vòng lặp cũng hoạt động theo cách tương tự; nếu tạo đúng đối tượng và đặt nó vào đúng vị trí thì có thể tái định nghĩa toàn bộ ngữ nghĩa của ngôn ngữ
- Các ngôn ngữ kiểu này thường lưu mã nguồn không phải trong tệp văn bản mà trong môi trường trực tiếp
- Lập trình viên sửa đổi hệ thống đang chạy, rồi lưu trạng thái đó thay vì biên dịch tệp để tạo ra hệ thống
- Các ví dụ quan trọng là Smalltalk và Self
- Nhiều ngôn ngữ chỉ tiếp thu một phần cách truyền thông điệp của họ này, và kiểu tiếp thu từng phần đó thường được gọi là lập trình hướng đối tượng
- Phần lớn trong số đó dựa trên Smalltalk; chỉ JavaScript là ngoại lệ, bắt nguồn từ hệ đối tượng không class của Self
- Hệ đối tượng của Common Lisp khái quát thêm bằng cách để runtime chọn mã thực thi dựa không chỉ trên một đối tượng nhận thông điệp mà trên mọi tham số
- Erlang đổi hướng theo kiểu các luồng thực thi song song lắng nghe và gửi thông điệp một cách tường minh, thay vì để luồng thực thi di chuyển giữa các đối tượng
- Ngôn ngữ khởi nguồn là Smalltalk, được phát triển tại Xerox Parc vào cuối thập niên 1970 và trong thập niên 1980
- Trong thập niên 1980 từng có nhiều hệ Smalltalk thương mại, và IBM dùng Smalltalk để phát triển bộ công cụ lập trình VisualAge cho các ngôn ngữ khác
- Ngày nay Smalltalk chủ yếu tồn tại dưới dạng mã nguồn mở Pharo Smalltalk
- Đã có nhiều nghiên cứu nhằm chạy Smalltalk nhanh và hiệu quả, với đỉnh cao là dự án Strongtalk
- Về mặt lịch sử, các khám phá của Strongtalk rất quan trọng vì đã trở thành nền tảng cho trình biên dịch JIT HotSpot của Java
- Smalltalk kế thừa khái niệm giá trị và kiểu từ các ngôn ngữ trước đó để hiện thực class; mọi đối tượng có một class gán kiểu cho nó, và class tạo ra đối tượng thuộc kiểu đó
- Self loại bỏ khái niệm class và chỉ cấu thành từ các đối tượng
- Vì là hình thức thuần khiết hơn, Self được chọn làm mẫu chuẩn cho ngôn ngữ nguyên mẫu này
-
Forth
- Ngôn ngữ ngăn xếp là dạng như hình ảnh đảo ngược của Lisp, và chia sẻ cú pháp với các máy tính bỏ túi ký pháp Ba Lan ngược của Hewlett Packard
- Nó có một ngăn xếp dữ liệu; khi viết literal như
42thì giá trị được đẩy lên ngăn xếp, còn tên hàm sẽ thao tác trên ngăn xếp mà không có tham số tường minh - Ngay cả số học đơn giản cũng có dạng đảo như
2 3 + 5 * - Định nghĩa hàm cũng rất ngắn gọn
- Trong hầu hết các biến thể Forth,
:dùng để định nghĩa một từ mới squaremang nghĩa tương đương với việc gọiduprồi*dupsao chép phần tử trên cùng của ngăn xếp, còn*nhân hai phần tử trên cùng
- Trong hầu hết các biến thể Forth,
- Có thể chặn parser và thay nó bằng mã của chính mình, nên toàn bộ cú pháp đều có thể bị thay thế
- Dạng chương trình Forth định nghĩa các ngôn ngữ nhỏ là chuyện phổ biến, chẳng hạn các tập con của Fortran, layout gói tin, hoặc cách phân tích trực tiếp sơ đồ ASCII biểu diễn chuyển trạng thái của máy trạng thái
- Bao gồm nhiều biến thể của Forth, cùng PostScript, Factor, Joy
- Joy là một ngôn ngữ hàm thuần túy dùng hình thức toán học của phép hợp thành thay vì ngăn xếp
- Forth lần đầu được viết vào năm 1970 để điều khiển kính thiên văn vô tuyến
- Sau đó nó lan rộng khắp thế giới hệ thống nhúng
- Hệ Forth đủ dễ bootstrap nên tồn tại hàng chục biến thể do nhiều lập trình viên tự làm cho mục đích riêng
- PostScript xuất hiện trong thập niên 1980 như một phương tiện linh hoạt để mô tả tài liệu cho máy in
- Xét trên nhiều phương diện, PostScript bị giới hạn hơn Forth, nhưng nó định nghĩa sẵn trong ngôn ngữ các phép toán cơ bản liên quan đến bố cục đồ họa
-
APL
- Mọi thứ trong ngôn ngữ đều là mảng n chiều
- Toán tử gồm một hoặc hai ký hiệu, và thực hiện các phép toán mức cao trên toàn bộ mảng
- Cách biểu đạt rất cô đặc, đến mức bản thân chuỗi ký hiệu đã là dấu hiệu của phép toán mà không cần đặt thêm tên
- Ví dụ, tính giá trị trung bình của biến
xcó dạng(+⌿÷≢) x - APL, J, K là các ví dụ tiêu biểu
- Các phép toán bậc cao trên mảng đã được xuất khẩu một phần sang nhiều môi trường như MATLAB, NumPy, R
- APL bắt đầu từ ký pháp toán học do Kenneth Iverson tạo ra trong thập niên 1960, rồi sau đó được hiện thực trên máy tính
- Từ đó đến nay nó vẫn giữ được một nhóm ủng hộ ngách trong giới làm tính toán nặng
- Ngôn ngữ hậu duệ K từng rất phổ biến trong môi trường tài chính
-
Prolog
- Chương trình được cấu thành từ một tập các sự kiện
father(bob, ed).father(bob, jane).
- Cũng dùng các sự kiện chưa gán giá trị cụ thể để suy ra sự kiện từ các sự kiện khác thông qua biến
grandfather(X, Y) :- father(X, Z), father(Z, Y).
- Runtime của Prolog nhận các sự kiện này cùng truy vấn và thực hiện tìm kiếm để tìm ra kết quả
- Nếu chọn cấu trúc định nghĩa sự kiện phù hợp thì có thể đạt tính Turing-complete
- Trong Prolog, các term tạo thành sự kiện tự chúng là những kiểu dữ liệu riêng biệt và có thể được tạo ra rồi chuyển cho runtime
- Ở điểm này nó giữ vị trí tương tự macro của Lisp hay việc thay parser của Forth
- Vì chương trình Prolog về bản chất là tìm kiếm, việc tinh chỉnh thường xoay quanh điều chỉnh thứ tự tìm kiếm và chặn sớm các nhánh không có kết quả, giống như truy vấn cơ sở dữ liệu
- Bao gồm Prolog, Mercury, Kanren
- Phần lớn lập trình thực tế trong họ ngôn ngữ nguyên mẫu này diễn ra ngay trong Prolog, và cộng đồng có tính thống nhất rất cao
- Trong thập niên 1970, các nhà logic học ở Pháp nhận ra có thể biểu diễn chương trình bằng logic bậc nhất và bắt đầu thử hiện thực
- Dự án máy tính thế hệ thứ năm của Nhật trong thập niên 1980 đã đặt cược lớn vào Prolog, nhưng cùng với thất bại của dự án, danh tiếng Prolog cũng suy giảm
- Tách biệt với điều đó, suốt nhiều thập niên vẫn có nghiên cứu nhằm làm cho runtime Prolog vận hành hiệu quả trong đa số trường hợp và bổ sung tính năng mới
- Các tính năng như ràng buộc số được thêm vào, dẫn tới lập trình logic ràng buộc
- Prolog vẫn tiếp tục xuất hiện trong các lĩnh vực ngách
- Việc kiểm tra kiểu của Java từng được hiện thực bằng Prolog trong nhiều năm
- Công cụ tìm kiếm mã nguồn ban đầu của Facebook cũng dựa trên Prolog
- Chương trình được cấu thành từ một tập các sự kiện
Nên vận dụng thế nào
- Với phần lớn lập trình viên, một phần hay toàn bộ các họ ngôn ngữ này có thể trông rất xa lạ, nhưng vẫn đáng dành thời gian vì những lối tư duy và các khả năng mới mà mỗi họ mang lại
- Từ góc nhìn ALGOL, hai thứ có vẻ hoàn toàn khác nhau thường lại chỉ là một phép so sánh nhỏ khi nhìn từ góc độ khác
-
Thứ tự ưu tiên
- Mọi lập trình viên nên thật sự nắm vững một ngôn ngữ họ ALGOL
- Sau đó, nên học SQL, một ngôn ngữ thuộc họ Prolog
- Đây là thứ mang lại hiệu quả lớn thứ hai trong sự nghiệp sau ALGOL
-
Mở rộng về sau
- Sau khi đã nắm hai họ trên, về dài hạn sẽ có lợi nếu mỗi năm học thêm một ngôn ngữ mới thuộc một họ nguyên mẫu còn xa lạ
- Các ngôn ngữ được đề xuất trong từng họ và thứ tự là như sau
- Lisp: PLT Racket
- ML: Haskell
- Self: Self
- Prolog: Prolog
- Forth: gForth
- APL: K, dùng qua
ok
-
Điều chỉnh thứ tự
- Nếu làm nhiều tính toán số, nên học K sớm hơn
- Nếu làm nhiều lập trình nhúng, nên học gForth sớm hơn
- Tuy nhiên, bản thân thứ tự hay việc chọn chính xác ngôn ngữ nào không phải điều quá quan trọng
- Có thể học Standard ML hoặc OCaml thay cho Haskell, Common Lisp thay cho PLT Racket, hoặc Factor thay cho gForth
-
Phần bổ sung trong chú thích
- Ngay cả sau khi học SQL, vẫn cần học chính Prolog
- Vì cách dùng thực tế của nó khá khác SQL
- Có ý kiến từ độc giả rằng để hiểu sâu Forth, cách tiếp cận phổ biến là tự tay viết một trình hiện thực Forth
- Có nhắc rằng Forth đủ nhỏ để một người có thể hiện thực từ nền tảng trong thời gian tương đối ngắn
- gForth là một trình hiện thực tốt để học ANS Forth
- Tài liệu học tập được nhắc đến là FORTH Fundamentals, Volume 1 của McCabe
- Các biến thể Forth nên xem thêm gồm PygmyForth, eForth, colorForth
- Ngay cả sau khi học SQL, vẫn cần học chính Prolog
5 bình luận
Thú vị đấy.
Hồi đại học tôi đã học các môn chuyên ngành và làm bài tập với họ ALGOL, Lisp và Prolog, nên đọc lại thấy thật bồi hồi.
Những ngôn ngữ đó đã để lại rất nhiều dấu ấn trong các ngôn ngữ lập trình chủ lưu hiện đại,
nhưng trong số đó chỉ có Forth là có vẻ như ảnh hưởng ít hơn.
Dù không cần đến ký pháp tiền tố, nhưng nếu phải code bằng ký pháp hậu tố thì đúng là quá bất tiện.
Ý kiến trên Hacker News
Trong lớp PL ở Tufts, họ đã tự tay làm các phiên bản mini của 4 họ ngôn ngữ đầu tiên là mệnh lệnh, Lisp, ML, Smalltalk, và thật vui khi quá trình đó giờ cũng đã có thành giáo trình. Hơi tiếc là trước đây còn có cả phần Prolog nhưng giờ đã bị bỏ đi
Nếu chỉ sửa đúng một điểm trong cách phân loại của bài này, thì tôi cho rằng Ruby rõ ràng là một ngôn ngữ hướng đối tượng hơn là thuộc họ Algol. Nó chịu ảnh hưởng lớn từ Smalltalk, và ngay cả tên thư viện chuẩn cũng còn dấu vết đó, kiểu dùng
collectthay vìmap. Trong Ruby, từ đầu đến cuối mọi thứ đều là đối tượng, và hiểu lời gọi phương thức như việc gửi thông điệp tới một đối tượng là cách nhìn tự nhiên hơn. Nó thường bị so với Python, nhưng con đường tiến hóa khá khác nhau, và giờ có cảm giác như đã hội tụ về những điểm tương tự trong hệ sinh thái. Với tôi, Ruby giống một con alpaca ấm áp hơn PythonHello Worldthì điều đó ít lộ rõ, nhưng ngay cả các kiểu cơ bản cũng đều đã là đối tượng. Với những người không thích OOP, cho họ xemtype(42)vàdir(42)là cách hay để nhấn mạnh rằng ngay cả số nguyên cũng là đối tượngTôi muốn thêm vào hệ phả ngôn ngữ một nhóm nữa là ngôn ngữ biểu diễn chứng minh. Đây là dòng mà chương trình cũng chính là chứng minh theo tương ứng Curry-Howard, và Lean là ví dụ tiêu biểu. Có thể xem như một phân nhánh con của hàm, nhưng vì mục tiêu chính là kiểm chứng hơn là thực thi, tôi thấy đáng để tách thành một trục riêng
Gần đây tôi xem lại một dự án so sánh ngôn ngữ, với benchmark là phân rã chu trình song song trên 3,715,891,200 signed permutation của 10 ký tự. Thứ tôi muốn tìm không hẳn là “ngôn ngữ nguyên mẫu”, mà là trong các hiện thực hiện đại của từng hệ hình thì ngôn ngữ nào thực sự đáng chọn cho kiểu lập trình nghiên cứu này. Tôi xem không chỉ hiệu năng, mà cả việc có dễ nhận trợ giúp từ AI hay không, và bản thân tôi có dễ đọc hiểu, suy nghĩ về mã hay không; nhờ AI, tôi cũng có thể đi một vòng tham quan khá sâu để tối ưu từng ngôn ngữ. Kết quả được tổng hợp ở đây, và việc F# đứng đầu quả thật khá bất ngờ
Tôi cũng từng viết một bài tương tự ở đây. Tôi đồng ý với Algol, Lisp, Forth, APL, Prolog, nhưng với ngôn ngữ hàm mang tính đột phá thì tôi chọn SASL, ra đời sớm hơn ML một chút, còn đại diện cho hướng đối tượng thì tôi chọn Smalltalk, có trước Self. Ngoài ra tôi còn thêm Fortran, COBOL, SNOBOL và Prograph vì cho rằng mỗi ngôn ngữ đều đã thay đổi cuộc chơi theo cách riêng
Tôi muốn thêm vào thảo luận này các họ ngữ nghĩa nữa. Ví dụ như Verilog, Petri nets, Kahn process networks, dataflow machines, process calculi, reactive, term rewriting, các họ constraint solver/theorem prover, probabilistic programming. Cũng có những ngôn ngữ không khớp gọn với 7 nhóm hiện có nhưng thực tế đã khá gần mức production như Unison, Darklang, temporal dataflow, DBSP. Nghe có vẻ hơi gian lận, nhưng phần lớn trong số đó là các mô hình tính toán song song với mô hình máy von Neumann. Từ lâu tôi đã muốn viết một bài kiểu “mọi cách tính toán mà ta biết, vượt ra ngoài von Neumann”
1+1thành dạng nhưADD(1,1)thì tôi có thể parse theo cách mình đã biết. Thêm nữa là tôi đã vô lý từ chối học regex nên mã trở nên khá kỳ quặc, và tôi vẫn còn nhớ đồng nghiệp nói “Andy bảo làm được thì cứ để cậu ấy làm”. Một người ở nhóm khác thì dùng regex và giải quyết xong với lượng mã ngắn hơn của tôi cỡ 20 lầnMôn “Concepts of programming languages” ở TU Delft là môn tôi thích nhất trong cả chương trình khoa học máy tính. Chúng tôi học C, phía hàm thì dùng Scala, và JavaScript cho khái niệm prototype; nhờ vậy mà vài năm sau khi học Elixir tôi thấy dễ hơn hẳn. Ngoài ra còn có một môn viết agent cho Unreal Tournament bằng GOAL, một ngôn ngữ dựa trên Prolog. Trong thời gian dài tôi không biết nên dùng Prolog vào việc gì, nhưng cuối cùng lại dùng nó để làm một spellcheck buộc các câu Papiamentu tệ do LLM sinh ra phải được sửa lặp đi lặp lại
Tôi đồng ý với quan điểm “nên học các ngôn ngữ thuộc những nhóm khác nhau”. Chỉ sau khi học OCaml tôi mới thực sự cảm thấy hàm giống hàm toán học, còn Mathematica thì rèn cho tôi thói quen nhìn biểu thức như chính dữ liệu đầu vào. Ký pháp Ba Lan ngược của PostScript không chỉ thay đổi cách làm số học đơn giản mà gần như còn đi lại dây toàn bộ cách suy nghĩ. Tuy vậy, tôi không đồng ý với ý cho rằng chọn Java, C#, C++, Python hay Ruby đều như nhau. Nếu mục tiêu chỉ là cài quicksort thì có thể tương tự, nhưng với người thực sự muốn xây thứ gì đó, lựa chọn ngôn ngữ tạo ra khác biệt một trời một vực. Đưa Ruby cho người muốn làm game 3D, hay đưa Java cho người muốn làm khoa học dữ liệu khám phá hoặc deep learning, có thể làm họ mất động lực
Bài này làm tôi nhớ tới 7 languages in 7 weeks của Bruce Tate. Tôi cũng biết đến Erlang lần đầu qua cuốn đó. Dù vậy, về mặt lịch sử thì xếp COBOL và Fortran vào họ Algol có phần hơi gượng, nhưng ít nhất nó cũng nhắc ta rằng lịch sử vốn dĩ luôn là một sự giản lược ở mức nào đó
Trước đây cũng đã có thảo luận HN liên quan. Xem thêm cuộc thảo luận trước sẽ giúp nắm bối cảnh tốt hơn