使用lisp和haskell的一部分来增强python的性能。

unpythonic的Python项目详细描述


我们为python提供了缺少的特性,主要来自列表处理 传统,但也夹杂着一些哈斯凯利斯主义。我们特别强调 clear,pythonic语法

我们还可以选择将python语言的扩展作为 设计用于协同工作的语法宏。每个宏添加一个 可以(主要)混合和匹配的正交功能块 和其他人一起。

设计考虑的是简单性、健壮性和最小的依赖性。 当前不需要;macropy可选,以启用语法宏。

没有宏,我们的功能包括尾部调用优化(tco)、tco'd fp样式的循环、call/ec、let&letrec、assign once、多表达式lambdas, 动态分配(也称为参数化特殊变量),记忆化 (也适用于发电机和发电机)、电流、功能组合, 折叠和扫描(左和右),打开,缓慢的部分打开。 序列、pythonic lispy链表(cons)和 用于创建支持中缀数学的数学序列的紧凑语法。

我们的curry修改了python的缩减规则。它传递任何额外的参数 右边的through,在剩下的部分调用一个可调用的返回值 参数,以便我们可以:

mymap = lambda f: curry(foldr, composerc(cons, f), nil)
myadd = lambda a, b: a + b
assert curry(mymap, myadd, ll(1, 2, 3), ll(2, 4, 6)) == ll(3, 6, 9)

with_n = lambda *args: (partial(f, n) for n, f in args)
clip = lambda n1, n2: composel(*with_n((n1, drop), (n2, take)))
assert tuple(curry(clip, 5, 10, range(20))) == tuple(range(5, 15))

如果安装了macropy,unpythonic.syntax将可用。它提供了 宏实际上扩展了python语言,添加了 要么复杂,要么不可能以其他方式提供(和/或使用)。

使用宏,我们添加了自动套现、自动尾调用优化 (tco)、按需调用(惰性函数)、连续性(python的call/cc), {TT4}$(宏扩展时间的拼接代码),词汇范围 letdo具有精简语法、隐式返回语句和 易于使用的带有局部变量的多表达式lambdas。

tco宏有一个相当广泛的表达式分析器,所以 andora if p else bdo[]和^{tt11}的任何用法$ 执行尾部调用转换时会考虑宏。

延续系统是基于 连续传递样式(CPS),连续表示为闭包。 它还使用与tco宏相同的机器自动应用tco。 为了使运行时开销保持合理,将捕获continuation 仅当使用call_cc[]显式请求时。

宏示例:

# let, letseq (let*), letrec with no boilerplate
a = let((x, 17),
        (y, 23))[
          (x, y)]

# alternate haskelly syntax
a = let[((x, 21),(y, 17), (z, 4)) in x + y + z]
a = let[x + y + z, where((x, 21), (y, 17), (z, 4))]

# cond: multi-branch "if" expression
answer = lambda x: cond[x == 2, "two",
                        x == 3, "three",
                        "something else"]
assert answer(42) == "something else"

# do: imperative code in any expression position
y = do[local[x << 17],
       print(x),
       x << 23,
       x]
assert y == 23

# autocurry like Haskell
with curry:
    def add3(a, b, c):
        return a + b + c
    assert add3(1)(2)(3) == 6
    # actually partial application so these work, too
    assert add3(1, 2)(3) == 6
    assert add3(1)(2, 3) == 6
    assert add3(1, 2, 3) == 6

    mymap = lambda f: foldr(composerc(cons, f), nil)
    myadd = lambda a, b: a + b
    assert mymap(myadd, ll(1, 2, 3), ll(2, 4, 6)) == ll(3, 6, 9)

# lazy functions (call-by-need) like Haskell
with lazify:
    def f(a, b):
        return a
    def g(a, b):
        return f(2*a, 3*b)
    assert g(21, 1/0) == 42  # the 1/0 is never evaluated

# automatic tail-call optimization (TCO) like Scheme, Racket
with tco:
    assert letrec((evenp, lambda x: (x == 0) or oddp(x - 1)),
                  (oddp,  lambda x: (x != 0) and evenp(x - 1)))[
                    evenp(10000)] is True

