TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

What Clojure Spec is and what you can do with it

263 点作者 icey超过 4 年前

13 条评论

gw超过 4 年前
I think the instrumenting and generator stuff gets disproportionate attention. For me by far the biggest win from spec has been with parsing. This completely changes how you&#x27;d write a library that takes a data structure and parses it into something meaningful (for example, what hiccup does for html or what honeysql does for sql).<p>In the past, this required a lot of very ugly parsing code and manual error-checking. With spec, you write specs and call s&#x2F;conform. If it failed, you get a nice error, especially if you pair it with expound. If it succeeded, you get a destructured value that is really easy to pull data out of. I&#x27;ve done this in a half dozen different libraries and i&#x27;m pretty sure i wouldn&#x27;t have even written them without spec.
评论 #24433500 未加载
评论 #24435247 未加载
评论 #24435219 未加载
评论 #24433419 未加载
评论 #24434983 未加载
评论 #24433785 未加载
tekacs超过 4 年前
As a very heavy user of spec, I’ve since switched to using Malli [0], which is similar but uses plain data to model specs (and doesn’t use Clojure Spec at all).<p>Also, Malli is being funded &#x2F; supported by Clojurists Together [1], which is a wonderful initiative that’s also worth a look.<p>[0]: <a href="https:&#x2F;&#x2F;github.com&#x2F;metosin&#x2F;malli" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;metosin&#x2F;malli</a><p>[1]: <a href="https:&#x2F;&#x2F;www.clojuriststogether.org&#x2F;news&#x2F;q3-2020-funding-announcement&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.clojuriststogether.org&#x2F;news&#x2F;q3-2020-funding-anno...</a>
jwr超过 4 年前
I found spec very useful and use it more and more. I&#x27;m looking forward to newer revisions, with support for optionality, it&#x27;s been a big problem area in my case.<p>Here&#x27;s a quick list of gotchas (well, they got me, so perhaps other people will find this list useful):<p>* `s&#x2F;valid?` does not actually tell you that the data is valid<p>The naming of `s&#x2F;valid?` suggests that you can call it on your data and find out if the data is valid according to the spec. This isn&#x27;t true. What it actually tells you is if the data, <i>when conformed</i>, will be valid according to the spec. If you pass the data as-is to your functions (without passing it through `s&#x2F;conform`), you might find that they will be surprised at what they get.<p>* Conformers are likely not what you think. They are not intended for coercion and have many pitfalls (for example, multi-specs dispatch on unconformed value).<p>* s&#x2F;merge doesn&#x27;t necessarily do what you wanted if you&#x27;re using conformers, only the last spec passed to merge will be used for s&#x2F;conform (but you&#x27;re not using conformers, right?)<p>* specs are checked eagerly. If you think that (s&#x2F;valid? ::my-spec x) will only check ::my-spec, that is not the case. It will check any key of x found in the spec registry.<p>I settled on a subset of spec, because of the pitfalls.
评论 #24434913 未加载
评论 #24433148 未加载
评论 #24437330 未加载
hospadar超过 4 年前
We use spec A LOT to validate a huge config file&#x2F;DSL thing for our internal ETL application.<p>My general feelings are:<p>- spec is great, you should use it, the composeability and flexibility are awesome features.<p>- I&#x27;ve never once used conformers - maybe I just don&#x27;t &quot;get it&quot; (which if so, speaks badly of them I think since I&#x27;ve been heavily using spec for years), but the use cases for them seem strange to me and I feel they cause more confusion than they&#x27;re worth. I wish they were separated out into more separate&#x2F;optional functionality.<p>- It&#x27;s SO MUCH more powerful than things like JSON schema, but that comes at the cost of portability - there&#x27;s no way we could send our spec over the wire and have someone else in a different environment use it. But also, there&#x27;s no way we could implement some of our features in a tool like JSON Schema [and have it be portable] (&quot;Is the graph represented by this data-structure free of cycles?&quot; &quot;When parsed by the spark SQL query parser, is this string a syntactically valid SQL query?&quot;).<p>- Being able to spec the whole data input up front has saved hundreds of lines of error-checking code and allows us to give much better errors up-front to our users and devs<p>- Spec has a lot of really cool features for generative testing, but we rarely use them since we&#x27;ve implemented lots of complex specs where it&#x27;s not really practical to implement a generator (i.e. &quot;strings which are valid sql queries&quot; or &quot;maps of maps of maps which when loaded in a particular way meet all the other requirements and are also valid DAGs&quot;). I feel torn about this because the test features are great, but the extreme extensibility of spec is what I love most about it. I haven&#x27;t often found a scenario where I actually have a use for the generative features (either the data is so simple I don&#x27;t need them, or so complex that they don&#x27;t work).
评论 #24433434 未加载
评论 #24435157 未加载
评论 #24433171 未加载
评论 #24433172 未加载
Jeaye超过 4 年前
I strongly recommend that anyone using spec for validation should check out Orchestra, to instrument the functions and have them automatically validated on each and every call: <a href="https:&#x2F;&#x2F;github.com&#x2F;jeaye&#x2F;orchestra" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;jeaye&#x2F;orchestra</a><p>For my team, generators and parsing are basically useless with spec. We just don&#x27;t use them. But describing the shape of data and instrumenting our functions, using defn-spec, to ensure that the data is correct as it flows through the system is exactly what we want and nothing I&#x27;ve seen in Clojure land does it like spec + Orchestra can.<p>I think part of this may boil down to different types of testing. We primarily use functional testing, especially for our back-end, so we&#x27;re starting from HTTP and hitting each endpoint as the client would. Then we ensure that the response is correct and any effects we wanted to happen did happen. This is much closer to running production code, but we do it with full instrumentation. Being able to see an error describing exactly how the data is malformed, which function was called, and what the callstack was is such a relief in Clojure.<p><pre><code> Call to #&#x27;com.okletsplay.back-end.challenge.lol.util&#x2F;provider-url did not conform to spec. -- Spec failed -------------------- Function arguments (nil) ^^^ should satisfy (-&gt; com.okletsplay.common.transit.game.lol&#x2F;region-&gt;info keys set) -- Relevant specs ------- :com.okletsplay.common.transit.game.lol&#x2F;region: (clojure.core&#x2F;-&gt; com.okletsplay.common.transit.game.lol&#x2F;region-&gt;info clojure.core&#x2F;keys clojure.core&#x2F;set) ------------------------- Detected 1 error</code></pre>
评论 #24435074 未加载
reitzensteinm超过 4 年前
My pet project is a partial evaluator for Clojure code that uses data generated from spec to fuzz code and optimize it. The coverage is accepted as complete, so there are no guards and deoptimizations like you&#x27;d have in a JIT, the programs are just wrong.<p>It seems like a fairly powerful technique, although you couldn&#x27;t ever rely on it with production code. After several years of tinkering I managed to get a Forth interpreter written in Clojure executing a specific input string partially evaluating down to OpenGL shader code, to hardware accelerate my friend&#x27;s Stackie experiment (link to his version below).<p>(nth (sort [0 n 5]) 1) where sort is a merge sort also successfully compiles down to just the branches you&#x27;d hand optimize it to, which is Graal&#x27;s party trick. Although they&#x27;re solving the problem in a bulletproof general way, so the difficulty is incomparable.<p>The eventual goal is to write Clojure in Clojure without it being horrendously inefficient.<p><a href="http:&#x2F;&#x2F;blag.fingswotidun.com&#x2F;2015_09_16_archive.html" rel="nofollow">http:&#x2F;&#x2F;blag.fingswotidun.com&#x2F;2015_09_16_archive.html</a>
dustingetz超过 4 年前
At Hyperfiddle we are using spec to specify UIs, so e.g. (s&#x2F;fdef foo :args (s&#x2F;cat :search-needle string? :selection keyword?) :ret (s&#x2F;coll-of (s&#x2F;keys ...))) describes exactly what you need to render a masterlist table with some query parameters. It&#x27;s being used with pilot customers, now in production. This stuff works!
krn超过 4 年前
Malli[1] and specmonstah[2] are my favourite Clojure(Script) libraries built on top of Clojure Spec.<p>[1] <a href="https:&#x2F;&#x2F;github.com&#x2F;metosin&#x2F;malli" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;metosin&#x2F;malli</a><p>[2] <a href="https:&#x2F;&#x2F;github.com&#x2F;reifyhealth&#x2F;specmonstah" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;reifyhealth&#x2F;specmonstah</a>
评论 #24433626 未加载
john-shaffer超过 4 年前
If you&#x27;re considering using spec, you should know that spec alpha2 is significantly different internally, and is much easier to write tooling for, but has not been ported to ClojureScript. I would highly recommend trying alpha2 if you&#x27;re not using CLJS, even if it&#x27;s a little less stable.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;clojure&#x2F;spec-alpha2" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;clojure&#x2F;spec-alpha2</a>
kmclean超过 4 年前
I find spec really interesting but struggle to find a good fit for it in my projects. I end up getting bogged down writing generators and give up, or end up breaking down functions into such small pieces that speccing every one of them results in an unreasonable proliferation of specs and generators. This was an interesting and helpful overview of some different ideas about how to take advantage of spec, so thank you!<p>Also I definitely share your feelings about clojure massively increasing my job satisfaction and teaching me how to think about programming in a new (and better tbh) way.
评论 #24433182 未加载
amgreg超过 4 年前
&gt; Still alpha: spec is still alpha and it looks like it will remain like that since the intention is for spec2 to completely replace it in the future.<p>Out of curiosity for the folks in the know: why is this the state of affairs? Where we have the library in alpha for a long time, and being replaced already?
评论 #24439017 未加载
fnord77超过 4 年前
for simple typing, does this seem more complex than plumatic&#x2F;schema?
评论 #24436267 未加载
tanrax超过 4 年前
Very interesting