So we need players. I would rant here, but I won't. But look at this guitar player with blisters. A harpist has blisters, a base player with blisters. There's this barrier to overcome for every musician. Imagine if you downloaded something from GitHub and it gave you blisters. - Rich Hickey (Design, Composition and Performance)
Clojure seems more concerned with power, expressiveness, and reach, rather than ease of use. Does this alienate new users, sure, but the Clojure community seems OK with that as a trade-off.
It's like you were getting blisters from stringing your guitar. You buy a guitar, get home, and it takes three days to open the case. Then another week to figure out which strings go where. God help you when you realize you have to tune the thing.
Two, five, seven days pass and you haven't played a note. I don't think that's what Hickey meant.
That said, it's worth it.
An example would be Clojure's newish approach to managing projects via the CLI and deps.edn. It's very powerful, and expressive, but definitely not a one-click approach.
But as I recall the original Rich Hickey talks on "Why Clojure?" he was explicit that dependency/project management were very hard problems that Clojure didn't really attempt to solve.
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.
Clojure is inferior to Java in that aspect because the number of things to keep track of roughly doubles (for every concept there seems to be a Clojure version and a Java version) and library management is bizarre and warty - see also the horrible import/require/use/some other one I can't even remember mess. And then there is unpicking the syntax differences between using things in the (ns) macro vs calling direct. I dunno; maybe something changed but that part of the experience is a mess. Unusually poorly done in Clojure too, everything else was so lovely.
I never got on top of it and I tried for months; as evidenced I can't even remember how to load a library after putting it down for a little while. Even assuming the classpath is correctly set. What would have to happen for a C programmer to forget #include "name.h" ?
Uh? Clojure locks everything down as a well. In fact, deps.edn solves many issues experienced with Maven.
Personally, I've found Clojure dependency management to be the best I've ever used in any language. It's simple, explicit, gets out of your way, and lets you just do your work.
> and Python has a better model for just keeping up with the current state of things.
I'd like to hear about this? Pip doesn't even have a command to update all dependencies in one go. And figuring what even are the dependencies of any given project is a mess.
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.
(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.
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.
> ...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.
Getting started in Clojure is not a nightmare, ordinary people do it all the time, the fact that somebody said it was a nightmare says very little.
Clojure's mechanism for requiring packages is far from byzantine, whether you "budge" on that or not; many Clojure libraries have the snippet for including the current stable release of that library at the top of their README on GitHub. It isn't matter of "sticking with it" or "figuring out something that works for you", it is literally one relatively simple piece of knowledge that is learned once and works forever.
In short, if you find namespaces and importing byzantine in Clojure, you are probably at the level of struggling to write fizzbuzz in any language. The fact that there are features other than :require in ns does not indicate that :require is complicated, it just indicates that ns has features.
Somehow a language designed from scratch with all the purported wisdom of Lisp ended up with a nastier import solution than JavaScript, which had none out of the box for its first two decades of life, and then had to reconcile as many as 5 different module systems.
Also Clojure is doing just fine, not sure what you mean by "dying". The core and the tooling continue to improve, there are lots of libraries, more people writing than ever. I just don't see this death you're describing.
The comments here just strike me as ignorant and incoherent as a whole. Why do people who clearly have no experience actually trying to do something in Clojure have so much to say about it?
Clojure may support things that look daunting to you, but if you actually had any goal other than critiquing the variety of things you actually have no use for, you would not have the difficulties you describe.
Maybe I'm spoiled, I remember JDK setup being a pain on Windows a decade ago when I used it last, if that's the problem then I get it. My spoiled experience on a system with a functioning package manager is basically install-and-go, and zero configuration required to get CIDER going after that.
I just don't get what's so bad about it, it's basically the same experience as Rust with Cargo; is that another "nasty" experience? What language with package manager has a better experience?
>...
>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?
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).
You just need Java installed on your system, then you install clojure (via brew, or sh install) and that's it, you're good to go.
I've written a guide to starting with Clojure covering installation to REPL & IDE configuration: https://grison.me/2020/04/04/starting-with-clojure/
In an extreme case, someone who doesn't know Java ecosystem might want to stop to research: what is JVM, why is it necessary, which version would be the best, what's the difference between Oracle's Java and OpenJDK, etc...
Out of the top of my head:
- There is the Python 2.7/3.X situation still going on, then there are the several distributions of python.
- GNU's R has a similar problem
- Installing gcc on windows was (perhaps still is) a confusing mess for a newcomer.
IMO I did not find installing clojure any harder than installing Scala for instance, and yet I have never heard (anecdotal, I know) complaining about Scala.
You might not share that users preference of caring about the installation experience of a PL, but arguing that this user's preference is somehow unfair because many other languages also have bad installation experiences makes absolutely no sense.
The vast majority of PCs are Windows, not Mac or Linux. Though WSL2 (available with Windows Insiders) makes working with Linux software a breeze, it's not the standard flow. Java isn't installed by default, either.
Your guide suggests using WSL and IntelliJ. Does IntilliJ actually work with Closure running in WSL? For that matter, does the VS Code plugin?
These are all headaches a new programmer won't have when getting setup with PHP, Python, JavaScript or most popular languages.
I think this is especially disappointing because there are mature, cross platform solutions available but whoever manages the Clojure project seems hell bent on pushing their "clj" tool which is, clearly, treating cross-platform concerns as an after thought. The Clojure organization conducts a survey every year and this is hurting their adoption with developers on Windows.
"One new question we asked this year was about the primary developer operating system to give us better guidance about tool-related work. As expected, MacOS was the leader (55%), followed by Linux (35%) and Windows (9%)"
Getting started with Leiningen, in my opinion, is much easier although, as has been pointed out, installing a JDK is an extra step that other languages don't have.
[0]: https://clojure.org/guides/getting_started
[1]: https://clojure.org/news/2020/02/20/state-of-clojure-2020
I'm doing a lot of Clojure since years both on my MBP and on Windows and there's no problem at all doing that way. Besides VSCode even has a plugin for WSL which will let you directly hook into it.
So yeah there are some questions like which Java to install, which IDE, .. but these questions are the same for other programming languages.
If you have any hint regarding how to improve my guide don't hesitate to tell me if something is not clear in it :)
Probably the biggest thing would be to assume the person reading the guide has a brand new computer and hasn't installed anything yet (including Java and Homebrew).
It's really hard to assume much about the background of someone just trying a new programming language. Maybe they've worked with other languages and you're familiar with, maybe not.
A Lisper sees a REPL, and thinks they have "gotten started." When I think most language learners don't think they have "gotten started" until they, on the low end, have printed something at a familiar terminal, or, on the high end, pointed a web browser to localhost:8080 and seen some text there.
I don't see who the "clj" shell script is somehow "part of Clojure" any more than Leiningen or Boot. IMHO it's just a shell script and it works similarly to the other tools, except not in any way cross platform.
"Then run:
Invoke-Expression (New-Object System.Net.WebClient) .DownloadString('https://download.clojure.org/install/win-install-1.10.1.536....
There's also no clj installer for Windows although there is a Scoop package.
https://github.com/clojure/tools.deps.alpha/wiki/clj-on-Wind...
And how to work with vscode as it all fails, at least windows.
But love clojure syntax. In particular I found it hard to see all () and the simple added some syntax sugars help the eye a lot.
Hence jump to janet. In fact the community is very helpful.
Not sure but the size is small enough to see whether one can do embedded as I try picolisp but it is bounded to a low end Env.
Very promising.
Btw the whole point I later schedule more time to try clojurescript to ... May be that can wait a bit.
2 - Dowload clojure.jar
3 - Start command.com or PowerShell
4 - cd into clojure installation directory
5 - java -jar clojure.jar
What there should be is an exe or MSI installer like every other Windows program.
Not directly the link you provided.
Yes, they require Java knowledge I guess, but then again using guest languages without caring for the host platform is a fallacy.
Now I do agree that an installer would be the right experience to provide.
1. Alpha version of "clj on Windows", which seems to be the recommended approach, and requires going to another page to get the instructions.
2. Homebrew on Linux or Windows with WSL, linked to under "Installation on Linux".
3. Build from source, under "Other ways to run Clojure", which assumes git, Java, and Maven installed, with no instructions on how to install them.
I would say it's pretty confusing from that what is the optimal, recommended way to install Clojure on Windows. It might be better to have subheadings under "Installation on Windows" like "For Java developers" (assuming Java tools already installed), "For WSL users" (Homebrew), "For Powershell users" (clj on Windows). This would consolidate the Windows installation strategies and reflect the diversity in the Windows developer population. Some are already full time Java developers, some live in WSL as much as possible, and some fully embrace Windows specific tools like Powershell.
...
2 - Download clojure-1.10.1.jar, spec.alpha-0.2.176.jar, core.specs.alpha-0.2.44.jar from mvnrepository.com
...
5 - java -cp clojure-1.10.1.jar;spec.alpha-0.2.176.jar;core.specs.alpha-0.2.44.jar clojure.main
2 - Dowload clojure.jar
as a shorthand for
2.1 - Install Maven
2.2 - Install git
2.3 - Clone https://github.com/clojure/clojure.git
2.4 - Run mvn -Plocal -Dmaven.test.skip=true package
It used to be so that they provided a zip to download.
In any case as mentioned on a sibling comment, I assume that anyone willing to use a guest language should get comfortable with the host platform.
So git, well for better or worse that is what most are using nowadays.
Maven, number one build tool on Java world, even if using another one, most likely those jars are coming from Maven Central.
Just like, regardless of my opinion on C, I keep my C knowledge up to date, because that is what I eventually might need to reach to when on UNIX like platforms.
command.com? Is it 1995?
CL is a breeze. Even installing new dependencies into a running image is a breeze, and no need to restart anything.
You don't even need to leave the REPL!
Idunno, I read the whole homepage and I don't really know where to go to download it. Is "clone and run Meson" what you meant by "one click install"?
> No matter what some people say, getting started in Clojure is a nightmare.
On my distro I just do pacman -S clojure and I have a working clojure environment, on everything else it's usually available as one package. Not much of a "nightmare" to my eyes, at least when compared to Janet, which doesn't tell you how to install it anywhere on the website.
- Easy to get started: one click install, great website and concise docs. No matter what some people say, getting started in Clojure is a nightmare.
- Lightweight and fresh. No JVM, no Node.
- Freedom and expressivity. Mutable or immutable data structures, ultimately is up to me. It might bite me down the road but for now it feels great.