Search code examples
hy

how to eval a cond case and return function object?


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

when run

;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)

How to create the "cond_expr" so that get the result [a_fn] ?


Solution

  • In order to eval a HyExpression it must first be compiled to Python ast. While you're allowed to put arbitrary objects into a HyExpression, that does not mean you can compile it. (There has been a little talk of simulating this feature, but it's not available currently.)

    The Hy compiler can only do this for a certain set of data types called Hy Model types, or for a few other types that can be automatically converted to these Hy Models.

    There's no obvious way to represent a function object in Python ast, so there is no Hy Model for it. But you can 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>
    

    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>