1 điểm bởi GN⁺ 1 ngày trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Lone Lisp là một Lisp chạy trực tiếp trên các lời gọi hệ thống Linux mà không cần libc, được Matheus Moreira bắt đầu để kiểm chứng liệu có thể xây dựng một ngôn ngữ hoàn chỉnh và các chương trình không gian người dùng chỉ bằng C freestanding hay không
  • Bằng cách dùng trực tiếp ABI không gian người dùng Linux ổn định, anh loại bỏ trạng thái toàn cục và các API cũ của thư viện C như errno, locale, bộ đệm tệp ngầm, đồng thời tự triển khai runtime, bộ cấp phát bộ nhớ và công cụ kiểm thử
  • Hỗ trợ FEXPR và tối ưu hóa gọi đuôi đúng nghĩa, cùng với generator, delimited continuations và xử lý lỗi có thể tiếp tục; vector, bảng và continuation cũng được xử lý theo cùng một cách gọi hàm
  • Khởi động nhanh nhưng hiện là một trình thông dịch mức danh sách chậm hơn Python 10~100 lần trong các benchmark tạm thời; về dài hạn anh dự định giữ trình thông dịch C làm mốc bootstrap và triển khai trình biên dịch JIT bằng chính Lone
  • Moreira dùng Claude cho việc rà soát mã và quản lý dự án, nhưng tự viết/tự duyệt mã của Lone, đồng thời muốn tạo trình tạo site tĩnh, shell và utility để tái xây dựng không gian người dùng Linux truyền thống

Từ game sang C++·Ruby·Lisp

  • Động lực khiến anh quan tâm đến lập trình là Mega Man Battle Network; để giao lưu trên các diễn đàn liên quan anh đã học tiếng Anh và cũng học luôn ngôn ngữ đầu tiên là C++
  • Khoảng 13~14 tuổi, anh bắt đầu học ngành tin học tại một trường trung học kỹ thuật ở Brazil
    • Dùng tutorial của Dev-C++cplusplus.com
    • Chỉ sau 6 tháng đã học xong toàn bộ chương trình ở trường, rồi được tuyển làm trợ giảng để hỗ trợ các học sinh khác
    • Cũng từng thử làm game nhưng không thành công vì thiếu kiến thức vật lý cần thiết
  • Sau C++, anh đi qua Java, Ruby, Python rồi tiếp cận Lisp và Scheme, bị thu hút bởi sự thanh nhã của ngôn ngữ trong Scheme
    • Gần như đọc hết tutorial Java của Sun để học lập trình hướng đối tượng
    • Thích Java Swing và thiết kế Nimbus đến mức từng làm một ứng dụng vẽ hình tròn và cung tròn cho giáo sư toán
    • Với Ruby, anh viết các gem, gồm cả Acclaim, một trình phân tích tham số dạng lệnh giống Git
  • Động lực khám phá nhiều ngôn ngữ ban đầu đến từ các dự án ở trường, nhưng về sau chủ yếu là tò mò và mong muốn tìm ra ngôn ngữ phù hợp với bản thân

Tính biểu đạt của Ruby và tính minh bạch của C

  • Ruby hợp với cách suy nghĩ của anh vì thường chỉ cần đoán tên method cũng đúng, đồng thời hỗ trợ cả dạng số ít/số nhiều và từ đồng nghĩa
    • Có thể làm được nhiều việc với ít mã nhờ các tổ hợp gần giống pipeline shell như items.each.with_index.map
    • Đến nay anh vẫn luôn cài Ruby, gần đây còn bắt đầu một dự án Rails
  • C dễ hiểu kết quả biên dịch hơn vì hàm tương ứng trực tiếp với ELF symbol và mã assembly
    • Anh cho rằng C++ hiện đại thực tế đã trở thành một ngôn ngữ khác so với trước đây, nên không còn nói mình biết C++ nữa
    • Từng thử chuyển sang Rust nhưng không gắn bó được; cũng quan tâm đến Zig và người tạo ra nó vì cách họ tìm lý do viết lại bằng C ở tốc độ và ABI
  • Khi còn tuổi teen, anh đọc mã nguồn CRuby VM để tìm câu trả lời ở mức triển khai cho các câu hỏi kiểu “vì sao Ruby lại hoạt động như thế này” trên Stack Overflow
  • Sau đó anh tiếp tục đọc mã của CRuby, CPython, JVM, Guile, V8, và đặc biệt lấy mã nguồn nhân Linux làm chuẩn đánh giá cho lập trình C chuyên nghiệp

