Grain: Ngôn ngữ lập trình đầu tiên tối ưu cho WebAssembly

Oscar Spencer mới đây đã giới thiệu Grain, một ngôn ngữ cấp cao mới, được định kiểu mạnh mẽ, và được biên dịch sang WebAssembly. Grain bao gồm các tính năng lập trình hàm (ví dụ: suy luận kiểu-type inference, đối sánh mẫu-pattern matching, hàm lồng trong hàm-closure) đồng thời cho phép các biến có thể thay đổi.

Grain cũng có một thư viện tiêu chuẩn, với các cấu trúc dữ liệu tổng hợp (Option, Stack, Result) và các lệnh gọi hệ thống (ví dụ: I/O, xử lý quy trình).

Trong cuộc nói chuyện tại Hội nghị thượng đỉnh WebAssembly Summit 2021, Spencer đã đi qua các đặc điểm chính của Grain, đây là một ngôn ngữ lập trình mà theo ông nói là được tạo riêng cho WebAssembly, mục tiêu biên dịch duy nhất của Grain.

Ngôn ngữ Grain tự mô tả sứ mệnh của nó như sau:

Grain nhằm mục đích hiện đại hóa các tính năng sáng tạo trong các ngôn ngữ lập trình hàm và học thuật và đưa chúng đến với đại chúng. Nhiều ngôn ngữ đã có những ý tưởng tuyệt vời, nhưng cuối cùng chúng đã bị coi là bí truyền hoặc quá khó để học, và do đó, đã phải vất vả khi tập hợp được một cộng đồng lớn xung quanh các ngôn ngữ lập trình này. Grain hy vọng sẽ mang lại sức sống mới cho những ý tưởng đó và trình bày chúng ở dạng dễ tiếp cận, dễ sử dụng và dễ hiểu.

Grain được định kiểu dữ liệu mạnh (với bộ kiểm tra kiểu của OCaml) và khả năng suy luận kiểu của nó làm giảm đáng kể nhu cầu về chú thích kiểu. Bên cạnh các kiểu dữ liệu cốt lõi của WebAssembly (ví dụ: i32 trở thành Int32), Grain cũng cung cấp các kiểu kết hợp thường được sử dụng trong các ngôn ngữ định kiểu cấp cao. Kiểu tùy chọn Option đại diện cho khả năng “có” (với biến Some), hoặc “không” (với biến None). Kiểu kết quả Result thể hiện trong trường hợp thành công (với biến Ok), hoặc trường hợp gặp lỗi (với biến Err). Kiểu ngăn xếp Stack đại diện cho một ngăn xếp bất biến. Các kiểu bổ sung và cú pháp ngôn ngữ hỗ trợ bộ dữ liệu, bản ghi, mảng, danh sách, phạm vi, ký tự, chuỗi, tập hợp, bản đồ, hàng đợi, v.v.

Các nhà phát triển Grain có thể sử dụng đối sánh mẫu trên các kiểu dữ liệu Enum như sau:

enum  Topping {  Cheese,  Pepperoni,  Peppers,  Pineapple  }  
enum  Menu {  Pizza(Topping),  Calzone(Topping)  }  
  
let item  =  Calzone(Peppers)  
  
match  (item)  {  
 Calzone(topping)  =>  {  
 if  (checkSpecials(topping))  {  
 print("These are half off this week.")  
 }  else  {  
 print("No current specials.")  
 }  
 },  
 _  =>  print("No current specials.")  
}

Trong đoạn mã trên, topping được ràng buộc với giá trị của kiểu Topping được sử dụng để xây dựng mục  item của  Menu.

Đối sánh mẫu cũng có thể được thực hiện trên các bản ghi record, bộ dữ liệu tuple và danh sách list như sau:

let list  =  [1,  2,  3]  
  
match  (list)  {  
 []  =>  print("List contains no elements"),  
 [_]  =>  print("List contains one element"),  
 [_,  _]  =>  print("List contains two elements"),  
 [_,  _,  _]  =>  print("List contains three elements"),  
 _  =>  print("List containes more than 3 elements")  
}

Hàm là một khái niệm hạng nhất trong Grain, tức là các hàm có thể được sử dụng dưới dạng giá trị. Các hàm có thể tự gọi chính nó một cách đệ quy. Giống như trong JavaScript, các hàm cũng có thể giữ một tham chiếu của các giá trị trong phạm vi của chúng (closure).

Grain hiểu cách xuất các giá trị mà không cần nhà phát triển phải xác định chuỗi đại diện cho các giá trị. Grain cũng cung cấp các lệnh gọi hệ thống phù hợp với các lệnh gọi được xác định trong Giao diện hệ thống WebAssembly System Interface (WASI). WASI bao gồm các API dành cho I/O không đồng bộ, tạo số ngẫu nhiên, truy cập thời điểm hiện tại, v.v.

Chương trình Grain có thể được chia thành các mô-đun có có khả năng nhập từ —hoặc xuất sang— các mô-đun Grain khác. Các mô-đun Grain cũng có thể nhập từ các hàm bên ngoài, với điều kiện các nhà phát triển phải định kiểu cho mhàm ngoại một cách rõ ràng.

Spencer đã minh họa kiểu lập trình cấp cao mà Grain cho phép bằng một ví dụ đơn giản như bên dưới:

Việc phát triển Grain trong tương lai nên bao gồm giao diện hàm ngoại tốt hơn, liên kết tĩnh, hỗ trợ chế độ 64-bit, thư viện chuẩn DOM, macro, v.v.

AssemblyScript, biên dịch một biến thể nghiêm ngặt của TypeScript thành WebAssembly, cũng tự mô tả là được tạo cho WebAssembly và bao gồm một thư viện tiêu chuẩn với các kiểu dữ liệu kết hợp phổ biến (ví dụ: mảng, ngày tháng). Giống như Grain, AssemblyScript biên dịch sang WebAssembly bằng cách sử dụng Binaryen. AssemblyScript cố gắng cung cấp cho các nhà phát triển quyền kiểm soát cấp thấp trong một ngôn ngữ cấp cao hơn, trong khi vẫn chú trọng đến kích thước mã. Tuy nhiên, AssemblyScript có thể yêu cầu nhiều chú thích kiểu dữ liệu hơn từ các nhà phát triển:

So với TypeScript, suy luận kiểu trong AssemblyScript bị hạn chế vì kiểu của mỗi biểu thức phải được biết trước. Điều này có nghĩa là các khai báo biến và tham số phải có chú thích kiểu của chúng hoặc phải có bộ khởi tạo.

Bộ công cụ của Grain (ví dụ: CLI, trình biên dịch, thời gian chạy và thư viện chuẩn) được cung cấp dưới dạng một file nhị phân duy nhất. File nhị phân này có sẵn cho các phiên bản MacOS x64, Linux x64Windows x64. Phiên bản JavaScript của trình biên dịch Grain đã được cung cấp để sử dụng trong các hệ điều hành chưa có sẵn file nhị phân riêng.

Toàn bộ bài nói chuyện được cung cấp trực tuyến gồm các slide trình bày, đoạn code mẫu và các giải thích chi tiết bổ sung. WebAssembly Summit là hội nghị hàng năm về tất cả mọi thứ liên quan đến WebAssembly. WebAssembly Summit 2021 được tổ chức trực tuyến vào tháng 4 năm nay.

* Grain: Your WebAssembly-First Programming Language – WebAssembly Summit 2021 (infoq.com)

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Back to top button