Fork me on GitHub
#clojure-spec
<
2017-10-19
>
jrychter07:10:43

I am having problems with circular dependencies. Spec strongly encourages splitting your data entities into separate namespaces. I have projects (`project`) which contain entries (`entry`). But entries also refer back to :project/id via a :entry/project-id attribute. If I split entries into their own namespace, I have to refer to it when defining what a project is, but the entry namespace also needs to know what a :project/id is.

Alex Miller (Clojure team)14:10:22

the qualifiers used in spec names do not have to correlate to an actual namespace nor do they have to be defined in that namespace. The word “namespace” is dangerously overloaded in this area.

Alex Miller (Clojure team)14:10:31

I think it’s most useful to declare stuff like this in some totally different “domain data” namespace

jrychter15:10:30

Interesting. But if they don't correlate to namespaces, I lose the (rather convenient) :: syntax. I guess the namespaced map reader syntax could make up for that.

bbrinck15:10:40

schec lets you create aliases to non-existing namespaces, and then you could use the alias to shorten writing specs

Alex Miller (Clojure team)17:10:37

you can do this without a library too

Alex Miller (Clojure team)17:10:37

(create-ns 'my.cool.thing)
(alias 't 'my.cool.thing)
::t/foo

Alex Miller (Clojure team)17:10:19

support for handling keyword aliasing in better ways (without doing that ^^) is something Rich is working on for future release btw

jrychter07:10:20

Also, I'm not sure about the new reader syntax for namespaced maps, specifically how it should work with destructuring:

(let [{a :some.ns/a} {:some.ns/a 1}] a) => 1
(let [#:some.ns{:keys [a]} {:some.ns/a 1}] a) => 1
(let [#:some.ns{a :a} {:some.ns/a 1}] a) => error
Is map destructuring with key renaming not supported?

gfredericks11:10:02

a problem with that last one is that the binding form is read in as {some.ns/a :a} which is sort of backwards from what you want, because the symbol gets namespaced but not the key

jrychter12:10:52

@gfredericks Right. But what now, do we give up key renaming? Is that expected/intended?

gfredericks12:10:25

you can do it the long way, at worst

gfredericks12:10:17

I have no idea whether there was any intention to make something like this work

jrychter12:10:32

Hmm. In that case, the push to use namespaced keys everywhere seems slightly premature.

Alex Miller (Clojure team)13:10:53

that’s not valid syntax

Alex Miller (Clojure team)13:10:29

the “left” part of destructuring is always the unqualified name of the local being bound

Alex Miller (Clojure team)13:10:14

so you want: (let [{a :some.ns/a} {:some.ns/a 1}] a)

Alex Miller (Clojure team)13:10:33

(this has worked since Clojure 1.6 I believe)

jrychter14:10:35

@alexmiller I am moving to ns-qualified keys everywhere and have many places where I do {:keys [a b c d e f]}. I was hoping I could do #:some.ns{:keys [a b c d e f]} and this works well, but what if I additionally want to extract {renamed-g :some.ns/g}?

Alex Miller (Clojure team)14:10:25

{:some.ns/keys [a b c d e f], renamed-g :some.ns/g}

Alex Miller (Clojure team)14:10:09

I think using the #:some.ns prefix is kind of confusing in this context - I usually put it inside the map

jrychter15:10:04

@alexmiller Oh, so that's the syntax! Thank you, I've never seen it until now.

Alex Miller (Clojure team)15:10:47

Means the same thing - just alternate syntax

Alex Miller (Clojure team)15:10:31

You can do multiple keys destructuring from different namespaces too

jrychter16:10:37

Thank you for your time and help!

rads18:10:58

can anyone explain to me why spec doesn't check :ret specs during instrumentation by default? I know there was a discussion about it a while back, but I'm curious if anyone has a succinct explanation for the decision

bbrinck19:10:11

IIRC, the rationale is that instrumentation is for checking that you called function X correctly, not for checking that the function X implemented correctly

bbrinck19:10:40

The recommendation is to use generative testing to confirm that function X works correctly (based on the :ret and :fn specs)

bbrinck19:10:48

I personally disagree with that distinction, since I have functions that can’t be realistically verified with generative testing due to a) side effects or b) disproportional work to get the specs perfectly tuned

bbrinck19:10:21

In my limited experience, instead of using check to test function X, we ended up just not speccing :ret or :fn because they were unverified and I preferred no documentation rather than documentation that was potentially incorrect or out of date

bbrinck19:10:49

In particular, using orchestra to instrument functions during non-generative testing gives me confidence that my :ret and :fn functions are correct, which makes them more valuable as documentation

rads19:10:04

thanks, that's very helpful

eriktjacobsen21:10:31

@alexmiller Is there any plan to allow multiple, or nested namespaces in spec? Example: A spec ::bar/type declared in the foo.core namspace that could be referenced as :foo.core/bar/type? We are currently struggling with a seeming limitation of spec, and while the underlying problems deserves a longer form post, before heading down that path, was just curious if this was something being thought about.

seancorfield22:10:39

A spec of ::bar/type would need a namespace alias of bar available in order to be legal. That could alias any namespace @eriktjacobsen but could be foo.core.bar if you wanted it to be. Then ::bar/type would be :foo.core.bar/type.

seancorfield22:10:31

Since namespaces are (supposed to be) globally unique and can be arbitrarily "nested" already, I'm not sure what you're asking for...

eriktjacobsen22:10:02

Thank you Sean. I realize what the current system provides, and how to work around it. I was mostly curious if that specific solution has been talked about... will write up an explanation in a bit.

Alex Miller (Clojure team)22:10:06

There is no plan (or need) for any kind of nesting

eriktjacobsen22:10:51

Thanks for answer. put another way, has there been any thought to allowing a component of a spec identifier that isn't tied to a namespace or part of the unqualified key

Alex Miller (Clojure team)22:10:48

That is, please help me understand the problem you're trying to solve

eriktjacobsen22:10:51

writing the why up now, mostly due to tradeoffs in workflow my team is seeing. Perhaps it just needs a better framework for how we're structuring things, but it could also be solved by what I mentioned.

Alex Miller (Clojure team)22:10:12

I think sometimes it's also unclear that keyword qualifiers can refer to Clojure namespaces but don't have to have any relation to them

Alex Miller (Clojure team)22:10:40

There is an unfortunate overload and common use for the word "namespace"

Alex Miller (Clojure team)22:10:27

Currently namespace aliases also have the unfortunate downside of being tied to the particular case where a qualifier is actually a namespace (I do not expect this to be as constrained in the future)