This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # adventofcode (326)
- # aws (1)
- # beginners (67)
- # cider (52)
- # cljs-dev (5)
- # cljsrn (5)
- # clojure (104)
- # clojure-art (2)
- # clojure-austin (34)
- # clojure-france (12)
- # clojure-greece (38)
- # clojure-india (2)
- # clojure-italy (6)
- # clojure-spec (11)
- # clojure-uk (32)
- # clojurescript (51)
- # core-async (5)
- # cursive (11)
- # data-science (5)
- # datascript (3)
- # datomic (3)
- # defnpodcast (7)
- # fulcro (26)
- # graphql (10)
- # hoplon (1)
- # instaparse (2)
- # jobs (1)
- # klipse (3)
- # lumo (13)
- # off-topic (50)
- # om (2)
- # onyx (19)
- # parinfer (1)
- # pedestal (4)
- # re-frame (18)
- # ring-swagger (1)
- # spacemacs (1)
- # specter (42)
- # sql (9)
- # uncomplicate (18)
- # unrepl (13)
@sova Thank you very much for your comment! I think I understand what you suggest, and it seems to do what's needed, except that if you just add a new record that Joe's ice-cream liking is now 7 then that won't automatically retract the previous 8. The solution I put in my most recent comment (`:liking-person-food` attribute unique) solves that problem but it admittedly looks inelegant in its own way...
In the repl, you can get
(str *ns*) for a human-friendly value of the current namespace
is there built-in way to
swap! an atom but return the atom itself instead of it's dereferenced value? it would be useful for threading scenarios:
(cond-> some-atom x? (swap! update :x inc) y? (swap! update :y inc))
I don’t believe there’s a built-in way, but you don’t really need it:
(swap! some-atom #(cond-> % x? (update :x inc) y? (update :y inc)))
I would go further and say you don’t want that. If you are outside the atom, you are outside the atomic update and I think you could get some very unexpected results
Where do you put test utils code so that
lein test won't try to run it as if it were a test?
lein test only runs things that are defined as tests via the
:test metadata or via
deftest (which puts :test metadata on your var for you)
as long as you don’t have side effects in your files, their code won’t be run unless it’s a test
Clojure yes. Boot/Lein, yeeees, but you have to do some mucking about. As I understand it.
@admay App development will take more than 10 months so at the time of release there will be no security fixes for Java 8.
@ghsgd2 That’s a very valid concern haha I hadn’t even thought of that. It looks like we have until September of 2018 to get our stuff together. I’m going to be holding out until summer to wait and see what happens. I’m guessing by then, there will be plans to make stuff work for Leiningen and Boot out of the box rather than having to muck about.
does moving to the new dep management features in clojure 1.9 help? (i honestly haven't looked at it yet)
the new dep management is for users looking for a bare minimum way to test out a clojure repl, it’s not relevant for project management
on the java 9 thing, I found that you have to add
:jvm-opts ["--add-modules" "java.xml.bind"] to your lein project.clj (probably have to do something similar with boot)
@joshkh I think the goal for
tools.deps.alpha is to assist those building tooling rather than those using the tooling. I wouldn’t dare use the new deps library to manage a web application project, I’ll always opt for Lein or Boot. However, if I was building a tool to manage projects,
tools.deps.alpha would be my go-to for building out my dependencies.
This is all assuming you’re asking about
aye, that's the one. i just had a look into it and you're right - great for building up projects concurrently but is out of scope for what lein/boot has to offer
Yeah, Lein and Boot are here to stay for a while, I think. I don’t think the Clojure team will ever focus on building out a specific developer tool for Clojure unless there is a desperate need for it or the current tooling diverges from the Clojure philosophy in a major way. There’s just too much opportunity to improve on the language itself to shift focus to tooling. However, now that the library does exist, I wouldn’t be surprised if we see more niche build tools coming out. Something like a plugin to build programmable templates for targeted applications like AWS Lambda maybe. As it stands, there’s no reasonable approach to running Clojure (not ClojureScript, just Clojure) on AWS Lambda due to startup time. However, with the
tools.deps library, there might be someone out there who figures out how to drastically speed up the startup time for small Clojure programs to make them Lambda-able.
Interestingly I was talking to someone at an AWS meetup about this the other week. They said they don't actually have any problems running Clojure in a Lambda, because as long as you trigger it at least once every 5 minutes it stays 'warm' waiting for a new request, rather than spinning up a new instance. So you don't pay the startup cost every time. Obviously if you have a sudden spike in requests it'll spin up a load of new instances which will be slow, but apparently for a fairly consistent and constant level of throughput the startup time for Clojure isn't a major issue in Lambdas. This is just what I was told though, I have no direct experience.
@admay There's a fairly fundamental limit to how much can be shaved off start up time and, while the core team do look at that, it's not really a priority use case for Clojure.
@joshkh There are Leiningen and Boot add-ons that leverage
tools.deps.alpha so you can specify dependencies etc in
deps.edn and then use
clojure) or you can use Leiningen/Boot with the same deps file(s). `tools.deps. is "just" a building block.
@seancorfield They would help Clojure a lot by updating
conj to have the same behavior for different collection types.
if order of insertion matters, you should be making some guarantee that the data type being used is one that naturally inserts in that order
@seancorfield yeah, that was the only contrived example that I could come up with on the spot lol
@ghsgd2 The different behaviors of
conj are deliberate. the idea is that different data structures are exactly that, different. I’m guessing an example you might refer to is
(conj '(1 2 3) 4)) vs
(conj [1 2 3] 4). The reason why they work differently is because different data structures are more useful in certain use cases than others.
I’ll admit though, a rationale doc behind the behavior of
conj and the like on data structures would be a good thing for beginners and it’s been a long time coming. This discussion is usually reserved for questions in the forums
The docstring is explicit about the behavior depending on the concrete type (of the collection) and http://clojuredocs.org has plenty of examples. And
clojure-site now accepts PRs (from anyone with a signed CA) so the community can add rationale docs etc. This isn't something we need to wait for the core team to do.
Also https://clojure.org/guides/learn/sequential_colls "However,
conj always adds elements where it can be done in constant time for the data structure."
I think Clojure places a lot more emphasis on understanding the primary abstractions than any other language -- and, in particular, the performance guarantees of various operations on various data structures. And, yes, that makes the on-ramp steeper for new-to-Clojure developers.
I can’t remember where I read it, but someone, somewhere said, “Clojure asks for more from you but gives more in return” or something like that. It’s absolutely got a bit of a steeper learning curve than other languages (in my own experience as well) but the payoff is incredible and filled with “AH-HA!” moments like when the design choice of
(conj) returning an empty vector in particular is explained, discovered, or otherwise made known!
I like that characterization of Clojure... yeah, the culture is definitely one that rewards careful thought (and, to some extent, punishes sloppy thinking!). Really grokking the abstractions can take a while. Even now, after knowing Clojure for over seven years, there are still times when I post some code snippet and someone says "You could do X instead" and I'm like, "Oh yeah! Wow! That's much more idiomatic!"...
(like the other day when I posted a transducer pipeline and I knew it could be cleaner but wasn't sure how -- and someone said "Use
mapcat and you can omit that middle step" -- real 💡 stuff!)
I think a big part of learning Clojure is not just watch the old talks (Hammock driven development, Programming with Hand Tools, etc…) but watching them continuously. I’m 24. I have a degree in Maths. I’ve been programming a WHOPPING 2 years. The philosophy is sticking a bit, but the more I watch those talks and read those heavy hitting papers, the more I learn (and I always learn something new from them). It’s not an easy journey to truly understanding the language.
@seancorfield I’m curious now, any idea why
(conj) returns an empty vector in particular?
@admay it’s for reducers and transducers that use a function with no args to return a base case
and  is the natural base case for reducers and transducers, and conj the most general reducing/transducing function
That makes much more sense now, especially when the idea of ‘choosing the proper data structures’ comes up. Thanks @noisesmith!
I’ve been thinking about my next doc production for a while now and I think it might revolve around Clojure data structures, design choices, and when to use them. I need to finish up the functional programming guide first though.
Hi 🙂 I’ve installed latest version of clojure and leiningen via brew but when I run lein repl I get a clojure 1.8.0 version. What I am doing wrong?
it’s not bundled. the default template just creates a project.clj dependent on 1.8.0 (will be updated in future version)