问题标签 [clojure.spec]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
405 浏览

clojure - Clojure 的规范是否等同于 Wadler 的提议?

Wadler写了一篇令人惊叹的论文:Propositions as Types - 他在其中谈到了Howard-Curry对应关系,您可以根据程序类型检查程序行为。(对于给定的语言子集)。

最近Rich Hickey发布了Clojure 规范,用于定义数据和函数规范。

评论员在这里写道

从 Wadler 我们有 props ≅ types, specs ≅ props -> types ergo 可以进行静态规范/合同/类型检查。

我的问题是:Clojure 的规范是否等同于 Wadler 的提议?

0 投票
1 回答
174 浏览

clojure - #inst "2000" 的含义是什么及其背后的概念(clojrue.spec/inst-in #inst "2000" #inst "2010")

我正在研究clojure.spec,并遇到以下情况:

我想这#inst "2000"可能意味着 2000 年初的一个时间实例。但我无法通过 google 找到描述该符号及其背后概念的正确文档。

我也没有在我的 Clojure 教科书中学习过。

0 投票
2 回答
1533 浏览

clojure - 什么是 Clojure 规范?

我无法理解clojure的意图。规格

它解决了什么样的问题?

我们为什么要使用它?

0 投票
4 回答
2556 浏览

clojure - Clojure.Spec 验证的有意义的错误消息:pre

我在最后几天深入挖掘了 Clojure 和 ClojureScript 中的clojure.spec

到目前为止,我发现在依赖特定格式数据的公共函数中:pre和公共函数中使用规范作为保护是最有用的。:post

这种方法的问题是,我得到了一个java.lang.AssertionError: Assert failed: (s/valid? ::person person)没有任何关于什么不符合规范的信息。

有谁知道如何获得更好的错误信息:pre守卫:post

我知道conformand ,但这对那些或守卫explain*没有帮助。:pre:post

0 投票
3 回答
5320 浏览

clojure - Clojure.Spec 的规范放在哪里?

因此,我对Clojure.Spec的研究越来越深入。

我偶然发现的一件事是,把我的规格放在哪里。我看到三个选项:

全球规格文件

在大多数示例中,我在网上发现,spec.clj主命名空间中需要一个大文件。它具有所有“数据类型”(s/def)(s/fdef)功能。

临:

  • 一个文件来统治他们

反对:

  • 这个文件可能很大
  • 违反单一责任原则?

生产命名空间中的规范

你可以把你的(s/def)and放在你(s/fdef)的生产代码旁边。因此,实现和规范共存于同一个命名空间中。

临:

  • 实施和规范的协同定位
  • 一个命名空间 - 一个问题?

反对:

  • 生产代码可能会变得混乱
  • 一个命名空间 - 两个问题?

专用规范命名空间结构

然后我想,也许 Specs 是第三种代码(在生产和测试之后)。所以也许他们应该拥有自己的命名空间结构,如下所示:

临:

  • 规范的专用(但相关)命名空间

反对:

  • 您必须获取并要求正确的命名空间

谁有使用其中一种方法的经验?
还有其他选择吗?
您如何看待不同的选择?

0 投票
3 回答
1162 浏览

clojure - 如何 Clojure.Spec 引用类型(如原子)?

我想知道如何指定一个函数,它有一个参数,在原子中保存一个映射。

这显然不起作用:

我如何指定这a是对地图的引用?

0 投票
1 回答
2519 浏览

clojure - 如果它们位于单独的命名空间中,我如何将我的规范用于其预期目的?

clojure.spec指南中的一个例子是一个简单的选项解析规范:

稍后,在验证部分,定义了一个函数,该函数在内部conform使用此规范作为其输入:

由于该指南旨在易于从 REPL 中遵循,因此所有这些代码都在同一个命名空间中进行评估。不过,在这个答案中,@levand 建议将规范放在单独的命名空间中:

我通常将规范放在他们自己的名称空间中,以及他们所描述的名称空间中。

这会破坏::config上面的用法,但可以解决这个问题:

规范键名最好位于代码的命名空间中,而不是规范的命名空间。通过在关键字上使用命名空间别名仍然很容易做到这一点:

他继续解释说,规范和实现可以放在同一个命名空间中,但这并不理想:

虽然我当然可以将它们放在同一个文件中的规范代码旁边,但这会损害 IMO 的可读性。

但是,我无法看到它如何与destructuring一起使用。作为一个例子,我把上面的代码翻译成多个命名空间放在了一个小的Boot项目中。

boot.properties

src/example/core.clj

src/example/spec.clj

build.boot

但是,当然,当我实际运行它时,我得到一个错误:

(require 'example.spec)我可以通过添加to来解决这个问题build.boot,但这很丑陋且容易出错,并且只会随着我的规范命名空间数量的增加而变得更多。由于几个原因,我不能require从实现命名空间中指定规范命名空间。这是一个使用fdef.

boot.properties

src/example/spec.clj

src/example/core.clj

build.boot

第一个问题是最明显的:

在我的规范中factor,我想使用我的prime?谓词来验证返回的因子。这个factor规范很酷的一点是,假设prime?是正确的,它既完整地记录了factor函数,又消除了我为该函数编写任何其他测试的需要。但是,如果您认为这太酷了,您可以将其替换为pos?或其他东西。

不过,不出所料,当您再次尝试时,您仍然会收到一个错误boot run,这一次抱怨缺少or or or (无论哪个碰巧先尝试)的:args规范。这是因为,无论您是否使用名称空间,都不会使用该别名,除非您为其指定的符号命名为 var that already exists。如果 var 不存在,则符号不会被扩展。(为了更有趣,删除from看看会发生什么。)#'example.core/divisible?#'example.core/prime?#'example.core/factoraliasfdef:as corebuild.boot

如果要保留该别名,则需要删除(:require [example.spec])fromexample.core并添加(require 'example.spec)to build.boot。当然,这require需要for之后example.core,否则它将不起作用。到那时,为什么不直接把它require放进example.spec去呢?

所有这些问题都可以通过将规范与实现放在同一个文件中来解决。那么,我真的应该将规范放在与实现不同的命名空间中吗?如果是这样,我上面详述的问题如何解决?

0 投票
2 回答
1590 浏览

clojure - clojure.spec 中的禁止键

我正在关注clojure.spec 指南。我知道在使用 clojure.spec/keys 时可以声明必需和可选属性。

我不明白可选是什么意思。对我来说 :opt 什么也没做。

该指南承诺向我解释这一点,“我们稍后会看到可选属性在哪里有用”,但我找不到解释。我可以声明禁止键吗?或者以某种方式声明一组有效键等于 :req 和 :opt 中的键?

0 投票
2 回答
382 浏览

clojure - 如何指定混合地图?

写完这个答案后,我受到启发,尝试使用以下方法指定Clojure 的解构语言spec

顺序解构部分很容易用正则表达式指定(所以我在这里忽略它),但我被困在关联解构中。最基本的情况是从绑定表单到键表达式的映射:

但是 Clojure 也提供了几个特殊的键:

如何为可以通过将符合的地图和::assoc符合的地图合并在一起创建的地图创建规范?我知道有:::mappings::optsmerge

但这不起作用,因为merge基本上是and. 我正在寻找类似于or,但用于地图的东西。

0 投票
1 回答
764 浏览

clojure - 可变参数函数上的 Clojure 规范

我正在尝试为合并函数编写规范,该函数将函数和映射作为输入并使用函数来解决冲突。但是我为该函数编写的规范失败了。我试图弄清楚如何为这些函数编写规范。

下面是代码片段。

我得到的规范错误是: