I wrote a small "hello world" program on Linux to get started with the language.
Now I'd like to run it and see what it outputs.
How can I run this code?
What command should I run?
FWIW, I'm interpreting the question here as specifically asking how to run a single file, like a script, versus as a part of a compiled project.
Obviously though, there's a relationship between how and why you would want to run a single file, and how you would want to build a full project, so I weigh that in some as well.
Best choice: the clj tooling
Docs are here:
https://clojure.org/guides/deps_and_cli
This is an official part of the Clojure project, which by itself is a pretty good reason to go this route. However, it has a couple of advantages over the other solutions here:
cleaner dependency resolution model, via deps.edn
also resolve dependencies via git references!
~/.clojure/deps.edn seems to do a better job of cleanly providing reusable functionality via its aliass than ~/.lein/profiles.clj
if you need to load your code in a repl, clj won't choke on a borked src file, like lein repl does
Simply
clj your-code-file.clj
Or if you have dependencies
clj -Sdeps '{:deps {clj-time {:mvn/version "0.14.2"}}}' -M your-code-file.clj
Works well as a shebang in scripts as well!
#!clj -Sdeps '{:deps {clj-time {:mvn/version "0.14.2"}}} -M
(ns my-crazy-script!
(:require ...))
...
I recommend installing with homebrew, which now works on both Mac and Linux. If you're on Windows I'd recommend using the WSL+brew.
The one advantage I see of lein (see below) tooling over clj generally is that lein handles a little more of the process of building and packaging your code base, when you get to that point.
However, there are other ways of handing that (see pack, uberdeps or cambada), and the advantages of clj mentioned above outweigh IMHO.
Babashka
If you are trying to run a single file, as apposed to an entire project, there's a good chance your in "scripting territory".
Unfortunately, the JVM takes a while to boot up, as does Clojure itself.
Via the magic of GraalVM and the SCI, Babashka is able to support most of the Clojure language with blazing fast startup times.
It also comes with quite a few "batteries included" for typical scripting tasks, making it a perfect complement to clj when you want fast-executing, short lived processes.
Once you install it you can simply bb you-code-file.clj, or use #!bb in your shebang.
See the docs for more usage instructions:
https://babashka.org/
With lein & lein-exec
If you prefer lein tooling, or have a ~/.lein/profiles.clj file handy already and don't want to invest in learning clj/deps.edn, you can consider looking at lein-exec.
If you already have a project.clj set up with dependencies, you can of course run lein run -m <yer-namespace>[/<yer-main-fn>].
As mentioned above, the one advantage of lein over clj is that it is a complete build tool, and can make jars/uberjars for you with lein jar or lein uberjar, do deploys and such.
For ClojureScript
I'd recommend http://planck-repl.org/. It now supports (bootstrapped) quick launching of ClojureScript scripts without having to fire up the JVM or Clojure.
Like babashka, this makes it great for scripting.
However, I find babashka both more powerful and more natural for scripting, so I'd start there unless you have a particular reason for wanting to use Cljs (more familiarity with JS/node, need of certain cljs libraries, etc).
For more substantial projects (beyond scripting), you may want to look at Shadlow-CLJS, for its ease of incorporating vanilla JS projects.
And FWIW, Shadow nicely integrates with both deps and lein, and has it's own built in hode code reloading, like figwheel.
With java
You can, of course, as has been suggested in another answer, use
java -cp clojure.jar clojure.main file.clj
But you don't see that in the wild too often, because it's a pain to have to find the path to your clojure.jar and manually composing classpaths for dependencies sucks.
But, you know, to each their own.
You can run script with following command:
java -cp clojure.jar clojure.main file.clj
but it's better to use leiningen, especially when you'll start to add dependencies to your project. lein provides number of commands to run your code (with all necessary dependencies), pack code into archive with lein jar, or create complete, independent archives with lein uberjar that you can run with:
java -jar your_app.jar
command
P.S. You can read how to use lein in following article - it describes base tasks & configurations
Once you've installed lein and the lein-exec plugin, running the .clj file you've created is as simple as
lein exec hello.clj
In case you're passing command line arguments like
lein exec hello.clj arg1 arg2 arg3
you can access them in the 'foo' function in your hello.clj like
(foo *command-line-args*)
For a single clj file you can add,
#!/usr/bin/env java -cp /path/to/clojure-1.2.0.jar clojure.main
to the top of the file and make it executable or you can use leiningen which is a clojure build tool it will create a single jar that has everything packed, then you can just do,
java -jar cool_app.jar
if you just want to execute a single file, how about piping it to the repl like:
cat $PATH_TO_FILE | lein repl
For running a single file through command line use the following commands:
clj -m (NameSpace name)
ex: clj -m Sample
Or if you want to run through repl:
(load-file filelocation)
ex:
(load-file "Sample.clj")
Drip is probably now the best answer to this question (see Drip's wiki for details on using Drip with Clojure).
Cake was incorporated into Leiningen and has since been superseded as the most stable implementation of Clojure automation by Drip - see this answer to a similar question here.
I really like writing small .clj scripts, but sometimes those scripts have dependencies that need to be installed. Since none of the other answers cover that case, I provide an example here. This example is a single-file script that requires the permutations function from the math.combinatorics library.
Cumbersome Mac-only solution
#!/usr/bin/env clj -Sdeps {:deps,{org.clojure/math.combinatorics,{:mvn/version,"0.1.6"}}} -M
; Explanation for the shebang:
; -Sdeps Specify deps in EDN format
; , Clojure interprets commas as whitespace. Without the commas, the EDN is
; broken up into multiple arguments and the command fails. On the
; command line you can use single quotes around the EDN string, but
; Mac shebangs don't support quoting around arguments.
; -M Run the program as a "main" function
(ns foo
(:use [clojure.math.combinatorics :only (permutations)]))
(dorun (map #(println (apply str %)) (permutations "abcde")))
Linux-only solution
#!/usr/bin/env -S clj -Sdeps '{:deps {org.clojure/math.combinatorics {:mvn/version "0.1.6"}}}' -M
; Explanation for the shebang:
; env -S Allow multiple arguments to be passed to the following command
; -Sdeps Specify deps in EDN format
; -M Run the program as a "main" function
(ns foo
(:use [clojure.math.combinatorics :only (permutations)]))
(dorun (map #(println (apply str %)) (permutations "abcde")))
Portable solution (Linux and Mac)
See the planck docs for an explanation. It's very clever!
#!/usr/bin/env bash
"exec" "clj" "-Sdeps" "{:deps {org.clojure/math.combinatorics {:mvn/version \"0.1.6\"}}}" "-M" "$0" "$#"
(ns foo
(:use [clojure.math.combinatorics :only (permutations)]))
(dorun (map #(println (apply str %)) (permutations "abcde")))
I had similar issue in running a specific clojure script file out of a clojure project using lein. Then I found a shortcut, thought of sharing the same.
In project.clj file, you can toggle the clojure script file name ( which has main method of course). Following is the statement for this.
:main ^:skip-aot conv.newconv ; here conv is namespace and newconv is the file name .
Note: I am new to clojure and I am not sure why '^:skip-aot` is used, I have not checked that.
Note: This methodology, does not require any plugin to be installed nor any jar file need to be generated. This only requires to change a name in project file.
Assumption: Your clojure project has multiple clojure files, each having main method. I am assuming this is created for testing purpose only. My solution will work for this specific scenario.
Install clojure from the below official link according to your OS
https://clojure.org/guides/install_clojure
Now we can easily execute files by below command tested on mac only. Other complicated steps aren't required now I think.
write a sample print statement in your file hello-world.clj
(println "Hello world")
Run your program with the below command in terminal
clj -M hello-world.clj
It will output
Hello world
Tested on Clojure Version: 1.11.1.1200
Related
I have a working Clojure-1.4.0 / emacs24 / leiningen-2.0 tool chain working on Mac OSX 10.8. I got it going very quickly by following the instructions at the following URLs:
http://clojure.org/getting_started
https://github.com/technomancy/leiningen
http://clojure-doc.org/articles/tutorials/emacs.html
One way I check that it works is I go to a project directory and type
lein test
and it runs all the unit tests in my project directory. I can also do C-c , in clojure-mode in emacs, and it does the same thing. Great! Now the question: all this runs the clojure installation I have in ~/clojure-1.4.0, which I see by typing
lein repl
in a project directory. I have a new installation of clojure in ~/clojure-1.5.0 now, and I would like to make leiningen and emacs point to that new version. However, during the setup of leiningen and the emacs mode, I never manually told them where to find the clojure version. They found that magically and opaquely -- in fact, the whole process was very magic, and that was great at that time. I suppose I could tear everything down and build it up again from scratch, but that seems brute-forcedly inefficient. I could also hack-replace the files in the 1.4 directory with the files from the 1.5 directory. That might work one time, but it's so obviously wrong I really don't want to think about it. I need to do this the right way so that when the next version updates come along, I can keep the toolchain going as smoothly as possible.
I am just starting with all this, so I am far from mastery of any of these tools and I'll be grateful for noob-level advice on keeping it all going.
Just change clojure version in ./project.clj in your project directory:
:dependencies [... [org.clojure/clojure "1.5.0"] ...]
test:
$ lein repl
user=> *clojure-version*
{:major 1, :minor 5, :incremental 0, :qualifier nil}
Edit:
They found that magically and opaquely
Default clojure version is built into lein's project.clj template which renders to your <name>/project.clj file when you do lein new <name>.
(David James both wrote the question and an answer. I'll edit it to conform to Stackoverflow standards.)
Using SBCL you can compile Lisp code to machine code.
Like Java, .net, C++ and even C you will need the runtime. So there are two ways to compile Common Lisp code.
First is to make huge binaries which is explained in SBCL documentation. No SBCL needed on target machine.
The other way is a more flexible one, which is to create machine code in a fasl (FASt Load) format. The SBCL runtime is needed on the target machine.
How does the second way work under a Unix-like operating system?
(Answer by David James:)
We are going to make two commands in our system: one for batch compiling Lisp code and the other for easily running Lisp code:
Using your favorite editor, open a file called sbcl.compile. The content should be:
#!/bin/bash
sbcl --noinform --eval "(compile-file \"$1\")" --eval "(quit)" > /dev/null
Now to compile Lisp files use:
# sbcl.compile hello.lisp
This will create a hello.fasl file.
Now to easily run these files, we create a new command. Using your favorite editor open a file called sbcl.run. The content should be:
#!/bin/bash
sbcl --noinform --load "$1" --quit --end-toplevel-options "$#"
Now you may invoke sbcl.run hello.fasl to run the native code.
# sbcl.run hello.fasl
Details are described in the SBCL manual: Starting SBCL
Another option is to add to the runtime all packages/functions/frameworks that you commonly use, and then save this state as a new core file, and use this as your default core while continuing development. I usually find fasls more trouble than they are worth, especially since lisp has the ability to save state in a VM-style core file. I just incrementally update the core as development moves along. And rebuild/update the core using GNU Make.
I've been using Scala with SBT quite a bit lately. The REPL loop of has a handy feature: ~ COMMAND, meaning perform COMMAND for every source file change in the project. For instance:
~ test
and
~ compile
are terrifically useful for rapid development. I wonder, does anyone know of something similar for Haskell, a cabal shell, maybe?
You can get something like this very easily using inotifywait.
Just fire up a terminal in your project directory and run something like this:
$ while inotifywait -qq -r -e modify .; do cabal build && ./dist/build/tests/tests; done
This also works for any other language; just insert the build commands of your choice.
You can script ghci to both define your own commands, and augment existing commands. To do this:
define a ~/.ghci file
write a macro using :def to replace e.g. :reload
More info on GHCi :def commands is here.
The ghcid project provides something limited to ~ :reload. It provides a few extra features (format to a fixed number of lines, persist warnings from previously loaded files), but not the generality of running any command.
The library suggests I use this in shell scripts to byte compile files:
emacs -batch -f batch-byte-compile files...
When I run this though, many don't compile, complaining because it hasn't loaded one library or another, I guess because it's starting up a new emacs instance without loading these libraries linked in my .emacs.
I keep Emacs running (24.0.50.1, cocoa emacs under Mac OS X, built from the git repo HEAD), with all these libraries loaded (or at least linked), so is it possible to batch compile files and have them find these libraries from this instance of Emacs?
Or is there an easier way to do this?
You probably need a bunch of eval-when-compiles:
eval-when-compile is a Lisp macro in
`byte-run.el'.
(eval-when-compile &rest BODY)
Like progn, but evaluates the body
at compile time if you're compiling.
Thus, the result of the body appears
to the compiler as a quoted constant.
In interpreted code, this is entirely
equivalent to progn.
Used as a scripting language, does Scala have some sort of include directive, or is there a way to launch a script from an other script ?
The scala command has the :load filename command to load a Scala file interactively. Alternatively the scala command's -i filename argument can be used to preload the file.
As of beginning of 2013, there seems to be no built-in support for multiple-file scripts.
There's one guy that implemented #include support for non-interactive scala scripts, by assembling and compiling the files in a prior stage (have not tried it yet).
Here is the blog post about it:
http://www.crosson.org/2012/01/simplifying-scala-scripts-adding.html
And the git repository:
https://github.com/dacr/bootstrap
I hope this, or something along the lines, get official some day, since the -i filename scala switch seems to apply only for the interactive console.
Until then a proper scripting language, like Ruby, might still remain the best option.
Ammonite is an option. It implements scala (plus extensions) including import in scripts.