2 điểm bởi GN⁺ 2023-09-29 | 1 bình luận | Chia sẻ qua WhatsApp
  • Trong cấu hình DevOps và CI, YAML được dùng gần như một tiêu chuẩn, nhưng do ép kiểu ngầm định và khác biệt giữa các parser, cùng một cấu hình vẫn có thể bị diễn giải khác với dự đoán
  • Trong YAML 1.1, các giá trị như NO, 07, 08, 04:30, 0666 có thể bị đổi thành boolean, số, thời gian, bát phân, nên cần làm rõ ý định chuỗi
  • Các ví dụ từ GitHub Actions, Kubernetes, CloudFormation và nhiều dịch vụ CI cho thấy cú pháp YAML và cấu trúc riêng của từng dịch vụ có thể dẫn tới commit lặp đi lặp lại, lồng escape, và cách biểu diễn job không thống nhất
  • Các liên kết tham khảo gom lại những nội dung như YAML có thể thực thi, khác biệt hành vi theo từng parser, ký pháp chuỗi nhiều dòng, vấn đề phiên bản 1.70 bị parse thành 1.7, và cơ sở thiết kế của StrictYAML
  • Các lựa chọn thay thế như Nickel, Dhall, CUE, Jsonnet cũng được đưa ra, nhưng bản thân trang này lại trông như một trường văn bản khổng lồ có thể chỉnh sửa, tiếp tục giữ nguyên chất châm biếm về tính khả dụng của YAML

Châm biếm YAML như một ngôn ngữ cấu hình DevOps

  • YAML thường được dùng trong cấu hình DevOps, nhưng trang này bộc lộ sự mệt mỏi với YAML bằng những câu kiểu như “không ai thực sự muốn dùng YAML”
  • Trang liệt kê một cách mỉa mai các lý do dùng YAML như một công nghệ DevOps
    • Châm biếm rằng nó luôn có thể compile và triển khai
    • Mỉa mai việc không có xử lý lỗi cưỡng bức trong lúc phát triển, và sự cố chỉ bùng ra khi runtime ở production
    • Nói kiểu rằng thông báo “có gì đó bị hỏng” còn tốt hơn stack trace có số dòng
    • Thể hiện sự bực bội vì phải đốt thời gian mỗi khi tạo một pipeline CI mới
    • Châm biếm tình huống nó được xem như lựa chọn an toàn chỉ vì Kubernetes dùng nó
    • Đồng thời cũng nhắc tới ưu điểm là hỗ trợ comment, khác với JSON

Những cái bẫy do ép kiểu ngầm định tạo ra

  • Trong YAML 1.1, NO có thể được parse thành kiểu boolean
    • NO: Norway có thể gây ra vấn đề diễn giải boolean thay vì mã quốc gia
    • Nếu muốn là chuỗi thì phải bọc trong dấu nháy như "NO"
    • Trang chỉ ra rằng trong đặc tả YAML 1.1 có tới 22 cách để viết true hoặc false
  • Các giá trị trông giống số cũng có thể được parser hiểu khác nhau
    • Ví dụ 0708 cho thấy kết quả có thể khác nhau như [ 7, "08" ]
    • Điều này được châm biếm thành việc cụm Kubernetes triển khai được tới bản thứ bảy rồi hỏng ở bản thứ tám
  • Chuỗi trông giống thời gian cũng là đối tượng bị chuyển đổi tự động
    • 04:30 có thể bị đổi từ chuỗi thời gian người dùng viết thành giá trị 16200 là số giây sau nửa đêm
    • Nếu muốn là chuỗi thì phải chỉ rõ như !!str 04:30
  • Khác biệt về ký pháp bát phân trong YAML cũng gây rối
    • YAML 1.1 dùng dạng 0666
    • YAML 1.2 dùng dạng 0o666
    • Việc Kubernetes dùng YAML 1.1 được nói như một “nghi thức trưởng thành của DevOps”

Vấn đề xử lý phiên bản, SHA và chuỗi

  • Phiên bản gói có thể bị parse như số thực
    • foo: 1.7bar: 1.70 có thể bị hiểu là cùng một phiên bản
    • fizz: 1.7.0buzz: 1.70.0 lại có thể được xử lý như các chuỗi phiên bản khác nhau
  • Git SHA ngắn dùng trong CI cũng có thể không an toàn
    • SHA 8 ký tự có thể toàn là số
    • my.flaky_version chèn ${GIT_SHORT_SHA} mà không có dấu nháy có thể không còn là chuỗi
    • Trang nêu rằng giá trị này là chuỗi khoảng 98% số lần, còn nếu bọc như "${GIT_SHORT_SHA}" thì là chuỗi 100%
  • Ví dụ về Rust toolchain cũng được đưa vào phần liên kết tham khảo