Cách anh đọc mã của người khác

  • Không chỉ dừng ở việc dùng thư viện, anh liên tục đọc mã nguồn để hiểu triển khai bên trong, cách driver giao tiếp với phần cứng, và những tầng ẩn phía dưới
  • Ngay cả khi đang làm ứng dụng thực tế, anh cũng thường bị cuốn sang việc đào sâu công nghệ nền tảng, đồng thời hình thành xu hướng làm lại những vấn đề vốn đã được giải quyết theo cách mà anh cho là tốt hơn
  • Anh nhận ra tính cách đó không hợp với lộ trình nghề nghiệp phát triển phần mềm thông thường, nên không chọn lập trình làm nghề mà giữ nó như một sở thích
  • Anh không hề hiểu được mã driver ngay từ đầu; dù nhiều lần nản lòng, anh vẫn tiếp tục đọc và dần nắm được cách một số phần hoạt động

Reverse engineering bàn phím RGB

  • Ứng dụng Windows dùng để điều khiển bàn phím RGB trên laptop barebone Clevo chậm tới mức mất hơn 1 phút chỉ để hiện cửa sổ, nên anh tự làm bản thay thế
  • Anh dùng Wireshark để bắt các gói USB mà ứng dụng gửi tới bàn phím, phân tích cấu trúc của chúng rồi viết một driver C trong không gian người dùng Linux
  • Đăng lên GitHub rồi quên mất, nhưng sau đó lại có người dùng thật, thậm chí có một người còn làm cả GUI
  • Tiếp đó anh còn reverse engineer các chức năng khác của laptop như quản lý nguồn ACPI, dù không thể giải mã toàn bộ mọi thứ

libc bị bỏ qua và liblinux

  • Các lời gọi hệ thống Linux có mã rất đơn giản, gần như tương tự gọi hàm thông thường, nên có thể nhắm trực tiếp vào Linux mà không cần đi qua libc
  • Linux nổi tiếng vì ABI không gian người dùng ổn định, nhưng anh cho rằng các thành phần không gian người dùng thì không như vậy
    • Từng thấy trong manual câu nói rằng glibc không hỗ trợ một số system call
    • Trường hợp getrandom mất khoảng 2 năm mới vào glibc mà LWN từng nêu ra cũng ảnh hưởng đến suy nghĩ của anh
  • Từ ý tưởng tạo liblinux.a chỉ chứa các system call để liên kết bằng -llinux, anh phát triển liblinux
    • Đây là một bộ wrapper system call Linux cho C freestanding
    • C runtime (CRT) ở đây chỉ các thư viện C chuẩn như glibc, musl, uclibc

Những vấn đề biến mất trong C freestanding

  • Linux trả lỗi như giá trị trả về thông thường, nhưng thư viện C lại lưu nó vào biến toàn cục errno
  • Khi bỏ libc, cũng có thể tránh được nhiều trạng thái toàn cục và API cũ khác
    • errno, rand/srand, trạng thái locale
    • strtok không reentrant
    • bộ đệm tệp ngầm có thể gây ra vấn đề bất ngờ
    • gets, atexit, signal, malloc
    • math.h trở nên phức tạp khi kết hợp với NaN và errno
  • Ngược lại, quy tắc integer promotion và việc không có kiểm tra overflow vẫn là vấn đề của chính C nên còn nguyên
    • Anh dùng các tính năng built-in của compiler để xử lý overflow
    • Đồng thời cũng cảnh giác khả năng tự tạo ra lỗi mới
  • Dù phải tự viết mọi thứ từ sao chép byte đến chuyển số nguyên thành chuỗi mà không có thư viện chuẩn, việc này không bất khả thi như dự đoán
    • Kho mã glibc khá khó đọc, nhưng mã nguồn musl libc sạch và dễ lần theo nên rất hữu ích
    • Anh cũng triển khai trong Lone một test suite tự động chỉ dùng bộ nhớ tĩnh, không cần thư viện C hay cấp phát bộ nhớ động

