zoukankan      html  css  js  c++  java
  • python + lisp hy的新手注记2 eval, HyModel and python AST

    来自我在Stack Overflow上的提问,https://stackoverflow.com/questions/51675355/how-to-eval-a-cond-case-and-return-function-object

    (hy作者回复真及时,但是之前在github issue里提问就被拒了 哈哈哈)

    我的问题是,我需要自己组装 带有条件表达式(cond [p  e]) 。

    p多变,而e基本不变。因此希望和gcc编译到中间语言RTL一样,在RTL层做点优化,部分求值。

    准确的说,先把e求值求出来,我的e语句的求值结果是function object

    然后在时节1装入 条件语句p

    在时节2 对(cond [p  e]) 用eval求值,就直接得到 想要的函数对象了

    代码大概这样

    ;a fn object
    (setv a_fn (fn [x] (+ 1 x)))
    ;a mock predicator
    (setv predicator True)
    ;inject predicator and a_fn into a (cond ..)
    (setv cond_expr `(cond [(~predicator) [~a_fn]]))
    ;eval at another place 
    (eval cond_expr)

    但是这样是报错的:

    got TypeError: Don't know how to wrap <class 'function'>: <function test_cond_list_fn.<locals>.<lambda> at 0x000001B879FD3D08>

    作者的解释说

    hy的eval是 首先要编译到python的ast。(类似gcc前端语言 编译到 RTL的AST)

    但“虽然可以把抽象对象放进hyExpression,但没法compile it”

    一方面   Hy的compiler 只接受 HyModel  (hyExpression  HyList  HySymbol 还有基本类型HyInt HyString 等等),

    另一方面:在 Python ast里,function object 没有显式的表示法, 所以就没有对应的HyModel  (同理可知,其他自定义的pyObejct也都这样了)

    ——但,不是完全无解。

    作者的给出的解决方案是,不要eval 含有function object  的hyExpression 但可以有 函数的 定义

     1 compile a function definition.

    => (setv a-fn '(fn [x] (+ 1 x)))
    => (setv cond-expr `(cond [True ~a-fn]))
    => (eval cond-expr)
    <function <lambda> at 0x0000020635231598>

    注意第一行是普通单引号',不是反引号`

    2 Or a function's symbol.

    => (defn b-fn [x] (- x 1))
    => (setv cond-expr2 `(cond [True b-fn]))
    => (eval cond-expr)
    <function <lambda> at 0x0000020635208378>

    Mmmm~  到了AST这个层次,还真是有点subtle 啊

    我还得消化一下。。 

  • 相关阅读:
    java架构之路-(面试篇)Mysql面试大全
    web工程的路径问题详解
    SQL知识点总结
    Mybatis简介
    mysql大全
    配置心得
    spring4.1.3+springmvc+mybatis3.2.1整合
    jstl标签
    jstl标签库
    Java并发控制机制
  • 原文地址:https://www.cnblogs.com/xuanmanstein/p/9417464.html
Copyright © 2011-2022 走看看