Chi phí bộc lộ trong cấu hình CI và hạ tầng

  • Có ví dụ kể rằng khi học GitHub Actions, tác giả đã commit/push 8 lần trong một giờ, và message commit cuối cùng là “I don't really like yml”
  • Trang cũng đưa ra ví dụ nếu viết SQL bằng YAML sẽ trông như thế nào
    • Các cấu trúc SQL như SELECT, FROM, WHERE EXISTS, AND, EQUALS, LT bị chuyển thành cấu trúc lồng nhau kiểu YAML
    • Điều này châm biếm việc một biểu thức SQL ngắn lại biến thành dạng YAML dài dòng và rườm rà
  • Cách biểu diễn job và step cũng khác nhau giữa các dịch vụ CI
    • Azure DevOps dùng dạng jobs bên dưới là job, steps, script
    • CircleCI dùng dạng jobs, job1, steps, checkout, run
    • Ví dụ về “hệ thống CI của tương lai” cho thấy cùng một tác vụ có thể lại được biểu diễn bằng một cấu trúc lồng khác nữa
  • Với CloudFormation, khi đặt hàm SEARCH bên trong DashboardBody của CloudWatch, có ví dụ phải escape lại nội dung vốn đã được escape và đóng toàn bộ JSON trong dấu nháy kép

YAML có thể thực thi và khác biệt giữa các parser

Tài liệu liên quan và các lựa chọn thay thế

Phản ứng với chính trang web

  • Tổng hợp phản ứng trên Reddit cũng chỉ trích cả thiết kế của trang
    • Có ý kiến cho rằng website trông như một trường văn bản khổng lồ có thể chỉnh sửa
    • Có phản ứng nói rằng không thể bấm vào hyperlink
    • Có câu đùa rằng có thể chọn toàn bộ văn bản của trang rồi xóa đi là vấn đề được giải quyết
    • Có phản ứng nói rằng đồng ý với tinh thần ghét YAML nhưng thấy quyết định thiết kế website vẫn khó hiểu
  • Câu cuối cùng nói rõ rằng trang được cố ý làm cho “có thể dùng ngang với YAML”