Phát hiện nolibc và sự khởi đầu của Lone Lisp

  • Anh từng hỏi Greg Kroah-Hartman vì sao Linux không có thư viện C chính thức, và nhận được câu trả lời rằng trước đây từng có dự án klibc
  • Sau đó anh phát hiện các nhà phát triển nhân Linux đã tạo nolibc.h cho các công cụ nội bộ
    • Anh thấy nó hoàn thiện và dễ dùng hơn liblinux của mình nên đã đưa dự án vào lưu trữ
    • Hiện nolibc.h đã phình ra thành một thư mục gần giống libc tạm thời trong cây kernel, nhưng độ ổn định cho bên ngoài vẫn chưa thực sự được đảm bảo
  • Là dự án tiếp theo, anh bắt đầu Lone Lisp
    • Anh cho rằng nếu có thể tạo một Lisp freestanding chạy trực tiếp trên Linux, thì về nguyên tắc có thể viết mọi chương trình khác theo cách tương tự
    • Đây là một thử nghiệm nhằm gạt bỏ không gian người dùng Linux hiện đại đầy phức tạp và bắt đầu lại trên giao diện nhị phân system call ổn định
  • Anh cũng gửi patch cho Cosmopolitan để triển khai việc phân tích số thực dấu chấm động
    • Anh đánh giá cao định dạng APE có thể được diễn giải đồng thời thành định dạng thực thi của nhiều nền tảng và khả năng nhúng archive trong file thực thi

Xử lý lỗi và delimited continuations

  • Ban đầu mọi nhánh lỗi trong Lone đều kết thúc bằng exit(255) ở trình thông dịch, nhưng sau đó anh triển khai hệ thống điều kiện có thể tiếp tục kiểu Common Lisp
  • Nền tảng của xử lý lỗi là delimited continuations
    • Anh hiểu continuation như việc sao chép stack frame rồi phát lại ở vị trí khác
    • Cũng xem exception là một dạng continuation không bắt giá trị
  • Các loại lỗi được ánh xạ từ symbol như 'not-found sang lambda
    • (lambda (error) ...) với một tham số hoạt động như trình xử lý ngoại lệ thông thường
    • (lambda (error continuation) ...) với hai tham số có thể gọi continuation để tiếp tục đoạn mã đang lỗi cùng với một giá trị
  • Anh cố ý không dùng restart API kiểu Common Lisp use-value, nơi mã phát tín hiệu liệt kê các lựa chọn restart
    • Thay vào đó, signal, throw, transfer được cấu thành như cơ chế nền tảng bên trong evaluator để chúng hoạt động đơn giản như thể chỉ đang trả về giá trị

FEXPR và các thành phần ngôn ngữ có thể gọi

  • Anh cũng tránh kiểu evaluator Lisp truyền thống xử lý trực tiếp special form như if
  • Lone hỗ trợ FEXPR, tương đương plugin cho evaluator, để tách special form ra ngoài evaluator
    • Thiết kế này giúp tối ưu hóa gọi đuôi cho các hàm Lisp thuần có thể làm trước, nhưng với primitive đã có bug trong một thời gian
    • Anh giải quyết bằng cách thêm một cơ chế riêng để primitive cũng có thể trả về ở vị trí đuôi
  • Vector và bảng cũng có thể gọi được
    • ([1 2 3] 0) trả về 1
    • ([1 2 3] 0 4) thay đổi vector thành [4 2 3]
  • Continuation và generator cũng theo cùng quy ước gọi
    • control giống begin nhưng hỗ trợ continuation
    • transfer thoát khỏi khối control gần nhất và trả về một continuation có thể gọi để biểu diễn điểm tạm dừng
    • Khi gọi continuation đó cùng với một giá trị, phép tính đang bị tạm dừng có thể được tiếp tục với giá trị trả về khác

