No project description provided
Project description
很急语言, 一个"过渡"语言.
安装pip, 命令ugt
(pip install urgent
, ugt --help
)
运行3.6, 编译3.7
(3.7, 3.8上, urgent编译出的字节码可以被3.6加载, 也就是没有使用ROT4和LOAD_METHOD这些新的指令)
跨版本加载用--raw_bytecode
flag.
ugt cc <xxx.ugt> <xxx.code> -- raw_bytecode --project bootstrap.toml
后,
import marshal
code_object = marshal.load(open("xxx.code", 'rb'))
exec(code_object, globals())
语句(伪)
let/def
和rec
.
let x = 1
def x = 1
一个意思.
rec
rec f = x -> (f, x)
是递归, 也就是自己的定义中可以出现自己.
let ..., ...
let x = 1, y = 2, z = ...,
定义时x, y, z
互不引用, 他们定义时用到的x, y, z
来自外部.
rec ..., ...
.
rec x = a -> (a, y), y = a -> (a, x) , z = ...,
定义时, x, y, z
互相引用.
If
<expr> ?
<expr>
else
<expr>
我觉得语法还行.
how?
fine
else
emmm
还阔以.
Match
let x =
(1, 2) match
(a, b, c) => a,
(1, 2) => 0
可以match
的很多, 更多例子见后面的variants.
注意, 二元运算符会被当作解构器.
我们还支持view pattern.
let f = x -> (x, 2 * x)
1 match (f -> (a, b)) => a + b # 1 + 2 * 1
5 match (f -> (a, b)) => a + b # 5 + 2 * 5
Open, Import
项目根目录那个hello.ugt
可以拿来试, 打开ugt repl
,
Urgent> import Hello
Urgent> print 1
Undef print
Urgent> let x = Hello
Urgent> x.print 1
1
Urgent> open x
Urgent> print 1
1
import
导入模块但不加载它的成员, open
加载成员.
看起来似乎是python的import <mod>
和from <mod> import *
, 其实不是.
一切都是静态的, 只有module可以被import和open. x
之所以可以被open,
是因为x
被分析为是模块Hello
的alias.
Urgent是pure的, 变量不可以多次赋值(只有绑定), 所以, 上面代码里任何使用x
的地方都会索引到模块Hello
.
如果说python import *
是有运行时开销的, 那么, 已经加载过的模块在urgent里,
无论在哪儿open都是0开销的.
一种来自于ML语言的用法是, 在局部打开模块.
Urgent> import Hello
Urgent> let x = 1
Urgent> print 1
Undef print
Urgent> let x = let y = 2 open Hello in print 1
1
Urgent> print 1
Undef print
语句引导的表达式
open
, let
, rec
, def
这些语句后面可以跟一个in
, 表示表达式.
Urgent> let x = def x = 1 in open Hello in print <| x + 1
2
连续的let
, open
, 这些语句, 可以不写in
.
Urgent> let x = let x = 1 let y = 2 let c = 3 open Hello in print <| x + y + c
6
Urgent> print <| 1 + 2 + 3
Undef operator.<|
Urgent> print (1+2)
Undef operator.+
中缀定义
+
左结合,优先级10.
infixl + 10
<|
右结合, 优先级0.
infixr <| 0
优先级是一个整数, 可以为负.
如果想要使用其他模块定义的运算符优先级和结合性, 可以open该模块. 如果不想污染作用域, 可以局部open该模块.
只有and
和or
两个是固定的优先级, 他们的优先级都比其他二元运算符低.
and
和or
也用在pattern matching中.
and
表示左右俩都要match, or
表示只match一个.
x match
1 or 2 or 3 => 0,
x and (y, z) => (y, x, z)
Variants
data Nil, Cons(_, _)
infixr :: 1
let :: = Cons
let l1 = Cons 1 Nil
let print_lst = lst ->
lst match
1 :: Cons a b => ...,
Cons a b => ...,
Nil => ...
[]
语法是Nil
的简写, [a, b]
这样的语法是Cons a (Cons b Nil)
的简写, 所以我们可以
data Nil, Cons(_, _)
infixr :: 1
let :: = Cons
let l1 = [1]
let print_lst = lst ->
lst match
1 :: a :: b => ...,
a :: b => ...,
[] => ...
局部定义的variants:
let x = data A, B, C in
(A, B, C)
A
# Undef: A
这是用来动态create数据类型的. 注意这对于运行时来说比较缓慢. 一般来说, 还是把数据创建放到模块顶层.
Variants的成员可以按名字访问:
data Either(left, right)
let x = Either(1, 2)
x.left |> print
尾递归
urgent实现了尾递归, 所以, 你可以随意地写递归函数定义.
我们不能说这个速度非常快, 实际上, 比起python循环, 相同情况下我们的尾递归性能只有其一半, 更别说我们还有柯里化.
然而, 既然你在看了, 那我可以开心地向你保证, 这是Python世界最快的, 且货真价实的尾递归实现.
其基本原理相当简单, 你可以在codegen.py
的preload
方法里找到一个用字节码书写的,
优化到极致的尾递归scheduler.
我会在非尾递归调用点应用这个scheduler,
你能同通过阅读compiler.py
的v_tco
以及v_call
方法, 来进一步理解尾递归优化的实现.
Python函数调用
f.(a, b, c)
像这样, 调用时加个点的函数, 就是按照Python的调用约定. 这并不和我们的尾递归优化冲突.
Imperative Programming
下面的代码需要加载项目目录下的base/prelude.ugt
.
ref
Urgent> let x = ref 1
=> ()
Urgent> x
=> ref 1
Urgent> x := 2
=> ()
Urgent> x
=> ref 2
Urgent> !x + 2
=> 4
for
Urgent> for [1, 2, 3] ( x ->
print x
)
1
2
3
=> ()
while
Urgent> let x = ref 1
=> ()
Urgent> while { !x < 10 } {
do print !x
in x := !x + 1
}
1
2
3
4
5
6
7
8
9
=> ()
上面的循环暂时是尾递归写的, 之后会用Python字节码重写.
for
和while
的实现如下:
rec for = seq -> f ->
seq match
[] => (),
hd :: tl =>
do f hd
in for tl f
rec while = cond -> f ->
cond () ?
do f ()
in while cond f
else ()
都可以良好地尾递归.
项目构建
urgent把所有代码编译成单个.pyc文件.
# 编译
sh> ugt cc <主模块.ugt> <a.pyc> --project <项目文件.toml>
# 直接执行
sh> ugt run <主模块.ugt> --project <项目文件.toml>
# 启动REPL
sh> ugt repl --project <项目文件.toml>
一个示例的项目文件见bootstrap.toml
.
packaging和project building这些方面其实还没设计好, 但先用着了. 做事第一.
WIP: Traits
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file urgent-0.1.2-py3-none-any.whl
.
File metadata
- Download URL: urgent-0.1.2-py3-none-any.whl
- Upload date:
- Size: 51.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.4.0 requests-toolbelt/0.8.0 tqdm/4.36.1 CPython/3.7.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b1180a2d146028789210be588e6883c23c3998d0ea9e80c9c8b89208f4cf7e13 |
|
MD5 | 4bc766a16f5c5c0f86f20af1dbca7014 |
|
BLAKE2b-256 | 28f1df42225cdc73496b179011f0317140474a39a63e63f9316264fcd7bc51e5 |