Live data from Hacker News

Clojure builds as an amalgamation of orthogonal parts

blog.fogus.me

71–80 of 99 posts

Re: Clojure builds as an amalgamation of orthogonal parts

#71

I don’t understand why deps was needed and I’m surprised its authors didn’t foresee the confusion it would create. I’m also confused as hell what I should be using now, and the idea of researching deps seems exhausting. I’ll just stick to cutting and pasting onto my leiningen config I think.

> I don’t understand why deps was needed

First, start here: https://clojure.org/about/rationale

Then Deps and CLI is explained here: https://clojure.org/reference/deps_and_cli

> what I should be using now

As always, depends. Building a project in a rush? Use whatever you're most comfortable with and have the most experience. Want to further your understanding of Clojure the ecosystem? Dig into Deps & co.

> I’ll just stick to cutting and pasting onto my leiningen config I think

Yeah, if that's your general approach to development, use whatever you already know. Once you're ready to understand the tools you depend on, then you can start looking into tools that was built with some more thought behind them, like Deps.

Re: Clojure builds as an amalgamation of orthogonal parts

#72

Glad they're finally making this stuff first-party. When I messed around and did a Clojure project, the build/dependencies story was the biggest sour note of the experience by far. It was bewildering to have to go set up some third-party tool with a mustache logo before I could follow along with the official tutorial. I think having a cohesive story for this is table-stakes in a modern programming language.

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.

Re: Clojure builds as an amalgamation of orthogonal parts

#73
post #42

It'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…

> I'm really happy this stuff exists and is being enhanced, but the flexibility kinda adds a barrier to getting started

Clojure (seems to me at least) has always preferred to cater to professionals who want to learn languages, tools and concepts deeply rather than being quick to learn. So naturally, the ecosystem tends to lean towards simple tools you use as building blocks rather than one-size-fits-them-all ala Ruby on Rails. This does make it harder to get started with Clojure, but once you've taken the time you to learn everything, it really pays off.

Re: Clojure builds as an amalgamation of orthogonal parts

#74
post #67

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…

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…

> I also worry that if we hit new Clojure devs with a wall of tooling issues like this, they won't stick around, even if we tell them the underlying theory of their tooling is more sound.

This sounds like a educational problem rather than "lets dumb down our tools to cater to new developers".

Clojure seems to balance "cater to professionals VS being easy to get started with" to the first mentioned segment, something I myself has no problem with.

Re: Clojure builds as an amalgamation of orthogonal parts

#75

Glad they're finally making this stuff first-party. When I messed around and did a Clojure project, the build/dependencies story was the biggest sour note of the experience by far. It was bewildering to have to go set up some third-party tool with a mustache logo before I could follow along with the official tutorial. I think having a cohesive story for this is table-stakes in a modern programming language.

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 until the point where you need dependency management and packaging. You can't even execute a .clj file (as far as I know) without going outside of the official resources.

Re: Clojure builds as an amalgamation of orthogonal parts

#76
post #42

It'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…

> I'm really happy this stuff exists and is being enhanced, but the flexibility kinda adds a barrier to getting started Clojure (seems to me at least) has always preferred to cater to professionals who want to learn languages, tools and concepts deeply rather than being quick to learn. So naturally, the ecosystem tends to lean towards simple tools you use as building blocks rather than one-size-fits-them-all ala Ruby…

The tools pay off for sure but even once you know how to use deps.edn and company, I'd argue you still really need quick one-file programs.

It's not just about education (though that's important as well). I think the top two use-cases are scripts and issues.

Issues, .. well you want to be a nice dev and post issues with some sample code that reproduces the problem.. but you don't want to have make a whole repo (and then have it floating around on your github indefinitely?) just to show an issue/problem that takes 20 lines of code. So then most people end up copying the problematic code into the github issue text box.. and... it sorta kinda works? but not really. Neither you nor the library maintainer can actually copy and run the code now, so you both end up squinting at it and trying to guess what went wrong. It's just a mess. Even if you make a repo, then how do you get feedback? Other people need to fork and upload their own versions of your demo repo? It's just too heavy handed.

For scripts and quick hacks you want to bang out code quickly. Open up a new file and write .. slurp some files, massage some data, look at some values .. maybe spit out a plot etc. And you want to be able to quickly look over them 2 months later and see what the hell you did. You want to be able to send and share them easily. It really needs to be all in one file otherwise it's just too much of a hassle.

I think the final killer features of `add-libs` that I'm appreciating more as I use it - is that since you can add libraries right in the REPL dynamically you never need to modify your deps.edn and reboot CIDER! It seems minor, but restarting CIDER just always sucks.. and at least for me it breaks the "flow". You loose all the state you had (if you're poking around you can have lots of little variables around) and you loose all your command history. You can only modify your workflow so much to accommodate the inevitable occasional CIDER reboots.

Re: Clojure builds as an amalgamation of orthogonal parts

#77
I asked some questions on slack related to this, and in case anyone else was confused like me thinking tools.build is a new framework for managing build tasks, that does not seem the be intent.

tools.build is a helper lib to write programs that make artifacts such as Jars or Uberjars. It competes with things like depstar in that sense.

Tasks are still meant to be managed by deps.edn (tools.deps) and the Clojure CLI by having tasks be Clojure programs that are invokable as either -X, -T or -M, and the idea is you would orchestrate them with another tool like make, a shell command or script, babashka task runner, npm scripts, just etc.

This means that any Clojure program can be a "task". All you need to add a new task to a project is define an alias for it in the project deps.edn.

Now one caveat is depending on the type of program the task is, you might need to call the alias with either -X, -T or -M option:

    clojure -T:alias
    clojure -X:alias
    clojure -M:alias
Ideally all Clojure programs that implement a task move to rely on exec-fns, and thus would be called with -T or -X, which will eventually allow you to chain tasks together where the return of the first task exec-fn will be passed to the next task's exec-fn, so you can compose tasks and run them consecutively from the clojure CLI.

So tools.build is just a lib that you can use to help you write tasks (which are just normal Clojure programs), but it is itself a set of exec-fns tasks which you can use directly as an alias as well:

    clojure -T:build-api copy-file :src '"./src/tempo.clj"' :target '"./output/tempo.clj"'
with alias as:

    :build-api {:deps {io.github.clojure/tools.build {:git/tag "v0.1.6" :git/sha "5636e61"}}
                :ns-default clojure.tools.build.api}

Re: Clojure builds as an amalgamation of orthogonal parts

#78

I don’t understand why deps was needed and I’m surprised its authors didn’t foresee the confusion it would create. I’m also confused as hell what I should be using now, and the idea of researching deps seems exhausting. I’ll just stick to cutting and pasting onto my leiningen config I think.

> I don’t understand why deps was needed First, start here: https://clojure.org/about/rationale Then Deps and CLI is explained here: https://clojure.org/reference/deps_and_cli > what I should be using now As always, depends. Building a project in a rush? Use whatever you're most comfortable with and have the most experience. Want to further your understanding of Clojure the ecosystem? Dig into Deps & co. > I’ll just…

It’s still alpha, and from what I can tell from the links referenced, a severe case of NIH. Hopefully it will be “made simple” and “de-complected” soon though so that I can tell what the point of it is in the presence of Leiningen.

Re: Clojure builds as an amalgamation of orthogonal parts

#79
post #42

It'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"'

Re: Clojure builds as an amalgamation of orthogonal parts

#80

Earlier quoted context omitted.

After using it with Datomic Cloud, do you prefer it also for local projects? Is there something that happened with Datomic Cloud configuration that made it “click” for you elsewhere? Did you just have to use it there and that experience informed your preferences? Data > functions > macros is a core concept of Clojure. Does that come into play here? These are prompts from a curious outsider’s perspective.

I do. I guess it boils down to the fact that I don't find it significantly harder to use than Leiningen, there are great libraries and tools that work well with it (shadow-cljs can source its deps from deps.edn for example), and I wrap the entire thing in a task system anyway (lately, Babashka tasks). I guess it helps that its the "official" way to do things, but that's not a primary concern for me.

Thanks. I hadn’t even considered Babashka, which I’m quite intrigued by.
Post reply on HN