- Cốt lõi của Lisp không nằm ở cú pháp nhiều dấu ngoặc, mà là tư duy mở rộng ngôn ngữ cho phù hợp với vấn đề; chỉ khi nắm được REPL, package, symbol, condition và restart mới thấy hết giá trị của nó
- Nhờ tính đồng hình khi cả mã và dữ liệu đều được biểu diễn bằng list, macro có thể xử lý mã như dữ liệu trước khi đánh giá, từ đó tạo ra cấu trúc điều khiển mới và trừu tượng hóa cú pháp
- Có thể thêm
while không có sẵn trong Common Lisp bằng defmacro, nhưng nếu giả lập bằng hàm thì tham số bị đánh giá ngay, khiến body trở thành giá trị chứ không còn là mã
- Phát triển Lisp gần với phát triển hướng REPL, liên tục đánh giá mã trong một process đang chạy, tái định nghĩa hàm, macro và biến để chương trình tiến hóa mà không cần dừng
- Khi khả năng mở rộng ngôn ngữ kết hợp với live system, có thể tạo ra phần mềm có thể mở rộng bằng cách đưa DSL nội bộ ra cho người dùng; AutoLISP và Emacs là các ví dụ tiêu biểu
Lisp đòi hỏi một cảm giác lập trình khác
- Lập trình viên mới tiếp xúc với Lisp thường thấy lạ với cú pháp nhiều dấu ngoặc, cách thụt lề đặc trưng, và việc chỉ định standard output làm tham số đầu tiên của
format
- Để học Lisp, không chỉ cần đọc mã mà còn phải xử lý package và symbol, tạo project, import thư viện, REPL, condition và restart
- Sự thay đổi lớn hơn nằm ở cách cấu thành thuật toán
- Lisp cho phép làm những việc khó thực hiện trong các ngôn ngữ khác, và cũng làm thay đổi hình dạng của thuật toán
- Luồng làm việc trở thành mở rộng ngôn ngữ trước cho phù hợp với vấn đề, rồi viết chương trình bằng chính ngôn ngữ đó
- Nghịch lý Blub là khái niệm giải thích vì sao lập trình viên chỉ từng dùng các ngôn ngữ kém mạnh hơn khó nhận ra điểm mạnh của Lisp
Ngôn ngữ có thể mở rộng
- Lisp có thể tự mở rộng chính nó, và các chuyên gia Lisp gọi đây là programmable programming language
- Công cụ cốt lõi là
macro
- Không chỉ dừng ở việc loại bỏ mã lặp như macro trong C, Rust hay Swift
- Macro của Lisp có thể tạo ra các thành phần mới trở thành một phần của ngôn ngữ
- Common Lisp không có toán tử
while mặc định, nhưng có thể tự thêm bằng defmacro
(defmacro while (condition &body body)
`(loop while ,condition do
(progn ,@body)))
- Macro
while này thực thi nhiều lệnh trong body khi condition còn đúng
loop là macro để viết các vòng lặp phức tạp
progn thực thi nhiều biểu thức theo thứ tự và trả về kết quả của biểu thức cuối cùng
- Kết quả là có thể dùng dạng
(while ...) thay cho (loop while ... do (progn ...)), giúp mã ngắn hơn và có cấu trúc tương tự while trong C
Khác biệt quyết định giữa macro và hàm
- Nếu tạo cùng hành vi bằng hàm
fake-while thì sẽ thất bại
(defun fake-while (condition body)
(loop while condition do
(funcall body)))
- Khi gọi
fake-while, các tham số được đánh giá trước
condition trở thành giá trị đúng t
(print counter) bên trong progn được thực thi và (decf counter) trả về 2
body không còn là khối mã mà trở thành giá trị 2
- Sau đó
funcall kỳ vọng một hàm nhưng nhận 2, nên phát sinh lỗi kiểu như The value 2 is not of type FUNCTION
- Ngược lại, macro
while không đánh giá ngay condition và body mà giữ nguyên chúng
- Có thể kiểm tra kết quả mở rộng bằng
macroexpand-1
- Compiler nhận mã ở dạng đã mở rộng
(LOOP WHILE ... DO (PROGN ...))
- Khác với hàm, macro không đánh giá trước tham số mà xử lý chúng như dữ liệu thuần, vì vậy mới có thể thực hiện dạng biến đổi này
List, s-expression và tính đồng hình
- Chương trình Lisp được cấu thành từ chuỗi symbolic expression, tức s-expression
- s-expression chia thành hai loại
- Atom: đơn vị dữ liệu như số, chuỗi, symbol
- List: collection chứa atom hoặc các list khác
- Tên Lisp bắt nguồn từ LISt Processing, và các lệnh tạo nên chương trình cũng được biểu diễn bằng list
- Trong Lisp, list vừa là cấu trúc dữ liệu chính vừa là cách viết mã
- Tính chất cả mã và dữ liệu đều được biểu diễn bằng list được gọi là tính đồng hình (homoiconicity)
- Cùng một list
(+ 1 2) sẽ hoạt động khác nhau tùy việc có được đánh giá hay không
(+ 1 2) được đánh giá như mã và trả về 3
'(+ 1 2) không được đánh giá mà trả về nguyên dạng list dữ liệu
- Lisp dùng ký pháp Ba Lan, đặt tên hàm làm phần tử đầu tiên của list, sau đó là các tham số
- Vì ranh giới giữa mã và dữ liệu rất mỏng, macro có thể biến đổi mã nguồn và tạo ra chương trình viết chương trình
Trừu tượng hóa mã do macro tạo ra
- Khi mở rộng ngôn ngữ, có thể tạo ra các thành phần mới biểu đạt tốt hơn cho một miền chương trình cụ thể
- Boilerplate lặp lại được thay bằng macro tùy chỉnh để giảm mã và tiết kiệm thời gian
- Có thể tạo cấu trúc điều khiển mới để kiểm soát việc truy cập tài nguyên và đánh giá form
- Macro tạo mã, cải thiện hiệu năng, và cung cấp trừu tượng hóa cú pháp để che giấu những đoạn mã phức tạp, dễ lỗi
Lisp là một live system
- Lisp được xem không chỉ là một ngôn ngữ lập trình đơn thuần, mà là live system đang chạy
- Với các ngôn ngữ thông thường, luồng làm việc thường là viết mã trong editor, rồi compile và chạy để quan sát, test, debug
- Trong Lisp, trước tiên khởi động Lisp process, gắn vào REPL, rồi load project vào trong process đó
- REPL là viết tắt của Read-Eval-Print Loop, một môi trường tương tác để đánh giá mã và xem kết quả ngay lập tức
- Nó đóng vai trò như cửa sổ nhìn vào Lisp process đang chạy chương trình hiện tại
- Lập trình viên Lisp liên tục đánh giá mã trong process đang chạy và kiểm tra kết quả ngay trên REPL
- Test từng hàm riêng lẻ
- Truy vấn cơ sở dữ liệu
- Kiểm tra biến
- Các tác vụ như debug cũng có thể thực hiện trong REPL
- Lisp process không cần dừng, nên có thể sống trong nhiều tuần
- Hàm, macro và biến liên tục được định nghĩa và tái định nghĩa trong môi trường nội bộ là environment; luồng này được gọi là phát triển hướng REPL
Hot reload trong Lisp
- Trên web frontend, trải nghiệm JavaScript code được hot reload qua việc lưu file hoặc refresh trang là rất phổ biến
- Hot reload thông thường phụ thuộc vào các công cụ và kỹ thuật riêng như theo dõi file, biên dịch lại module thay đổi, và inject thay đổi qua websocket
- Không phải mọi software stack đều cung cấp cùng mức hot reload
- Một số backend framework cần biên dịch lại
- Môi trường phát triển desktop và mobile có tình hình lẫn lộn
- Ngôn ngữ low-level cần compile toàn bộ mỗi lần
- Trong Lisp, hot reload không phải công cụ riêng mà xuất hiện tự nhiên khi đánh giá mã trong live environment
- Khi tái định nghĩa symbol, cả hàm, dữ liệu và macro đều dùng định nghĩa mới
- Giảm nhu cầu dừng rồi compile, chạy test riêng, hoặc dùng debugger đặc thù
- Lập trình Lisp gần với việc tiến hóa chương trình hơn là lắp ráp chương trình
Phần mềm có thể mở rộng
- Khả năng mở rộng ngôn ngữ và live system khiến Lisp dễ tạo phần mềm có thể mở rộng
- Chương trình desktop thông thường được mở rộng qua plugin hoặc ngôn ngữ scripting
- Nhà phát triển phải thiết kế và duy trì hệ thống mở rộng
- Người dùng phải học API cụ thể để viết plugin hoặc extension
- Trong Lisp, việc đóng gói hành vi bằng macro để dễ tái sử dụng sẽ tự nhiên dẫn đến viết DSL
- Muốn làm phần mềm có thể mở rộng, chỉ cần cho người dùng dùng DSL đã tạo bên trong
- Trong ví dụ CMS server, có thể đưa macro
html dùng để tạo trang web phía server ra cho người dùng
- Người dùng có thể dùng nguyên các biến Lisp, vòng lặp
dolist, và định dạng chuỗi bằng format cùng lúc
- Không cần học cú pháp riêng như
{{ user_name }} hay {% for %} như các template language truyền thống
- DSL này thừa hưởng nguyên khả năng về câu điều kiện, đệ quy, hàm bậc cao và debug từng bước trong REPL của Lisp
- Trong ví dụ phần mềm đồ thị toán học, có thể đưa ra DSL cho công thức và vẽ, để người dùng vẽ đường cong và điểm bằng rất ít mã
Các trường hợp thực tế và vị trí của Lisp
- AutoCAD dùng AutoLISP để tự động hóa tác vụ lặp lại và tạo hình học phức tạp
- Emacs là text editor được triển khai phần lớn bằng dialect Lisp riêng, nhờ đó có khả năng mở rộng cao
- Trình đọc PDF
- Trình duyệt web
- Email client
- RSS reader
- Terminal multiplexer
- Git client
- Trình phát nhạc
- Chat client
- Spreadsheet
- IRC client
- Thậm chí có cả ví dụ mở rộng thành desktop window manager
- R. M. Stallman đánh giá Lisp là ngôn ngữ giúp hiểu ý nghĩa của một ngôn ngữ lập trình mạnh mẽ và thanh nhã
- Kỳ vọng Lisp một ngày nào đó sẽ được dùng rộng rãi như ngôn ngữ mặc định đã không thành hiện thực, và có vẻ khả năng đó trong tương lai cũng thấp
- Dù vậy, Lisp vẫn tồn tại từ thập niên 1960 và trở thành ngôn ngữ lập trình còn hoạt động lâu đời thứ hai sau Fortran
- Giá trị của Lisp không đến từ một tính năng riêng lẻ như khả năng mở rộng, môi trường tương tác hay REPL, mà đến từ sự kết hợp của chúng
1 bình luận
Các ý kiến trên Hacker News
Lập trình tồn tại trên sự căng thẳng giữa phe sáng và phe tối
Phe sáng là phía ngăn lập trình viên mắc lỗi: loại bỏ
goto, đưa vào kiểu tĩnh, làm cho bug không thể biểu diễn được, kiểu như vậyPhe tối là phía trao sức mạnh cho lập trình viên: cho phép thoải mái macro, nạp chồng toán tử, mã tự sửa đổi, thậm chí cả regex nhiều dòng
Lisp rõ ràng thuộc phe tối ở chỗ lập trình viên có thể làm bất cứ điều gì, nhưng điều thú vị là nó vẫn được các lập trình viên phe sáng kính trọng. Có thể sự đơn giản của ngôn ngữ mang tính kiểu Platon và trông gần như không thể sa ngã, hoặc có thể Lisp quá thuần khiết đến mức như vị thần đã sinh ra vũ trụ lập trình, bao chứa cả hai phía
Ta không thể chọn người sẽ làm việc cùng, và năng lực trong nhóm cũng không đồng đều. Khi một đồng nghiệp kém kinh nghiệm hơn tạo ra lỗi, ngôn ngữ càng permissive thì hậu quả càng lớn
Vì vậy cần code review, nhưng như thế lại biến lập trình viên có kinh nghiệm thành giáo viên. Một phần thời gian dùng để nâng trình cho lập trình viên khác bị lãng phí là vì lập trình viên có thể vào và ra bất cứ lúc nào. AI có thể thay đổi cục diện này
Cuối cùng, điểm cốt lõi là duy trì một nhóm nhỏ và lành nghề, nhưng điều đó không dễ vì chính trị công ty. Ví dụ, thường sẽ xuất hiện cách bổ sung thêm lập trình viên vì cân nhắc bus factor hoặc để rút ngắn thời gian phát hành
Các hệ thống độ tin cậy cao cũng được viết bằng Erlang, mà nếu nheo mắt nhìn thì có thể xem như một phương ngữ Lisp khác. Cũng có một phiên bản dựa trên S-expression tên là LFE, tức Erlang mang phong cách Lisp
Trọng tâm độ tin cậy của Erlang không nằm ở việc phòng ngừa lỗi ở mức ngoại lệ, mà ở khôi phục lỗi. Bản thân cách phân loại sáng/tối thì tôi thích
Dù không có kiểu tĩnh và macro có thể trở thành một mớ hỗn độn, baseline của tư duy khai báo・hàm vẫn mạnh hơn nhiều, nên đó là điểm xuất phát tốt để suy nghĩ và suy luận về chương trình rõ ràng hơn
Cách chia sáng/tối có vẻ quá đơn giản hóa. Sự cân bằng của ngôn ngữ lập trình là một chủ đề rất phức tạp và thú vị
Sau nhiều năm thử nghiệm nhiều ngôn ngữ, rốt cuộc đó là vấn đề về bối cảnh sử dụng, sở thích cá nhân và mục tiêu. Không có thứ gọi là “ngôn ngữ lập trình hay nhất mọi thời đại”, và cũng không có “tốt nhất cho lập trình phe sáng” hay “tốt nhất cho lập trình phe tối”
Trong hội họa nghệ thuật cũng không có thứ như phe sáng/phe tối. Chắc chắn có những bức tranh vĩ đại hơn, nhưng không có “bức tranh hay nhất” mà mọi người đều cảm thấy đẹp nhất khi so với mọi bức tranh khác
https://en.wikipedia.org/wiki/Malbolge
https://en.wikipedia.org/wiki/Clean_(programming_language)
https://en.wikipedia.org/wiki/K_(programming_language)
Trong vài tháng gần đây đã có những trình soạn thảo và công cụ mới rất hay, không nên bỏ lỡ
Mine là một ứng dụng tải xuống đơn lẻ, cung cấp mọi thứ cần thiết để trải nghiệm luồng phát triển tương tác・tăng dần, bao gồm hot reloading và gỡ lỗi tức thì. Dành cho CL và Coalton
https://coalton-lang.github.io/20260424-mine/
OLIVE là plugin thủ công cho VSCode, còn ICL là REPL mới cho terminal và trình duyệt, cung cấp các tính năng nâng cao. Thêm nữa, còn có kernel JupyterLite dựa trên JSCL, chạy 100% trong trình duyệt
Có thể xem tất cả tại đây: https://lispcookbook.github.io/cl-cookbook/editor-support.ht...
mine. Có link không?Có vẻ website có bug tô sáng cú pháp. Các đoạn mã trong bài hiện màu đen, và khi chọn bằng chuột thì mới thấy được văn bản thực
Thấy cùng bug trên Chrome desktop và Safari iPad
Cách обход là mở một phần tử code trong trình gỡ lỗi của trình duyệt và thêm
color: whitevào style:not(pre) > codeCó nhiều bài ca ngợi ưu điểm của Lisp. Tôi cũng muốn đọc những bài phê bình một cách điềm tĩnh về Lisp, các ý tưởng của nó, và vị trí của nó trong hệ sinh thái ngôn ngữ
Những bài như thế này, hay các bài của PG được tham chiếu ở đây, rốt cuộc vẫn khá gần với kiểu “ai biết thì biết”. Tôi hiểu sức hấp dẫn của nó, và cũng hiểu các luận điểm mà bài này đưa ra một cách tường minh lẫn hàm ý
Lập trình máy tính đã trưởng thành khá nhiều trong 60 năm qua. Tôi muốn thấy thêm những bài viết có sự xem xét thấu đáo hơn
Khuyết điểm thứ hai là nó ngốn hàng năm thời gian của những người đủ năng lực, trong khi kết quả không biện minh được cho lượng thời gian đầu tư đó. Những thứ như Python cũng đã đủ tốt. Tôi nghĩ phần lớn thời gian bỏ vào Lisp lẽ ra nên được dùng vào việc khác
Clojure, Clojurescript, Clojure-Dart, Fennel, Jade, Jank, Jolt, Coalton là các ngôn ngữ tương đối gần đây và vẫn đang phát triển. Đó mới chỉ là những cái tôi nghĩ ra lúc này, còn nhiều hơn nữa
Theo một nghĩa nào đó, Lisp không phải là một ngôn ngữ lập trình mà là một ý tưởng. Nó đã ảnh hưởng đến gần như mọi ngôn ngữ lập trình chúng ta dùng ngày nay, và vẫn tiếp tục như vậy. Rất khó để phê bình một ý tưởng một cách “điềm tĩnh”, cũng giống như phê bình lý thuyết nhóm. Tuy nhiên, ta có thể thảo luận ưu và nhược điểm của những triển khai cụ thể của ý tưởng đó
async/awaithay mô hình concurrency được chuẩn hóa. Chuẩn đã không được cập nhật từ sau năm 1995, nên điều đó cũng sẽ không xảy ra trong tương laiVới một số người, nó tạo cảm giác hấp dẫn về mặt tinh thần. Tôi muốn ví nó với một thể loại nhạc cực kỳ ngách. Ít người thích, nhưng những người thích thì thích rất mãnh liệt. Nó giống như Stockhausen của giới lập trình
Về cơ bản, đó là một fandom. Một fandom tồn tại lâu đến đáng kinh ngạc, nhưng chưa bao giờ thật sự bứt ra đại chúng, và khả năng đó trong tương lai cũng thấp. Giờ vị thế của nó còn tệ hơn. Nếu được trang bị LLM và bản thân không quan tâm mấy đến code, thì tại sao lại phải bảo nó viết bằng Lisp?
Tôi đã dùng Lisp quá lâu đến mức không còn biết trân trọng đúng mức các tính năng của nó. Rồi khi nhìn thấy, trong sốc và kinh hoàng, cách mọi người tự làm hỏng mình trong những ngôn ngữ phổ biến hơn và ít rủi ro kinh tế hơn, tôi bỗng lại cảm nhận được giá trị của Lisp
Trong môi trường thương mại, ngôn ngữ chuyên biệt theo miền là một anti-pattern. Ai đó tạo ra một ngôn ngữ chuyên biệt theo miền thiếu tài liệu, chỉ mình họ hiểu, rồi rời đi
Các lập trình viên đến sau phải vật lộn giải mã thứ ngôn ngữ kỳ lạ này. Gần như lúc nào dùng cấu trúc và tính năng của ngôn ngữ tiêu chuẩn cũng tốt hơn. Code được đọc nhiều hơn được viết
Có khả năng điều bạn thật sự phản đối là sự thiếu tính trong suốt tham chiếu. Công bằng mà nói, đây là vấn đề trong nhiều ngôn ngữ, bao gồm cả Lisp
Một ví dụ tốt là macro
LOOPcủa chính Common Lisp. Nếu cách dùng của ai đó khó hiểu, bạn có thể yêu cầu Lisp mở rộng nó thành các lời gọi cơ bản dài dòng hơn, không dùngLOOP, và không cần hiểuLOOPchút nào. Thực tế, bạn cũng có thể thay thế formLOOPbằng code đã được mở rộngĐây là khác biệt cốt lõi so với hầu hết ngôn ngữ khác, nơi code của ngôn ngữ chuyên biệt theo miền thực ra là một cấu trúc dữ liệu được diễn giải
Lisps có những điểm thật sự mạnh mẽ và độc đáo, nhưng tôi mong các bài kiểu này đừng cứ đưa REPL và hot reloading vào nữa
REPL từ lâu đã là điều kiện cơ bản trong các ngôn ngữ thông dịch, thậm chí cả một số ngôn ngữ biên dịch. Hot reloading không độc đáo, cũng không đặc biệt được dùng rộng rãi. Vì phải xử lý trạng thái và patch, nên có lý do để việc reset toàn bộ nhằm dễ suy luận được xem là best practice
Nhờ vậy, việc phát triển trở nên tương tác hơn nhiều so với các ngôn ngữ thông dịch khác
Tất nhiên nó không hoàn hảo. Nhưng với các loại thay đổi dùng để lặp cải thiện trải nghiệm người dùng, nó hoạt động rất tốt
Tuy nhiên, đáng nhấn mạnh rằng phần lớn các khía cạnh nâng cao của hot reloading đã được xử lý trong Common Lisp. REPL cũng vậy: nó chủ yếu được dùng như một giao diện rất mạnh để công cụ tương tác với image đang chạy, hơn là nơi để gõ trực tiếp
Dù vậy, tôi đồng ý rằng chỉ riêng việc những thứ này tồn tại thì ngày nay không còn đặc biệt lắm
Nếu định nghĩa class bị thay thế do reload nhưng các instance cũ vẫn còn thì làm gì? Các phương ngữ Common Lisp có câu trả lời hữu ích cho những câu hỏi như vậy, nhưng không phải Lisp nào bạn gặp cũng nhất thiết có
Bash cũng hỗ trợ hot reloading. Tôi từng phát triển các module được cập nhật tại chỗ bằng cách
sourcenhư sau$ . /path/to/script.shTính hữu dụng có giới hạn, nhưng nếu bắt đầu với quan điểm rằng bạn sẽ dùng nó nhiều, các giới hạn đó bắt đầu biến mất khá nhanh
Cá nhân tôi thì đã vượt qua những giai đoạn như thế. Tôi đã dùng thử Common Lisp, Forth, Haskell, và đọc 『On Lisp』 cùng 『Let Over Lambda』 một cách thích thú
Hiện giờ tôi nghĩ ngôn ngữ lập trình tốt nhất là Triage Calculus của Barry Jay. Nó gần với logic tổ hợp hoặc phép tính lambda không kiểu
Nhưng khác với phép tính lambda, Triage Calculus có cơ chế trích dẫn và nội quan tích hợp, tương tự
CARvàCDRcủa Lisp, nên có thể dễ dàng thêm kiểm tra kiểu. Vì vậy trong TC, chỉ cần tạo đúng các trừu tượng, bạn có thể có bất kỳ cú pháp nào mình muốn. Đó thật sự là ngôn ngữ lập trình tối thượngTC cho thấy sự phân biệt giữa một bên là tính năng và cú pháp của ngôn ngữ lập trình, bên kia là định nghĩa hàm/API trong thư viện chuẩn hoặc mã người dùng, là một lưỡng phân giả tạo. Mỗi khi viết mã với mục đích tái sử dụng, bạn đang thêm thứ gì đó vào ngôn ngữ. Tất cả những thứ này đều có thể được biểu diễn bằng một hạng nào đó trong TC
Mọi cuộc tranh luận về cú pháp đều là vấn đề thói quen. Tuy nhiên, một tính năng cú pháp mà tôi thật sự muốn trong TC là trừu tượng
let over lambda, vì việc tự tay sắp xếp các combinator hơi phiềnBài viết hay
Trước đây tôi từng nghĩ rằng một ngày nào đó mọi người sẽ dùng Lisp, và khi có công cụ cùng thư viện tốt thì mọi thứ sẽ trở nên tuyệt vời. Thật ra kế hoạch sau khi nghỉ hưu của tôi cũng là tạo các thư viện chất lượng cao cho ngôn ngữ Lisp để đẩy nhanh quá trình đó
Liệu sự trỗi dậy của AI có chấm dứt giấc mơ này không? Có phải chúng ta lại giải quyết vấn đề bằng cách thêm nhiều thứ hỗn tạp hơn nữa? Thay vì một AI siêu trí tuệ viết mã bằng ngôn ngữ lập trình tốt nhất có thể, liệu rốt cuộc nó chỉ rải ra hàng đống mã Python rồi cố thúc cho đến khi chạy được?
Tôi không biết điều này có quan trọng không. Tôi chỉ muốn một thế giới có sự thanh lịch
“Jean-Marie Hullot, khi đang làm việc tại INRIA, đã tạo ra ‘SOS Interface’ viết bằng Lisp cho Macintosh, và đó là ‘interface builder’ hiện đại đầu tiên”
https://denninginstitute.com/itcore/userinterface/GUIHistory...
Tôi tự hỏi nếu nó trở thành một sản phẩm Mac chủ đạo, thay vì chuyển sang NeXT và được dùng cùng Objective-C, thì sẽ ra sao
LISP rất hợp với tôi. Trong lớp ngôn ngữ so sánh ở đại học, tôi là người duy nhất hoàn thành tất cả bài tập LISP, và việc học LISP cũng giúp tôi rất nhiều khi dùng TeX
Điều tôi mong muốn là một bộ công cụ GUI native hoặc đa nền tảng ổn, mã nguồn mở, cùng một cách dễ dàng để phân phối dự án dưới dạng mã đã biên dịch chạy độc lập
Con người có thể diễn đạt ý tưởng hay bằng cả hai. Tốt hơn nên xem ngôn ngữ như công cụ. Máy khoan búa không vượt trội hơn máy khoan xoay đơn thuần. Khi làm sàn deck thì máy khoan búa có thể phù hợp hơn, nhưng cả hai đều làm được việc
Tôi cứ tưởng bài này sẽ là https://web.archive.org/web/20120106121645/http://wiki.alu.o...
Nó gợi tôi nhớ lại thời theo dõi comp.lang.lisp. Cũng giống như một dạng drama. Không chỉ có ma thuật lập trình, mà còn có nhiều nhân vật cá tính mạnh và nhiều sự kiện nữa