# lambdas with multiple expressions, local variables, and a name
with multilambda, namedlambda:
    myadd = lambda x, y: [print("myadding", x, y),
                          local[tmp << x + y],
                          print("result is", tmp),
                          tmp]
    assert myadd(2, 3) == 5
    assert myadd.__name__ == "myadd"

# implicit "return" in tail position, like Lisps
with autoreturn:
    def f():
        print("hi")
        "I'll just return this"
    assert f() == "I'll just return this"

    def g(x):
        if x == 1:
            "one"
        elif x == 2:
            "two"
        else:
            "something else"
    assert g(1) == "one"
    assert g(2) == "two"
    assert g(42) == "something else"

# splice code at macro expansion time
with let_syntax:
    with block(a) as twice:
        a
        a
    with block(x, y, z) as appendxyz:
        lst += [x, y, z]
    lst = []
    twice(appendxyz(7, 8, 9))
    assert lst == [7, 8, 9]*2

# lispy prefix syntax for function calls
with prefix:
    (print, "hello world")

# the LisThEll programming language
with prefix, curry:
    mymap = lambda f: (foldr, (compose, cons, f), nil)
    double = lambda x: 2 * x
    (print, (mymap, double, (q, 1, 2, 3)))
    assert (mymap, double, (q, 1, 2, 3)) == ll(2, 4, 6)

# the HasThon programming language
with curry, lazify:
    def add2first(a, b, c):
        return a + b
    assert add2first(2)(3)(1/0) == 5

    assert letrec[((c, 42),
                   (d, 1/0),
                   (e, 2*c)) in
                  add2first(c)(e)(d)] == 126

# call/cc for Python
with continuations:
    stack = []
    def amb(lst, cc):  # McCarthy's amb operator
        if not lst:
            return fail()
        first, *rest = tuple(lst)
        if rest:
            ourcc = cc
            stack.append(lambda: amb(rest, cc=ourcc))
        return first
    def fail():
        if stack:
            f = stack.pop()
            return f()

    def pythagorean_triples(maxn):
        z = call_cc[amb(range(1, maxn+1))]
        y = call_cc[amb(range(1, z+1))]
        x = call_cc[amb(range(1, y+1))]
        if x*x + y*y != z*z:
            return fail()
        return x, y, z
    x = pythagorean_triples(20)
    while x:
        print(x)
        x = fail()

# if Python didn't already have generators, we could add them with call/cc:
with continuations:
    @dlet((k, None))  # let-over-def decorator
    def g():
        if k:
            return k()
        def my_yield(value, cc):
            k << cc        # rebind the k in the @dlet env
            cc = identity  # override current continuation
            return value
        # generator body
        call_cc[my_yield(1)]
        call_cc[my_yield(2)]
        call_cc[my_yield(3)]
    out = []
    x = g()
    while x is not None:
        out.append(x)
        x = g()
    assert out == [1, 2, 3]

有关文档和完整示例,请参见项目的github主页, 以及各个特性的文档字符串。举更多的例子, 请参阅源发行版中包含的单元测试。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java正则表达式查找但不包含在组中   java在for循环内的主线程中调用AsyncTask   java解析SOAP服务的响应时遇到问题。XML有什么问题?   java Servlet ClassNotFoundException出现在包中时。。。为什么?   Facebook SDK中的安卓 R.Java与应用程序R.Java冲突   java为什么我得到SSLProtocolexception:尝试发送http请求时握手失败?   java Base64编码字符串搜索   在htmlunit中选择java下拉菜单   java列表添加到HashMap   java设置断点的最短NOOP语句是什么?   java如何检索windows中所有应用程序最近使用的文件   java正则表达式,包含正向向后看和向前看   如何在java中通过API从url获取图像?   如何将for-each循环转换为Java流和lambda函数?   java如何使用jackson流式api解析给定的json?   java暂停调用方法jdbcTemplate。getDataSource()   java如何在使用getJdbcTemplate时使用union运算符设置sql查询的参数。查询(sql、新对象[]、行映射器)?   java我可以为HQL查询指定结果对象类型吗?   java Spring未满足的依赖项错误   maven试图重新定位poi jar,但未找到java类异常