System call và cấu trúc thực thi

  • Trước khi Lone khởi động, tiến trình cha gọi execve, còn Lone tự thực hiện khoảng 12 lần mmap để quản lý bộ nhớ nội bộ
  • Nó đọc script từ standard input, thực thi rồi thoát; trong quá trình chạy có thể phát sinh thêm mmap, munmap, mremap
  • Hệ thống module dùng openatclose
  • Trong hơn 300 system call của Linux, Lone chỉ tự dùng một phần, nhưng cung cấp system-call primitive ở mức Lisp để chương trình có thể gọi cả những cái còn lại
  • Với các lời gọi cần cấu trúc C của kernel như ioctl, sẽ phải bổ sung khả năng tạo và thao tác struct
    • Việc lấy kích thước terminal cũng là một ví dụ cần hỗ trợ kiểu này

Không gian người dùng mà anh muốn xây bằng Lone

  • Ở cấp ngôn ngữ, anh đã triển khai xử lý lỗi, tối ưu hóa gọi đuôi đúng nghĩa, generator và delimited continuations, đồng thời về dài hạn còn muốn đưa vào các ý tưởng từ Erlang/BEAM
  • Cấu trúc cũng đã được chuẩn bị để nhiều trình thông dịch có thể chạy mã Lisp song song
  • Chương trình đầu tiên anh định viết bằng Lone là bản thay thế cho trình tạo site tĩnh dựa trên PugJS fork mà anh đang dùng
  • Sau đó anh sẽ viết shell và utility của riêng mình để tái tạo không gian người dùng Linux truyền thống theo cách riêng
  • Anh cũng đã làm một triển khai xuất env thành bảng Lone Lisp; khi đó chưa có khả năng duyệt nhưng hiện đã hỗ trợ generator
  • Trình thông dịch còn có thể đọc và chạy mã Lisp trong một ELF segment đặc biệt
    • Chỉ cần sao chép binary của trình thông dịch và chèn mã Lisp vào là có thể tạo chương trình độc lập

Rà soát và quản lý dự án với Claude

  • Khối lượng công việc tổng thể thì không có giới hạn, nhưng anh cho rằng bộ tính năng của bản thân ngôn ngữ đang tiến khá gần tới mức hoàn thiện
  • Anh dùng Claude như một kiểu quản lý, và nhận được giúp đỡ lớn nhất ở việc rà soát mã và quản lý dự án
    • Anh yêu cầu nó nghiêm khắc chỉ ra vấn đề, phần còn thiếu và hướng đi tương lai trên toàn bộ codebase
    • Các cách tiếp cận đã bác bỏ và các tính năng để dành sau được quản lý bằng tài liệu và bộ nhớ dự án
    • Bộ gom rác và bộ cấp phát bộ nhớ đã được cải thiện đáng kể nhờ Claude gợi ý thuật toán tốt hơn
  • Tuy vậy, anh tự rà soát mọi dòng đưa vào Lone, và vì xem bản thân việc viết mã là một quá trình học hỏi nên không tin AI đủ để viết thay mã Lone
  • Ngược lại, với trình tạo site tĩnh bằng JavaScript, anh từng để Claude viết trọn một tính năng
  • Các tính năng dự kiến tiếp theo gồm API compiler của GCC/Clang và hỗ trợ hàm bảo vệ stack

