【问题标题】:Checking Clojure pre-conditions without running the function?在不运行函数的情况下检查 Clojure 前置条件?
【发布时间】:2015-06-01 22:17:36
【问题描述】:

我有一个函数可以完成一些(可能很长)工作 (defn workwork [x] ...) 和一些其他函数来检查调用是否会提前成功 (defn workwork-precondition-1 [x] ...)

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

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

特别是,有什么方法可以在不运行函数体的情况下评估函数的前置条件?

【问题讨论】:

    标签: clojure idioms preconditions


    【解决方案1】:

    您可以将您的先决条件收集到一个函数中:

    (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)]}
    

    对于任何其他 arities 的 :arglists 条目也是如此。

    这里有两个警告:

    1. Var 元数据中自动生成的:arglists 条目可能会被覆盖。覆盖 :arglists 会导致上述有用的自动生成的元数据被丢弃。

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

      李>

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

    【讨论】:

      【解决方案2】:

      要在不运行函数体的情况下评估函数前置条件,可以使用robert-hookehttps://github.com/technomancy/robert-hooke/

      
          (use 'robert.hooke)
      
          (defn workwork [x] ...)
      
          (defn workwork-precondition-1 
            [f x]
            (if (precondition-1-satisfied? x)
              (f x)
              :precondition-1-not-satisfied))
      
          (add-hook #'workwork #'workwork-precondition-1)
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多