Fork me on GitHub

Does anyone know if it’s possible to run just a single test or test class? It’s a bit tedious to run all tests for clojure everytime

Alex Miller (Clojure team)00:09:50

if so, lein help test will explain how to run single test namespaces or how to set up selectors for subsets of your test suite


I’m not using lein for this, not sure if that’s even supported


since half the stuff is java


Trying to contribute to clojure is a bit difficult, with no setup instructions 😛


lein has test selectors, but there's no way that I've found to use them from the repl, so for me they seem like a bit of a non-starter. clojure.test/run-all-tests accepts a regex for namespaces, and clojure.test/run-tests will accept a list of namespaces. which I've found mostly sufficient


@deiga if it helps, all deftest macros create a function that you can call in the general fashion of calling clojure functions, which will report whether the tests succeeded or not

Alex Miller (Clojure team)00:09:29

oh, you’re actually talking about clojure itself!

Alex Miller (Clojure team)00:09:37

yeah, there is a how-to page


Oh! Where? 🙂


Lovely, ty ❤️

Alex Miller (Clojure team)00:09:22

the developing patches page has info on this

Alex Miller (Clojure team)00:09:39

under "Run An Individual Test"

Alex Miller (Clojure team)00:09:06

also see #clojure-dev here or the clojure-dev mailing list

Alex Miller (Clojure team)00:09:52

for places to discuss with people doing similar things

Alex Miller (Clojure team)00:09:52

what are you working on?


I’m looking into clojure.xml. I had a problem getting the parsed XML as string, so I though I could add that. Also add some tests and maybe rewrite parse to use records since structmaps seem to be outdated

Alex Miller (Clojure team)00:09:43

ok, it’s unlikely we will do much with that though - while we’re not planning to remove it we also don’t have plans to spend time enhancing it. It seems like switching from structmaps to records would possibly be a breaking change too.

Alex Miller (Clojure team)00:09:35

generally it’s best to discuss these kinds of things on clojure-dev first before working on them


I’ve been trying to get into the google group where I was supposed to open a discussion about this. But my name still hasn’t appeared on the contributers list so I can’t get in there. I’d rather work on something and then scrapping it than just wait around 😛


it uses defrecords and because it isn't part of the core language, active development is a little easier


hiredman Yeah, I have. It seems to be a bit stale though


the release notes were updated 15 days ago


And 9months before that


clojure.xml was last touched in 2010


fair enough


but it’s at least in the core library


I’d rather spend my efforts to improve the language core than work on some external library


I understand the impulse, but it is extremely unlikely that any work on clojure.xml will actually get merged


you are likely looking at years of watching the patch go no where in jira, there is no guarantee a patch for data.xml wouldn't do the same thing, but it is slightly less likely


alexmiller: You say something about not planning to spend time enhancing clojure.xml, how much time can it take to look over a contribution and merging that?


hiredman: years?

Alex Miller (Clojure team)00:09:04

particularly in opportunity cost of not working on something else we consider important

Alex Miller (Clojure team)00:09:36

data.xml is where I would put any energy around xml


it can take years for an issue to be closed as wontfix

Alex Miller (Clojure team)00:09:02

well, I’ve been trying to be better about that :)


there was an issue in the clojure jira to make subs take negative numbers, the guy wrote a patch, it sat there for years, and then was closed as declined


dude was not pleased


that was sort of extreme case, but there are lots of similar little things


As someone who actively maintains one contrib library (and less actively maintains another, plus occasionally helps out with others), I would strongly support hiredman’s suggestion that you direct your efforts at the contrib library for XML stuff @deiga and not worry about the core stuff.


Changes to core are very carefully considered and reviewed which means they have to be much more conservative by definition. That’s what gives Clojure its amazing stability (and why we happily run Alpha builds in production all the time!).


my point with subs is not to argue about subs, but that was a pretty small change, it took years to be dealt with, so expect a larger change to take longer


and by years, I think it was around 3


it may have been like, there was an issue for it open for three years without a patch, someone opened a new issue, with a patch, and the patch was declined and both issues were closed


anyway, scale the mountain, but take an oxygen tank


Eh, It’s kinda discouraging when one of the core team says to not bother


I would like to get a hash map to respond to clojure.core/name like a keyword. Suggestions?

