Bảy ngôn ngữ lập trình gốc (ur-languages) định hình thế giới công nghệ

19 tháng 4, 2026·8 phút đọc

Bài viết khám phá bảy "ngôn ngữ gốc" (ur-languages) quan trọng nhất như ALGOL, Lisp, ML, Self, Forth, APL và Prolog. Hiểu rõ các nền tảng này giúp lập trình viên nắm bắt các khái niệm cốt lõi, vượt qua sự khác biệt về cú pháp của các ngôn ngữ hiện đại.

Tôi thường xuyên nghe mọi người hỏi rằng họ nên học ngôn ngữ lập trình nào, sau đó liệt kê một loạt các ngôn ngữ rất giống nhau ("Tôi nên học Java, C#, C++, Python hay Ruby?"). Đáp lại, tôi thường bảo họ rằng điều đó không thực sự quan trọng, miễn là họ bắt đầu. Đằng sau những ngôn ngữ đó là những nguyên lý (fundamentals) cơ bản.

Vậy tôi nói đến nguyên lý là gì? Nếu bạn có một mảng (array) các mục và bạn cần lặp qua nó, điều đó giống hệt nhau trong bất kỳ ngôn ngữ mệnh lệnh nào. Có những dòng lệnh lặp đơn giản, gán giá trị thay đổi trạng thái và các khối mã. Dù cú pháp có khác biệt, ý tưởng về vòng lặp for hay câu lệnh if là bất biến.

Để thực sự hiểu sâu về lập trình, chúng ta cần nhìn về quá khứ, về những "ngôn ngữ gốc" (ur-languages) — những tổ tiên đã định hình nên hầu hết các ngôn ngữ ngày nay. Dưới đây là bảy gia đình ngôn ngữ gốc mà mọi lập trình viên nên biết đến.

ALGOL (Ngôn ngữ mệnh lệnh)

Đặc điểm: Chương trình là một chuỗi các câu lệnh thực hiện tuần tự để thay đổi trạng thái. Các ngôn ngữ trong họ này thường có cấu trúc khối (blocks) và các câu lệnh điều khiển luồng quen thuộc như if, while, for. Cốt lõi của chúng là việc gán giá trị cho các biến.

Ví dụ: Họ ALGOL bao gồm C, C++, Java, Python, Pascal, v.v.

Lịch sử: ALGOL được phát triển vào cuối những năm 1950 với tư cách là một ngôn ngữ khoa học máy tính và thuật toán. Mặc dù bản thân ALGOL không được sử dụng rộng rãi trong thương mại lâu dài, nhưng nó đã trở thành tổ tiên trực tiếp của C, và qua đó ảnh hưởng đến hầu hết mọi ngôn ngữ mệnh lệnh hiện đại.

Lisp (Lập trình hàm & Meta-programming)

Đặc điểm: Mọi thứ trong Lisp đều là biểu tượng, bao gồm cả mã nguồn. Mã chương trình được viết dưới dạng danh sách (list), giúp việc thao tác mã như thể nó là dữ liệu trở nên dễ dàng (được gọi là macro). Cú pháp tiền tố (prefix notation) với dấu ngoặc đơn đặc trưng cho phép biểu diễn bất kỳ cấu trúc tính toán nào.

Ví dụ: Common Lisp, Scheme, Clojure, Racket.

Lịch sử: Lisp được phát triển vào cuối những năm 1950 và là ngôn ngữ lập trình hàm (functional programming) thứ hai sau Fortran. Nổi tiếng với tính linh hoạt và sức mạnh của hệ thống macro, Lisp vẫn là ngôn ngữ được ưa chuộng trong các nghiên cứu về trí tuệ nhân tạo và lập trình cấp cao.

ML (Lập trình hàm với hệ thống kiểu)

Đặc điểm: ML tập trung vào tính toán bằng các hàm thay vì thay đổi trạng thái. Một trong những đóng góp lớn nhất của ML là type inference (suy luận kiểu) — trình biên dịch tự động suy ra kiểu dữ liệu của biến mà không cần lập trình viên khai báo tường minh. ML cũng nổi tiếng với pattern matching (khớp mẫu) và các đệ quy đuôi (tail recursion). Một số ngôn ngữ trong họ này (như Miranda và Haskell) là "lazy" (đánh giá lười), chỉ tính toán khi thực sự cần thiết.

Ví dụ: ML là nền tảng cho Standard ML, OCaml, Miranda, Haskell, và các ngôn ngữ có kiểu phụ thuộc (dependently typed) như Agda và Idris.

Lịch sử: ML ban đầu là ngôn ngữ meta (metalanguage) cho một chương trình chứng minh định lý được phát triển tại Cambridge, Anh. Ngôn ngữ này thoát ra khỏi bối cảnh học thuật và trở nên phổ biến ở châu Âu, đặc biệt là Anh và Pháp.

Self (Lập trình hướng đối tượng)

Đặc điểm: Một chương trình bao gồm một tập hợp các đối tượng có thể gửi và nhận tin nhắn lẫn nhau. Tất cả hành vi đều được thực hiện theo cách này. Bạn tạo một đối tượng mới bằng cách gửi tin nhắn đến một đối tượng hiện có. Không có khái niệm "class" (lớp) như trong Java hay C++; thay vào đó là sự kế thừa dựa trên nguyên mẫu (prototype-based). Ngay cả điều kiện if/else hay vòng lặp cũng được thực hiện thông qua việc gửi tin nhắn đến các đối tượng đặc biệt. Các ngôn ngữ này thường hoạt động trong một "môi trường sống" (live environment) nơi lập trình viên sửa đổi hệ thống khi nó đang chạy thay vì biên dịch tập tin mã nguồn.