1 bình luận

 
GN⁺ 2023-09-29
Các ý kiến trên Hacker News
  • Rắc rối “ưa thích” nhất của tôi là cái này:
    07
    08
    Kết quả trở thành [ 7, "08" ]
    Vì giả định về số bát phân và chuỗi
    Giả định này được phát hiện trong YAML được tạo bằng template ở sâu bên dưới ba tầng, và dẫn tới sự cố toàn bộ cụm k8s của chúng tôi, nhưng chỉ cụm 08 bị hỏng. 7 cụm trước đó vẫn chạy tốt

    • Tôi là người tạo website này. Nếu bạn gửi cái này thành pull request thì tốt quá
    • Chết tiệt, có lẽ phần lớn lập trình viên ngày nay không biết số bát phân hay literal số bát phân viết với tiền tố 0
      Đọc bình luận này tôi có cười, nhưng xét việc gần như chẳng ai dùng số bát phân trong file cấu hình vào năm 2023, hành vi và giả định như vậy thật vô lý. Nếu là thập lục phân thì còn hiểu được, thập phân thì hiển nhiên, còn bát phân thì hơi quá
    • Tôi không hiểu làm sao đây có thể là hành vi đúng được
    • Việc “phát hiện” giả định đó có nghĩa là họ không đọc đặc tả mà bắt đầu dùng vì tưởng mình biết hành vi à?
      Phía tạo ra thứ đó chắc chắn đã không tuần tự hóa dữ liệu bằng thư viện. Nếu dùng thư viện thì nó đã chuyển kiểu sang định dạng đúng rồi
  • YAML có nhiều vấn đề, nhưng tôi nghĩ vấn đề cốt lõi thật sự nằm ở việc cố nhét logic vào cấu hình
    Nếu chỉ dùng YAML cho dữ liệu chứ không dùng cho logic, nó là một trong những định dạng dữ liệu dễ đọc và dễ viết đối với con người
    CI/CD luôn có một mức logic nào đó, hiếm khi chỉ thuần YAML là xong, lại còn trộn cả template kỳ quặc. Tôi tự hỏi sao không cung cấp một API thật sự cho một ngôn ngữ lập trình thật sự

    • Đó không phải là vấn đề của YAML mà gần với lạm dụng YAML hơn. Turing-complete một cách tình cờ thì ở đâu cũng là vấn đề
      15 năm trước khi dùng Ant dựa trên XML cũng có cùng vấn đề, và đó không phải lỗi của XML
      Tôi nghĩ vấn đề chính của YAML là thiếu an toàn kiểu. Những thứ như thụt lề sai, gõ nhầm khóa, chuỗi bị parse thành boolean
      Ngoài ra, tôi nghĩ đây là một định dạng tốt vì ngắn gọn và ít nhiễu cú pháp hơn nhiều so với các định dạng khác. Vì vậy tôi đã tạo https://github.com/crdoconnor/strictyaml để mọi người dùng YAML an toàn kiểu và nhận được thông báo lỗi tức thì, rõ ràng cho các vấn đề như vậy
    • Theo kinh nghiệm của tôi, ngôn ngữ càng làm được nhiều thứ, người ta càng dùng nó theo cách phức tạp hơn
      Vì họ kéo các trừu tượng vào vì nghĩ rằng mình cần chúng. Do đó tôi luôn tránh dùng ngôn ngữ lập trình Turing-complete làm định dạng cấu hình
      Tôi từng mất vài giờ bước từng dòng qua AWS CDK bằng JavaScript debugger. Nếu đó chỉ là một file yaml/Json/gì cũng được đơn giản và ngớ ngẩn thì đã không có vấn đề đó. Đó là một dự án nhỏ và không cần độ phức tạp ấy
      Vì vậy trong cấu hình công cụ JS tôi cũng thích JSON hơn JS. Đây cũng là lý do cấu hình webpack trở nên hỗn loạn. Khi được dùng ngôn ngữ thật, “cảm biến DRY” của mọi người sẽ kích hoạt và làm mọi thứ phức tạp hơn
      Nếu là khai báo, việc tuân theo thực hành chuẩn cũng dễ hơn và hỗ trợ công cụ tốt hơn. Nếu package.json thật sự trở nên giống build.gradle thì sẽ tệ hơn nhiều
    • Cấu hình có thể thực thi có thể mang lại lợi ích lớn. Python là lựa chọn hiển nhiên
      Chỉ cần quy định rằng “chạy script trong một trình thông dịch Python bên trong cgroup bị giới hạn chặt, và kết quả phải là một dictionary tên CONFIG”. Logic wrapper sẽ tuần tự hóa nó theo cách thuận tiện cho chương trình đích cần cấu hình
    • Tôi không hiểu vì sao thiết kế schema tệ lại là lỗi của YAML chứ không phải của người thiết kế schema
      Nó giống như phàn nàn về độ phức tạp hay cứng nhắc của helm. Helm chart không tự viết ra. Có lẽ vì phàn nàn và phớt lờ dễ hơn là hiểu vấn đề rồi triển khai
    • Đồng ý 100%. Khi mọi người nói họ ghét YAML, tôi nghĩ trong nhiều trường hợp ý thật sự gần với “tôi ghét mô tả pipeline bằng YAML”. Tôi cũng hiểu cảm giác đó
      Là một định dạng file, YAML có ưu và nhược điểm. Nhưng vấn đề thật sự là cố biểu diễn những thứ như điều kiện, vòng lặp, hàm, lớp/lớp con thông qua template trong một định dạng file tương đương JSON
      YAML ổn cho các cấu hình nhỏ. Nhưng ngay khi cần bất kỳ loại luồng điều khiển nào, nó rất nhanh phình thành spaghetti theo từng vendor
  • Jinja trong YAML rõ ràng là một anti-pattern
    Có vẻ ngay từ đầu nó đã không được thiết kế với đủ khả năng lập trình, rồi về sau mọi người bắt chước các dự án đã chọn con đường đó và thành công
    Bài viết có nhắc đến các lựa chọn thay thế như Dhall và Jsonnet, nhưng có thể nghĩ thêm hai hướng nữa
    Thứ nhất là tạo một thư viện cấu hình cho một ngôn ngữ lập trình thực thụ, và để thư viện này sinh ra file cấu hình JSON. JSON đó không phải thứ để chỉnh tay, mà chỉ được xem như một artifact có thể kiểm tra. Người dùng sẽ đưa cấu hình dưới dạng code, có hỗ trợ công cụ, vào quản lý phiên bản. Việc khó hotfix trực tiếp trên server vừa là nhược điểm vừa là ưu điểm
    Thứ hai là Starlark. Đây là một ngôn ngữ phái sinh từ Python, không Turing-complete, ban đầu được phát triển cho hệ thống build Bazel. Có nhiều implementation và tôi không rõ mức độ tương thích sâu đến đâu, nhưng cũng có binding cho Python: https://github.com/caketop/python-starlark-go, https://github.com/inducer/starlark-pyo3

    • Tôi đồng ý rằng Jinja trong YAML là anti-pattern, nhưng đặc biệt là vì các ký tự block/expression mặc định {%{{ đều là ký tự YAML, nên mọi chỗ dùng đều phải được đặt trong dấu ngoặc kép
      Tôi thấy các cách như ${{ của GitHub Actions, hay <%, << tốt hơn nhiều. Tất nhiên có rủi ro là <<: là cú pháp YAML, nhưng nó không phải Jinja hợp lệ
      Nếu ý là không nên nhét bất cứ thứ gì có thể thực thi vào YAML, thì tôi nghĩ con thuyền đó đã rời bến rồi. Vì mọi người đã nhận ra rằng cách để phần literal làm mặc định và thỉnh thoảng chỉ chèn phần thực thi vào rất tiện để tạo nội dung, giống ASP/JSP/PHP
      Nếu muốn khơi mào một cuộc flame war anh em trong thread này thì chỉ cần nói về HCL và for_each, nhưng ít nhất ở đây thì tốt nhất là đừng
    • Đây là con đường Amazon đã chọn với CDK. Nó hoạt động ở một mức nào đó, nhưng nếu muốn làm việc không tầm thường thì rất dễ có cảm giác như đang chế một cỗ máy Rube Goldberg
      Tôi không rõ trong đó bao nhiêu là lỗi của CDK và bao nhiêu là do CloudFormation vốn đã không hay
    • Đồng ý. Việc làm YAML có template quá phiền phức nên cuối cùng tôi đã tạo một công cụ tên Cels vì chuyện đó: https://github.com/pacha/cels
      Tôi thích Jsonnet và Starlark, nhưng thực tế là trong hầu hết use case không cần một ngôn ngữ lập trình mới. Thường thì chỉ muốn tạo tài liệu cơ sở rồi áp dụng patch để chỉnh sửa. Như vậy mọi thứ đơn giản hơn nhiều
      Trải nghiệm dùng YAML thuần túy tự thân nó không quá tệ. Định dạng này có vài điểm khá đáng nghi, nhưng vẫn dùng được. Tôi nghĩ vấn đề nằm ở độ phức tạp của các giải pháp phải thêm vào để điều chỉnh tài liệu cho nhiều môi trường
    • Chỉ nghĩ đến việc phải đụng lại Ansible vì chuyện này thôi đã như ác mộng
      Tôi nghe nói trước đây từng có một Python DSL thực sự có thể dùng thay YAML, nhưng hình như đã bị ngừng. Vì vậy giờ đây vòng lặp và if-then trở thành những đống YAML dài dòng kinh khủng, còn Jinja thì được diễn giải theo cách hoàn toàn không thể dự đoán
    • Tôi tự hỏi liệu có công cụ độc lập nào có thể chạy code Starlark để sinh JSON hoặc YAML, giống như jsonnet, hay không
  • Bản thân YAML thì tôi thấy rất tuyệt. Điều không tuyệt là việc chúng ta đã biến phần triển khai của CD trở nên quá khó
    Tôi thừa nhận cấu hình của chúng tôi trong Azure DevOps không hẳn là xuất sắc, nhưng thật đáng ngạc nhiên khi có những tổ chức mà nhiều nhóm hoặc 5–6 người vận hành phải xử lý các công cụ như thế này. Có thể những nơi như Google thì khác, nhưng với các doanh nghiệp thông thường có tối đa 50.000 người dùng đồng thời, hoặc thường là ít hơn nhiều, thì tôi thấy như vậy là quá mức
    Vào đầu những năm 2000, việc triển khai một ứng dụng web doanh nghiệp lên IIS on-premises, nơi mọi thứ như cân bằng tải, networking, v.v. được xử lý bởi chưa tới 0,25 nhân viên toàn thời gian, còn dễ hơn triển khai cùng thứ đó lên một thiết lập “hiện đại” ngày nay
    Tất nhiên các pipeline hiện đại có ưu điểm. Chúng ta đã vượt qua được nhiều vấn đề kiểu “trên máy tôi thì chạy”, và nâng chất lượng quản lý lên đáng kể nhờ các cổng phê duyệt tốt hơn. Nhưng bản thân việc triển khai, ngay cả năm 2023, vẫn là cơn ác mộng
    Điều này có thể không phải là vấn đề với các lập trình viên HN ở những công ty công nghệ thực thụ hoặc những nơi có đội DevOps chuyên trách giỏi. Nhưng trong thế giới doanh nghiệp phi công nghệ, CI/CD chưa bao giờ tệ đến thế trong sự nghiệp của tôi
    Có thể đổ lỗi cho YAML, hoặc đổ lỗi cho việc muốn làm gì cũng cần quá nhiều YAML và template thì khó. Nhưng theo tôi, vấn đề tổ chức lớn hơn nhiều so với vấn đề kỹ thuật. Công cụ CD cần được tự động hóa hơn rất nhiều để việc mô tả hạ tầng bằng code không còn là công việc của lập trình viên
    Việc có thể làm vậy là tốt, nhưng thực tế là chúng ta đang yêu cầu hàng triệu lập trình viên triển khai hạ tầng mà có thể chính họ hầu như không hiểu. Tôi chưa từng thấy lập trình viên nào không muốn chỉ đưa container sang rồi để networking và “việc phía server” tự xử lý
    Nếu không làm như vậy, cuối cùng sẽ có hàng đống VNET và subnet mà chẳng ai hiểu rõ cách chúng hoạt động, và tổ chức sẽ mất rất nhiều tiền vì các lập trình viên không biết rằng có thể làm bằng /x

    • Cloud là mainframe mới
      Ta viết một loại “định nghĩa công việc” nào đó offline, gửi lên một hệ thống chia sẻ độc quyền, chờ trong hàng đợi, rồi nhận các file log do một hệ thống mà mình không kiểm soát tạo ra. Vì không thể chạy mã hệ thống độc quyền đó cục bộ trên workstation, vòng lặp nội bộ ngắn thì cũng mất hàng chục phút, dài thì hàng giờ hoặc hàng ngày
      Không có chế độ xem trước hay “what if”, cũng không có “dry run”. Dù có gọi là “kiểm thử”, vì chỉ có một hệ thống nên về thực chất là đang thao tác trên production
      Vấn đề thật sự không phải là YAML. Kể cả pipeline được script bằng ngôn ngữ lập trình của thần thánh thì cũng chẳng khác mấy
      Lý do cách phát triển phần mềm trên workstation thay vì mainframe chia thời gian tập trung trở nên rất phổ biến là vì nó làm vòng lặp nội bộ nhanh hơn một cách ngoạn mục, tách biệt khỏi môi trường production, và trao quyền kiểm soát lại cho lập trình viên
      Thế hệ pipeline CI/CD hiện nay về cơ bản đã đảo ngược tất cả những điều đó
      Kubernetes chạy trên một máy duy nhất khôi phục phần lớn lợi ích của phát triển dựa trên workstation, nhưng đây vẫn là một hệ thống rất mới nên còn nhiều đau đớn trong quá trình trưởng thành
      Một vấn đề liên quan là: có những giải pháp rất tốt cho lập trình viên một mình vận hành một ứng dụng bằng thao tác click, và cũng có những giải pháp rất tốt cho các siêu công ty làm tự động hóa quy mô lớn cho hàng nghìn lập trình viên. Nhưng khoảng giữa, nơi vài lập trình viên doanh nghiệp quản lý vài chục ứng dụng, thì chỉ là hỗn loạn
    • Tôi không chắc chúng ta đã hoàn toàn vượt qua được chuyện “trên máy tôi thì chạy”
      Đã có khá nhiều lần mọi thứ chạy tốt nhiều lần trong Docker image của tôi, nhưng lại vỡ khi là image đã triển khai
      Đây là loại vấn đề chỉ có thể vượt qua nếu toàn bộ pipeline build và triển khai hoàn toàn minh bạch, có toàn quyền truy cập vào image repository, và thực sự kiểm soát được các chỉ thị build. Điều này cũng hạn chế chẳng kém gì việc kiểm soát hệ điều hành cục bộ, và tôi nghĩ nó sẽ thất bại ở nhiều tổ chức như số nơi từng gặp cảnh code vỡ khi chuyển sang máy khác
    • Tôi không hiểu triển khai thì có vấn đề gì. Những thứ tôi cấu hình chỉ cần gắn tag cho commit rồi push là commit đó được triển khai
      Việc thiết lập như vậy trong bất kỳ hệ thống CI/CD nào trông cũng khá trực quan
  • Tôi nghĩ có một giải pháp để giữ hòa khí nếu mọi người đều tôn trọng phổ quát chỉ một quy tắc: đừng dùng YAML bên ngoài hệ sinh thái Python
    Như vậy những người thích một định dạng scripting khó hiểu, ưu tiên tính dễ đọc hơn tính chính xác, độ bền và khả năng bảo trì, vẫn có thể tiếp tục dùng ký tự tab, kiểu lỏng lẻo và cú pháp rối rắm. Phần còn lại thì không cần phải vậy nữa. Những người thích cú pháp kiểu C có thể giữ được sự tỉnh táo
    Có vẻ cuối cùng tôi đã chạm đúng cốt lõi vấn đề. Với tôi, một lập trình viên cú pháp C, khoảng trắng có ý nghĩa cú pháp là sự điên rồ thuần túy. Khoảng trắng là định dạng, không phải thông tin hay mệnh lệnh. Định dạng tốt thì hữu ích và có ích, và lập trình viên cú pháp C giỏi cũng quan tâm đến định dạng dễ đọc
    Trong Python và YAML, định dạng là thông tin chỉ thị. Nó có ưu điểm là mọi đoạn code chạy được đều trở nên dễ đọc. Nhưng tại sao code muốn chạy được thì nhất thiết phải dễ đọc?
    Cứ tưởng tượng làm việc với một đồng nghiệp giống YAML. Bạn gửi một tin nhắn dài, rồi người đó trả lời “Gì cơ? Cái này vô lý.” Hóa ra vì bạn không chèn dòng trống giữa các đoạn nên ý nghĩa bị hỏng. Bạn thêm lại các dòng trống và gửi tin nhắn thì lúc đó họ mới đọc được. Nếu không có định dạng đúng về mặt cú pháp, thông tin bạn gửi đã trở nên vô nghĩa

    • Một mục đích khác của code với tư cách phần mềm, ngoài khả năng thực thi, là có thể đọc được
      Có vô số cách để định dạng, và tôi thích mọi người dùng linter khi viết code. Nếu được thì tốt nhất là cùng loại linter với tôi đang dùng
      Những ngôn ngữ đó buộc dùng các cấu trúc cú pháp chuẩn. Số cách để viết code khó đọc giảm đi, nên đó là điều tốt
    • Thông thường, khoảng trắng có ý nghĩa được xem là vấn đề triết học hoặc tôn giáo. Có người thích, có người ghét; cả hai bên đều hợp lý hóa sở thích của mình, nhưng rốt cuộc chỉ là chuyện khẩu vị mạnh mẽ
      Nhưng giờ tôi nghĩ sự khác biệt đó không phải là triết học mà là vấn đề công cụ. Một số công cụ, chẳng hạn trình soạn thảo văn bản hay chương trình email, hỗ trợ tốt khoảng trắng có ý nghĩa, còn một số thì không
      Tất cả trình soạn thảo văn bản tôi dùng đều được thiết lập để hiển thị dấu cách và ký tự tab, và hiển thị chúng khác nhau. Thường là kiểu chấm mờ và gạch mờ. Tôi đã quen nên hoàn toàn không thấy vướng
      Theo quan điểm của tôi, code không phải văn bản tùy ý. Ta dùng phông chữ monospace mà ta sẽ không dùng trong sách, và phân biệt cú pháp bằng màu sắc. Cũng chẳng có lý do gì để không làm cho khoảng trắng hiện ra
      Tôi vẫn thích các ngôn ngữ không có khoảng trắng có ý nghĩa hơn, nhưng cũng không ghét những ngôn ngữ đó. Với tôi nó hoàn toàn không thành vấn đề
      Nhưng nếu công cụ bạn thích không hỗ trợ tốt khoảng trắng có ý nghĩa, không làm cho khoảng trắng hiện ra, hoặc thậm chí bạn code bằng phông chữ tỷ lệ, thì bạn sẽ không còn cách nào khác ngoài việc căm ghét khoảng trắng có ý nghĩa và xem nó là sự điên rồ thuần túy
    • Tôi cũng xuất thân từ C nên từng nghĩ tương tự rằng khoảng trắng không phải là thông tin hay mệnh lệnh. Thời kỳ đầu của Python, vì chuyện đó tôi còn hơi coi thường nó
      Điều khiến tôi đổi ý lại bất ngờ là khi dùng CoffeeScript. Tôi không thích JavaScript lắm, nhưng cảm giác dùng CoffeeScript giống như phiên bản đã chắt lọc của The Good Parts của Crockford. Không thể vô tình tạo ra những phần xấu
      Hơn nữa cách indentation trở thành code khá dễ chịu. Bất tiện duy nhất là trong Vi, tôi không thể nhấn % ở dấu ngoặc nhọn mở hoặc đóng để tìm đầu kia của block. Ngược lại, nhờ indentation, nếu code trông kỳ lạ thì thường đúng là nó có vấn đề
      Dù vậy tôi vẫn chưa học Python nhiều. Dạo này tôi dùng TypeScript, nhưng nếu một ngày nào đó CoffeeTypeScript xuất hiện thì…
    • Hơi lạ là TOML có trong thư viện chuẩn còn YAML thì không. Và TOML thì xấu
    • Cộng đồng Kubernetes đang nhìn với ánh mắt đầy hứng thú
  • Vì vậy tôi bắt đầu tự tạo một định dạng tên là BCL: https://github.com/wkhere/bcl
    Nó sẽ không giúp ngay cho mọi trường hợp dùng YAML, nhưng ít nhất có thể là một cách đẹp hơn để định nghĩa tài nguyên theo phong cách như Terraform. Thực tế nó đã hữu ích như một thay thế HCL trong một dự án nội bộ, và đó là động lực cuối cùng khiến tôi làm nó
    Nhìn rộng hơn, tôi không biết nó sẽ giúp thế nào với vấn đề YAML xuất hiện khắp nơi trong Kubernetes. Hơn một nửa vấn đề trong $daily_job của tôi nằm ở việc ghép biểu đồ Helm cuối cùng từ nhiều nguồn quá thô sơ
    Tôi không có ý nói Helm về bản chất là công cụ tệ, hay công ty chúng tôi đã chọn Helm theo một cách khá tệ. Tôi nghĩ mọi người đều đang cố hết sức trong hoàn cảnh của mình
    Nhưng thao tác với template văn bản có khoảng trắng có ý nghĩa thì quá dễ lỗi, và lỗi cũng được phát hiện quá muộn. Tôi nghĩ Kubernetes lẽ ra đã tốt hơn nhiều nếu dùng một định dạng tùy chỉnh dựa trên cú pháp kiểu C, thay vì cố chứng minh YAML tuyệt vời đến mức nào. Nhất là khi YAML cũng chẳng tuyệt vời

  • Đây là hiệu ứng nền tảng nội bộ. Khi ứng dụng lớn lên, cấu hình cũng mở rộng rồi cuối cùng trở thành một ngôn ngữ lập trình, nhưng là một ngôn ngữ nhiều lỗi, thiếu đặc tả và có tính khả dụng khủng khiếp
    Tuyên bố phá sản cấu hình rồi chọn một định dạng cấu hình mới. Và lặp lại
    Tất nhiên bản thân định dạng cũng không phải vô can. Càng linh hoạt thì càng dễ bị tái sử dụng thành một ngôn ngữ lập trình tệ
    Sau khi lặp đi lặp lại sai lầm này, ngày nay tôi sẽ chọn định dạng cấu hình đơn giản nhất có thể cho cấu hình cơ bản. Ngay cả .ini cũng có thể quá mạnh. Những “cấu hình” phức tạp hơn thì tôi sẽ giao cho một ngôn ngữ lập trình thực sự, nếu được thì là ngôn ngữ mà ứng dụng được viết bằng

  • Phần lớn áp đảo các ví dụ kiểu “YAML dở” đều có thể giải quyết bằng cách đặt toàn bộ các literal kỳ quặc trong dấu ngoặc kép
    Đúng là YAML đôi khi gây khó chịu. Ví dụ, danh sách trong map rất nhanh trở nên kỳ quặc, và khoảng trắng có ý nghĩa gần như chắc chắn một ngày nào đó sẽ gây rắc rối. Nhưng những bài viết kiểu này, nói nhẹ thì trông hơi thiếu nghiêm túc

    • Thế nhưng trong các ví dụ đó không có trường hợp nào dùng dấu ngoặc kép, và các công cụ cũng không làm như vậy
      Cả hệ sinh thái YAML khuyến khích viết giá trị không có ngoặc kép. Thường thì nó hoạt động tốt, rồi thỉnh thoảng hỏng vừa đủ để làm bạn vấp ngã trong production
  • EDN là một tập con của Clojure: https://github.com/edn-format/edn
    Rõ ràng, có thể streaming, có thể mở rộng, và không nhạy cảm với khoảng trắng. Tuy vậy vẫn có các quy ước định dạng để dễ đọc

    • Đây là lần đầu tôi thấy một định dạng dữ liệu phân biệt tường minh giữa list và set, và điều đó rất hay
      Nhưng tôi không rõ khác biệt về ngữ nghĩa giữa list và vector là gì. Trong đầu tôi, array và linked list là chi tiết triển khai của cấu trúc dữ liệu trong code, chứ không phải khác biệt của định dạng dữ liệu
    • Tốt hơn các lựa chọn thay thế rất nhiều. Tôi thật sự hy vọng nó bắt đầu được dùng cả bên ngoài hệ sinh thái Clojure
    • Nói chính xác thì khó gọi là không phụ thuộc vào khoảng trắng, vì vẫn cần khoảng trắng để xác định ranh giới hoặc phân tách phần tử
      Dù vậy hoàn toàn không có trò phù phép thụt lề mang tính ngữ nghĩa. Việc dấu phẩy được xem như khoảng trắng và không bắt buộc là một điểm rất đẹp
  • Khi sinh viên nộp bài qua nền tảng e-learning, chúng tôi nhận tất cả bài nộp dưới dạng một file XML khá lớn
    Chúng tôi đọc bài nộp, chuyển chúng cho phân tích tĩnh và chạy ví dụ, rồi viết một file YAML cho từng bài tập, trong đó có tất cả bài nộp, gợi ý chấm điểm, nhận xét và các trường nhập điểm
    Sau đó từ file YAML, chúng tôi tạo báo cáo, thống kê và PDF phản hồi thông qua markdown+rendering (Pandoc)
    Với chúng tôi, YAML rất phù hợp. Lý do là có thể dễ dàng thêm phản hồi bổ sung bằng cú pháp Markdown. Ví dụ như - you missed a \NOT` here` được thụt lề đúng
    Nhờ nhiều cách escape block text, dù sinh viên dùng các dấu phân cách SQL khác nhau, chúng tôi vẫn có thể hiển thị bài nộp SQL đẹp mắt mà không cần ký tự escape
    Tất cả đều là plain text nên chỉ cần dùng trình soạn thảo văn bản, và lưu trong git để bảo đảm trách nhiệm giải trình khi chấm điểm. Vì mọi thứ được lưu theo cách máy có thể đọc, chúng tôi cũng có thể thử nghiệm các công cụ phân tích tĩnh mới trên bài nộp cũ
    Nhưng vì cả CI pipeline và cấu hình home automation cũng phải viết bằng YAML, nên tôi hiểu nỗi đau đó

    • Loại bỏ thụt lề của văn bản nhúng có lẽ là tính năng tốt nhất của YAML
      Trong TOML, bạn phải từ bỏ việc thụt lề chuỗi nhiều dòng, làm giảm khả năng đọc, hoặc phải đặt dấu gạch chéo ngược ở cuối mỗi dòng. Không cách nào là lý tưởng
      Vì vậy với DSL hoặc cấu hình cần chứa Markdown hay định dạng văn bản khác, YAML khá tốt và có lợi thế so với những thứ như TOML
      Nhưng tôi sẽ không quy toàn bộ trách nhiệm của “sự mệt mỏi với YAML” chỉ cho các công cụ CI và DevOps đã chọn YAML làm định dạng vận chuyển cho DSL. Như bài gốc đã tổng hợp tốt, bản thân YAML cũng có vấn đề lớn
      “Vấn đề Norway” nổi tiếng đã được giải quyết trong YAML 1.2, và vấn đề parse số có số 0 đứng đầu thành hệ bát phân cũng đã được giải quyết trong YAML 1.2. Việc ép kiểu quá mức đối với số, ngày, giờ, v.v. có thể gây bối rối. Các chế độ xử lý chuỗi nhiều dòng cũng có thể khá khó hiểu. Serialization không an toàn không còn là vấn đề với các parser hiện đại, nhưng khi dùng YAML trong các ngôn ngữ cũ có tính năng động như Ruby, Python, Java thì cần cẩn trọng
      Tất cả những điều này là vấn đề của chính đặc tả YAML