<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged spec 2</title>
<link>https://ask.clojure.org/index.php/tag/spec+2</link>
<description></description>
<item>
<title>clojure spec vs plumatic schema</title>
<link>https://ask.clojure.org/index.php/13817/clojure-spec-vs-plumatic-schema</link>
<description>&lt;p&gt;A colleague brought to my attention that Clojure Spec is still alpha and that Plumatic Schema might be a better way to do the same tipe of spec.&lt;/p&gt;
&lt;p&gt;Do you folks have any advice?&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
</description>
<category>Spec</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13817/clojure-spec-vs-plumatic-schema</guid>
<pubDate>Wed, 17 Apr 2024 04:11:04 +0000</pubDate>
</item>
<item>
<title>Spec 2: Closed Generators</title>
<link>https://ask.clojure.org/index.php/12198/spec-2-closed-generators</link>
<description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;is it possible to get a &quot;closed&quot; generator from a `s/select` form&lt;br&gt;
and/or make it the default in Spec 2?&lt;/p&gt;
&lt;p&gt;From the example in the Wiki:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(ns user
  (:require [clojure.alpha.spec :as s]))

(s/def ::id int?)
(s/def ::first string?)
(s/def ::last string?)
(s/def ::user (s/schema [::id ::first ::last ::addr]))

(s/def ::my-user (s/select ::user [::id]))

