What all the critics miss is that Lein is "Easy" but tools.deps, tools.build are "Simple". Rich wants all of clojure to be built from simple orthogonal parts that compose together. Ideally a multi-purpose tool like leiningen should be built on top of those simple parts. Other tools can re-use those parts in different ways. With Leiningen - its a great tool but it's a complex thing that you take on an all-or-nothing b…
Theory is all very well, but adding a library to a project is a critical requirement for all projects. A new starter comes over to Clojure from Python and the Deps guide [0] confidently explains too them that they add {:deps {clojure.java-time/clojure.java-time {:mvn/version "0.3.2"}}} to their deps.edn and they're good to go. Raising only the questions of: 1. What are the available keys of this map? 2. Why do I have…
Clojure builds as an amalgamation of orthogonal parts
81–90 of 99 posts
Re: Clojure builds as an amalgamation of orthogonal parts
#82What all the critics miss is that Lein is "Easy" but tools.deps, tools.build are "Simple". Rich wants all of clojure to be built from simple orthogonal parts that compose together. Ideally a multi-purpose tool like leiningen should be built on top of those simple parts. Other tools can re-use those parts in different ways. With Leiningen - its a great tool but it's a complex thing that you take on an all-or-nothing b…
As a Clojure developer focused on creating correct/working software, I find the "Simple"-ness of my tooling's internal architecture to be a lower priority than it not leaking additional cognitive load onto my dev experience. It may be the case that lein's internals are a blob of complexity, without boundaries defined in the "right" places. Maybe Clojure Tools' 3 or 4 components have it correct (though I'm skeptical o…
There are lots of other things - they are all additive. Many Clojure libraries and tools don't need a build.clj or tools.build at all.
My experience is that deps.edn is much easier to get started with. With a template from something like clj-new you can get testing, a basic jar building script, etc to get started with and it's all there for you to muck with if needed.
Re: Clojure builds as an amalgamation of orthogonal parts
#83Earlier quoted context omitted.
> RICH HICKEY: I think that, collectively, we are infatuated with these two notions of easy. We are just so self-involved in these two aspects; it's hurting us tremendously. Right? All we care about is, can I get this instantly and start running it in five seconds? It could be this giant hairball that you got, but all you care is, can you get it. Simple Made Easy is what attracted me to Clojure, and tools.build, tool…
You forget that on the ground-floor, where programming languages compete for mind-share, easy matters. In fact easy, in terms of getting something working, trumps difficult simplicity any day of the week. Easy is part of what makes an employer want to use your technology.
There's lots of other things you can do with clj - these are all additive. At some point, you might (possibly) need a build script. When you do, it's written in Clojure using a pretty straightforward set of functions and you can copy/paste in a starting point. You can grow that build file forever.
Re: Clojure builds as an amalgamation of orthogonal parts
#84Earlier quoted context omitted.
Leinengen vs Maven dependency resolution is pretty distant to my concerns. I may be in the minority there, but I don’t think I am. I guess the thing I’m struggling to understand in the build tool differences is: Leinengen’s (defproject) takes a series of keys and values. It is declarative. You can probably get into dependency hell if your config is complex enough, and I’m almost certain it’s doing more than I underst…
i agree that it’s possible to have both, but you have to start with simple, and as he said in the talk which we just reread, easy is often relative to your local priors also those custom hand rolled fns are … a library, which is way better than a build plugin
If tools.* is the language maintainers’ preferred method, I think there is value in having a single command to set up a “simple/default Clojure project” in a folder, even if that only cuts the commands down from four to one.
$ mkdir hello-world
$ cp deps.edn hello-world
$ cd hello-world
$ mkdir src
I don’t understand where that deps.edn comes from in a fresh project. It’d be great to have “clj create hello-world” build one for me in ./hello-world, use my running Clojure version as a dependency (if that’s how “clj” works), create the child src/ (and /test if that’s a best practice) folders, etc. The idea being to generate a local library on-demand with sane boilerplate defaults and almost no knowledge. I can learn later what Else I might need if I can get it up and running quickly first.Leinengen looks easier to me for my admittedly trivial use cases, because I don’t need a library or plugins at all. And again, I might be in the minority. But if folks keep saying “lein handles 90% and is easier,” and if we can make tools.* handle those same 90% cases trivially, it seems worthwhile.
Re: Clojure builds as an amalgamation of orthogonal parts
#85It's nice to have complex build/test setups with deep directory structures, I'm really happy this stuff exists and is being enhanced, but the flexibility kinda adds a barrier to getting started. It's also important to be able to just drop into a REPL, load some libraries and go. I think the coolest thing in the pipeline is going to be `add-libs`: https://insideclojure.org/2018/05/04/add-lib/ I made a little orgmode l…
gists are git repos and can contain multiple files. Since clj supports git deps, you've been able to use them as deps for a long time. Example gist: https://gist.github.com/puredanger/cbcdd9f54deb7fb7309fdd632... Run it: clj -Sdeps '{:deps {a/gist {:git/url " https://gist.github.com/puredanger/cbcdd9f54deb7fb7309fdd632... " :sha "116ac594c922be6ed9d3366f5ac89ed2b0a082f5"}}}' -X foo/bar :name '"Alex"'
and thank you for the demo. With the`:paths ["."]` you flatten the project and minimize the example size. It would make demos look much better
In the end it's not quite as ergonomic as using `add-libs`, but it something that works today. Hope`add-libs` makes it into core some day. Having one-file programs would really take away the remaining friction of sharing code.
PS: thank you for your help on ask.clojure.org the other day. I got your book and am looking forward to reading it
Re: Clojure builds as an amalgamation of orthogonal parts
#86Earlier quoted context omitted.
A bit of context, because your post could easily be taken in bad faith: > Ideally a multi-purpose tool like leiningen should be built on top of those simple parts tools.build is 2 weeks old according to the announcement. Leiningen is nearly 12 years old. I haven't looked into tools.build, so not arguing for or against it. Disclaimer: Have been doing some work on leiningen from time to time. Also I first ran into Cloj…
"Easy" is important for someone to start playing around with something, to initially hook the user (the developer in this case). But for professionals who spend a lot of time with the same tool, "simple" is more important in the long run.
The whole thing was "it must be simple, even if the user needs to spend more time learning it" which is only true for people who learn the thing and keep on using it. For us who come back to a project after months (because we switch between tech stacks) it might be just twice the amount of work, if you need to relearn it every time.
Re: Clojure builds as an amalgamation of orthogonal parts
#87Earlier quoted context omitted.
For as long as I can remember, the instructions from the official docs leads you into a REPL where you can start learning. Not sure what this "official tutorial" you are talking about, but as long as you get a REPL running, you should be able to get started.
I couldn't start writing and compiling my own source files until I went through all these unofficial channels to get stuff set up. I might be misremembering about the actual tutorial itself, but step 2 (do your own project) was literally impossible without the detour. This is even worse than how it is for Python - which does have a similar problem - because at least in Python's case you can "just run" your scripts up…
$ clj --version
Clojure CLI version 1.10.3.849
$ echo "(println \"hello world\")" >> hello-world.clj
$ clj hello-world.clj
hello worldRe: Clojure builds as an amalgamation of orthogonal parts
#88Given the general tone of comments here, I thought it worth pointing out the advantages of using deps.edn instead of a Leiningen project: - REPLs start up very slightly quicker
I don't understand why people keep complaining about slow REPL startup time. How many times do you really restart your REPL? In my day job, I usually start up the REPL once and then close it when I'm done during the day, or just fold up the laptop which suspends the REPL and then it's ready to go when I unsuspend. Only time I can think of when I need to restart the REPL is when I add a new dependency, but that doesn'…
The whole 'reloaded workflow' is a workaround to the slow restart IMGO. It works well, but there is a learning curve, especially coming from languages with fast edit-compile-run cycles such as go.
I've also worked with scheme, and having a repl up and running in milliseconds is really nice.
Re: Clojure builds as an amalgamation of orthogonal parts
#89Earlier quoted context omitted.
I don't understand why people keep complaining about slow REPL startup time. How many times do you really restart your REPL? In my day job, I usually start up the REPL once and then close it when I'm done during the day, or just fold up the laptop which suspends the REPL and then it's ready to go when I unsuspend. Only time I can think of when I need to restart the REPL is when I add a new dependency, but that doesn'…
I also go without restaring the repl for weeks, but there are plenty of situations where you need to restart the repl: adding libraries, servers binding to ports, making sure you have no temporary edits, etc, etc. The whole 'reloaded workflow' is a workaround to the slow restart IMGO. It works well, but there is a learning curve, especially coming from languages with fast edit-compile-run cycles such as go. I've also…
True that temporary edits could in theory get in the way, although I never had that happen to me in ~6 years of experience with Clojure. Server bindings to port should not warrant a REPL restart, usually you can save the returned function/data from starting the server to also turn it off (and unbind the sockets).
> The whole 'reloaded workflow' is a workaround to the slow restart IMGO
I disagree with this, it's not a workaround. It's a different workflow, yes, but it is different on purpose, not by accident.
Being able to evaluate and run snippets of code will (for me) always be a faster workflow than even the fastest edit-compile-run languages, since I can evaluate code in the middle of functions and won't have to have any unit tests just to test something temporarily in isolation.
Re: Clojure builds as an amalgamation of orthogonal parts
#90Earlier quoted context omitted.
I couldn't start writing and compiling my own source files until I went through all these unofficial channels to get stuff set up. I might be misremembering about the actual tutorial itself, but step 2 (do your own project) was literally impossible without the detour. This is even worse than how it is for Python - which does have a similar problem - because at least in Python's case you can "just run" your scripts up…
I'm not sure how they can make it easier than what it currently is, no need for any unofficial channels. If you follow the guide at https://clojure.org/guides/getting_started to install Clojure, you'll end up with `clj` in your `$PATH`, and then it is as easy as it is with Python, unless I misunderstand what you mean. $ clj --version Clojure CLI version 1.10.3.849 $ echo "(println \"hello world\")" >> hello-world.clj…