Cú pháp lấy từ Ruby và Scheme

  • Anh cố gắng kết hợp tính biểu đạt của Ruby với sự cô đọng của Scheme; parser của Lisp lại đơn giản nên anh có thể tự viết và xử lý trực tiếp các nested list
  • Khoảnh khắc thực sự hiểu Lisp đến khi anh triển khai FEXPR, nơi hàm nhận chính list thay vì giá trị đã được đánh giá
  • Mảng dùng cú pháp [1 2 3], từ điển dùng cú pháp {k v}
    • Không chỉ quen thuộc với người dùng Clojure và newLisp mà còn cả Ruby, Python, JavaScript, giúp giảm rào cản tiếp cận không cần thiết
  • Phong cách viết C dựa trên style của nhân Linux nhưng được chỉnh sửa theo sở thích căn chỉnh và trang trí nhiều hơn của anh
  • Trong Ruby, anh thích cách giảm dấu câu để viết gần với câu tiếng Anh hơn, như method 'arg' thay vì method('arg')
  • Trong Lisp, anh cũng giảm bớt độ lồng của cú pháp
    • let của Lone có dạng (let (a b c d ...) body...)
    • Anh cho rằng cách để tên và giá trị xuất hiện tuần tự như vậy tự nhiên hơn với mô hình áp dụng hàm so với dạng truyền thống (let ((a b) (c d) ...) body...)

Hiệu năng và kế hoạch bootstrap

  • Benchmark mà Lone vượt trội là tốc độ khởi động: có thể bắt đầu và kết thúc chương trình nhanh hơn thời gian Ruby đọc Rubygems
  • Trong các phép đo tạm thời, nó chậm hơn Python khoảng 10~100 lần
    • Lone là một trình thông dịch mức danh sách gần giống hình thức ở chương 5.4 của SICP
    • Python và Ruby là trình thông dịch bytecode nên thuộc một nhóm hiệu năng khác
  • Anh tránh biên dịch sang bytecode vì cảm thấy như thế sẽ làm mất bản chất của Lisp
  • Về dài hạn, trình thông dịch C sẽ được giữ làm mốc bootstrap cuối cùng, còn bên trong Lone anh dự định viết trình biên dịch JIT
    • Cách làm là lấy các trang bộ nhớ thực thi được bằng mmap rồi sinh lệnh lên đó
  • Trong so sánh tạm với Bash bằng Fibonacci đệ quy, Lone nhanh hơn nhiều, nhưng anh cũng thừa nhận phép đo có thể méo mó vì Bash có thể tạo tiến trình ở mỗi vòng lặp
  • Với script, thời gian khởi động là quan trọng nên anh xem bootstrap nhanh của Lone là hữu ích
    • Nếu tính trước hash table ở bước build và biến chúng thành dữ liệu khởi tạo trong C, chi phí khởi tạo khi chạy còn có thể giảm thêm

Bộ nhớ và môi trường tối thiểu

  • mmap là lời gọi yêu cầu kernel cấp các trang bộ nhớ; kích thước trang thông thường là 4,096 byte
  • Có thể chỉ định quyền đọc/ghi/thực thi, và JIT dùng các trang có quyền thực thi
  • Nếu chỉ cần 16 byte mà vẫn xin 4KiB thì rất lãng phí, nên bộ cấp phát thông thường sẽ nhận một vùng lớn như 128MB rồi chia thành các mảnh nhỏ
  • Môi trường top-level của Lone chỉ có hai symbol là importexport
    • Ngoài list, literal và cơ chế gọi hàm, mọi thứ kể cả if, quote đều phải tự import vào
    • Đây là thiết kế để người dùng trực tiếp kiểm soát mọi tên trong môi trường
  • Hiện có khoảng 50 hàm, trọng tâm là if, let, begin, control/transfer, intercept/signal, flatten v.v.