(s/exercise ::my-user)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This generates users that have more keys than what I selected:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;([#:user{:id 0} #:user{:id 0}]
 [#:user{:addr #:user{:city &quot;1&quot;}, :first &quot;O&quot;, :id 0}
  #:user{:addr #:user{:city &quot;1&quot;}, :first &quot;O&quot;, :id 0}])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I believe it is the same data which the `s/schema` for the `::user`&lt;br&gt;
spec generates. My guess is this just hasn't been implemented yet.&lt;/p&gt;
&lt;p&gt;Would it be possible to support this?  &lt;/p&gt;
</description>
<category>Spec</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12198/spec-2-closed-generators</guid>
<pubDate>Mon, 12 Sep 2022 08:36:26 +0000</pubDate>
</item>
<item>
<title>Clojure Spec 2. Unexpected s/with-gen behaviour</title>
<link>https://ask.clojure.org/index.php/12185/clojure-spec-2-unexpected-s-with-gen-behaviour</link>
<description>&lt;p&gt;When using regular expression operators (&lt;code&gt;s/alt&lt;/code&gt; &lt;code&gt;s/cat&lt;/code&gt; etc ) to describe sequences, &lt;code&gt;s/with-gen&lt;/code&gt; doesn't work as I would have expected. It completely ignores the generator passed to the definition. Eg:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(require '[clojure.alpha.spec :as s])
(require '[clojure.alpha.spec.gen :as gen])
(s/def ::some-spec 
 (s/with-gen string? (constantly (gen/return &quot;olar&quot;))))

(gen/sample (s/gen ::some-spec))
 ;;=&amp;gt; (&quot;olar&quot; &quot;olar&quot; &quot;olar&quot; &quot;olar&quot; &quot;olar&quot; &quot;olar&quot; &quot;olar&quot; &quot;olar&quot; &quot;olar&quot; &quot;olar&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; The above generator works as I would expected, now if we try to create a similar one for s/alt we get unexpected results: &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(s/def ::some-other-spec 
 (s/with-gen
  (s/alt :greetings #{:olar :oizito :oi :hello :hey :yo :hallo}
             :farewell #{:bye :bye-bye :hasta-la-vista :tchussy :tchau-kakao})
  (constantly (gen/return [:tchau-kakao]))))

(gen/sample (s/gen ::some-other-spec))
;;=&amp;gt; =&amp;gt; ([:olar] [:hasta-la-vista] [:hallo] [:hallo] [:tchussy] [:oi] [:bye-bye] [:tchussy] [:tchau-kakao] [:yo])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Is this a bug or is it expected somehow?&lt;/p&gt;
</description>
<category>Spec</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12185/clojure-spec-2-unexpected-s-with-gen-behaviour</guid>
<pubDate>Fri, 09 Sep 2022 10:49:50 +0000</pubDate>
</item>
<item>
<title>What is the canonical way to share bundles of predicates + generators in clojure spec?</title>
<link>https://ask.clojure.org/index.php/11282/what-canonical-share-bundles-predicates-generators-clojure</link>
<description>&lt;p&gt;I've been trying out Clojure spec and I often face situations in which I have to come up with a custom predicate function. Then sometimes these predicate functions require a custom generator. How can I share this predicate+generator bundle between different attributes?&lt;/p&gt;
&lt;p&gt;(Also not so important but, can I call this bundle of predicate-fn + generator a spec?)&lt;/p&gt;
&lt;p&gt;Example:&lt;br&gt;
Suppose I have the custom predicate:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   (defn local-date? [x]
      (instance? LocalDate x))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then I define a brand new generator function for it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn local-date-generator []
  (gen/fmap #(LocalDate/ofInstant (Instant/ofEpochMilli %) (ZoneId/of &quot;UTC&quot;)) 
                       (gen/large-integer)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can go on and define an attribute like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(s/def :person/birth-date (s/with-gen local-date local-date-generator))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;but then I would have to define this &lt;code&gt;s/with-gen&lt;/code&gt; every time I create a LocalDate attribute. &lt;/p&gt;
&lt;p&gt;How can I abstract that away?&lt;/p&gt;
&lt;p&gt;I've come to the conclusion that the right way to do that would be to define an attribute in a namespace (e.g &lt;code&gt;myprojec.specs&lt;/code&gt;) in which I create an attribute with that spec &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(s/def ::local-date (s/with-gen local-date local-date-generator))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then just re-use it elsewhere&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(s/def :person/birth-date :myproject.specs/localdate)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What are the alternatives? &lt;/p&gt;
</description>
<category>Libs</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11282/what-canonical-share-bundles-predicates-generators-clojure</guid>
<pubDate>Wed, 17 Nov 2021 11:51:41 +0000</pubDate>
</item>
<item>
<title>Spec2: Use case for multi-spec as Schema provider</title>
<link>https://ask.clojure.org/index.php/10696/spec2-use-case-for-multi-spec-as-schema-provider</link>
<description>&lt;p&gt;I have a scenario where I'd like to define some attributes that are internal and common, and some other attributes that are external and dynamic, both related to the same &quot;things&quot;. Specifically, I am trying to model a trading library. There are many different exchanges/brokers/services, but all of them talk about similar/equivalent things.&lt;br&gt;
   Let's take the example of an order, you can have some attributes that can be common in all services (they don't necessarily appear on all services):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(spec/def :order/id string?)
(spec/def :order/quantity number?)
(spec/def :order/side #{:buy :sell})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, every external service can have specific attributes related to how that service handles orders:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(spec/def :service1-order/execution-instructions (spec/coll-of string?))
(spec/def :service2-order/iceberg-quantity (spec/coll-of string?))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I was thinking on having a multi-spec returning schemas, so each service can define what schema to use for an order, on a key like :service/name, but all of them can be &quot;selected&quot; from :order/order. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defmulti order-schema :service/name)

(defmethod order-schema :service1
  [_]
  (spec/schema [:order/id :order/quantity :order/side :service1-order/execution-instructions]))

(defmethod order-schema :service2
  [_]
  (spec/schema [:order/id :order/quantity :order/side :service2-order/iceberg-quantity]))

(defmethod order-schema :default
  [_]
  (spec/schema [:order/id :order/quantity :order/side]))

(spec/def :order/order (spec/multi-spec order-schema :service/name))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This can be useful also when nesting objects. Imagine I have an account that will contain orders. The account can also be specced as a multi-spec for each service:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(spec/def :account/id string?)
(spec/def :account/orders (spec/coll-of :order/order))

(spec/def :service1-account/type #{:spot :margin :futures})

(defmulti account-schema :service/id)

(defmethod account-schema :service1
  [_]
  (spec/schema [:account/id :account/orders :service1-account/type]))

(defmethod account-schema :default
  [_]
  (spec/schema [:account/id :account/orders]))

(spec/def :account/account (spec/multi-spec account-schema :service/id))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This would allow to select in the following manner: &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(spec/def ::service1-account-info (spec/select :account/account [:service1-account/type :account/orders {:account/orders [:order/id :order/quantity :service1-order/execution-instructions]}]))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This way, external services can specify the information they handle about the common layer domain attributes and entities, as well as specify their specific attributes. The user is able to reuse a set of common functions that operate on the common attributes, and if different services provide these common attributes, they can be used interchangeably, while keeping a way to create functions and selections that are specific to specific services.&lt;/p&gt;
&lt;p&gt;Does this use case make sense? Is there a different way to model this that would be better?&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;
</description>
<category>Spec</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10696/spec2-use-case-for-multi-spec-as-schema-provider</guid>
<pubDate>Tue, 15 Jun 2021 21:18:25 +0000</pubDate>
</item>
<item>
<title>Problems with s/union</title>
<link>https://ask.clojure.org/index.php/10345/problems-with-s-union</link>
<description>&lt;p&gt;While playing around with spec2, I'm seeing the following behavior which seems like a bug:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(s/def ::s1 (s/schema {:a string?}))
=&amp;gt; :dev.fp.livingdocs.specs/s1
(s/def ::s2 (s/schema {:b string?}))
=&amp;gt; :dev.fp.livingdocs.specs/s2
(s/def ::s3 (s/schema {:c string?}))
=&amp;gt; :dev.fp.livingdocs.specs/s3

;; The following is unexpected (neseted unions)
(s/def ::u (s/union ::s1 (s/union ::s2 ::s3)))
Execution error (IllegalArgumentException) at clojure.alpha.spec.protocols/eval1665$fn$G     (protocols.clj:20).
No implementation of method: :keyspecs* of protocol: #'clojure.alpha.spec.protocols/Schema found for class: clojure.lang.PersistentList
(s/def ::u (s/union (s/union ::s1 ::s2) ::s3))
Execution error (IllegalArgumentException) at clojure.alpha.spec.protocols/eval1665$fn$G (protocols.clj:20).
No implementation of method: :keyspecs* of protocol: #'clojure.alpha.spec.protocols/Schema found for class: clojure.lang.PersistentList

;; if I try to pull out the nested union into a separate keyword, it starts working 
(s/def ::u' (s/union ::s1 ::s2))
=&amp;gt; :dev.fp.livingdocs.specs/u'
(s/def ::u (s/union ::u' ::s3))
=&amp;gt; :dev.fp.livingdocs.specs/u
(s/explain (s/select ::u [:a :c]) {:a &quot;bdfd&quot;})
{:a &quot;bdfd&quot;} - failed: (fn [m] (contains? m :c))

;; but also this
(s/form ::ld/typed)
=&amp;gt;
(clojure.alpha.spec/schema
 [{:name clojure.core/string?, :type clojure.core/string?}])
(s/form ::ldd/editable)
=&amp;gt;
(clojure.alpha.spec/schema
 [{:optional clojure.core/boolean?,
   :maxLength clojure.core/integer?,
   :plainText clojure.core/boolean?,
   :excluexcludeFromTextCount clojure.core/boolean?}])
 
(s/def ::service
  (s/or :single (s/select (s/union ::ld/typed ::ldd/editable) [:type :name :optional])
         :multiple (s/select (s/union :ld/typed ::ldd/editable) [:type :name :maxLength])))
Execution error (IllegalArgumentException) at clojure.alpha.spec.protocols/eval1665$fn$G (protocols.clj:20).
No implementation of method: :keyspecs* of protocol: #'clojure.alpha.spec.protocols/Schema found for class: clojure.lang.PersistentList
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In both cases &lt;code&gt;s/union&lt;/code&gt; shows up in a nested position inside a form passed to a spec macro. &lt;/p&gt;
</description>
<category>Spec</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10345/problems-with-s-union</guid>
<pubDate>Mon, 15 Mar 2021 09:49:01 +0000</pubDate>
</item>
<item>
<title>I think there's a typo in spec2 that breaks if you don't alias clojure.alpha.spec -&gt; s</title>
<link>https://ask.clojure.org/index.php/9811/think-theres-typo-spec2-that-breaks-alias-clojure-alpha-spec</link>
<description>&lt;p&gt;In a project, I required + aliased &lt;code&gt;clojure.alpha.spec&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(ns example.core
    (:require [clojure.alpha.spec :as spec]))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I tried to define a simple spec like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(spec/def ::example-spec #(not (neg? %)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compiling gave the error that namespace &lt;code&gt;s&lt;/code&gt; was undefined. &lt;/p&gt;
&lt;p&gt;I believe this came down to a typo in &lt;code&gt;clojure.alpha.spec/def&lt;/code&gt;. In file &lt;code&gt;spec-alpha2/src/main/clojure/clojure/alpha/spec.clj&lt;/code&gt;,  line 456, there is a backquoted &lt;code&gt;s/spec&lt;/code&gt; but the alias at the top of the file is to &lt;code&gt;sa&lt;/code&gt;. Here's line 456:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    (#{'fn 'fn* `c/fn} op) `(s/spec ~explicated-form)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; After changing the line to &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(#{'fn 'fn* `c/fn} op) `(sa/spec ~explicated-form)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;my &lt;code&gt;spec/def&lt;/code&gt; works successfully. &lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9811/think-theres-typo-spec2-that-breaks-alias-clojure-alpha-spec</guid>
<pubDate>Mon, 16 Nov 2020 06:12:55 +0000</pubDate>
</item>
<item>
<title>Problem with (s/nest) and (s/describe) in spec-alpha2</title>
<link>https://ask.clojure.org/index.php/9730/problem-with-s-nest-and-s-describe-in-spec-alpha2</link>
<description>&lt;p&gt;It looks like calling &lt;code&gt;(s/describe)&lt;/code&gt; for &lt;code&gt;(s/nest)&lt;/code&gt; specs fails with an exception.&lt;/p&gt;
&lt;p&gt;The following call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(s/describe (s/nest int?))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;fails with this exception:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IllegalStateException Attempting to call unbound fn: #'clojure.core/unquote
    clojure.lang.Var$Unbound.throwArity (Var.java:45)
    clojure.alpha.spec.impl/nest-impl/reify--1676 (impl.clj:647)
    clojure.alpha.spec/form (spec.clj:258)
    clojure.alpha.spec/form (spec.clj:254)
    clojure.alpha.spec/describe (spec.clj:282)
    clojure.alpha.spec/describe (spec.clj:279)
    stem.i.log/eval16342 (log.clj:91)
    stem.i.log/eval16342 (log.clj:91)
    clojure.lang.Compiler.eval (Compiler.java:7177)
    clojure.lang.Compiler.eval (Compiler.java:7132)
    clojure.core/eval (core.clj:3214)
    clojure.core.server/prepl/fn--8941 (server.clj:232)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in spec-alpha2 with the latest commit from master&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{:git/url &quot;https://github.com/clojure/spec-alpha2.git&quot; :sha &quot;d514b06b25c41a676b95afcc9bfac8ca34c5741e&quot;}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Spec</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9730/problem-with-s-nest-and-s-describe-in-spec-alpha2</guid>
<pubDate>Tue, 20 Oct 2020 16:55:08 +0000</pubDate>
</item>
<item>
<title>Problem with select in schema with namespaced keys of schema with unnamespaced keys</title>
<link>https://ask.clojure.org/index.php/9501/problem-with-select-schema-namespaced-schema-unnamespaced</link>
<description>&lt;p&gt;In specs alpha 2,  if we define a &lt;code&gt;clojure.alpha.spec/select&lt;/code&gt; of a spec defined as a   &lt;code&gt;s/schema&lt;/code&gt; of a nested spec that is itself a &lt;code&gt;s/schema&lt;/code&gt;, but of unnamespaced keys, and try to use it with either &lt;code&gt;s/valid?&lt;/code&gt; or &lt;code&gt;s/exercise&lt;/code&gt;, we get exceptions: &lt;br&gt;
&lt;code&gt;s/valid&lt;/code&gt; throws *&lt;em&gt;&quot;No implementation of method: :conform&lt;/em&gt; of protocol: #'clojure.alpha.spec.protocols/Spec found for class: clojure.lang.Keyword&quot;&lt;strong&gt; and &lt;code&gt;s/exercise&lt;/code&gt; throws &lt;/strong&gt;&quot;Unable to resolve spec: :foo&quot;** (where &lt;code&gt;:foo&lt;/code&gt; is the unnamespaced key).&lt;/p&gt;
&lt;p&gt;An example can illustrate the issue better:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;; Context
(s/def ::foo int?)
(s/def ::inner (s/schema [{:foo ::foo}]))
(s/def ::outer (s/schema [::inner]))

; Works as expected:
(s/exercise ::outer)
(s/exercise (s/select ::inner [*]))
(s/valid? (s/select ::inner [*]) {:foo 10})

; Fails with &quot;Unable to resolve spec: :foo&quot;
(s/exercise (s/select ::outer [*]))

; Fails with &quot;No implementation of method: :conform* of protocol: #'clojure.alpha.spec.protocols/Spec found for class: clojure.lang.Keyword&quot;
(s/valid? (s/select ::outer [*]) {::inner {:foo 10}})
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Libs</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9501/problem-with-select-schema-namespaced-schema-unnamespaced</guid>
<pubDate>Fri, 24 Jul 2020 18:43:51 +0000</pubDate>
</item>
<item>
<title>In Spec 2, is this a bug?</title>
<link>https://ask.clojure.org/index.php/9145/in-spec-2-is-this-a-bug</link>
<description>&lt;p&gt;Just reporting an error I've come across while using Spec 2 of SHA &quot;b29ae46&quot;. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(s/def ::special-name   
  (s/and string? #(clojure.string/starts-with? % &quot;Special&quot;)))
(s/def ::schema-1    (s/schema [::special-name]))
(s/valid? ::schema-1 {::special-name &quot;Special Person&quot;})
;;=&amp;gt; true

(s/def ::name        ::special-name)
(s/def ::schema-2    (s/schema [::name]))
(s/valid? ::schema-2 {::name &quot;Special Person&quot;})
Execution error (IllegalArgumentException) at clojure.alpha.spec.protocols/eval5664$fn$G (protocols.clj:11).
No implementation of method: :conform* of protocol: #'clojure.alpha.spec.protocols/Spec found for class: clojure.lang.Keyword
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Spec</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9145/in-spec-2-is-this-a-bug</guid>
<pubDate>Wed, 11 Mar 2020 10:06:44 +0000</pubDate>
</item>
<item>
<title>In Spec 2, are nested schemas illegal?</title>
<link>https://ask.clojure.org/index.php/9144/in-spec-2-are-nested-schemas-illegal</link>
<description>&lt;p&gt;One of the problems that I've run into while using Spec 2.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(s/def ::number      number?)
(s/def ::boolean     boolean?)
(s/def ::schema      (s/schema [::number ::boolean]))
(s/def ::only-number (s/select ::schema [::number]))
(s/def ::this-works  (s/keys :req [::only-number]))
(s/def ::this-fails  (s/schema [::only-number]))
Execution error (AssertionError) at clojure.alpha.spec.impl/schema-impl (impl.clj:422).
Assert failed: (every? (fn* [p1__6948#] (if-let [sp (s/get-spec p1__6948#)] (not (select? sp)) true)) ks)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I made up this example to replicate an error I've got while I was creating a wrapper for AWS DynamoDB REST API.&lt;/p&gt;
</description>
<category>Spec</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9144/in-spec-2-are-nested-schemas-illegal</guid>
<pubDate>Wed, 11 Mar 2020 09:27:15 +0000</pubDate>
</item>
</channel>
</rss>