--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
(def BinaryTree (maybe ;; any empty binary tree is represented by nil {:value long :left (recursive #'BinaryTree) :right (recursive #'BinaryTree)}))
>
> I did most of the design of spec in a (paper) notebook.
>
> The rationale tries to capture the salient driving forces.
>
> If there is a specific question you have I’d be happy to answer.
>
> Rich
>
> > On May 23, 2016, at 4:11 PM, Ivan Reese <ivanreese <at> gmail.com>
wrote:
> >
> > Is there anywhere we can read anything about the design process behind
clojure.spec? I took a look at
> dev.clojure.org / JIRA, but I haven't yet found anything on the topic.
> >
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To post to this group, send email to clojure <at> googlegroups.com
> > Note that posts from new members are moderated - please be patient with
your first post.
> > To unsubscribe from this group, send email to
> > clojure+unsubscribe <at> googlegroups.com
> > For more options, visit this group at
> > http://groups.google.com/group/clojure?hl=en
> > ---
> > You received this message because you are subscribed to the Google
Groups "Clojure" group.
> > To unsubscribe from this group and stop receiving emails from it, send
an email to clojure+unsubscribe <at> googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
>
I'd love to hear Rich give a talk about this (the design process, his
rationale, and so forth) -- especially how it relates to static type
systems. I know that there's write-up already on the clojure website, but
this would be a great talk also.
Can't wait to use this.
Thank you for spending you hammock time on this important feature/library. Looking forward to using it.
Alan
I was a bit puzzled by the :req-un / :opt-un stuff in maps. Am I right that there is a requirement here for the keys to be namespaced but the actual namespace is completely irrelevant / ignored?
(defn thing [m]
(+ (:a m) (:b m) (or (:c m) 1)))
(s/fdef thing
:args (s/cat :map (s/and (s/keys :req-un [:x/a :y/b]
:opt-un [:z/c])
(s/map-of keyword? number?)))
:ret number?)
I tried several namespace prefixes here and it seemed I can use anything and they don’t even need to be consistent.
Wouldn’t it be easier to just allow un-namespaced keywords here? Or is there some aspect of the namespacing here that I’m missing?
Sean Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org
From: Rich Hickey
Sent: Monday, May 23, 2016 7:12 AM
To: clo...@googlegroups.com
Subject: clojure.spec
Introducing clojure.spec
I'm happy to introduce today clojure.spec, a new core library and support for data and function specifications in Clojure.
Better communication
Clojure is a dynamic language, and thus far we have relied on documentation or external libraries to explain the use and behavior of functions and libraries. But documentation is difficult to produce, is frequently not maintained, cannot be automatically checked and varies greatly in quality. Specs are expressive and precise. Including spec in Clojure creates a lingua franca with which we can state how our programs work and how to use them.
More leverage and power
A key advantage of specifications over documentation is the leverage they provide. In particular, specs can be utilized by programs in ways that docs cannot. Defining specs takes effort, and spec aims to maximize the return you get from making that effort. spec gives you tools for leveraging specs in documentation, validation, error reporting, destructuring, instrumentation, test-data generation and generative testing.
Improved developer experience
Error messages from macros are a perennial challenge for new (and experienced) users of Clojure. specs can be used to conform data in macros instead of using a custom parser. And Clojure's macro expansion will automatically use specs, when present, to explain errors to users. This should result in a greatly improved experience for users when errors occur.
More robust software
Clojure has always been about simplifying the development of robust software. In all languages, dynamic or not, tests are essential to quality - too many critical properties are not captured by common type systems. spec has been designed from the ground up to directly support generative testing via test.check https://github.com/clojure/test.check. When you use spec you get generative tests for free.
Taken together, I think the features of spec demonstrate the ongoing advantages of a powerful dynamic language like Clojure for building robust software - superior expressivity, instrumentation-enhanced REPL-driven development, sophisticated testing and more flexible systems. I encourage you to read the spec rationale and overview http://clojure.org/about/spec. Look for spec's inclusion in the next alpha release of Clojure, within a day or so.
Note that spec is still alpha, and some details are likely to change. Feedback welcome.
I hope you find spec useful and powerful!
Rich
--
I was a bit puzzled by the :req-un / :opt-un stuff in maps. Am I right that there is a requirement here for the keys to be namespaced but the actual namespace is completely irrelevant / ignored?
(defn thing [m]
(+ (:a m) (:b m) (or (:c m) 1)))
(s/fdef thing
:args (s/cat :map (s/and (s/keys :req-un [:x/a :y/b]
:opt-un [:z/c])
(s/map-of keyword? number?)))
:ret number?)
I tried several namespace prefixes here and it seemed I can use anything and they don’t even need to be consistent.
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@googlegroups.com.
OK, that explains a lot. Thank you. That needs to be clarified on the web page I think…
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
user=> (require '[clojure.spec :as s])(s/def ::even? (s/and integer? even?))(s/def ::odd? (s/and integer? odd?))(s/def ::a integer?)(s/def ::b integer?)(s/def ::c integer?)(def s (s/cat :forty-two #{42}:odds (s/+ ::odd?):m (s/keys :req-un [::a ::b ::c]):oes (s/* (s/cat :o ::odd? :e ::even?)):ex (s/alt :odd ::odd? :even ::even?)))user=> (s/conform s [42 11 13 15 {:a 1 :b 2 :c 3} 1 2 3 42 43 44 11]){:forty-two 42,:odds [11 13 15],:m {:a 1, :b 2, :c 3},:oes [{:o 1, :e 2} {:o 3, :e 42} {:o 43, :e 44}],:ex {:odd 11}}
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
On May 24, 2016, at 8:10 AM, Alex Miller <al...@puredanger.com> wrote:The first use is a namespace alias and the second is a var - they don't overlap in usage.
Yes, you can create recursive definitions by registering a spec that refers to itself via registered name (a namespaced keyword).
On Monday, May 23, 2016 at 11:13:24 AM UTC-5, Andrey Grin wrote:Is it planned to support recursive definitions? Example from.plumatic schema:(def BinaryTree (maybe ;; any empty binary tree is represented by nil {:value long :left (recursive #'BinaryTree) :right (recursive #'BinaryTree)}))
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
The philosophy is - generative testing has made sure your function complies with the specs. So, testing the :ret and :fn properties over and over is redundant and serves no point.
OTOH, you may encounter user- or externally-supplied data at runtime and want to use the facilities of spec to validate/process it. Then you can use valid? or conform *explicitly* to do so.
> Would you ever expect to use fdef/instrument active in production for validation
No, definitely not. It’s that kind of runtime checking (and expense) that gives some dynamic lang checking systems a bad rep.
The philosophy is - generative testing has made sure your function complies with the specs. So, testing the :ret and :fn properties over and over is redundant and serves no point.
OTOH, you may encounter user- or externally-supplied data at runtime and want to use the facilities of spec to validate/process it. Then you can use valid? or conform *explicitly* to do so.
The intent is that running with wrappers (instrumentation) should be done only during testing.
|
Species - appearance, form, sort, kind, equivalent to spec (ere) to look, regard Specify - species + -ficus -fic (make) |
A specification is about how something 'looks', but is, most importantly, something that is looked at. Specs should be readable, composed of 'words' (predicate functions) programmers are already using, and integrated in documentation.
What's the difference between clojure.spec/or and clojure.spec/alt? They seem to accept the same inputs, multiple keyword-predicate pairs, and output tagged values when used with clojure.spec/conform. Is clojure.spec/or usable within a regular expression?
--
I did most of the design of spec in a (paper) notebook.
The rationale tries to capture the salient driving forces.
If there is a specific question you have I’d be happy to answer.
Rich
> On May 23, 2016, at 4:11 PM, Ivan Reese <ivan...@gmail.com> wrote:
>
> Is there anywhere we can read anything about the design process behind clojure.spec? I took a look at dev.clojure.org / JIRA, but I haven't yet found anything on the topic.
spec is not a contract system.
> Would you ever expect to use fdef/instrument active in production for validation
No, definitely not. It’s that kind of runtime checking (and expense) that gives some dynamic lang checking systems a bad rep.
The philosophy is - generative testing has made sure your function complies with the specs. So, testing the :ret and :fn properties over and over is redundant and serves no point.
The intent is that running with wrappers (instrumentation) should be done only during testing.
> On May 24, 2016, at 7:43 PM, Elliot <ell...@deck36.net> wrote:
>
> Super super excited for this feature, thanks so much for creating this.
>
> In the runtime-validation case, the guide mentions:
>
> 1. Calling `valid?` in a precondition
> 2. Calling `conform` in the fn implementation
>
> However neither of these appear to use the `fdef`/`instrument` combo, which seems the closest to "type annotating" the function. Would you ever expect to use fdef/instrument active in production for validation, or is that a misunderstanding of its use?
>
> Thanks!
>
> - E
>
>
> On Tuesday, May 24, 2016 at 11:12:59 AM UTC-7, scott stackelhouse wrote:
> I restructured my data to make this section an optional sub-map, which I think is actually better anyway.
>
> On Tuesday, May 24, 2016 at 11:08:27 AM UTC-7, scott stackelhouse wrote:
> Ok.
>
> Thanks all who have worked on this, btw. It is incredibly timely for me and is already great help for a work project.
>
> --Scott
>
> On Tuesday, May 24, 2016 at 10:57:26 AM UTC-7, Rich Hickey wrote:
> ‘and' and ‘or’ are not currently supported in :opt
>
>
> > On May 24, 2016, at 1:45 PM, scott stackelhouse <scott.sta...@gmail.com> wrote:
> >
> > I'm having a problem writing a spec for a map with some required keywords and some optional keywords. The caveat here is that the optional keywords are all or none... that is they are optional but if one is present they must all be present.
> >
> > What I tried to write was:
> >
> > (s/keys :req [::a ::b ::c] :opt [(and ::d ::e ::f)])
> >
> > and that fails an assertion. It appears that the logicals (and, or) are not allowed in the optional section?
> >
> > Am I thinking about this in the wrong way?
> >
> > --Scott
Hello,How can I differentiate between the same keyword, but with difference semantics? Example:
{:attack 100:bonus {:attack {:category {:heavy 100}}}}I have:(s/def ::attack (s/and pos? #(<= 1 1000))(s/def ::bonus (s/keys :req-un [::attack ; <---Is there a way to do this?--Another question: is there a way to spec a fn that handles channels? Something like:
(s/fdef some-fn:args (s/cat :ch (s/chan ::unq/model)):ret (s/chan :unq/model))--And yet another: I have a game project with some test.check scenarios. The test run takes 8s without instrumenting and 22s with instrumentation, and this makes me think on starting to split tests in test suites. Is there something to handle this in clojure.test?
Thanks!
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@googlegroups.com.