Thư viện chuẩn và tài liệu

  • Tài liệu ngôn ngữ vẫn còn chưa hoàn chỉnh, nhưng công việc về thư viện chuẩn đang tiến gần hơn cả phần tính năng ngôn ngữ
  • Anh dự định tham khảo thư viện chuẩn của Ruby và cách đặt tên của Scheme
  • Việc tiếp theo là giao thức duyệt
    • Anh đang cân nhắc dạng (for (each collection) (lambda (item) ...))
    • Toàn bộ các hàm each hiện có sẽ được thiết kế lại để luôn trả về generator
  • Sau đó anh muốn triển khai thao tác chuỗi và một string builder để nối chuỗi hiệu quả
  • Khi hoàn thiện phần duyệt và chuỗi, anh cho rằng có thể viết cả một web framework kiểu Hiccup
  • Anh lo rằng sau khi xong phần low-level và chuyển sang công việc thư viện chuẩn mang tính lặp lại, khả năng tập trung sẽ giảm, nên dự định tận dụng Claude cho phần hỗ trợ quản lý

Mục tiêu tự sở hữu toàn bộ stack

  • Ngay cả những tính năng từng có vẻ huyền bí như continuation, khi hiểu là sao chép stack frame thì cũng chỉ còn là một bài toán triển khai bình thường; Lone muốn khuyến khích người khác tự xây và tự khám phá hệ thống của mình
  • Anh không muốn chỉ là người tiêu thụ thư viện mà muốn trở thành người tạo ra thư viện, và cũng muốn trực tiếp dùng các system call vốn thường bị xem như cấm kỵ với lập trình viên phổ thông
  • Muốn có hệ thống của riêng mình thì khi nó hỏng cũng phải tự sửa, nhưng anh mong nhiều người hơn sẽ chọn cả trách nhiệm lẫn phần thưởng đó
  • Anh cho rằng không nên sợ khối mã cũ tích tụ trong ngành tính toán, và hoàn toàn có thể loại bỏ các tầng không cần thiết
    • Chủ thể tái tạo không gian người dùng Linux có thể không phải anh mà là các nhà phát triển Rust hoặc Zig
    • Ngay cả khi Lone không thành công, anh vẫn hài lòng nếu nó khích lệ được những nỗ lực kiểu này

Phần mềm tự do và Android

  • Anh coi trọng mục tiêu trao quyền cho người dùng của phần mềm tự do, và lo ngại máy tính đa dụng đang bị thu hẹp thành những thiết bị gia dụng do doanh nghiệp hoặc chính phủ quản lý
  • Anh đánh giá systemd là một ví dụ thành công về việc hình dung lại và tái xây dựng không gian người dùng Linux truyền thống, dù cách tiếp cận có phần nặng nề
  • Theo anh, không thể tự làm mọi tầng mà phải chọn trận để đánh
    • Nếu làm Lone thành Lisp bare-metal thì có lẽ anh còn chưa tới được giai đoạn boot
    • Anh nêu ví dụ Sector Lisp của jart, một boot sector Lisp dưới 512 byte
  • Lone khởi đầu trong Termux và phần lớn được viết trên điện thoại
  • Dù Android chặn một số system call gồm cả statx, Lone vẫn chạy được trên Android và test suite đạt 100%

Bác sĩ và lập trình viên không chuyên

  • Moreira là một bác sĩ tốt nghiệp y khoa năm 2019
    • Khi đọc về lập trình mạng nơ-ron ở trung học, anh bắt đầu quan tâm đến sinh học
    • Có ngày anh khám bệnh 10~14 giờ, có ngày lại nghỉ nên vẫn sắp xếp được thời gian lập trình
  • Ở bệnh viện dùng hồ sơ bệnh án điện tử, anh rút ngắn đáng kể công việc nhờ template và khả năng gõ máy
    • Có thể vừa nhìn bệnh nhân vừa ghi chép
    • Dự án Rails anh mới bắt đầu gần đây là một hệ thống hồ sơ bệnh nhân điện tử để giải quyết nhu cầu của chính mình
  • Anh cho rằng một trong những lý do các lập trình viên chuyên nghiệp không tự giải quyết vấn đề cá nhân là vì thiếu quan tâm đến bản thân máy tính
  • Để đào sâu vào bên trong triển khai, cần có sự tò mò chứ không chỉ thái độ muốn lấy kết quả; còn làm sao khơi gợi sự tò mò ấy ở mọi người thì anh vẫn chưa biết