Chris O’Donnell01:09:35

@creese could you give an example of input/output you'd expect?


Mmm...I guess a spec where all the keys can be missing is not a very good one right? I can do: (s/def ::info (s/keys :opt-un [::name ::twitter-handle ::facebook-id ::domain ::telegram-token])) but then {:asd "asd"} is always valid, am I approaching the problem from the wrong angle?

Alex Miller (Clojure team)01:09:43

well that’s a perfectly fine spec and the opt-un will help it generate interesting values

Alex Miller (Clojure team)01:09:03

you could just do (s/keys) too to validate all the keys per their specs


Thanks Alex, the generative part is working fine, maybe I am missing a way to validate that ::info can only have this spec and {:anything "bla"} is not a valid one

Alex Miller (Clojure team)01:09:06

maybe it will be valid in the future


Is there a predicate that matches seqs, lists, vectors, and sets, but not maps? i.e. I want to be able to call seq on the collection and iterate over the values. map is the odd one out here


sequential? maybe, not sure about sets though

Alex Miller (Clojure team)01:09:14

usually when I ask this question I end up changing my mind about needing that later though :)


yeah I do wonder that too 🙂

Alex Miller (Clojure team)01:09:29

@richiardiandrea you can use an additional predicate to exclude all but a known set of keys but spec (and Rich) would encourage you to maybe not do that


yes I was wondering if it was good practice, but I am using spec to validate data at the boundaries and I cannot avoid adding that check, or anything will pass through


@alexmiller Thanks for your answer earlier about specialized sets! Good to know that my core objective was ill-advised. I found a better way of efficiently rendering my lines, fortunately, and if I ever do have to confront this use case, I will be better armed.

Alex Miller (Clojure team)01:09:59

@richiardiandrea that is one of the best places to need such a thing


@alexmiller thanks for confirming!

Alex Miller (Clojure team)01:09:46

so (s/merge (s/keys) (s/map-of #{:name :twitter-handle :facebook-id :domain :telegram-token} any?)) will work

Alex Miller (Clojure team)01:09:03

or add the opt-un if you want generative


yes I'll opt for opt-un 🙂


@alexmiller if I may add a question, will this work in the 1.9.0 release?

(def ::info-keys [::name ::twitter-handle ::facebook-id ::domain ::telegram-token])
(s/def ::info (s/keys :opt-un ::info-keys))
It would be neat 😄

Alex Miller (Clojure team)01:09:29

This whole exact same conversation happened in #clojure-spec this morning btw :)


oh too bad ... ok tnx, oh cool let me go there and read 😄

Alex Miller (Clojure team)01:09:12

No worries, but there is more explanation there


btw this now works:

(s/def ::info (s/merge (s/keys :opt-un [::name ::twitter-handle ::facebook-id ::domain ::telegram-token])
                       (s/map-of #{:name :twitter-handle :facebook-id :domain :telegram-token} any?)))
(s/explain ::info {:twitter-handle "@trat" :asr "rst" :domain ""})
In: [:asr 0] val: :asr fails spec: :app.division/info at: [0] predicate: #{:telegram-token :name :facebook-id :domain :twitter-handle}


For everyone who has been answering all my dumb questions, you'll be glad to know that I'm at least making good progress on this map rendering business! Perhaps this SVG will render when I upload it...


...okay, not particularly. Guess Slack doesn't recognize SVGs as images it can embed. Just take my work for it that it works! Eventually I'll get an actual web page up to render this stuff for live coding with Figwheel.

Alex Miller (Clojure team)02:09:52

I see it in Chrome! Nice.


@rui.yang yep - Clojure has multimethods. different functions are called depending on a dispatch function


Having a protocol and dynamic var in ns1:

(ns ns1)
(def ^:dynamic *m* {:a 1 :b 2})
(defprotocol Protocol
  (f [arg]))
(extend-protocol Protocol
  (f [arg] (println *m*)))
and a second namespace ns2:
(ns ns2)
  (binding [ns1/*m* (conj ns1/*m* {:c "three"})]
    (f m))
I expect the map *m*, inside the binding, to contain 3 entries. However, there are only 2, the result of the (println *m*) being {:a 1 :b 2}, so the binding doesn't seem to work. Why is that?


Or better, how to change the dynamic var temporary inside the scope of a function in another namespace?


just curious, what happens if you do (bound-fn [] (f m)) instead of (f m) ?


another idea, did you require ns1 inside (ns ns2)?


yeah, I actually did require - I just removed all non-important code (well, at least, I think it's not important 🙂 )


that bound-fn idea is stupid,


got an error using bound-fn 😛


I wanted to test if there is any async code between your (f m) and println, that would explain it


well, there's really not much more code in between


try to println something before (f m), after (f m) and after exitting the binding


the code how you presented it here looks good to me


hmmm weird... binding doesn't seem to work fine. Just a sec.


oh, the binding does work in ns2


but it doesn't on ns1


can you show your ns2 code?


or is it the exact same?


(binding [ns1/*m* (conj ns1/*m* {:c "three"})]
  (println ns1/*m*)
  (-> ...


the println here shows the conjed binding. the println inside ns1 shows the wrong one. There's nothing in between them.


oh, got it...


so I didn't add all important code:



  (:require [ns1 :as n]))
I cannot do: (binding [n/*m*...] ...) but I should do: (binding [ns1/*m*...] ...) I really thought I could use the namespace alias. Seems I can't


Hi, I’m trying to create a spec for a vector of maps that insures uniqueness based on key of map. For Example, I’d like to insure the maps in below vector are unique by the :id key.

[{:id 1 :name “foo”}
 {:id 2 :name “bar”}
 {:id 3 :name “foo”}]


Below only works if complete maps are distinct

(s/coll-of map? distinct true)
This would fail, as the maps are distinct, but it’s not what I want because the id’s are not unique.
[{:id 1 :name “foo”}
 {:id 2 :name “bar”}
 {:id 2 :name “foo”}]

Alex Miller (Clojure team)13:09:52

you’ll need a custom predicate for that


passed to coll-of instead of map??

Alex Miller (Clojure team)13:09:11

no s/and’ed with the coll-of spec

Alex Miller (Clojure team)13:09:40

(s/and (s/coll-of map?) #(thing that verifies uniqueness))


ok, great, thx, I’ll look at that.


did you ever think of allowing functions to be passed to distinct, e.g. (s/coll-of map? distinct :id) would make distinct by :id.

Alex Miller (Clojure team)13:09:45

it’s an interesting idea, but it might be harder to make that gen automatically


understandable. I’ll see where I get with using (s/and as generating a sample set is one of my goals.

Alex Miller (Clojure team)13:09:46

you may also find it hard then :) you might need a custom generator with s/with-gen (or maybe the generated things will be unique enough that it doesn’t matter, not sure)

Madara Uchiha14:09:59

Does clojure have the concept of an interruptible function?


You mean a generator?

Madara Uchiha14:09:46

Yeah, for instance

Madara Uchiha14:09:31

And it does so without blocking the thread.

Madara Uchiha14:09:55

This same behavior can (and is, when accounting for older browsers that don't support this syntax) be implemented with generators


expected: (== (+ (:margin render-env) (* (:mazes.grid/x top-right-cell) (:cell-width render-env)) (* (:mazes.grid/x top-right-cell) (:cell-h-spacing render-env))) (:x top-right))
  actual: (not (== 920.0 919.9999999999999))


Floating point inaccuracy is the devil. Is there a better solution than writing is-more-or-less-equal-i-guess? and using that instead?


generators could be nice to simplify certain boilerplatey patterns inside lazy-seqs


or reducible sources. costs in the compiler & runtime would have to be quantifiably minimal... Definitely possible


I would like to encourage all of you to try Clojure 1.9.0 alphas. Spec is great, but the new checking of macros and many builtin forms is uncovering bugs in a lot of software. Most of these are super easy to fix, but that’s work that parallelizes well. Here’s an example:


Syntax aside:

(reify clojure.lang.IReduceInit
  (reduce [_ rf init]
    (loop [res init]
      (let [v (f)]
        (if (identical? v eof)
          (let [res (rf res v)]
            (if (reduced? res)
              (recur res))))))))

   [f eof]
   (loop []
     (let [v (f)]
       (when-not (identical? v eof)
         (yield v)


hypothetical generator ^


with standard yield semantics


If a lot of folks give this a shot, then by the time 1.9.0 rolls around, a lot of newbies are going to have a much better time 🙂


Can I add things to that as well?


added prone 🙂

Alex Miller (Clojure team)14:09:14

maybe you’re just lucky :)


=> (map #(.hashCode %) {0 0, 7 7, 1 1, 4 4, 6 6, 3 3, 2 2, 9 9, 8 8, 10 10})
(961 1185 993 1089 1153 1057 1025 1249 1281 1217)

Alex Miller (Clojure team)14:09:18

maps don’t use .hashCode

Alex Miller (Clojure team)14:09:25

they use hash (backed by hasheq)


oh, cool. TIL 🙂


=> (map hash {0 0, 7 7, 1 1, 4 4, 6 6, 3 3, 2 2, 9 9, 8 8, 10 10})          
(-1663711614 825985219 670845861 1457028219 -645429335 921681221 1199864066 -813835253 2145648727 1228926976)


not sure how big the backing vector is, but I’m guessing that number ends up first


(after a mod operation)


I am not sure how first works


oh… coffee kicking in…. I should only be looking at the keys 😳

Alex Miller (Clojure team)15:09:17

it coerces its arg to a sequence, then takes the first element

Alex Miller (Clojure team)15:09:31

in this case that’s a sequence of map entries (2-element tuples)

Alex Miller (Clojure team)15:09:47

maps are unordered, so no particular order is guaranteed


user> (first { 7 7, 1 1, 4 4, 6 6, 3 3, 2 2, 9 9, 0 0, 8 8})
[0 0]


The order is deterministic… if you know the algorithm. I was just trying to pick at it without looking at the code 🙂

Alex Miller (Clojure team)15:09:11

well of course, but you should not rely on it as it can (and has) changed

Chris O’Donnell15:09:51

if you want the order to be consistent, you could use a sorted map


I know. I spent a week fixing people’s borked tests when Java changed their hash function from 1.5 -> 1.6

Alex Miller (Clojure team)15:09:22

well in this case it’s Clojure’s hash function that’s important (and it changed in 1.6)

Chris O’Donnell15:09:23

though I suppose your keys would need to be comparable


this was in a Java project (you know which one) 🙂


I think I saw a couple of tests fail when Clojure 1.6 came out too… luckily by that point people had learned (after all, Clojure devs at that point were usually pretty experienced Java devs first) so it wasn’t too messy



(map hash (keys { 7 7, 1 1, 4 4, 6 6, 3 3, 2 2, 9 9, 0 0, 8 8}))
(0 -137604029 1392991556 -803074778 1795257809 -1556392013 -971005196 1887164919 -153401025)


I can’t guess the algorithm


Calling in user.clj hangs. The same call in another namespace doesn't hang. Requiring that other namespace in user.clj hangs. There's something special about user at load time that I don't understand.


well, hash tables usually order by (hash key), and then mod into the size of the table. The keys here are longs, and Java uses identity for the Long.hashCode (or they did? They still seem to). Based on that, I was wondering if an entry of [0 0] would end up at the start of the table, no matter what. That’s what I went looking for


but Alex pointed out hash… which, now that I think about it, I think I knew that once, and then forgot


I was just poking around for fun, to see if there was another explanation for [0 0] showing up first, other than pure randomness. Even if there were, Clojure 1.10 could change the ordering again. It was just navel gazing, since any expectation of ordering on a hash is The Wrong Thing™


sure. 👍

Alex Miller (Clojure team)15:09:00

@quoll there is no mod. entries in hash maps are stored in hash array-mapped tries and the sequence ordering is based on traversing that tree


also, aren't maps ordered under 7 keys maybe, and then swap to an unordered implementation above that?


so possible small examples mislead about ordering of map keys

Alex Miller (Clojure team)15:09:09

yes, it’s <= 8 although there is at least one case (maybe with literals) where there is an off-by-one and it’s actually 9 I think


and presumably that's not spec'd and therefore subject to change? (trademark)


ah, I had presumed that hashmaps were using a vector to get their persistence. OK… I now have code to learn from. Thank you

Alex Miller (Clojure team)15:09:13

array maps will produce sequences based on the order of insertion (as it’s just backed by an array)

Alex Miller (Clojure team)15:09:05

vectors are also backed by hash array-mapped tries, keyed by index

Alex Miller (Clojure team)15:09:18

it’s a little different but same idea

Alex Miller (Clojure team)15:09:58

is a good starting point


at clojure/west, there was a guy who did an excellent presentation on reordering the way key/value pairs and pointers to other tries were stored in HAMT. Has there been any more movement on his work?


@alexmiller Since we’re talking about insertion order; given what I understand of prefix tries, they wouldn’t have the attacker-triggrable pathological insertion behavior that prompted randomized hashing for Python, Perl… &c’s hash tables — right?


I guess I should go validate that assumption though 🙂


bummer. it was a great talk

Alex Miller (Clojure team)15:09:17

@lvh that is still a concern as there are hash collision nodes

Alex Miller (Clojure team)15:09:23

which devolve to linked lists


i've been reading papers on HAMT as well. super cool


ah, crud

Alex Miller (Clojure team)15:09:31

there’s actually a ticket about this

Alex Miller (Clojure team)15:09:49

not sure if you’ve looked at how Java handled it, but the details are pretty interesting


got a link to that ticket or more info? I'd like to read that

Alex Miller (Clojure team)15:09:59

but it doesn’t have many of the details

Alex Miller (Clojure team)15:09:41

in Java 7 they started seeding hash maps so every map was basically hashing differently

Alex Miller (Clojure team)15:09:06

in Java 8 they undid all that and just changed the implementation to not devolve to linked list behavior on hash collision but instead to use a red/black tree

Alex Miller (Clojure team)15:09:19

a similar approach could be used in Clojure as well

Alex Miller (Clojure team)15:09:42

another workaround would be to wrap keys in a deftype that used an alternate hash function

Alex Miller (Clojure team)15:09:32

if you’re interested in this, tracking down the Java JEPs had a lot of useful info iirc

Alex Miller (Clojure team)15:09:52

haven’t thought about this in a couple years :)


thanks for the info

Alex Miller (Clojure team)15:09:22

having looked at this stuff a bit I have a lot of appreciation for the apparent thought involved in Java’s choices, both tactically and strategically


Alex, one of the reasons I moved from Java to Clojure was the HashSet/HashMap change in 1.8. It used to be that Set membership was defined by .equals() which had to be consistent with .hashCode(). Now they sometimes use the Comparable interface (HashSet is implemented using HashMap). We had code break on the 1.7->1.8 upgrade.


The Javadoc for Set.contains still claims "More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e))." which is not true for HashSet in all cases.


Fortunately, Clojure has correctly working sets and maps.

Alex Miller (Clojure team)16:09:22

Clojure’s sets are based on = and hash

Alex Miller (Clojure team)16:09:41

of course, it helps that = is not something that is open for interpretation in Clojure :)


Is there an elegant way (say with threading macros) to do nested maps?


(map #(map #(get-in % :_source :ecr_code))) non-empty)


obviously nested function literals are disallowed


the fn form can be nested though


Ahh, and so maybe I just setup the anonymous functions to be argument compatible with threading macro?


sounds right


Thank you


@smw usually if my map gets too hairy i rewrite it as a for


in fact my rule is (which I think I inherited from technomancy) that if you're having to use function literals its already complicated enough for a for, being able to name your iteratee and do lets and whens makes a for much more readable IMO


Is there a switch to lein run to watch the project files and recompile? I'm trying to learn Clojure and Pedistal, and would like to see my changes with out stopping and starting with each change. Thanks!!!


@linicks nothing for lein run that I know of. There are some specialized tools for autotesting, or in the case of ring there's a reload middleware. Perhaps there's something like that for Pedestal? Otherwise you could hook up a REPL to your editor and run the Pedestal app from your REPL, then you can recompile code into the same process that Pedestal is running from.


@pjstadig, Thanks for the tips! I'll start investigating in those directions 🙂


@smw, as an alternate to @pjstadig’s rule, I usually just create defn-s outside of the map and call them that way. That way, you end up with flexibility, functions can be used elsewhere, and with good naming, the map becomes self-describing.


@akiva yes, i agree that splitting out functions is also a good way to go. sometimes I find it hard to come up with good names for intermediate computations, but also a for can get to the point where it's doing too much as well.


Agreed. Nothing wrong with a good for.


When it comes to internal functions like that, I don’t fuss too much since the API’s… well, internal. So, going back to @smw’s example, that inner function would be fine for me as get-source or something. And then I’d make both maps transducers and string them together rather than nest them.


(let [keys-for-hit #(get-in % :_source :ecr-code)
      keys-for-object #(map keys-for-hit %)]


I was away for a bit, but I was trying to do it this way 🙂


but maybe a for is the right answer


for in clojure is basically a list comprehension, right?


Honestly, as long as there isn’t a performance hit and it reads well, then go with what you like.


I’ve discovered there’s almost always a more succinct way to do things but nothing wrong with a little verbosity if it makes the code easier to reason about.


Not sure if letfn would be better here for this rather than defining functions in a let.


Yeah, I just don’t like polluting the namespace with one-off function defs that aren’t obviously related to the task at hand… even if they’re private.


oooh, I don’t know letfn


I also found clojure.walk while searching


Actually, @smw, that’s one of the foundations of functional programming (those foundations being rather fractalized) is that it’s better to have 100 functions that each do one thing incredibly well than one bloated function that does many things poorly.


Sure, but if the functions are one-shot and not really composable, does it make sense to name them at the root of the namespace?


Good question and something I sometimes struggle with. But I’ve no qualms wrapping a deeper namespace in a one-liner in a namespace closer to the API layer if it makes the code clearer. For instance, in one project, I have a bunch of entities that need to be saved to the database and instead of just always calling directly to the raw database save, they each have their own save function that literally just wraps the raw save. That way, I can have code like (entity/save entity-instance).


And if later I need to do some customization before save, I won’t break calling code. And I’d rather compose off of that than an integration layer.


so each entity is in a separate file?


Yep. Once you get comfortable with function proliferation, it becomes a matter of organization, really.


I still use anonymous functions, mind you, when it’s something super-terse and easily understood.


But I’d probably not nest a filter in a map, for instance.


Does Clojure have any notion of self-referential data structures, such as you might see in Lisp '#1=(1 2 3 . #1#)

Alex Miller (Clojure team)19:09:48

you can do it via atoms or other stateful things if you work at it, but: don’t :)


similar to 'tying the knot'. Reiterating it's not a good idea because clojure favors values rather than references.... but @bbloom has done it in fipp i think


christophe grand has some examples with promises somewhere


mostly just curious, but sometimes in maps such as the one in lein's project.clj, I've had to duplicate stuff in another key. Thought it might be nice if there was a way to refer to other parts of the same data structure.


@ghadi i don’t believe fipp does anything like that


not slot references per se


oh tying the knot was the haskell impl


@akiva wow didn't know you had created that, it looks nice 😉


oh yeah - the “lazy” version vs the yield version


Thanks, @richiardiandrea! I hope that wasn’t sarcasm. Hah.


lol, no no I am checking the code 🙂 You also have Twitter in there, that I always wanted to have in a blog. When I was working for Lambda-X we used cryogen


I’m the world’s worst at taking compliments.


The twitter-api library is kind of old but it works… except with Clojure 1.9. It breaks spec all over the place.


yeah I opened an issue there 🙂


And cryogen’s great. I did my own version in JavaScript/Node.


we will eventually need to fix it because my current project has that dependency


That reminds me: I need to file an issue against 1.9’s new uuid function.


This might just be me but as it is right now it throws if it encounters anything that isn’t already a java.util.UUID instance so it’s kind of useless when you’re pulling UUIDs as strings out of a database. So it isn’t a breaking issue, really, it just seems rather limited in comparison with how I’ve seen people handle and process UUIDs from different sources.


To further the point a bit, if you have to convert a string to a java.util.UUID, you’ll never need uuid? anyway because you’ve already converted to a UUID instance.


But if you’re passing data through multiple layers and you have a routine that expects a UUID then it’s useful.


I agree. I just think it could be more useful.


Also bear in mind that there are multiple string forms of UUID. And also multiple binary forms.


I think we have to deal with four different UUID representations at work.


We’re mainly dealing with java.util.UUID with uuid? so the other representations aren’t as relevant and would require handling on the dev end. I’m fine with it staying in line with java.util.UUID but being able to recognize a string that adheres to the JVM’s UUID as something that could be converted correctly to an instance would be helpful.


At least for me, anyway. Heh. I just wrote my own version.


This actually relates with @lvh having an issue with prone. I forgot about that.

Alex Miller (Clojure team)19:09:58

how could it check whether a string is a uuid?


is this a setup for the old "a programmer has a problem and thinks I'll solve it with a regex" joke/


Eh, I just needed it to work so I wrapped (. java.util.UUID fromString s) in a try.


@alpheus, hah, believe it or not, not this time.

Alex Miller (Clojure team)19:09:53

I suppose, not sure if Rich would go for that or not


And honestly, I’ve been hesitant because I simply wasn’t sure how halo this case is.


I just know that a lot of people deal with UUID strings a lot.


I think it'd be surprising if uuid? returned true for both a string and a UUID. would it also need to generate both strings and UUID objects?


uuid? doesn’t generate objects. It just says, ‘Yes, this is a java.util.UUID.'


sorry I mean would the associated generator also have to generate both uuid strings and uuid objects


Or, in my use case, a string that could be one.


Well if uuid? returned true for a string I would consider this a bug


@bfabry, possibly. I’m coding against MongoDB so I’m using its random-uuid.


(s/exercise uuid?) does indeed produce UUID objects @akiva


And you could write a generator for UUID strings based on that (use uuid? to generate the UUID and then fmap it to a string of the appropriate form.


boot.user=> (s/exercise uuid?)
([#uuid "d46604d9-43be-415b-96fd-616992227e0b" #uuid "d46604d9-43be-415b-96fd-616992227e0b"] [#uuid "219f702b-59f3-4165-ac7f-2ffb76a06e73" #uuid "219f702b-59f3-4165-ac7f-2ffb76a06e73"] [#uuid "fe832237-2f88-4621-a912-45c45959d3b1" #uuid "fe832237-2f88-4621-a912-45c45959d3b1"] [#uuid "10e03132-a9da-4b4b-9880-b497310967a4" #uuid "10e03132-a9da-4b4b-9880-b497310967a4"] [#uuid "cbcd32a3-7e21-452a-9505-59d36de3c2fd" #uuid "cbcd32a3-7e21-452a-9505-59d36de3c2fd"] [#uuid "50d2dce5-2427-4304-9a17-e259f3db78bf" #uuid "50d2dce5-2427-4304-9a17-e259f3db78bf"] [#uuid "3fc3768a-68ec-46da-ba1e-15b7e91063bc" #uuid "3fc3768a-68ec-46da-ba1e-15b7e91063bc"] [#uuid "b992038c-f4dc-41fe-8349-41849fa90c36" #uuid "b992038c-f4dc-41fe-8349-41849fa90c36"] [#uuid "5d1f1321-9bba-4806-9a86-88cc3977047a" #uuid "5d1f1321-9bba-4806-9a86-88cc3977047a"] [#uuid "8f4327b4-6869-4c61-ae94-cc7d8e1822f8" #uuid "8f4327b4-6869-4c61-ae94-cc7d8e1822f8"])


(just showing that uuid? can generate objects)


is there a way to tell if an object can be treated as a value in clojure?


I have to admit, I’m spec-ignorant at this point. I’m just looking at the code and it shows it returning a boolean. I need to read up on this some more. It’s also why I haven’t filed an issue. I’m not about to bust through a wall like the Kool-Aid man on clojure.core. Heh.


Bringing this back home to my point with @smw, though, this is a good example of how uuid? simply wraps a one-liner around deeper code.


Interesting, @bfabry. It’s showing uuid? mapping to (uuid) which, I imagine, would produce UUID instances.


The uuid? function merely tests whether the input is (instance? java.util.UUID x).


Thanks, akiva. Good point.


But I also like @sveri’s comment that a string representation of a UUID isn’t actually a UUID even if it could be used as input to creating a proper java.util.UUID.


I think my issue is solved with (class #uuid "550e8400-e29b-41d4-a716-446655440000”). Wrapping the string in the (class #uuid) and passing that to uuid?. Boom.


Heh, basically. What could be used to create a UUID isn’t yet a UUID and thus would fail uuid? because it’s not a UUID yet.


Glad I brought it up. I learned a lot. Thanks, everybody!


is it ok when replaces clojure.core/read-string?

hiredman23:09:02 is more like clojure.edn/read-string, but all the read-strings have a large overlap


sorry, I meant clojure.edn/read-string