Fork me on GitHub

@didibus the alpha versions of test.check have a docstring for fmap


@didibus I don't think you want multi-spec, that's for multimethods. you just want s/or I think


Hum, what would multi-spec do that s/or wouldn't?


requires a defined multimethod by the looks


I guess its just that multi-spec is open for extension


So maybe useful for libraries?


seems to require a tag of some sort on your entity


which you don't have in your original example?


Oh right, hum. I guess I see. I think multi-spec is more what I'm imagining in my head, since I'm thinking of it as an inheritance of some sort. Like a shape can be a block square or cube.


But, I guess I don't really care about the type name, what's that called, when you have types defines by there shape and not a name?


in static typing land I believe it's called "structural typing", but I've been writing in dynamic languages for like 8 years at this point


so not the person to ask 🙂


haha, anyways, thanks for the alternative, I'll think about which one works best for what I'm trying to do


@alexmiller I submitted a patch on . I tried to find a spec.alpha JIRA project. Am I correct to submit the patch to Clojure?


question of style: when you spec (deeply) nested maps inside a namespace. do you create tons of new deep ns for keys specs corresponding to the map shape ex:* or do you use a more flat naming scheme (like inner classes in java) so ::foo$bar$baz/* (spec-tools seems to do something like this for the Schema like api I think)?

Alex Miller (Clojure team)12:08:16

I would definitely not do the latter and would potentially not even do the former but instead use the same namespace for many of the levels


how would you do that when you spec a json api for instance, there often are duplicates in key names

mpenet12:08:42 etc


yeah, like in

(s/def one-name-pred?)
(s/def :foo.baz/name different-name-pred?)
(s/def :foo/bar (s/keys :req-un []))
(s/def :foo/baz (s/keys :req-un [:foo.baz/name]))


I try to keep all specs in a single file, at least in active design/development phase, so I end up with something like above (or your 1st approach, @U050SC7SV )


yup, involves a lof of create-ns juggling


same, I tend to create foo.clj foo_specs.clj pairs


not, if you are willing to use long qualified keywords, instead of aliases.


hence the create-ns stuff


I still did not calibrate my preference of aliases over long kws. Converted 300 lines of specs yesterday to aliases – can't understand shit now dafuq



(alias 'fc 'fsm.compiled)
(alias 'fcs 'fsm.compiled.state)
(alias 'fce 'fsm.compiled.event)
(alias 'fcg 'fsm.compiled.guard)
(alias 'fcb 'fsm.compiled.behavior)
(alias 'fcm 'fsm.compiled.machine)
(alias 'fctran 'fsm.compiled.transition)
(alias 'fctrig 'fsm.compiled.trigger)


I don't abuse aliases (I never create them manually)


now quick, whose ids are those? ::fcb/id and ::fcs/id kappa


I just create-ns under the current ns (via a macro) and add dotted childs foo.clj -> :foo/***


I might revert all of the aliases, and settle down with just long qualified kws. Will have to spend ~same amount of time to comprehend same spec, but at least I will not need to jump around the file in process


if you do it "locally" aliases are not really necessary you can use ::bar.baz.prout within 'foo ns for etc


it's what I have found to be the less horrible to deal with that stuff, and semantically it's kinda clean


on the other hand, those namespaces are not that long. I'd not like to have 1kloc of specs for, say, ring.middleware, where nss are 100 chars long harold


let me try that. (sorry, for highjacking thread, and driving chances of @alexmiller reading all of it to zero opieop )



Invalid token: ::foo/bar, compiling (/.../src/kek/fsm_spec.cljc:15:1)


you still have to create-ns the ns yep


no way around this (for now)


same after

(create-ns '
=> #object[clojure.lang.Namespace 0x80d220d ""]


basically, I just need longer alias names


(I usually go with the former)


does not really feel "reuse", man harold


@souenzzo interesting, but I will still require to copy/paste dispatch keys by hand


Question: What versioning scheme does clojure.spec uses. Specifically, what part of the version do indicates non-backward compatibility if it changes? "1.9.0-alpha17". Is it the number following alpha? Is it the minor 0 version, or the 9 or the 1?


inside -alphaXX, any change can break i think


Also note that Spec is currently clojure.spec.alpha and has a different version number to Clojure itself, as do the also separate core specs.


Oh I see: 0.1.17


So, the way they have it now, is there a strict notion of breaking change on the version? Like 0.2 would be breaking, but not 0.1.18 ?


I would say while it's still labelled alpha any release could be breaking, as it's more just a "new build"


I get the impression -- from talking to Rich and Alex and others, and from what they've said in public talks at conferences -- that "The Clojure Way" doesn't really pay much attention to version numbers... After all, "major" releases of Clojure are all 1.x so far, and nearly all the Contrib libraries are 0.x.y but are production-ready...


I suspect we'll see a bigger push -- across the whole community -- for non-breaking future releases while the artifact/namespace name is unchanged.


For example, Rich's Spec-ulation talk.


I've struggled with this with because I've had several releases that have been breaking ones because the API took a long time to drift toward "best practices" as they've evolved over the last 5-6 years I've been maintaining it.


Its true, but all Clojure versions have historically maintained backwards compatibility. Also, while Rich Hickey doesn't seem to like versions, he does like clearly indicating when things break backward compatibility, though he suggest a whole new name instead of a version bump. At least that's what I got from his talk.


At one point, I pushed the entire API into a "deprecated" namespace, allowing for a simple cross-application edit for users, if they wanted to upgrade without changing all their calls. I think the new way means we'll get "versions" encoded in the namespace names instead, at least until we figure out a better approach.


Not really an aversion for versions, just that we could do much better I guess


At least with clojure.spec.alpha, you know it's subject to change and can (and has!) cause(d) code breakage.


Once it's ready to become stable, it'll get renamed back to clojure.spec (and folks can continue using clojure.spec.alpha until they're ready to switch).


Ya, I'm assuming this now. I think its the right assumption for spec when in alpha


We've just had a long discussion about this with clj-time because I'd originally pushed to switch its implementation from Joda Time to Java Time. With discussions over about a year, it became clear that wouldn't be possible while retaining the clj-time/clj-time coordinate due to possible conflicts in versions across multiple libraries that depend on clj-time -- so it's sort of become the poster child for "don't break code when you only change the version".


Well, in fact, my reason for asking was that at my company, we internally maintain our own package repo. And our version scheme actually goes like this: Any.Number.Affects.Backwards.Compatibility. And we drop all part of a version that doesn't affect backwards compatibility.


lol, I appreciate you not breaking clj-time sean, that would definitely give me a headache


In that way, conflicts auto-resolve to the newest version that does not break backwards compatibility. But for that, you have to tell the build tool what numbers in the library versioning scheme is the backward breaking one.


So, I think its actually more in line with Rick's vision. Just freely upgrade things, but don't break people. And if you need to break people, then and only then, just make a fork as a whole new name. So sure, that could be clj-time_v2, but the version is now only a way to indicate incompatibility, and nothing else.


P.S.: Aren't you stuck using joda-time until clojure drops supports for Java 1.6 and 1.7?


Heh... read the discussion (that started in November 2015!) about that: /cc @U050MP39D


My solution to this at work was to introduce and start switching code over to use that instead (of clj-time and date-clj which we were previously using).


Given the presence of, I'm not very inclined to create a "somewhat API-compatible version of clj-time" based on Java Time -- I'd rather support instead.


Ah, didn't know about Looks good. Though what I'd like to see is a common clojure/clojurescript API for date and time.


Well, there's cljs-time which mirrors clj-time, and in the repo there's an issue proposing a cljs API that matches...


Oh, okay ya, I guess that's good enough.