Skip to main content

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/defrec.
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该模块.

只有andor两个是固定的优先级, 他们的优先级都比其他二元运算符低.

andor也用在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.pypreload方法里找到一个用字节码书写的, 优化到极致的尾递归scheduler.

我会在非尾递归调用点应用这个scheduler, 你能同通过阅读compiler.pyv_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字节码重写.

forwhile的实现如下:

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

urgent-0.1.2-py3-none-any.whl (51.1 kB view details)

Uploaded Python 3

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

Hashes for urgent-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b1180a2d146028789210be588e6883c23c3998d0ea9e80c9c8b89208f4cf7e13
MD5 4bc766a16f5c5c0f86f20af1dbca7014
BLAKE2b-256 28f1df42225cdc73496b179011f0317140474a39a63e63f9316264fcd7bc51e5

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page