问题标签 [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.
clojure - Clojure 的规范是否等同于 Wadler 的提议?
Wadler写了一篇令人惊叹的论文:Propositions as Types - 他在其中谈到了Howard-Curry对应关系,您可以根据程序类型检查程序行为。(对于给定的语言子集)。
最近Rich Hickey发布了Clojure 规范,用于定义数据和函数规范。
评论员在这里写道:
从 Wadler 我们有 props ≅ types, specs ≅ props -> types ergo 可以进行静态规范/合同/类型检查。
我的问题是:Clojure 的规范是否等同于 Wadler 的提议?
clojure - #inst "2000" 的含义是什么及其背后的概念(clojrue.spec/inst-in #inst "2000" #inst "2010")
我正在研究clojure.spec,并遇到以下情况:
我想这#inst "2000"
可能意味着 2000 年初的一个时间实例。但我无法通过 google 找到描述该符号及其背后概念的正确文档。
我也没有在我的 Clojure 教科书中学习过。
clojure - 什么是 Clojure 规范?
我无法理解clojure的意图。规格
它解决了什么样的问题?
我们为什么要使用它?
clojure - Clojure.Spec 验证的有意义的错误消息:pre
我在最后几天深入挖掘了 Clojure 和 ClojureScript 中的clojure.spec。
到目前为止,我发现在依赖特定格式数据的公共函数中:pre
和公共函数中使用规范作为保护是最有用的。:post
这种方法的问题是,我得到了一个java.lang.AssertionError: Assert failed: (s/valid? ::person person)
没有任何关于什么不符合规范的信息。
有谁知道如何获得更好的错误信息或:pre
守卫:post
?
我知道conform
and ,但这对那些或守卫explain*
没有帮助。:pre
:post
clojure - Clojure.Spec 的规范放在哪里?
因此,我对Clojure.Spec的研究越来越深入。
我偶然发现的一件事是,把我的规格放在哪里。我看到三个选项:
全球规格文件
在大多数示例中,我在网上发现,spec.clj
主命名空间中需要一个大文件。它具有所有“数据类型”(s/def)
和(s/fdef)
功能。
临:
- 一个文件来统治他们
反对:
- 这个文件可能很大
- 违反单一责任原则?
生产命名空间中的规范
你可以把你的(s/def)
and放在你(s/fdef)
的生产代码旁边。因此,实现和规范共存于同一个命名空间中。
临:
- 实施和规范的协同定位
- 一个命名空间 - 一个问题?
反对:
- 生产代码可能会变得混乱
- 一个命名空间 - 两个问题?
专用规范命名空间结构
然后我想,也许 Specs 是第三种代码(在生产和测试之后)。所以也许他们应该拥有自己的命名空间结构,如下所示:
临:
- 规范的专用(但相关)命名空间
反对:
- 您必须获取并要求正确的命名空间
谁有使用其中一种方法的经验?
还有其他选择吗?
您如何看待不同的选择?
clojure - 如何 Clojure.Spec 引用类型(如原子)?
我想知道如何指定一个函数,它有一个参数,在原子中保存一个映射。
这显然不起作用:
我如何指定这a
是对地图的引用?
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/factor
alias
fdef
:as core
build.boot
如果要保留该别名,则需要删除(:require [example.spec])
fromexample.core
并添加(require 'example.spec)
to build.boot
。当然,这require
需要在for之后example.core
,否则它将不起作用。到那时,为什么不直接把它require
放进example.spec
去呢?
所有这些问题都可以通过将规范与实现放在同一个文件中来解决。那么,我真的应该将规范放在与实现不同的命名空间中吗?如果是这样,我上面详述的问题如何解决?
clojure - clojure.spec 中的禁止键
我正在关注clojure.spec 指南。我知道在使用 clojure.spec/keys 时可以声明必需和可选属性。
我不明白可选是什么意思。对我来说 :opt 什么也没做。
该指南承诺向我解释这一点,“我们稍后会看到可选属性在哪里有用”,但我找不到解释。我可以声明禁止键吗?或者以某种方式声明一组有效键等于 :req 和 :opt 中的键?
clojure - 可变参数函数上的 Clojure 规范
我正在尝试为合并函数编写规范,该函数将函数和映射作为输入并使用函数来解决冲突。但是我为该函数编写的规范失败了。我试图弄清楚如何为这些函数编写规范。
下面是代码片段。
我得到的规范错误是: