Fork me on GitHub
#clojure-spec
<
2018-12-07
>
ro600:12:19

I'm starting to try using ::keyword style keywords more, but running into a limitation and wondering if it's a misconception on my part. I tried using the namespace as a prefix on a longer keyword, eg ::more.prefix/name, but that's an "Invalid token". Is there something about the Clojure impl (eg around namespaces or interning?) that would break if that were allowed? Is there a "good idea" that's being enforced here to save me from a "bad idea"? I was hoping it would expand to :the.ns.more.prefix/name.

seancorfield00:12:24

::foo/bar will expand the alias foo into the full namespace.

seancorfield00:12:23

user=> (alias 'foo.bar (create-ns 'long.ns.foo.bar))
nil
user=> ::foo.bar/quux
:long.ns.foo.bar/quux
user=> 

seancorfield00:12:56

(that's essentially the same as (require '[long.ns.foo.bar :as foo.bar])

ro600:12:05

right, at the usage site. I'm inside the defining namespace and conceptually wanting to "group" some things without creating a whole new ns

seancorfield00:12:23

:: can only be used with an alias.

seancorfield00:12:39

(or a bare keyword -- the "alias" is implicitly the current namespace)

ro600:12:32

I'm just wondering if there's a deeper "why" for that.

seancorfield00:12:01

I'm not sure what your question is...?

noisesmith00:12:08

:: is a keyword reading feature that works with aliases

seancorfield00:12:45

::more.prefix/name means "look up more.prefix as an alias and resolve it (to some namespace) and then construct a keyword with that namespace and /name"

seancorfield00:12:52

That is the semantics of ::

ro600:12:42

I think what's going on in my mind is that as I imagine these ns-qualified keywords escaping my Clojure system, I want to narrow them to remove ambiguity. In other words, I'm trying to name things so they still make sense with fewer contextual assumptions.

seancorfield00:12:48

Not much outside Clojure is going to be able to accept qualified keywords... Or am I misunderstanding you?

ro600:12:45

No, I think you're right on.

ro600:12:29

I guess this line of thought is more about self-documenting keywords for human consumption than machine disambiguation.

seancorfield00:12:31

If you want an alias, to avoid typing, you can always do this inside your the.ns namespace:

(alias 'more.prefix (create-ns 'the.ns.more.prefix))
... ::more.prefix/name ...

ro600:12:11

interesting compromise. That would let me organize my code into files independently of how I'm organizing my names/concepts.

seancorfield00:12:32

(there's talk of an easier way to create aliases being added to Clojure at some point but that's what we have right now)

seancorfield00:12:55

There's no need for the "namespace" portion of a qualified keyword to be an actual namespace with code.

seancorfield00:12:12

We have several qualified keywords in our code base that do not map to namespaces.

ro600:12:43

ok. Thanks for the info.

ro600:12:56

I also just realized that dot-separated segments after the / are possible too

ro600:12:12

I guess at runtime what separates keywords (ns-qualified or not) from strings is mostly faster equality checks due to interning.

ro600:12:25

haha, thanks.

mac07:12:05

Does anyone know of a (stateful) generator of locally unique integers for use with spec?

gfredericks16:12:15

what does "locally unique" mean?

ro617:12:11

(guessing) Non-repeating relative to some local scope (eg the generator itself, the running process, ....)?

ro617:12:39

Not sure about the "stateful" part

mac19:12:28

@gfredericks Just means that for the run of the test no two ints produced will be the same.

gfredericks19:12:59

@mac depends what "for the run of the test" means in this context; is this the generative test that spec does with spec/check or whatever it is?

gfredericks19:12:24

I'll probably just end up recommending https://www.youtube.com/watch?v=F4VZPxLZUdA

👍 4
taylor19:12:14

maybe (gen/vector-distinct gen/int) would be useful... somewhere

mac20:12:11

@gfredericks Yes it is "the generative test that spec does with spec/check"

mac20:12:32

@robert.mather.rmm Stateful because I cannot imagine being able to guarantee uniqueness without maintaining state.

gfredericks20:12:06

the standard way to do it would be to write your own generator at the lowest level that encompasses the whole relevant scope of uniqueness

gfredericks20:12:24

you could take the default generator and gen/fmap it to something that uniqueifies the ints

gfredericks20:12:45

an alternative, if you don't care how big the ints are, is to just generate really big integers and not allow them to shrink

gfredericks20:12:32

(you'd need to take care to make the generator something like uniform-distribution, so it doesn't start small either)

ro620:12:11

I don't know if it can be done lazily/immutably, but if you're worried about performance and you know how many random+unique ints you need up front, there's a cool algorithm for that.