This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # announcements (8)
- # aws (8)
- # babashka (21)
- # beginners (125)
- # calva (12)
- # cider (10)
- # circleci (29)
- # clara (6)
- # clj-kondo (34)
- # cljdoc (3)
- # cljfx (65)
- # cljs-dev (18)
- # clojure (38)
- # clojure-australia (4)
- # clojure-berlin (5)
- # clojure-czech (2)
- # clojure-dev (15)
- # clojure-europe (22)
- # clojure-nl (3)
- # clojure-uk (31)
- # clojuredesign-podcast (7)
- # clojurescript (87)
- # code-reviews (1)
- # conjure (3)
- # cursive (2)
- # data-science (1)
- # datalog (1)
- # datomic (36)
- # emacs (12)
- # events (1)
- # fulcro (3)
- # graalvm (68)
- # instaparse (2)
- # jackdaw (2)
- # jobs (2)
- # leiningen (8)
- # luminus (2)
- # nrepl (31)
- # pedestal (44)
- # releases (1)
- # remote-jobs (6)
- # shadow-cljs (4)
- # spacemacs (4)
- # sql (13)
- # tools-deps (52)
- # uncomplicate (4)
- # xtdb (40)
- # yada (11)
Apologies if this has been asked & answered before (I did search, but couldn’t find anything relevant), but in recent versions (specifically v184.108.40.2067) the following occurs:
I understand that this can be “fixed” with
$ clj -e '(println "Hello, world")' WARNING: When invoking clojure.main, use -M Hello, world $
clj -M -e '(println "Hello, world")', but is that intentional?
It seems to me that evaluation of a something provided on the command line should be considered at the same level of importance as running a REPL or invoking a main function, FWIW.
expression eval is done by invoking clojure.main. -M is how you (now) invoke clojure.main.
clj was originally built solely around clojure.main. we are in the process of making it bigger than that and this is part of segmenting off that part of the functionality.
I understand the improvements that brings to the implementation, I’m more making a comment about the (negative, imho) UX that creates, especially for newcomers.
i.e. why should a newcomer have to know that in order to evaluate an expression on the command line, they are actually invoking
clojure.main? That seems like incidental complexity to me…
I don't think evaluating an expression on the command line is actually a thing most people do compared to running a repl
Sure, but that doesn’t mean that CLI evaluation isn’t worth supporting in a clear and concise (and backwards compatible, though I know we’re in a period of time where that is being consciously and deliberately broken) manner.
My complaint is why does anyone need to know they’re invoking
clojure.main in order to evaluate something on the command line. Shouldn’t this be a “first class” operation, regardless of how it’s implemented under the hood?
After all that’s how most other languages handle this - Principle of Least Surprise etc. etc.
$ python -c 'print("Hello, world")' Hello, world $ perl -e 'print "Hello, world"' Hello, world
And to be clear, I don’t do this all that often, but it is a handy feature (e.g. in shell scripts).
the most common use of it that I'm aware of is to trigger deps loading without doing something else, which you can now do with -P
Sure, but -P won’t evaluate an arbitrary expression. I like to
(println a specific message to make build log searching easier.
> I don't think evaluating an expression on the command line is actually a thing most people do compared to running a repl I do this all the time on the command line
A lot of things I do in my open source projects is testing out command line applications which are usually one shot. Yes, I also use a REPL, but actually more often I execute one time invocations
ok, I wrote this horrible script now:
#!/usr/bin/env bash history | bb -iO '(->> *input* (map #(as-> % x (str/trim x) (str/split x #"\s+") (rest x) (take 2 x))) (keep #(when (and (str/starts-with? (first %) "cl") (second %) (> (count (second %)) 1)) (subs (second %) 0 2))) frequencies (sort-by second >) (take 10))'
which indicates I use
["-A" 326] ["-S" 208] ["-e" 172] ["--" 79] ["-M" 76] ["/t" 30] ["-J" 22] ["-m" 18] ["-X" 12] ["-R" 8]
-eway more often on the command line
because instead of
-m there's usually an alias for it. But with
-e there isn't. So when invoking main directly,
-e is my primary use case.
clj /tmp/foo.clj is also one of my primary use cases, this is where
["/t" 30] probably comes from
I just checked my history, my dot-clojure file, and my deps.edn at work and I almost never use
-e without also using
-m it seems. Just as a contrary data point to the above.
For my own brief experiences, I only every used
-e once as a saw an example in the Clojure CLI docs. I am not aware of any use cases where I would want to evaluate clojure on the command line, especially if I can run the repl just as quickly. If I was going to script something with Clojure, then I'd try using Babashka, it looks great. I am fascinated as to what the scenarios could be for using the
-e . If anyone has a link to examples, please let me know.
The only thing I find a little strange is when running an application from the command line, eg.
clojure -M -m namespace.main , from a usability point of view the
-M looks a little redundant.. After thinking about this for a few days, I realize I don't actually run the application that way. I'll either run in the REPL or create a jar/uberjar and run it that way. I though about using an alias called
:project/run that ran the unpackaged project, which I could include in a project template (eg. for clj-new), but not sure how valuable that would be.
I find the
-X flag more appealing (and more Clojurey) approach, as I've been writing command line
-main functions to take hash-map as an argument for a while now. It seems an idiomatic approach to have all entry point functions in a project take a hash-map where possible.
in fish i have these handy shell functions
function clj-doc --description 'Get the docstring of a function' clj -e "(require 'clojure.repl)(clojure.repl/doc $argv)" end
clj-docand the other
clj-source. easy to update to -M -e though
Well, sometimes I use
-e to require some namespace or a
compile invocation for example
No big deal, can be easily hidden in a script, Makefile or whatever, I just don't find
-M -m aesthetically pleasing, which may not be an important argument. Whatever :)
For what it is worth, I am updating rewrite-cljc to use the new cli syntax, and updating from
-m is not causing me any terrible discomfort.
Out of curiosity, what is the purpose of the sourceDirectory tag addition in the pom target? I don't see where it is used by other mvn tasks and the clojure-maven-plugin puts the same data into its own config (which I realize is unrelated to tools.deps, but it's the only mvn plugin I can think of that is directly related to building Clojure). For example:
<build> <plugins> <plugin> <groupId>com.theoryinpractise</groupId> <artifactId>clojure-maven-plugin</artifactId> <version>1.8.4</version> <extensions>true</extensions> <configuration> <sourceDirectories> <sourceDirectory>src</sourceDirectory> </sourceDirectories> </configuration> </plugin> </plugins> <!-- How does maven use this? --> <sourceDirectory>src</sourceDirectory> </build>
Pretty sure Maven uses that to know where to go to build Java source. IOW it’s probably not relevant for a deployed artifact.