在不运行函数的情况下检查Clojure前置条件?

在不运行函数的情况下检查Clojure前置条件?,clojure,idioms,preconditions,Clojure,Idioms,Preconditions,我有一个函数可以执行一些(可能很长的)工作(defn-workwork[x]…),还有一些其他函数可以检查调用是否会提前成功(defn-work-premission-1[x]…) 每次调用workwork时(例如,使用:pre)都应评估前提条件函数。前提条件函数也应在单个函数中收集(和:ed),并直接提供给客户端代码(例如,禁用按钮) 在Clojure中解决这个问题的惯用方法是什么,同时避免代码重复 特别是,是否有任何方法可以在不运行函数体的情况下评估函数的前提条件?您可以将前提条件收集到函数

我有一个函数可以执行一些(可能很长的)工作
(defn-workwork[x]…)
,还有一些其他函数可以检查调用是否会提前成功
(defn-work-premission-1[x]…)

每次调用
workwork
时(例如,使用
:pre
)都应评估前提条件函数。前提条件函数也应在单个函数中收集(和:ed),并直接提供给客户端代码(例如,禁用按钮)

在Clojure中解决这个问题的惯用方法是什么,同时避免代码重复


特别是,是否有任何方法可以在不运行函数体的情况下评估函数的前提条件?

您可以将前提条件收集到函数中:

(defn foo-pre [x]
  (even? x))
然后在
:pre
样式的前提条件中调用函数:

(defn foo [x]
  {:pre [(foo-pre x)]}
  …)
对于使用
defn
引入的函数,您可以从Var上的元数据中提取
:pre
样式的前提条件:

(-> #'foo meta :arglists first meta)
;= {:pre [(foo-pre x)]}
类似地,对于
:arg列出了任何其他算术的
条目

这里有两个警告:

  • Var元数据中自动生成的
    :arglists
    条目可能会被覆盖。重写
    :arglists
    会导致抛出上述类型的有用的自动生成元数据

  • 上述
    (>#'foo meta…
    表达式返回的
    {:pre[(foo pre x)]}
    值包含
    foo pre
    作为文字符号–您有责任找出它在
    foo
    定义点引用的函数。(这可能是也可能是不可能的–例如,
    foo
    可以是顶级
    let
    letfn
    表单中的
    defn
    ,带有
    foo-pre
    本地函数。)


  • 最后,匿名函数可以使用
    :pre
    :post
    ,但目前没有从函数本身提取它们的机制。

    您可以将前提条件收集到函数中:

    (defn foo-pre [x]
      (even? x))
    
    然后在
    :pre
    样式的前提条件中调用函数:

    (defn foo [x]
      {:pre [(foo-pre x)]}
      …)
    
    对于使用
    defn
    引入的函数,您可以从Var上的元数据中提取
    :pre
    样式的前提条件:

    (-> #'foo meta :arglists first meta)
    ;= {:pre [(foo-pre x)]}
    
    类似地,对于
    :arg列出了任何其他算术的
    条目

    这里有两个警告:

  • Var元数据中自动生成的
    :arglists
    条目可能会被覆盖。重写
    :arglists
    会导致抛出上述类型的有用的自动生成元数据

  • 上述
    (>#'foo meta…
    表达式返回的
    {:pre[(foo pre x)]}
    值包含
    foo pre
    作为文字符号–您有责任找出它在
    foo
    定义点引用的函数。(这可能是也可能是不可能的–例如,
    foo
    可以是顶级
    let
    letfn
    表单中的
    defn
    ,带有
    foo-pre
    本地函数。)


  • 最后,匿名函数可以使用
    :pre
    :post
    ,但目前没有从函数本身提取它们的机制。

    要在不运行函数体的情况下评估函数前提条件,可以使用
    robert hooke


    要在不运行函数体的情况下计算函数前提条件,可以使用
    robert hooke
    library