Hurl, ngôn ngữ lập trình ngoại lệ
(hurl.wtf)- Hurl là một ngôn ngữ lập trình thử nghiệm xây dựng luồng điều khiển chỉ bằng xử lý ngoại lệ, thay vì các nhánh hay vòng lặp thông thường
- Nó bắt đầu từ cuộc trò chuyện giữa Nicole Tietz-Sokolskaya và những người bạn ở Recurse Center, và trang web cung cấp tài liệu cách dùng, ví dụ, hướng dẫn gỡ lỗi và phần hỏi đáp
- Các lời giới thiệu trên trang mở đầu như “monstrosity is beautiful”, “Certified unhinged™” cố ý đẩy mạnh bầu không khí mang tính đùa cợt
- Hurl và mã nguồn của trang web được công khai, nhưng để gửi bản vá qua email thì cần chuyển nhượng quyền đối với bản vá
- Giấy phép được cung cấp theo lựa chọn giữa AGPL-3.0, GAL-1.0 và giấy phép thương mại
Thử nghiệm ngôn ngữ chỉ giữ lại xử lý ngoại lệ
- Hurl được tạo ra vì một mục đích: khám phá xem liệu có thể tồn tại một ngôn ngữ được cấu thành chỉ từ luồng điều khiển dựa trên xử lý ngoại lệ hay không
- Ý tưởng xuất phát từ cuộc trò chuyện giữa Nicole Tietz-Sokolskaya và những người bạn ở Recurse Center; danh tính các bạn này không được tiết lộ “để giữ thể diện”
- Trang web cung cấp tài liệu sử dụng Hurl, ví dụ, hướng dẫn gỡ lỗi và phần hỏi đáp
Trông như trò đùa nhưng là dự án được công khai thật
- Trang giới thiệu đăng các lời nhận xét thể hiện đúng tính chất của Hurl
- “This monstrosity is beautiful, and I must never touch it”
- “Certified unhinged™!”
- “is "🤮" an available quote?”
- Nếu muốn đưa thêm lời nhận xét, bạn phải gửi email cho Nicole và cần có sự đồng ý rõ ràng về việc đưa trích dẫn vào
Mã nguồn và điều kiện giấy phép
- Mã nguồn của ngôn ngữ Hurl và của trang web này được công khai tại Hurl's repo
- Nếu phát hiện bug hoặc lỗi, bạn có thể gửi bản vá qua email, nhưng phải chuyển giao mọi quyền đối với bản vá đó
- Đây là điều kiện để duy trì khả năng cấp phép lại và cấp phép thương mại
- Dự án có thể được sử dụng theo một trong ba giấy phép sau
-
AGPL-3.0
- GAL-1.0: Gay Agenda License
- Giấy phép thương mại
- Trong quá trình xem xét giấy phép, dự án cũng đã cân nhắc joke licenses và unfortunate licenses, nhưng cuối cùng chọn ba giấy phép trên
-
1 bình luận
Các ý kiến trên Hacker News
Nếu thiết kế một ngôn ngữ lập trình, có lẽ nên bắt buộc include/import phải có namespace, và nếu có thể thì cũng nên chặn các side effect ở cấp cao nhất
Nhận kiểu
let foo = include "lib/foo.hurl"rồi gọifoo.init()sẽ dễ suy luận hơn nhiềuNgược lại, nếu sau
include "lib/foo.hurl" // side effectslại xuất hiệnbaz(buz), sẽ khó biết hàm và biến đó thuộc thư viện chuẩn hay được include từ đâu đóimport "foo/bar"nên cho phép dùngfoo.*hoặcbar.*, chứ không nên xuất hiệnbazz.*. Nghĩ ngay đến GoVSCode cũng làm được tương tự bằng plugin và LSP, nhưng kém hơn nhiều. Việc điều hướng code quá chậm nên mình không thể làm việc bằng VSCode
Mình tự hỏi những đề xuất như vậy chỉ hữu ích khi không có các công cụ đó hay không. Ít nhất trong môi trường chuyên nghiệp, sống thiếu những công cụ như vậy có vẻ là bất khả thi
foo.init(), còn import trần thì không thểNói vậy không có nghĩa dự án này vô giá trị; ngược lại, mình xem nó như một tác phẩm nghệ thuật
Mình từng fork Ruby để làm cho
requirekhông ghi đè bảng symbol, nhưng có vẻ hệ sinh thái Ruby phụ thuộc quá nhiều vào trạng thái mutable toàn cục dùng chung, nên cuối cùng mình mất hứng thú với chính RubyException luôn khiến việc nắm bắt hợp đồng giữa caller và callee trở nên khó hơn, đồng thời làm tăng độ coupling của code, nên mình chưa bao giờ thích
Mình thích cách xử lý bằng giá trị trả về như Go hay Rust hơn. Khi lướt qua ngôn ngữ này, mình không chắc có yếu tố nào giải quyết vấn đề đó không
Nếu IDE có thể động xác định tất cả exception chưa được bắt của một hàm, và cho nhảy đến những vị trí exception có thể được ném ra, thì mô hình này cũng có thể ổn. Nhưng mình không biết sẽ xử lý coupling thế nào, và có vẻ control-flow graph sẽ cực kỳ bất ổn
Tuy nhiên trong Java, trừ khi kế thừa
RuntimeException, các exception mà hàm có thể ném là một phần của chữ ký hàm. Trong trường hợp đó, nếu ném exception mà không thêm vào chữ ký thì sẽ không biên dịchĐiều kiện của Java khiến IDE dễ báo cáo exception chưa được bắt hơn nhiều, nhưng nếu không phải runtime exception thì đây là vấn đề có thể giải bằng phân tích tĩnh
Ngược lại, cách trả về giá trị bọc
Ok/Errđã chuẩn hóa có vẻ đơn giản hơn cả về hỗ trợ công cụ lẫn sự tiện lợi cho lập trình viênKhác biệt duy nhất là với cách truyền exception, phần boilerplate code mà compiler sẽ làm hộ thì bạn lại phải tự viết bằng tay
Mình thật sự không thể hiểu nổi vì sao vào năm 2024, một người đầu óc hoạt động bình thường lại muốn tự tay làm việc đó
Trong thời gian dùng nó, việc tìm nguyên nhân gốc khi không có debugger đau khổ hơn nhiều
Ví dụ
tossnói rằng “chủ yếu dùng để truyền nhiều giá trị ra khỏi hàm, không thật sự cần thiết nhưng dễ thương”, nhưng nó hoàn toàn không vô dụng; đây là một cách triển khai generator có thể tiếp tụcTất nhiên, nếu muốn nó làm việc khác ngoài việc tiếp tục ngay lập tức thì có thể khá thú vị. Chỉ cần tổ chức toàn bộ codebase thành stack bên trong-bên ngoài của
tosslà đượcreturnphải được scope theo lexical về phía handlerVí dụ trong Python, có thể gọi
next()ở bất cứ đâuCái này gần với việc truyền callback qua một kênh phụ hơn.
tossgọi callback đó, cònreturntheo đúng nghĩa là trả về từ đóMột tính năng thật sự hữu ích trong ngôn ngữ khác lại được đối xử ở đây như một tính năng dễ thương có thể bỏ đi, khiến mình hơi tự hỏi có phải đây là một trò đùa không
yieldcủa C# không?Hurl trông khá gần với condition system kiểu Smalltalk hoặc Common Lisp
Unwinding stack và resume chỉ là hai trong số các restart khả dĩ: https://gigamonkeys.com/book/beyond-exception-handling-condi...
Tách khỏi bản thân dự án, mình tin chắc rằng thế giới sẽ tốt đẹp hơn nếu nhiều thứ hơn dùng đuôi .wtf cho domain
Điều này nghe giống một dạng yếu của algebraic effects, nhưng vẫn rất thú vị khi thấy những ngôn ngữ như thế này và những gì có thể làm với chúng
Nếu algebraic effects về cơ bản giống từ khóa
tosscủa Hurl, thì mình tò mò nó mạnh hơntossở điểm nàoMột thử nghiệm tư duy thú vị
Mình thật sự ghét exception, và muốn một ngôn ngữ không có exception
Exception là
gotocủa thời đại chúng taKhi đã có
Maybe/OptionvàEffect/Result, gần như không còn lý do gì để ném exception rồi phải lần theo trong đầu xem nó được xử lý ở đâuMình hơi lo rằng algebraic effects sẽ phổ biến hơn, và sẽ ảnh hưởng cả đến frontend JS vốn đã quá phức tạp. Vì nó khuyến khích cách ném “exception” để flow control
Nếu tất cả những thứ này nhằm tránh vấn đề màu sắc async/sync, thì cá nhân mình thấy hoàn toàn không đáng
Chà, mình không thích cái này. Nhưng kỳ lạ là nó gần như có một vẻ thanh nhã
Rất khó mô hình hóa trong đầu, nhưng vẫn là vậy
Nói nghiêm túc hơn một chút, mình muốn có các cú pháp
catchkhác nhau cho exception có thể resume và exception không thể resume. Như vậy sẽ loại bỏ sự mơ hồ cú pháp về việcreturncó chuyển luồng điều khiển về phía đã ném exception tức thời gần nhất hay khôngVà thư viện chuẩn không nên chạy trốn sang các hàm trả về giá trị thông thường. Không có lý do gì để không ăn món mình tự nấu chỉ vì ăn thử thấy ợ nóng
Mình hiểu đúng là thứ bị
hurlthì có thể bắt, còn thứ bịtossthì không thể bắt phải không? Chắc sẽ mất một thời gian để quenMình cũng hơi lo không biết phải viết bao nhiêu Hurl thì mọi người bắt đầu gọi mình là tosser
Tossnghe như một cấu trúc ngôn ngữ thú vị. Nó đi ngược lên stack để tìm exception handler, rồi quay lại vị trí ban đầu và tiếp tục thực thi như chưa có gì xảy raCó vẻ có thể dùng cấu trúc này để tiêm hành vi bổ sung vào runtime
Trong code hướng đối tượng thông thường, dependency injection được thực hiện qua constructor của service, còn
tosscó cho phép làm điều đó bằng “toss handler” không?https://koka-lang.github.io/koka/doc/book.html#why-handlers
Mình không biết nhiều, nhưng biết rằng nó cho phép tiêm hành vi vào runtime theo kiểu này
Resume Nextcủa VB