Chào mọi người, mình muốn giới thiệu ý tưởng về một ngôn ngữ lập trình mới được cải tiến từ Golang, bổ sung thêm các tính năng mà Golang còn thiếu.
Nguồn cảm hứng:
Ý tưởng xuất phát từ quá trình mình học 3 ngôn ngữ: Python, Rust và Go. Mình nhận thấy các ưu và nhược điểm sau:
- Python: Dễ học, code dễ đọc, metaprogramming ổn. Dùng FastAPI để viết API có OpenAPI tự động gen rất tiện cho vibe code ở frontend. Nhược điểm: Hiệu suất có phần đuối hơn so với Go hay Rust.
- Go: Học rất dễ, syntax tối giản, hiệu suất thuộc top đầu (theo TechEmpower). Nhược điểm: Syntax quá tối giản dẫn đến thiếu Enum và các chức năng Macro mạnh mẽ.
- Rust: Memory safety, siêu tối ưu, Macro mạnh mẽ. Viết API bằng Rust thực sự rất chất lượng. Nhược điểm: Đường cong học tập dốc (Steep learning curve), Macro khó sử dụng.
Mục tiêu của Goplus: Mình mong muốn có một ngôn ngữ dễ như Go nhưng sở hữu các tính năng mạnh mẽ như Rust (bỏ qua Ownership/Borrowing, sử dụng Garbage Collector cho đơn giản). Vì thế, mình đã viết một trình biên dịch bằng Rust để dịch từ Goplus sang Golang .
Các tính năng đã có ở phiên bản hiện tại:
-
Syntax:
fn,struct,enum(Simple + Tagged Generic),impl. -
Error Sugar:
-> T!,-> !,expr?. -
Pattern Matching:
matchvới tính năng exhaustive checking cho Enum. -
Derive:
@derive(String)cho struct/enum. -
Compile-time decorators:
- Built-in:
@log,@retry(times[, backoff_ms]),@memoize. - Custom decorators (Python-like factory style:
next -> wrapped).
- Built-in:
Example goplus:
package main
import "fmt"
@derive(String)
enum Status {
Pending
Running
Done
}
@log
@retry(3, 10)
fn readName() -> string! {
return "goplus"
}
fn statusText(s: Status) -> string {
match s {
Status::Pending => "pending",
Status::Running => "running",
Status::Done => "done",
}
}
fn trace(next: (fn(name: string) -> string!), label: string) -> (fn(name: string) -> string!) {
return fn(name: string) -> string! {
fmt.Println("trace:", label)
return next(name)
}
}
@trace("custom")
fn greet(name: string) -> string! {
return "hello " + name
}
fn main() -> ! {
name := readName()?
fmt.Println(name)
fmt.Println(statusText(Status::Running))
msg := greet("goplus")?
fmt.Println(msg)
return
}
Output golang
package main
import (
"fmt"
"os"
"time"
)
type Status int
const (
StatusPending Status = iota
StatusRunning
StatusDone
)
func (e Status) String() string {
switch e {
case StatusPending:
return "Pending"
case StatusRunning:
return "Running"
case StatusDone:
return "Done"
default:
return "Status(?)"
}
}
func readName__inner() (string, error) {
return "goplus", nil
}
func readName__decor0() (string, error) {
var lastErr error
for attempt := 0; attempt < 3; attempt++ {
result, err := readName__inner()
if err == nil {
return result, nil
}
lastErr = err
time.Sleep(time.Duration(10) * time.Millisecond)
}
return "", lastErr
}
func readName__decor1() (string, error) {
fmt.Printf("[goplus] enter readName\n")
result, err := readName__decor0()
if err != nil {
fmt.Printf("[goplus] error readName: %v\n", err)
return result, err
}
fmt.Printf("[goplus] exit readName\n")
return result, nil
}
func readName() (string, error) {
return readName__decor1()
}
func statusText(s Status) string {
switch s {
case StatusPending:
return "pending"
case StatusRunning:
return "running"
case StatusDone:
return "done"
default:
panic("unreachable")
}
}
func trace(next func(name string) (string, error), label string) func(name string) (string, error) {
return func(name string) (string, error) {
fmt.Println("trace:", label)
return next(name)
}
}
func greet__inner(name string) (string, error) {
return "hello " + name, nil
}
func greet__decor0(name string) (string, error) {
decorated := trace(greet__inner, "custom")
return decorated(name)
}
func greet(name string) (string, error) {
return greet__decor0(name)
}
func mainWarp() error {
name, __gp_err0 := readName()
if __gp_err0 != nil {
return __gp_err0
}
fmt.Println(name)
fmt.Println(statusText(StatusRunning))
msg, __gp_err1 := greet("goplus")
if __gp_err1 != nil {
return __gp_err1
}
fmt.Println(msg)
return nil
}
func main() {
if err := mainWarp(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?