3 ms·
> he was explicit that dependency/project management where very hard problems that Clojure didn't really attempt to solve. For what it's worth, having used Clo
by microcolonel 6y ago
> he was explicit that dependency/project management where very hard problems that Clojure didn't really attempt to solve.
For what it's worth, having used Clojure for work for a couple years now, and ditching leiningen for deps.edn (built in package and dependency management that hooks into maven), I've not had an issue with it. You just add the dependencies to your deps.edn, and run your program. If your namespace needs something from a package, you add it to the (:require ...) section of your ns declaration.
Here's an example ns from one of our messiest modules:
(ns profusion.core
(:require
[clojure.core.match :refer [match]]
[clojure.set :as set]
[clojure.string :as string]
[clojure.walk :as walk]
[clojure.zip :as z]
[instaparse.core :as insta]
[profusion.infix :refer [infix-to-prefix]]
[profusion.standard-library :refer [comparison]]
[profusion.utils :refer :all]
)
(:import
(org.jgrapht Graph)
(org.jgrapht.traverse TopologicalOrderIterator)
(org.jgrapht.graph
DefaultEdge
SimpleDirectedGraph)
))
To be clear, projects like this can be run with the base Clojure distribution, no additional tools required.
> I'm not aware of any Clojure tools that are best-of-breed for project management. Java has a better model for locking everything down (or maybe how the Linux Distros manage their repositories) and Python has a better model for just keeping up with the current state of things. I'm not aware of any half-and-half model that gives satisfying results.
deps.edn generally asks you for specific versions if you're getting things from maven, so you don't risk not "locking everything down". If you really want to lock everything down however, you should check all your dependencies into your source tree, this is an option that deps.edn supports well, through the :local keyword instead of :mvn/version for maven dependencies. That namespace declaration I showed you is from a subproject that we import into one of our other subprojects using the :local keyword, and the deps.edn for it just declares the source directories and and the dependencies, everything else is handled automatically.
- roenxi 6y agoThat is a perfectly reasonable way of doing things. However, the official reference [0] recommends: (1) Your way (but also throw in an :only and doesn't mention :refer) (2) (require 'clojure.contrib.def 'clojure.contrib.except 'clojure.contrib.sql) (3) (require '(clojure.contrib def except sql)) And leaves open a lot of room for someone to try to use (use) which is probably a mistake since you don't use it. And sometimes your way has [] and sometimes it doesn't. Pretty much at random considering '[profusion.utils :refer :all]'. And the official docs add in a dizzying number of combinations of quoting requirements to recall. It isn't the end of the world but that is a far cry from how good all the other parts of the language are. It is really sloppy and confusing to learn. There is no recommended approach and I personally can't remember which easy way I used last time so my personal projects cycle randomly. I think Clojure has the worst library loading mechanism of any language I think is good. Even your way has two completely different code paths (import vs require) to bring in dependencies. [0] https://clojure.org/reference/libs https://clojure.org/reference/libs
- microcolonel 6y ago> Even your way has two completely different code paths (import vs require) to bring in dependencies. import and require have different purposes though, it makes perfect sense to me that they are separate. Import, here, is used to import Java classes, which don't hook into Clojure's namespaces directly; require is for bringing in symbols from Clojure namespaces. In general, a beginner or intermediate Clojure user will not touch the :import feature at all, nor the :use feature. > It is really sloppy and confusing to learn. That's one opinion of it I guess; though in my experience, the way that I do it is very common in publicly-visible Clojure modules. I've been doing it the same way since day one, without issue. There may be other ways, but you don't really need to care about them. With this you'll understand most modules you come across, and you'll be able to accomplish basically anything you'll want to. Given the average completeness of documentation on publicly-visible packages (though to be fair most big ones have what most would consider adequate documentation) including the core, you're going to have lots of opportunities to read other people's modules, and these minutiae will fade into obscurity and be overshadowed by your own program's problem space.
- roenxi 6y ago> For what it's worth, having used Clojure for work for a couple years now... > ...it makes perfect sense to me that they are separate... > A lib’s container is a Java resource whose classpath-relative path is derived from the lib name [0] > No matter what some people say, getting started in Clojure is a nightmare. ~ galfarragem (earlier in the thread). I'm hoping this smorgasbord of quotes is making my point for me - the fact that there is an easy way is good, but the problem is that the easy way is very well hidden and Clojure is competing with systems like 'pip install foo', 'import foo' in every single piece of documentation on Python there is on the internet. I'm not budging from Clojure's import system being byzantine. I don't care that the people who stuck with Clojure figured out something that works for them, it is stupid and it is a very effective filter on keeping people out of the language. The lesson 'ignore half the reference manual page' is not an appropriate lesson to be learning while working out how to load dependencies. EDIT If all the other parts of the project build were easy then obviously this wouldn't be an effective filter; but this combined with a misconfigured classpath issue for someone who doesn't know Java well would be the end of it. [0] https://clojure.org/reference/libs https://clojure.org/reference/libs
- oalae5niMiel7qu 6y ago>For what it's worth, having used Clojure for work for a couple years now, and ditching leiningen for deps.edn (built in package and dependency management that hooks into maven), I've not had an issue with it. >... >To be clear, projects like this can be run with the base Clojure distribution, no additional tools required. Didn't you just say that dependency management hooks into Maven? So doesn't that imply you need to get Maven set up before you can run a Clojure project?
- microcolonel 6y ago> So doesn't that imply you need to get Maven set up before you can run a Clojure project? Not sure what is meant by "get Maven set up". With Clojure it does not involve any additional work, it's just built in to the Clojure runtime, and it goes ahead and fetches your dependencies either when you ask it to, or right before loading your program for the first time. I think they just use the Maven repositories, as in the servers themselves, not the Maven client software for Java, whatever that may be (I've never used it).
- oalae5niMiel7qu 6y agoThen surely, you need to set up a Maven server before you can use Clojure.