Q Language - The Go++ language for Data Technology
Mission & vision
最新的 qlang v6 版本在能力上较以前的版本有极大的调整。其核心变化为:
- 完全推翻重来,从动态类型转向静态类型!
- 完全兼容 Go 语言文法。
- 在 Go 语言兼容基础上,保留当初 qlang 动态类型版本的重要特性。比如:
a := [1, 2, 3.4]
为什么人们需要 qlang?它的使命与愿景是什么?
一句话:qlang 希望能够将 Go 语言带到数据科技(DT)的世界。
对于服务端编程的最佳实践而言,Go 语言非常优雅。所以 Go 制霸了云计算领域。
但是当前 Go 是有舒适区的,从数据科技的角度,Go 语言显得很笨拙。有没有办法让 Go 在数据科技领域变得一样优雅?
这就是 qlang v6 的由来。它兼容 Go,扩展 Go,以 Go++ 的姿态出现,让数据科技享受 Go 的简洁之美。
qlang 将支持生成 Go 代码,方便 Go 编译 qlang 代码并与其他 Go 项目进行集成。
关于新版本的详细规划,参考:
代码样例:
Old versions
当前 qlang v6 还在快速迭代中。在正式场合建议使用正式 release 的版本:
最近的老版本代码可以从 qlang v1.5 分支获得:
Supported features
Variable & operator
x := 123.1 - 3i
y, z := 1, 123
s := "Hello"
println(s + " complex")
println(x - 1, y * z)
Condition
x := 0
if t := false; t {
x = 3
} else {
x = 5
}
x = 0
switch s := "Hello"; s {
default:
x = 7
case "world", "hi":
x = 5
case "xsw":
x = 3
}
v := "Hello"
switch {
case v == "xsw":
x = 3
case v == "Hello", v == "world":
x = 5
default:
x = 7
}
Import go package
import (
"fmt"
"strings"
)
x := strings.NewReplacer("?", "!").Replace("hello, world???")
fmt.Println("x:", x)
Func & closure
import (
"fmt"
"strings"
)
func foo(x string) string {
return strings.NewReplacer("?", "!").Replace(x)
}
func printf(format string, args ...interface{}) (n int, err error) {
n, err = fmt.Printf(format, args...)
return
}
func bar(f func(string, ...interface{}) (int, error)) {
f("Hello, %v!\n", "qlang")
}
x := "qlang"
fooVar := func(prompt string) (n int, err error) {
n, err = fmt.Println(prompt + x)
return
}
printfVar := func(format string, args ...interface{}) (n int, err error) {
n, err = fmt.Printf(format, args...)
return
}
barVar := func(f func(string, ...interface{}) (int, error)) {
f("Hello, %v!\n", "qlang")
}
bar(printf)
barVar(printfVar)
String, map, array & slice
x := []float64{1, 3.4, 5}
y := map[string]float64{"Hello": 1, "xsw": 3.4}
a := [...]float64{1, 3.4, 5}
b := [...]float64{1, 3: 3.4, 5}
c := []float64{2: 1.2, 3, 6: 4.5}
x[1], y["xsw"] = 1.7, 2.8
println(`x[1]:`, x[1], `y["xsw"]:`, y["xsw"])
title := "Hello,world!" + "2020-05-27"
println(title[:len(title)-len("2006-01-02")], len(a), a[1:])
Map literal
x := {"Hello": 1, "xsw": 3.4} // map[string]float64
y := {"Hello": 1, "xsw": "qlang"} // map[string]interface{}
z := {"Hello": 1, "xsw": 3} // map[string]int
empty := {} // map[string]interface{}
Slice literal
x := [1, 3.4] // []float64
y := [1] // []int
z := [1+2i, "xsw"] // []interface{}
a := [1, 3.4, 3+4i] // []complex128
b := [5+6i] // []complex128
c := ["xsw", 3] // []interface{}
empty := [] // []interface{}
List/Map comprehension
a := [x * x for x <- [1, 3, 5, 7, 11]]
b := [x * x for x <- [1, 3, 5, 7, 11], x > 3]
c := [i + v for i, v <- [1, 3, 5, 7, 11], i%2 == 1]
d := [k + "," + s for k, s <- {"Hello": "xsw", "Hi": "qlang"}]
arr := [1, 2, 3, 4, 5, 6]
e := [[a, b] for a <- arr, a < b for b <- arr, b > 2]
x := {x: i for i, x <- [1, 3, 5, 7, 11]}
y := {x: i for i, x <- [1, 3, 5, 7, 11], i%2 == 1}
z := {v: k for k, v <- {1: "Hello", 3: "Hi", 5: "xsw", 7: "qlang"}, k > 3}
For loop
sum := 0
for x <- [1, 3, 5, 7, 11, 13, 17], x > 3 {
sum += x
}
Builtin & typecast
a := make([]int, uint64(2))
a = append(a, 1, 2, 3)
println(a, "len:", len(a), "cap:", cap(a))
b := make([]int, 0, uint16(4))
c := [1, 2, 3]
b = append(b, c...)
println(b, "len:", len(b), "cap:", cap(b))
Using qlang in Go
See tutorial/14-Using-qlang-in-Go.
Write a qlang package named qlfoo
:
package qlfoo
func ReverseMap(m map[string]int) map[int]string {
return {v: k for k, v <- m}
}
Then use it in a Go package:
package main
import (
"fmt"
"github.com/qiniu/qlang/v6/tutorial/14-Using-qlang-in-Go/qlfoo"
)
func main() {
rmap := qlfoo.ReverseMap(map[string]int{"Hi": 1, "Hello": 2})
fmt.Println(rmap)
}
How to compile this exmaple?
qgo tutorial/ # Convert all qlang code in tutorial/ into Go packages
go install ./...