python + lisp hy的新手注记2 eval, HyModel and python AST

Posted 永远的幻想

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 啊

我还得消化一下。。 

 

以上是关于python + lisp hy的新手注记2 eval, HyModel and python AST的主要内容,如果未能解决你的问题,请参考以下文章

ArcGIS微课1000例0038:注记(Annotation)的使用方法

ArcGIS微课1000例0053:注记(水平沿直线跟随要素牵引线弯曲注记)的创建与编辑

arcgis10如何添加注记

ArcGIS微课1000例0054:尺寸注记的创建与编辑

ArcGIS微课1000例0039:ArcGIS注记转CAD注记的方法

翻译:Lisp Style Tips for the Beginner - Heinrich Taube