We already discussed the reasons you should try Clojure and also configured our development tools and installed Clojure.
Hello, Clojure!
As every developer knows since the dawn of computing the first program that we have to write to be successful in any programming language we're learning is print 'Hello World' on console.
For this we gonna start a new project:
$ lein new app hello-world
And open it on our IDE:
$ code hello-world
The project will have the following structure:
.
├── CHANGELOG.md
├── doc
│ └── intro.md
├── LICENSE
├── project.clj
├── README.md
├── resources
├── src
│ └── hello_world
├── target
│ └── default+test
└── test
└── hello_world
Where:
- CHANGELOG: That's a model for CHANGELOG in the project.
- doc: Is a folder dedicated to the documentation of the project, it's initialized with an intro.md for writing the first steps.
- LICENSE: Is a file containing the Eclipse Public License - v 2.0 the same license used in Clojure and default in most Open Source projects that use the language.
- project.clj: That we're gonna declare our dependencies and configuration for the project.
- README: That's a entry document and front page in remote repository for the project.
- resources: Where we can put the files we want to zip in the final jar when we compile the project.
- src: That's where our code will really be.
- target: Where will be the compiled jar's.
- test: That's where the tests will be place.
Now we can run our code using leiningen:
$ lein run
And if we want to build it as a jar (if you're not from Java and not familiar with the concept we'll explain next) for distribute we can use:
$ lein uberjar
If we want to run the generated jar file:
$ java -jar target/uberjar/hello-world-0.1.0-SNAPSHOT-standalone.jar
And we should receive the same message as before.
What's a jar?
The JAR (Java Archive) it's a compressed format of a compiled project for Java Virtual Machine (JVM). When the project is compiled to a JAR File all the JVM bytecode generated will be compressed in this file together with metadata and additional resources needed to run the code.
This is analog to what most people think about an auto executable .exe or .dll on Windows. The JAR file is the format that is used to distribute programs written to be executed in JVM or libraries to be used in languages that run on it.
How Clojure works
Clojure is 100% written in Java (and Clojure itself). In fact, the whole language runs from a JAR file that can be built from Clojure source code. But the process of compilation and execution of the code it's little different from Java.
When we run a Java program the source code is send to the compiler who will parse, tokenize, structure... the code and then compile it to a .class file that contains the compiled bytecode and that file when run will be sent to JVM who will translate it to the optimized machine code for where it's running.
"Traditional Evaluation (Java)" by Rich Hickey is copyrighted material of clojure.org
By other way, when a Clojure program is evaluated first it passes by a special step that's the reader a program written for receive the source parse it and return all code structured in some data structure, only after it the code gets in compiler. In Clojure the compile only receive data structures and never text, separating the reader from compiling makes it easier to process macros and substitutions. As most times the Clojure program is running in live mode (like REPL) the bytecode is immediately sent to JVM that caches and executes it.
"Clojure Evaluation" by Rich Hickey is copyrighted material of clojure.org
How our hello-world JAR works
If we use an online Java decompiler tool to analyze the compressed bytecode in the JAR we created when compile our project we'll get that the JAR has a folder structure like that:
hello-world-0.1.0-SNAPSHOT-standalone.jar
├── clojure
└── hello-world
Where the clojure folder contains the compiled bytecode of the reader and compiler altogether with the language source compiled.
While the hello-world folder have the original Clojure file we written and also helper classes to run main and these same files compiled in Java, but the compiled result are internal symbols of the Clojure language and not a simple and readable Java program.
So every time we compile our Clojure apps for a JAR to be run in JVM the JAR itself contains also the whole code needed to run Clojure including the the language functions, reader and compiler that can be executed if needed.
See ya!
Our Clojure journey is still far from the end, now we can understand how the process compilation and execution of Clojure works we can understand how it's different from a Java project and how JVM can execute the JAR since it was not thought to run Clojure code. Hope to see you in part IV.
Top comments (5)
Thanks! I've been curious about clojure & cjs for a couple of years now and did a side-project myself and absoultely loved it.
I think the dream of it being a business-viable language is still far, even though I have seen a few companies use it for their backend.
Where I work we're using to build all our applications from frontend with ClojureScript and React (reagent) to the backend (compojure) and I absolutely love it too, I would even say that is probably one of most pragmatic functional programming language to choose for build products (maybe behind Elixir).
The main problem in being a more viable option is the fact that Clojure is not popular as Java or Ruby, is hard to find developers that are willing to learn a language that is so different and not so popular, so when starting a new thing in Clojure is very hard to scale the team for scale the product.
One of my main goals in dev.to is to make more people have interest in experiment Clojure, I think even most people don't use it as daily basis there's a lot of benefit in experiment different ideas in programming and hope that more people goes further than the initial antipathy on parenthesis and try it.
Awesome! Thanks for your reply, I think clojure is beautiful and has contributed a lot to my current coding skills (I'm a web developer mainly using node and react) and so even if people will not use it in their day to day a side project can still bring a lot of value in thinking about problems from a different angle than they're used to.
Another tool for the arsenal!
The diagrams were copied without attribution from clojure.org/guides/learn/syntax. Could you at least add attribution? Images on the clojure.org web site are copyright Rich Hickey.
Sure, I thought whole clojure.org was on EPL 2.0, but as the footer says only the website code is. As the content is copyrighted I will add the attribution.