Cangjie: Ngôn ngữ lập trình mới hỗ trợ Effect Handlers và Algebraic Data Types
Giáo sư Dan Ghica từ Huawei đã giới thiệu Cangjie (CJ), một ngôn ngữ lập trình ứng dụng mã nguồn mở mới nổi bật với kiểu dữ liệu đại số và bộ xử lý hiệu ứng tích hợp sẵn. Được định vị là đối thủ cạnh tranh của Java, Kotlin hay Swift, Cangjie hiện đã được giảng dạy tại hơn 80 trường đại học tại Trung Quốc.

Giáo sư Dan Ghica, người đứng đầu Phòng thí nghiệm Ngôn ngữ lập trình tại Trung tâm Nghiên cứu Edinburgh của Huawei, gần đây đã giới thiệu Cangjie (CJ). Đây là một ngôn ngữ phát triển ứng dụng mới sở hữu các tính năng nổi bật như kiểu dữ liệu đại số (algebraic data types) và bộ xử lý hiệu ứng (effect handlers). Ngôn ngữ mã nguồn mở này được định vị là một đối trọng tương tự như Java, Kotlin hay Swift. Hiện tại, Cangjie đã được đưa vào giảng dạy tại hơn 80 trường đại học tại Trung Quốc.
Theo ông Ghica, Cangjie là một ngôn ngữ cấp cao, đa mục đích và giàu tính biểu đạt, được thiết kế để đảm bảo tính an toàn và hiệu quả. Giống như bất kỳ ngôn ngữ mới nào, CJ đã học hỏi từ các tiền nhiệm và tìm cách khẳng định vị thế riêng trong không gian ngôn ngữ lập trình (PL). CJ biên dịch thành mã máy thô (raw machine code), cung cấp nhiều backend khác nhau cho phép nó chạy trên Linux, macOS, Windows, Android, iOS và HarmonyOS.
Các tính năng cốt lõi
Các tính năng chính bao gồm kiểu tĩnh (static typing), khớp mẫu (pattern matching), thu gom rác đồng thời (concurrent garbage collection), kiểu dữ liệu đại số (ADTs) và các cơ sở lập trình siêu cấp (metaprogramming) như macro và chú thích. Dưới đây là một ví dụ về khớp mẫu trong Cangjie:
enum TimeUnit {
| Year(UInt64)
| Month(UInt64)
}
enum Command {
| SetTimeUnit(TimeUnit)
| GetTimeUnit
| Quit
}
main() {
let command = SetTimeUnit(Year(2022))
match (command) {
case SetTimeUnit(Year(year)) => println("Set year ${year}")
case SetTimeUnit(Month(month)) => println("Set month ${month}")
case _ => ()
}
}
Bộ xử lý hiệu ứng (Effect Handlers)
Tuy nhiên, tính năng quan trọng nhất về mặt học thuật mà Cangjie mang đến cho dòng chính (mainstream) có lẽ là sự hỗ trợ native cho bộ xử lý hiệu ứng. Việc triển khai effect handlers của CJ tổng quát hóa các ngoại lệ (exceptions) và tuyên bố giúp đơn giản hóa việc ràng buộc động (dynamic binding). Effect handlers trong CJ giới thiệu các từ khóa mới là perform và resume. Khối try/catch/finally tiêu chuẩn trở thành try/catch/handle/finally.
class FileNotFound {
public FileNotFound(let filename: String) {}
}
func readFile(name: String): String {
var actualName = name
if !fileExists(name) {
actualName = perform FileNotFound(name) // (1): điều khiển nhảy đến (2)
}
return File(actualName).read()
}
main() {
try {
let str: String = readFile("foo.txt")
println(str)
} handle (e: FileNotFound, r: Resumption ) {
resume r with "/etc/default.txt" // (2): điều khiển nhảy ngược lại (1), trả về giá trị
}
}
Effect handlers có thể được sử dụng cho nhiều mục đích, bao gồm tính không xác định và quay lui (nondeterminism and backtracking), lập lịch (scheduling), tính toán tăng dần (incremental computing), tiêm phụ thuộc và cấu hình (ví dụ: reader effect), mô phỏng (mocking), và như đã trình bày ở trên, xử lý ngoại lệ.
Dưới đây là ví dụ về CJ effect handler được sử dụng cho bộ nhớ đệm và memoization:
func withCache(fn: () -> Return): Return
where Cmd & Command
{
let cache = HashMap()
try {
fn()
} handle (cmd: Cmd, next: Resumption) {
let result = match (cache.get(cmd)) {
case None =>
let result = perform cmd
cache.put(cmd, result)
result
case Some(cached) =>
cached
}
resume next with result
}
}
Ràng buộc động và khả năng tương thích
Ông Ghica nhấn mạnh rằng effect handlers của CJ cũng cung cấp hỗ trợ native cho ràng buộc động, cho phép mã tương tác với ngữ cảnh gọi của nó. Ông Ghica lấy ví dụ về một thư viện ghi nhật ký (logging library) định nghĩa phương thức ghi log của mình dựa trên thiết bị đang chạy chương trình:
"Hãy tưởng tượng rằng bạn viết một thư viện cho một khung như Oniro. Thư viện đó có thể chạy trên máy tính xách tay, điện thoại di động, đồng hồ thông minh, hoặc một loại thiết bị IoT nào đó không có màn hình, ổ cứng hay bảng điều khiển. Không có cách tiêu chuẩn để thực hiện ghi nhật ký trên tất cả các nền tảng này. Vậy bạn phải làm sao?
Trong trường hợp đó, bạn cần sử dụng ràng buộc động. Bất cứ khi nào mã của bạn cần ghi lại một cái gì đó, bạn cần thông báo cho ngữ cảnh, nói rằng cần thực hiện một số ghi nhật ký, và ngữ cảnh sẽ biết cách xử lý việc ghi nhật ký đó. Nhưng cũng không giống như ngoại lệ, bạn cần có thể quay trở lại. Bạn không muốn chỉ ném một ngoại lệ và thoát thực thi. Bạn muốn thực hiện ghi nhật ký đó theo cách được kiểm soát bởi ngữ cảnh và sau đó tiếp tục tính toán."
Ví dụ, trên máy tính để bàn, ta có thể chỉ cần in ra bảng điều khiển. Trong khi đó, trên thiết bị di động không có bảng điều khiển, nếu muốn ghi nhật ký, có thể quyết định mở một loại cảnh báo hiển thị nhật ký, hoặc gửi nó qua email, hoặc đơn giản là bỏ qua. Ngữ cảnh có thể quyết định phù hợp. Với Cangjie, việc ghi nhật ký có thể thực hiện chỉ trong ba dòng mã.
Trong khi một số khung sử dụng effect handlers đã có sẵn dưới dạng thành phần bên thứ ba cho Cangjie, thì effect handlers vẫn được coi là một phần đang được phát triển tích cực và mang tính thử nghiệm của ngôn ngữ.
Bài phát biểu của ông Ghica đã diễn ra tại OCX (Trải nghiệm Cộng đồng Mở) 2026 vào tháng 4 tại Brussels. OCX là hội nghị mã nguồn mở hàng đầu của Eclipse Foundation, quy tụ các nhà phát triển, nhà nghiên cứu, lãnh đạo ngành công nghiệp và các nhà hoạch định chính sách trong ba ngày.
Bài viết liên quan

Công nghệ
Cerebras, đối tác thân thiết của OpenAI, sẵn sàng cho đợt IPO kỷ lục định giá tới 26,6 tỷ USD
04 tháng 5, 2026

Công nghệ
Microsoft giới thiệu Surface Pro 12 và Surface Laptop 8: Sức mạnh chip Intel, giá thành gây sốc
19 tháng 5, 2026
Công nghệ
Trang web ngăn chặn tự tử tại Hà Lan bị phát hiện chia sẻ dữ liệu người dùng cho các công ty công nghệ
13 tháng 5, 2026