Ví dụ: Smalltalk, Self. JavaScript là một ví dụ nổi tiếng thừa hưởng hệ thống đối tượng không dựa trên lớp (classless) của Self.

Lịch sử: Smalltalk là ngôn ngữ gốc, được phát triển tại Xerox Parc vào cuối những năm 1970. Self sau đó đã bỏ đi khái niệm lớp để làm việc hoàn toàn với đối tượng, thể hiện một hình thức thuần túy hơn của lập trình hướng đối tượng.

Forth (Ngôn ngữ Stack - Ngăn xếp)

Đặc điểm: Các ngôn ngữ Stack đảo ngược cách tư duy thông thường, chia sẻ ngữ pháp với các máy tính ký pháp Ba Lan ngược (RPN) của Hewlett Packard. Chúng sử dụng một ngăn xếp dữ liệu. Khi bạn viết một số như 42, nó được đẩy vào ngăn xếp. Khi viết tên một hàm, nó lấy tham số từ ngăn xếp để thao tác. Ví dụ, phép tính 2 3 + 5 * sẽ đẩy 2, 3, cộng lại, đẩy 5, rồi nhân.

Forth cho phép lập trình viên chặn trình phân tích cú pháp (parser) và thay thế bằng mã của riêng họ, nghĩa là ngữ pháp hoàn toàn có thể thay đổi. Rất phổ biến để thấy các chương trình Forth định nghĩa các ngôn ngữ nhỏ riêng biệt.

Ví dụ: Forth và các biến thể của nó, PostScript, Factor, Joy.

Lịch sử: Forth ban đầu được viết vào năm 1970 để điều khiển kính viễn vọng vô tuyến, sau đó lan rộng sang các hệ thống nhúng. Nó đủ đơn giản để có thể khởi tạo (bootstrap) một hệ thống Forth nhanh chóng.

APL (Ngôn ngữ mảng)

Đặc điểm: Mọi thứ trong ngôn ngữ đều là một mảng (n chiều). Các toán tử thường dài một hoặc hai ký hiệu và thực hiện các phép toán cấp cao trên các mảng này. Kết quả là mã nguồn cực kỳ súc tích, đôi khi các chuỗi ký hiệu trở thành tên của một phép toán. Ví dụ, để tính trung bình của một mảng trong biến x, bạn có thể viết: (+⌿÷≢) x.

Ví dụ: APL, J, K. Các khái niệm này đã được xuất khẩu một phần sang nhiều môi trường khác như MATLAB, NumPy và R.

Lịch sử: APL bắt đầu như một ký hiệu toán học do Kenneth Iverson tạo ra vào những năm 1960, sau đó được triển khai trên máy tính. Nó có một cộng đồng người dùng đam mê các phép tính toán học nặng nề.

Prolog (Ngôn ngữ logic)

Đặc điểm: Chương trình bao gồm các sự thật (facts) và quy tắc. Ví dụ: "Bob là cha của Ed" (father(bob, ed)). Bạn có thể định nghĩa các quy tắc để suy ra sự thật khác. Thời gian chạy (runtime) của Prolog sẽ nhận các sự thật này và một câu truy vấn, sau đó tìm kiếm kết quả. Nếu chọn cấu trúc đúng, việc này là Turing hoàn toàn. Các chương trình Prolog bản chất là các thuật toán tìm kiếm và được tối ưu hóa tương tự như truy vấn cơ sở dữ liệu.

Ví dụ: Prolog, Mercury, Kanren.

Lịch sử: Vào những năm 1970, các nhà logic học ở Pháp nhận ra họ có thể biểu diễn chương trình dưới dạng logic bậc nhất. Dự án máy tính thế hệ thứ năm của Nhật Bản vào những năm 1980 đã đánh cược lớn vào Prolog.

Lời khuyên cho lập trình viên

Đối với hầu hết các lập trình viên, một số hoặc tất cả các ngôn ngữ này có vẻ rất kỳ lạ. Tuy nhiên, đáng để dành thời gian tìm hiểu từng ngôn ngữ một chút vì những tư duy mới mẻ mà chúng mang lại.

Thứ nhất, mọi lập trình viên cần thành thạo một ngôn ngữ trong họ ALGOL. Đây là nền tảng của hầu hết các công việc lập trình thương mại hiện nay.

Thứ hai, hãy học một ngôn ngữ trong họ Prolog: SQL. Sau họ ALGOL, SQL sẽ mang lại lợi ích lớn nhất cho sự nghiệp của bạn.

Sau khi nắm vững hai cái này, hãy thử mở rộng. Việc học một ngôn ngữ mới thuộc một họ nguyên bản (ur-language) lạ mắt mỗi năm sẽ mang lại những khoản đầu tư lớn. Các gợi ý ngôn ngữ ngày nay cho từng họ là:

  • Lisp: PLT Racket
  • ML: Haskell
  • Self: Self
  • Prolog: Prolog
  • Forth: gForth
  • APL: K (thông qua ok)

Nếu bạn làm nhiều việc tính toán số học, hãy học K sớm hơn. Nếu bạn làm nhiều lập trình nhúng, hãy học gForth sớm hơn. Nhưng thứ tự không quan trọng, cũng như việc lựa chọn ngôn ngữ cụ thể nào trong họ đó. Bạn có thể học Standard ML thay vì Haskell, hay Common Lisp thay vì Racket — tất cả đều là những sự lựa chọn đúng đắn.

Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