Viết mã cho con người còn khó hơn viết mã cho máy tính
(erikbern.com)- Công cụ cho lập trình viên khó hơn vì không chỉ phải thiết kế logic để máy tính thực thi mà còn phải thiết kế cả mô hình tinh thần để người khác hiểu và sử dụng
- Onboarding nhanh không phải tính năng phụ mà gần như là chính sản phẩm, và cần giảm ma sát ở khâu cấu hình, API token, chạy lần đầu để người dùng có thể thử trên laptop chỉ trong vài phút
- Thay vì giải thích dài dòng về khái niệm cốt lõi, người dùng học mẫu nhanh hơn bằng cách sửa ví dụ đang chạy được, và càng có nhiều điểm khởi đầu gần với bài toán của họ thì khả năng thành công càng cao
- Thông báo lỗi, số lượng khái niệm, cách đặt tên, phương thức cấu hình, giá trị mặc định, magic, cú pháp sugar đều làm thay đổi con đường đi tới thành công của người dùng, nên cần một thiết kế dễ đọc và có thể tùy biến
- Trải nghiệm lập trình viên tốt không phải là chỉ cắt giảm tính năng, mà là giữ nguyên phạm vi có thể tạo ra trong khi hạ thấp mạnh độ phức tạp cần phải biết
Mã dành cho con người còn phải xử lý cả mô hình tinh thần
- Mã cho máy tính là công việc chia nhỏ mục tiêu kinh doanh lớn thành các câu lệnh logic để máy tính có thể làm theo
- Với những thứ con người trực tiếp sử dụng như framework, library, API, SDK, DSL, embedded DSL, hay ngôn ngữ lập trình, chỉ khả năng thực thi thôi là chưa đủ
- Loại mã này vừa phải chỉ thị cho máy tính, vừa phải xử lý cách người dùng sẽ đọc và hiểu đoạn mã đó
- Thiết kế công cụ cho lập trình viên đòi hỏi không chỉ khoa học máy tính mà còn cả hiểu biết tâm lý về cách người dùng suy luận
Trải nghiệm bắt đầu chính là sản phẩm
- Phản hồi về công cụ cho lập trình viên thường đến nhiều từ power user là những người dùng sản phẩm rất thường xuyên
- Người bị kẹt ngay từ bước bắt đầu thường không để lại phản hồi, nên sẽ xuất hiện thiên lệch người sống sót
- Cũng như sản phẩm tiêu dùng tối ưu onboarding funnel, công cụ cho lập trình viên cũng phải xem toàn bộ quá trình đến lần chạy đầu tiên là phần cốt lõi của sản phẩm
- Để onboarding nhanh, đáng để thay đổi chính cấu trúc của sản phẩm
- Loại bỏ cấu hình bắt buộc
- Biến việc thiết lập API token thành thứ cực kỳ dễ dàng
- Giảm ma sát ban đầu
- Giúp người dùng có thể thử sản phẩm trên chính laptop của họ chỉ trong vài phút
- Trong môi trường có quá nhiều công cụ cho lập trình viên, người dùng khó có đủ năng lượng hay kiên nhẫn để hiểu sâu sự khác nhau giữa một package NPM LRU cache cụ thể với package khác
Ví dụ dạy nhanh hơn khái niệm cốt lõi
- Con người, không giống máy tính chỉ giỏi tuân theo mệnh lệnh chặt chẽ, lại mạnh ở so khớp mẫu
- Nhiều tài liệu công cụ cho lập trình viên bắt đầu bằng việc giải thích mô hình dữ liệu cốt lõi, quan hệ, khái niệm nguyên tử, cấu hình và cách chạy, nhưng con người học tốt hơn khi sửa một ví dụ đang chạy và quan sát kết quả
- Nhiều ví dụ có thể hữu ích hơn một bài giải thích “core concepts” dài 5.000 từ
- Người dùng nhìn ví dụ để học cách công cụ hoạt động
- Người có một bài toán cụ thể có thể tìm được điểm khởi đầu đủ gần
- Càng nhiều điểm khởi đầu, càng dễ gặp một ví dụ gần với thứ họ cần
Đẩy người dùng vào hố thành công
- Trạng thái mặc định của lập trình gần như là liên tục sửa một kiểu lỗi nào đó
- Người dùng có thể dành phần lớn thời gian dùng công cụ để tìm ra “cái gì đang không hoạt động”
- Nếu lập trình viên thành công nhanh hơn, họ sẽ thích công cụ; nhưng nếu liên tục bị lỗi chặn lại, họ sẽ đổ lỗi cho công cụ
- Mọi lỗi đều là cơ hội để đưa người dùng quay lại happy path
- Chèn code snippet vào thông báo exception
- In ra cảnh báo hữu ích khi người dùng có khả năng làm điều gì đó bất thường
- Cung cấp hành động cần thiết để người dùng đi tới thành công
Giảm quá tải khái niệm
- Mỗi khái niệm mới mà người dùng phải hiểu trước khi dùng công cụ đều là một điểm ma sát
- 2–3 khái niệm có thể chấp nhận được, nhưng không nhiều người sẵn sàng học 8 khái niệm mới
- Kubernetes không đòi hỏi tất cả khái niệm ngay lúc bắt đầu, nhưng số lượng khái niệm mới càng tăng thì gánh nặng càng lớn
- Có một vẻ thanh nhã ở những framework mạnh mẽ mà chỉ có 3–5 khái niệm
- Khi dùng React lần đầu, sau một hai giờ vượt qua con dốc khái niệm ban đầu, người dùng có thể cảm nhận rằng mình đang xây cấu trúc lớn bằng vài khối lắp ghép đơn giản
- Mục tiêu không chỉ là giảm số lượng khái niệm, mà là giảm số khái niệm người dùng phải biết trong khi vẫn giữ nguyên phạm vi những gì có thể tạo ra
- Công cụ xuất sắc có thể giảm 90% độ phức tạp mà vẫn giữ nguyên năng lực
- Ngay cả công cụ giảm 90% độ phức tạp và chỉ giảm 10% năng lực cũng không tệ
Nguyên tắc vịt trong thiết kế khái niệm
- Nếu trong framework có một thành phần nhận giá trị và tính ra giá trị mới, thì thay vì đặt tên mới như “compute node”, “valuator”, hay “frobniscator”, tốt hơn là gọi nó là function
- Nguyên tắc “nếu thứ gì đi như vịt và kêu như vịt thì rất có thể nó là vịt” cũng có thể áp dụng vào thiết kế khái niệm
- Dù có khác biệt tinh tế hoặc giá trị được cache, nếu nó đủ gần với function thì có thể gọi là function
- Dùng thuật ngữ sẵn có giúp gắn vào mô hình tinh thần mà người dùng đã có, từ đó giảm rất nhiều thứ cần phải giải thích
Làm cho nó có thể lập trình được
- Người dùng sẽ làm những điều ngoài dự đoán với codebase, và có thể đặt các thành phần của framework vào trong for-loop, trong function, hay trong cấu trúc khác
- Vì vậy, gần như mọi thứ trong framework đều phải có thể lập trình được
- Các hướng thiết kế liên quan với nhau gồm
- Cho phép gọi trực tiếp từ code thay vì phải đi qua CLI
- Giảm file cấu hình và chuyển sang SDK hoặc API
- Đừng chỉ cho phép tạo một cái; hãy tham số hóa để có thể tạo ra n cái
- Những thiết kế như vậy có thể khiến người dùng khám phá ra các use case mới
- Nếu tận dụng được mong muốn “hack” trên framework, thì dù có chút hỗn loạn cũng có thể dẫn tới những khám phá ngoài dự kiến
Cần thận trọng với magic, giá trị mặc định và cú pháp sugar
- Giả sử có một hàm
run_notebookđể chạy Jupyter notebook trên cloud, và người dùng phải chỉ định image container sẽ dùng - Có nhiều lựa chọn khả dĩ
- Luôn bắt buộc tham số
image=... - Có một image mặc định với hầu hết library khoa học dữ liệu đã được cài sẵn để người dùng có thể override
- Kiểm tra code trong cell và chọn image theo kiểu “magic” dựa trên dependency cần thiết
- Ngoài cách magic, vẫn cho phép người dùng chọn một image cụ thể
- Luôn bắt buộc tham số
- Để giảm lượng nhập liệu và hỗ trợ phạm vi use case rộng nhất, lựa chọn cuối cùng có thể trông hấp dẫn
- Nhưng nếu không chọn phương án đầu tiên thì vẫn còn vấn đề
- Magic sẽ hỏng trong một số tình huống
- Người đọc code dựa vào giá trị mặc định có thể không nhận ra khả năng tùy biến tồn tại
- Trừ khi giá trị mặc định áp dụng được trên 97% trường hợp và magic đúng trên hơn 99% trường hợp, cần phải cực kỳ cẩn trọng
- Viết code không phải chơi golf, và công việc của người làm công cụ không chỉ là tối thiểu hóa lượng code mà người dùng phải viết
- Perl tối ưu rất mạnh cho code ngắn, nhưng chương trình có thể trông như một chuỗi ký tự đặc biệt, còn Python dù dài hơn 50% vẫn dễ đọc và dễ hiểu hơn
- Con người đọc code nhiều gấp 10 lần so với viết, nên tính dễ đọc là rất quan trọng
- Cú pháp sugar cũng nên được đánh giá theo cùng tiêu chuẩn
- Có thể sẽ muốn thêm cú pháp đặc biệt cho use case phổ biến
- Nhưng nó có thể làm mất tính nhất quán và khiến cách tùy biến trở nên kém rõ ràng
- Nếu cú pháp sugar không áp dụng được trên hơn 99% trường hợp thì có lẽ tốt hơn là không nên đưa vào
Nguyên tắc thiết kế cho người dùng lần đầu
- Viết mã cho con người vẫn còn rất nhiều bài toán thiết kế
- Phần lớn nên là immutable, nhưng không phải tất cả
- Tránh scaffolding, tức là sinh code
- Làm feedback loop thật nhanh
- Giúp người dùng dễ phản ứng với tính năng sắp bị loại bỏ
- Dùng kiểm thử tự động cho code snippet trong tài liệu và ví dụ
- Thiết kế trải nghiệm cho người dùng đầu tiên giống với việc tạo ra một bài pop hit
- Dù producer có nghe bài hát đến cả nghìn lần, ở lần nghe thứ 999 họ vẫn phải tưởng tượng xem nó sẽ vang lên thế nào với một người nghe lần đầu
- Với công cụ cho lập trình viên cũng vậy, người đã lặp đi lặp lại việc xây nó sẽ rất khó tưởng tượng trải nghiệm của người dùng lần đầu
1 bình luận
Các ý kiến trên Hacker News
Mỗi người có cách học khác nhau. Với tôi, trước khi đi vào ví dụ, trước hết tôi cần khái niệm cốt lõi. Điều này càng đúng nếu khái niệm cốt lõi không quá đơn giản
Nhiều tutorial giống như kiểu cầm tay chỉ việc để lắp Lego. Kiểu như: “Đây là các mảnh Lego, cứ làm theo tôi khi tôi tạo một dự án đồ chơi, rồi đến cuối ngày bạn sẽ biết chơi Lego”
Cách này không hợp với tôi. Tôi muốn biết các quyết định được đưa ra như thế nào và vì sao, muốn nhìn từ góc nhìn của tác giả. Tôi muốn biết từng mảnh Lego có cảm giác ra sao, chúng kết nối với nhau thế nào, và làm sao đi đến một thiết kế cụ thể
Làm theo tutorial mà không có ít nhất một phần giải thích khái niệm cấp cao tối thiểu khiến tôi có cảm giác như đang đảo ngược thiết kế một thứ lẽ ra không cần phải làm vậy. Khi xem một thư viện hay framework mới, tôi thường đọc bài giới thiệu và bỏ qua ví dụ code “bắt đầu”. Thường thì phần “nâng cao” có nhiều thảo luận về khái niệm hơn, nên tôi xem từ đó trước; tiếp theo là tham chiếu API để nắm các interface quan trọng, rồi cuối cùng mới quay lại các ví dụ code cơ bản ở đầu tutorial
Dạo này tôi thường nhảy thẳng vào và làm việc ngay với ví dụ nhiều hơn, và cảm thấy năng suất cũng cao hơn. Ở mức nào đó, đây là vấn đề niềm tin. Tức là tin rằng những người đã tạo ra phần mềm chất lượng đã suy nghĩ đủ kỹ để làm cho interface dễ hiểu trong các use case thông thường mà không cần đào sâu vào bên trong
Tất nhiên tôi vẫn thường gặp những chướng ngại buộc phải đi sâu hơn. Nhưng tình huống đó xảy ra vì trước đó đã có 10 thứ khác tôi vượt qua thành công chỉ bằng ấn tượng bề mặt. Vì vậy, khi thật sự đào sâu, tôi thường thấy đó không phải là lãng phí thời gian
Những công cụ như vậy tạo ra một cấu trúc thư mục cụ thể, các file template và các công cụ được cấu hình sẵn. Nếu không lập tức hiểu ở mức cao các file được tạo ra làm gì và vì sao chúng được tạo như vậy, tôi sẽ thấy khó chịu vì có quá nhiều phép màu mà mình không hiểu
Mỗi khi có thứ mới xuất hiện, tôi cần một phần giới thiệu cấp cao giải thích mục đích của nó bằng cách liên hệ với những khái niệm tôi đã biết. Tôi không thấy thoải mái khi xử lý những hộp đen ma thuật cho đến khi ít nhất cũng hiểu sơ bộ interface chính của hộp đen đó. Chẳng hạn, nếu học create-react-app từ đầu, hẳn tôi sẽ ngay lập tức bắt đầu tìm hiểu mục đích của các công cụ mà nó cấu hình, như Babel hay ESLint
Vài năm sau, sau khi xem nhiều ví dụ thực tiễn tốt, tôi mới hiểu các khái niệm đó đang nói gì. Sau nhận thức đó, tôi đã tinh chỉnh cách học của mình
Trước tiên tôi lướt qua các khái niệm cốt lõi, thử nhiều ví dụ cho đến khi hiểu vì sao khái niệm đó cần thiết, rồi đọc kỹ lại các khái niệm cốt lõi để loại bỏ những trường hợp biên bị thiếu trong các ví dụ ngây thơ
Tuy vậy, tôi nghĩ cách bắt đầu từ ví dụ có thể hữu ích cho việc thiết kế API tốt. Nếu thiết kế API theo kiểu “khái niệm cốt lõi trước”, cuối cùng rất dễ tạo ra một API chỉ dùng được sau khi đã hiểu các khái niệm cốt lõi, và điều đó không tốt cho những người dùng chỉ thỉnh thoảng mới dùng
Đúng kiểu hacker, không có trích dẫn nào. Tôi chỉ xem qua giáo dục học một chút, nhưng đó là một lĩnh vực học thuật đồ sộ và trưởng thành, rút ra các nguyên lý hiện đại từ tâm lý học kinh nghiệm của Dewey và Piaget. Có nhiều điều để nói hơn rất nhiều so với những gì có thể gói trong một bài blog, chứ chưa nói đến một mục của bài blog
Vấn đề lớn nhất, như đã chỉ ra, là mỗi người khác nhau. Vấn đề lớn tiếp theo là ta thậm chí còn không biết chắc vì sao những khác biệt đó xuất hiện, hay chúng ổn định đến mức nào theo thời gian. Bản thân bài viết được viết tốt và đào sâu khá hay vào tính thực dụng của một chiến lược giáo dục cụ thể, nhưng tôi mong nó có thêm chút khiêm tốn
Chưa đầy 2 tuần trước đã có một bài tương tự: https://news.ycombinator.com/item?id=41566097
Viết cho con người rốt cuộc có thể cô đọng thành hai kỹ năng: đồng cảm và viết lách
Có một khác biệt lớn giữa việc viết một chút code và việc viết một ứng dụng hay sản phẩm. Bài này tuy ít nói thẳng hơn, nhưng rốt cuộc cũng là nói chuyện đó. Lý do đồng cảm quan trọng là vì nó tạo ra khác biệt giữa tính vị kỷ và hướng ra bên ngoài
Lập trình viên vị kỷ chủ yếu quan tâm đến sự dễ dàng, tiện lợi, phù phiếm về code và các tiêu chí chủ quan khác. Cuối cùng họ chỉ tính đến nỗ lực truyền đạt của chính mình. Lập trình viên hướng ra bên ngoài chủ yếu quan tâm đến kiến trúc và tài liệu hóa. Vì họ cho rằng thành công phụ thuộc vào việc người khác tiếp nhận thành quả của mình ra sao
Sự đơn giản quan trọng hơn sự dễ dàng. Vì lập trình viên hướng ra bên ngoài không thể đọc được suy nghĩ của người khác và không biết họ sẽ cảm thấy điều gì là dễ, nhưng họ biết cách giảm số bước và giữ code nhỏ gọn
Nhìn từ góc độ sản phẩm tổng thể, việc viết một ứng dụng trong não không khác gì viết một bài luận, bài viết hay cuốn sách. Cốt lõi là tổ chức và chức năng. Code đến sau, giống như những từ trên trang giấy. Người chỉ viết các mẩu code sẽ không phát triển được kỹ năng tổ chức ở tầng cao để gắn mọi thứ thành một khối
Vì vậy tôi cực kỳ ghét framework. Framework tước đi của lập trình viên sự luyện tập cần thiết để viết phần mềm độc đáo, và kết quả là ngăn họ phát triển kỹ năng tổ chức. Bản thân người đó không thấy được, nhưng với người thấy được thì đó là một khoảng cách lớn cực kỳ rõ ràng
Nhưng những người khác giờ phải học lớp trừu tượng của họ, và vì thế càng xa rời các khái niệm nền tảng. Điều đó có thể khiến việc học các kỹ năng cốt lõi cần thiết để vượt ra ngoài framework trở nên khó hơn. Khi học Rails tôi đã có cảm giác như vậy, và cuối cùng nhận ra nó che giấu quá nhiều thứ nên bỏ nó đi và thử làm từ đầu
Nhận ra đây là một kỹ năng hoàn toàn khác thật sự là một sự khai sáng. Có thể nói giờ nó đã trở thành một điều chưa biết đã biết
Đoạn code này sẽ trông như thế nào với một người đang bị sếp bóp cổ, hoặc với người đang sửa sự cố vận hành lúc 2 giờ sáng? Bạn sẽ không biết câu trả lời đó có giá trị đến đâu cho đến khi thực sự cần nó. Và khoảnh khắc cần đến, bạn sẽ phải trả rất nhiều tiền cho câu trả lời đó. Nếu bạn tìm được người biết làm chuyện đó. Những người như vậy rất hiếm
Tôi không đồng ý với câu “con người học từ ví dụ chứ không phải từ khái niệm cốt lõi”. Có thể là bắt bẻ, nhưng không phải mọi con người đều vận hành theo cách đó
Những người thích đi từ cái chung đến cái cụ thể vốn đã bị giáo dục tiểu học và trung học phần lớn phớt lờ, và có khi phải đến giáo dục đại học mới bắt đầu thấy hợp. Họ đã bị xa lánh đủ rồi, nên không cần phủ nhận luôn cả sự tồn tại của họ
Tôi không hiểu được sắc thái của việc khi nào phải làm gì, cái gì phải làm hoàn toàn đồng thời và cái gì phải làm ngay sau đó. Lúc ấy bố bạn gái tôi giải thích ngắn gọn côn thực sự làm gì, việc nối bánh xe với động cơ ảnh hưởng đến hai phía ra sao
Ngay khoảnh khắc đó tôi hiểu luôn, và không cần nghe chỉ dẫn phải làm gì trong từng tình huống cụ thể nữa. Khoảng 20 phút sau, tôi đã có thể lái xe bằng số sàn trong tình huống được cho là khó nhất: khởi hành bằng phanh tay trên dốc nghiêng về phía sau. Với một số người, hiểu cách hoạt động từ nguyên lý đầu tiên hữu ích hơn nhiều, và tôi nghĩ trong giới kỹ sư phần mềm có khá nhiều “một số người” như vậy
Nếu trong ví dụ có phần gây ngạc nhiên, nghĩa là mô hình của tôi vẫn chưa hoàn chỉnh. Hoặc là ví dụ sai
Không phải “điều chúng ta muốn đạt được là thế này, cái này hoạt động như thế này, và chúng ta làm như thế này”, mà thứ luôn được phơi ra cho người thực thi chỉ là “chúng ta làm như thế này”. Chỉ cần khác đi một chút là không thể suy luận, điều chỉnh và giải quyết vấn đề
Với các công việc được làm thường xuyên thì cũng có tài liệu ở mức nào đó, nhưng thường đã cũ hoặc không đầy đủ. Nó không phải wiki nên không phải ai cũng có thể sửa bất cứ lúc nào, và muốn sửa tài liệu phải qua một quy trình khó chịu, nên rốt cuộc nó không được cập nhật. Nghĩ lại thì khá giống thời tôi còn trong quân đội
Hiện giờ tôi cũng đang gặp chuyện đó khi dành thời gian học Drizzle ORM. Những tài liệu đầu tiên tôi tìm được toàn là “sáu ví dụ truy vấn”, và tôi bực vì không biết tại sao lại dùng cú pháp đó, các lựa chọn khác là gì. Tôi thấy thoải mái hơn nhiều với cách của mình: đóng những tài liệu đó lại, đọc mọi trang trong tài liệu rồi mới làm gì đó
Tôi không biết giờ mình còn làm được theo thời gian thực không. Cách này dùng khá nhiều chu kỳ suy nghĩ, nên hiện tại tốc độ đọc chữ hoặc tạm dừng video để xử lý phù hợp với tôi hơn
Tôi thường bất chợt phải dạy những người vẫn chưa hiểu. Khi có một lý thuyết về hệ thống, bạn có thể trả lời cả những câu hỏi mà bạn cùng lớp mới chỉ vượt qua mức học thuộc lòng đơn giản không trả lời được
Đây là một câu trong Code Complete: “Một phần nhỏ của công việc lập trình là viết chương trình để máy tính có thể đọc được, còn phần lớn hơn là viết để những con người khác có thể đọc được.” trang 733
Nó vẫn đọng lại trong trí nhớ gần 20 năm
Câu này xuất hiện trong lời tựa ấn bản đầu tiên của Structure and Interpretation of Computer Programs của Abelson và Sussman, và có trước Code Complete 10 năm
Đây là châm ngôn mà tôi cố gắng tuân theo, nhưng kỳ lạ là các nhà tuyển dụng dường như luôn khăng khăng vào phần máy tính thực thi
Hơi lạc đề một chút, nhưng vài ngày trước khi làm một game Unity, tôi đã nghĩ rằng IDE trong 10–20 năm qua dường như thật sự không tiến bộ được bao nhiêu
IntelliSense cơ bản chắc chắn đã tốt hơn rất nhiều, nhưng ngoài vài điểm nhỏ khác, toàn bộ khái niệm viết code trông gần như vẫn giống ngày xưa
Thay đổi tích cực lớn nhất nằm bên ngoài trình soạn thảo. Việc tiếp cận thư viện và tài liệu đã dễ hơn nhiều, số lượng câu hỏi và câu trả lời của người dùng tăng lên khổng lồ, và thỉnh thoảng còn có những công cụ mới như ChatGPT tổng hợp các câu trả lời đó để đưa ra một câu trả lời có vẻ hợp lý
Nhưng nhìn chung, hành vi viết code có vẻ bị đình trệ. Vì vậy hiện giờ tôi tạm dừng làm game và đang thử vài thí nghiệm. Tôi không muốn tạo một ngôn ngữ mới, mà muốn giao mọi việc lặt vặt có thể cho máy tính để tập trung vào sáng tạo
Ba thứ đầu tiên tôi muốn thử là như sau. Tại sao tôi phải bận tâm đến những chi tiết nhỏ của ngôn ngữ như ngoặc hay ký tự kết thúc; công cụ không thể tự hoàn thành chúng sao? Các modifier như chuỗi truy cập private-public hay unsafe cũng không thể để công cụ tự quyết định tập hợp hiệu quả nhất sao? Khi tập trung vào khoảng 5 phương thức tương tác với nhau, tôi muốn thấy tất cả trên một màn hình mà không phải mở nhiều cửa sổ và vật lộn với thanh trượt ngang/dọc của VS. Nếu tôi đã tạo một HashSet rồi cần đổi sang Dictionary hay Tuple thì cứ đổi giúp, chỉ hiển thị những chỗ cần phán đoán để tôi phê duyệt hoặc tự sửa. Trong Unity, tôi cũng muốn có thể nhấp vào một phương thức hay tập dữ liệu và ra lệnh chuyển nó thành Burst Job cùng tập NativeData đi kèm
Nhưng rốt cuộc tất cả đều là trừu tượng, và chúng ta chỉ đang viết lệnh để một cỗ máy cực kỳ ngu ngốc tính toán dữ liệu mà thôi
Bạn nói chẳng phải công cụ có thể tự hoàn thành ngoặc hay ký tự kết thúc sao, nhưng máy tính thật sự rất đơn giản, còn ngôn ngữ lập trình là kênh để truyền đạt ý nghĩ trong đầu. Những ký tự phân tách như vậy quan trọng ngang với từ khóa của ngôn ngữ. Vì chúng là một phần của quy tắc. Muốn tự hoàn thành chúng thì cần nhiều quy tắc hơn và nhiều ký tự phân tách hơn
Nếu muốn thấy nhiều phương thức tương tác với nhau trên một màn hình, có Vim và Emacs, hoặc IDE Smalltalk như Pharo
Việc chuyển đổi dữ liệu có thể làm bằng macro của Vim và Emacs. Nhưng sự thật là mã hóa dữ liệu rất quan trọng. Đối với máy tính thì tất cả đều là bit, còn chúng ta gán ý nghĩa cho các bit đó và tạo ra các quy tắc thao tác theo ý nghĩa ấy. Muốn đổi hình thái từ một tập quy tắc sang một tập quy tắc khác thì cần thêm quy tắc
Tôi khuyên nên thử môi trường lập trình trực tiếp. Chẳng hạn như SLIME của Common Lisp, Pharo của Smalltalk, hay trình kiểm tra web của JavaScript. Cảm giác giống như làm việc trên một con tàu đang ở giữa biển, thay vì đặt con tàu trên đất liền rồi tưởng tượng việc đi biển sẽ ra sao
Phần khó nhất trong lập trình là suy nghĩ và học hỏi. Gõ nhanh hơn cũng không giúp ích được nhiều
Ví dụ khi viết chương trình C, có thể cho “f” mở rộng thành “for (=; <=; ++) {;}” hoặc theo kiểu thụt lề ưa thích
Nhiều trình soạn thảo lập trình hiện đại cũng hỗ trợ cấu hình người dùng tương tự, nhưng đáng tiếc là trong nhiều trường hợp quy trình lại phức tạp hơn rất nhiều so với thời xa xưa
Nếu là một ngôn ngữ lập trình có cú pháp dài dòng, tôi nghĩ cần dành thời gian định nghĩa các template trong trình soạn thảo để có thể viết nhanh bất kỳ cấu trúc chương trình nào với số lần gõ phím tối thiểu
Vấn đề nên dùng HashSet, Dictionary hay Tuple có ảnh hưởng đến hiệu năng, và về mặt trừu tượng không phải lúc nào cũng rõ nên dùng cái nào. Với các ngôn ngữ tường minh như Java, và có lẽ C# cũng vậy, có thể refactor để lời gọi phương thức nhận kiểu khác. Khi đó chỉ cần đổi một phương thức rồi refactor tất cả các lời gọi của nó
Tôi đã thử Gemini pro và ChatGPT o1, cả hai đều viết code Python và JavaScript thật sự kém. Chúng viết code có bug, và thường khi sửa một bug lại đưa bug khác vào. Cả hai có cảm giác vội đưa ra câu trả lời hơn là suy nghĩ về yêu cầu. Tôi nghĩ vẫn còn khá xa mới có công cụ “đọc được suy nghĩ” hoặc hiểu điều gì quan trọng và không quan trọng theo cách chúng ta muốn
Điều có thể còn tệ hơn là dữ liệu huấn luyện. Vì phần lớn code được tạo bởi các coder dưới trung bình và trung bình, những công cụ này sẽ tiếp nhận kiểu tư duy của coder trung bình. Ngay cả khi chỉ huấn luyện bằng code chất lượng cao nhất, cũng không rõ liệu đa số coder có thể prompt đúng hay không. Vì vậy nếu bạn đã viết code 10–20 năm, khả năng cao là bạn sẽ luôn hơi thất vọng với một công cụ nếu kỳ vọng phép màu tức thì
Dù vậy, các công cụ phân tích tĩnh không dùng AI đã rất tuyệt vời từ lâu và sẽ còn tốt hơn. Nếu thêm AI vào đó, chúng có thể được cải thiện hơn nữa. Nếu xem công cụ là thứ giúp mình trở thành nghệ sĩ, chứ không phải một nghệ sĩ để mình ném đặc tả vào rồi nhận về kết quả ổn, tôi nghĩ bạn có thể có trải nghiệm tuyệt vời
Thử nói với AI những việc bạn muốn trình soạn thảo làm thêm và nhờ nó giúp cấu hình cũng có thể thú vị. Trong các plugin có nhiều công cụ không dùng AI. Dùng mô hình ngôn ngữ lớn để chọn plugin phù hợp với lối làm việc của mình có thể là cách hiệu quả nhất
https://haystackeditor.com/
Tôi chưa tự dùng, nhưng đang định thử
Tiêu đề bài viết có thể gây tranh cãi. Vì code chỉ được viết cho con người. Máy tính không cần “code”, đặc biệt càng không cần code bậc cao. Với máy tính, lệnh máy là đủ
Lý do chúng ta viết code là vì lệnh máy quá khó để con người viết, và còn khó đọc hơn nữa
Không nên nghĩ code là cách tương tác với máy tính. Code là cách con người hình thức hóa suy nghĩ, khiến chúng trở nên không mơ hồ đến mức ngay cả máy móc cũng có thể làm theo
Tự quảng bá một cách vị tha bài blog tôi đã viết và chia sẻ tuần trước
Move Fast & Document Things [1]
Tôi không định viết một bài mang tính triết lý, mà muốn chia sẻ các mẹo thực tế về cách đội ngũ nhỏ của chúng tôi [2] buộc thực thi văn hóa viết code cho chính mình và cho nhau thông qua việc review sâu và khó, chứ không phải bằng tự động hóa hay AI
Những người bạn cá nhân đang làm lãnh đạo kỹ thuật ở các tổ chức khác đều nói: “Chúng tôi cũng làm y như vậy, nhưng bạn đã thực sự viết nó ra.” Nếu thấy có giá trị thì mong mọi người đề xuất
[1] https://olshansky.substack.com/p/move-fast-and-document-thin...
[2] https://github.com/pokt-network/poktroll/graphs/contributors
“Quá nhiều sách và tutorial lập trình đi theo kiểu ‘hãy xây một ngôi nhà từ đầu, từng viên gạch một’, trong khi thứ tôi muốn là ‘đây là một ngôi nhà đang hoạt động, hãy thử thay đổi gì đó và xem chuyện gì xảy ra’”
Tôi đã tự học lập trình theo cách đó. Tôi đã dành nhiều năm để sử dụng thành thạo những chương trình nhỏ, đơn giản và hơi tệ
Về sau tôi nhận ra mình không phù hợp với các công việc phát triển phần mềm tốt hơn, vì tôi hoàn toàn không có kiến thức nền tảng về thiết kế phần mềm, ngôn ngữ lập trình và máy tính. Vì không học theo cách nhàm chán, việc bước ra khỏi phòng phỏng vấn và nhận ra mình không biết nhiều đến mức nào là một trải nghiệm khiến tôi khiêm tốn hơn
Luôn đọc toàn bộ tài liệu hướng dẫn, và luôn học các kiến thức nền tảng
Toàn bộ code của tôi đều viết cho con người
Dù con người đó là tôi, hay một ai đó tội nghiệp vài năm sau phải tìm hiểu ý định của tôi, thì cũng vậy
Tôi cho rằng bản thân việc viết code không khó. Phần thể hiện tài năng nằm ở việc suy luận toàn diện về vấn đề, cộng tác với các bên liên quan khác để tìm ra con đường tốt nhất và dẫn dắt họ, học các kỹ năng chuyên môn như toán học mới hoặc thông lệ trong ngành, nghĩ ra các thuật toán hiệu quả, và truyền đạt sao cho cấu trúc cùng pattern của chương trình có ranh giới rõ ràng, thanh nhã
Rốt cuộc, rất nhiều thứ phụ thuộc vào giao tiếp và sự rõ ràng
Một phần lớn bài viết này nói về tài liệu hóa, và sẽ rất hữu ích nếu tham chiếu mô hình 4doc: https://docs.divio.com/documentation-system/
Về cơ bản, ý là đừng chỉ cung cấp tài liệu tham chiếu, mà hãy cung cấp cả tài liệu hướng dẫn sử dụng. Và vì đó thường là phần người dùng muốn xem trước trong toàn bộ tài liệu, hãy đưa nó lên trước
Tất nhiên đó là nói chung; còn tôi thì thường đi thẳng tới tài liệu tham chiếu, nhưng không phải lúc nào cũng vậy
Điều đó không có nghĩa 4doc là lời giải vạn năng hay một quy luật tự nhiên. Hillel Wayne cũng bàn rất rõ các vấn đề của nó ở đây: https://www.hillelwayne.com/post/problems-with-the-4doc-mode...