1 bình luận

 
Các ý kiến trên Lobste.rs
  • Tôi thích loạt phỏng vấn này đến mức không bỏ sót bài nào; điều thú vị lớn là được biết mối quan hệ cá nhân mà mỗi người đã có với điện toán

    • Việc gom lại và so sánh với nhau những cơ duyên nhập môn khiến họ trân trọng máy tính hơn là một công cụ đơn thuần đặc biệt thú vị
      Shonumi, tác giả trình giả lập GBE+ GBA, cũng như tôi, đã chịu ảnh hưởng từ các game Mega Man Battle Network, và tôi cũng muốn một ngày nào đó được đọc phỏng vấn của anh ấy
  • Ngoại lệ có thể khởi động lại không nhất thiết cần continuation hạng nhất (first-class continuation)
    Common Lisp cung cấp ngoại lệ có thể khởi động lại ngay cả khi không có continuation; điểm cốt lõi là không unwind stack trước khi gọi handler
    Vì vậy stack và trạng thái tại nơi ngoại lệ xảy ra vẫn được giữ nguyên, để handler có thể return bình thường, hoặc như Common Lisp, có thể nhảy tới một restart handler ở đâu đó trên stack

    • Nếu tôi đã tạo cảm giác rằng đó là điều bắt buộc, thì là do tôi quá phấn khích với nhận thức mới của mình
      Tuy nhiên trong Lone Lisp, continuation được trả về có thể được gọi nhiều lần và có thể thoát ra ngoài signal handler, nên trên thực tế là cần thiết
      (import (lone print set quote lambda intercept signal))
      
      (set continuation  
        (intercept  
          (('return (lambda (value continuation) continuation)))  
          (signal 'return 'value)))
      
      (print (continuation 1)); 1  
      (print (continuation 2)); 2  
      (print (continuation 3)); 3  
      
      Generator là nền tảng của xử lý lặp nên hiệu năng quan trọng hơn; vì vậy thay vì dùng continuation giới hạn, tôi dùng stack riêng để loại bỏ việc sao chép
      Xử lý lỗi là đường đi tương đối hiếm, nên tôi quyết định cung cấp đầy đủ chức năng
  • Với nhiều người, công việc hay dự án quan trọng nhất có lẽ là những việc làm cho vui, không thù lao trong thời gian rảnh
    Tôi tưởng tượng rằng bác sĩ của mình cũng có thể đang sống hai cuộc đời, âm thầm tạo ra một ngôn ngữ Lisp của riêng mình

    • Hóa ra không chỉ mình tôi như vậy
      Dr. Cameron Kaiser cũng đã thực hiện những dự án lớn, thậm chí chia sẻ triết lý về quyền sở hữu máy móc, và hằng ngày sử dụng một workstation POWER9 hoàn toàn mở
  • Đây là lần đầu tôi biết đến Lone Lisp, và nó trông là một dự án rất hay
    Tôi cũng bắt đầu học C++ bằng Dev-C++ cũ trong giờ tin học khoảng năm 13–14 tuổi, nên lâu lắm rồi mới nhớ lại, khá gợi hoài niệm

    • Thật ngạc nhiên khi Dev-C++ vẫn còn được duy trì và vẫn có bản phát hành vào năm 2021
  • Tôi hoàn toàn không ngờ anh ấy là bác sĩ, và điều đó làm tôi nhớ đến Con Kolivas
    Có vẻ những bác sĩ kiêm lập trình viên như vậy nhiều hơn ta tưởng
    https://en.wikipedia.org/wiki/Con_Kolivas