Chơi chữ đỉnh cao nhất trong JavaScript: Khi cú pháp ngôn ngữ trở thành trò đùa
Bài viết khám phá cách một lập trình viên sử dụng tagged template literal trong JavaScript để tạo ra cú pháp {{ }} giống hệt các template engine quen thuộc, nhưng thực chất chỉ là sự trùng hợp của cú pháp ${...} và object shorthand. Đây được tác giả gọi là "trò chơi chữ vĩ đại nhất" — một chuỗi ký tự mang hai cách phân tích khác nhau.

JavaScript vốn nổi tiếng với những cú pháp kỳ quặc, nhưng đôi khi chính sự kỳ quặc đó lại tạo ra những điều thú vị bất ngờ. Mới đây, một bài viết trên blog shukla.io đã gây chú ý trong cộng đồng lập trình khi chỉ ra một "trò chơi chữ" tinh tế trong JavaScript — thứ mà tác giả gọi là trò chơi chữ vĩ đại nhất mà anh từng phát hiện.
Trò chơi chữ không chỉ có trong ngôn ngữ tự nhiên
Shakespeare nổi tiếng với những lối chơi chữ tinh tế, nơi chỉ cần hoán đổi hai từ là có thể tạo ra một câu đúng ngữ pháp nhưng mang nghĩa hoàn toàn khác. Ví dụ kinh điển: danh từ "fool" chuyển thành tính từ "foolish", còn tính từ "witty" chuyển thành danh từ "wit". Những lối chơi chữ đơn giản nhất khai thác chính các quy tắc ngữ pháp để thay đổi ý nghĩa của từ.
Ở mức độ cao hơn, có những lối chơi chữ dựa vào ngữ cảnh nằm ngoài ngữ pháp. Câu nói nổi tiếng trong Othello: "Put out the light, and then put out the light" — vế đầu nghĩa đen là thổi tắt ngọn nến, còn vế sau là ẩn dụ cho việc giết người.
Điều thú vị là ngôn ngữ tự nhiên và ngôn ngữ lập trình có chung một đặc tính: ngữ pháp. Và nếu ngữ pháp có thể bị "lợi dụng" để chơi chữ, thì ngôn ngữ lập trình cũng vậy.
Tagged template literal — vũ khí bí mật của JavaScript
Trong JavaScript có một tính năng gọi là tagged template literal, cho phép xử lý chuỗi một cách mạnh mẽ. Hàm tag (tag function) nhận các phần văn bản của template literal và các giá trị ${...} đã được đánh giá như những tham số riêng biệt, từ đó có thể làm bất cứ điều gì với chúng.
Ví dụ, hàm dedent có thể xử lý template literal để loại bỏ phần thụt lề dư thừa. Điều đáng chú ý là hầu hết các ngôn ngữ template đều cho phép viết template bằng chính môi trường của sản phẩm đầu ra — văn bản với các "lỗ hổng" để chèn biến vào.
Cú pháp {{ }} cực kỳ phổ biến trong các template engine như Handlebars, Mustache, Jinja và nhiều thư viện khác. Vậy điều gì sẽ xảy ra nếu ta định nghĩa một hàm tag tên là prompt trông như đang nhận template {{ }}?
Khi sự trùng hợp tạo nên trò chơi chữ
Điểm thú vị nằm ở chỗ: cú pháp {{ }} xuất hiện trong code JavaScript hoàn toàn do sự trùng hợp ngẫu nhiên. Cụ thể:
$được đánh giá là bất cứ thứ gì bên trong nó — đây là cú pháp chuẩn của template literal{ name }trong JavaScript là object shorthand, tương đương với{ name: name }
Kết hợp hai điều này, ${{ url }} vừa là một template literal hợp lệ trong JavaScript, vừa trông giống hệt cú pháp {{ url }} quen thuộc của các template engine. Hàm tag prompt nhận được tất cả những gì nó cần để chú thích chuỗi một cách chính xác.
JavaScript nhìn thấy một thứ, còn bạn nhìn thấy một thứ khác. Cú pháp
{{ url }}chỉ tồn tại trong đầu bạn.
Ứng dụng thực tế: Helicone và observability cho prompt AI
Tác giả bài viết đã hợp tác với Justin từ Helicone vào năm 2024 để đưa ý tưởng này vào SDK chính thức. Mục đích thực tế là tạo ra một chuỗi sẽ được xử lý bởi công cụ observability (Helicone) để giúp phân tích các prompt gửi đến mô hình ngôn ngữ lớn.
Với sự bùng nổ của các ứng dụng AI, việc theo dõi và phân tích prompt đã trở thành nhu cầu thiết yếu. Các đội phát triển tại Việt Nam đang ngày càng sử dụng nhiều công cụ observability cho LLM, và những thủ thuật như thế này giúp code vừa dễ đọc, vừa dễ bảo trì hơn.
Tại sao điều này quan trọng với lập trình viên Việt Nam?
Với cộng đồng lập trình viên Việt Nam đang ngày càng tham gia sâu vào các dự án AI và phát triển phần mềm quốc tế, những hiểu biết về các tính năng tinh tế của JavaScript như tagged template literal là rất giá trị. Nó không chỉ giúp viết code sạch hơn mà còn mở ra những cách tư duy mới về cách ngôn ngữ lập trình có thể được "uốn nắn" để phục vụ mục đích cụ thể.
Tác giả bài viết kết luận bằng một suy ngẫm thú vị: một trò chơi chữ là một chuỗi ký tự với hai cách phân tích. Trong ngôn ngữ tự nhiên, đó là sự tinh tế của người viết. Trong ngôn ngữ lập trình, đó là sự giao thoa giữa thiết kế ngôn ngữ và trí tưởng tượng của lập trình viên.
Đôi khi, thứ tưởng như chỉ là một trò đùa nhỏ lại phản ánh một điều sâu sắc: ranh giới giữa cú pháp và ngữ nghĩa, giữa những gì máy tính thấy và những gì con người thấy, luôn là nơi những điều thú vị nhất xảy ra.

