'clojure returning hello world and nothing in the output
I just started learning Clojure and I have my own Clojure script but it's not returning the output that I am hoping for (Hello World
). Here is my code:
(ns com.playground.core
(:gen-class))
(defn -main
[]
((defn CHEESE
[]
(str "Hello World"))
(CHEESE)))
This is the output that I get in the REPL:
clj꞉com.playground.core꞉>
#'com.playground.core/-main
I want to see Hello World
in the output.
Solution 1:[1]
You have a double parentheses there. Try this:
(defn -main
[]
(defn CHEESE
[]
(str "Hello World"))
(CHEESE))
Of course your MUST call -main
, otherwise you'll see nothing:
(defn -main
[]
(defn CHEESE
[]
(str "Hello World"))
(CHEESE))
=> #'com.playground.core/-main
(-main)
=> "Hello World"
I see your define a function inside another function. You should use let
or letfn
for this purpose.
Solution 2:[2]
Starting a REPL for the project does not run -main
. Running your program produces the following:
Execution error (ArityException) at com.playground.core/-main (core.clj:6).
Wrong number of args (1) passed to: com.playground.core/-main/CHEESE--177
What is happening?
- The
defn
form creates and registers a function under the nameCHEESE
in thecom.playground.core
namespace. - The
defn
form returns the created var, which evaluates to the function. - The containing
((defn ...) (CHEESE))
form applies theCHEESE
function to(CHEESE)
, the result of evaluating theCHEESE
function without arguments, - ... which is the string
"Hello World"
.
It doesn't matter what the argument is, because CHEESE
has no arity 1 invocation: you can't apply it to any argument.
You can get the same (bad) effect more simply by pulling the defn
for CHEESE
out of -main
. While we're at it, let's drop the str
, which has no effect:
(defn CHEESE []
"Hello World")
(defn -main []
(CHEESE (CHEESE)))
Execution error (ArityException) at com.playground.core/-main (core.clj:8).
Wrong number of args (1) passed to: com.playground.core/CHEESE
To put it right, we simply drop the (CHEESE)
argument:
(defn -main []
(CHEESE))
producing ...
Process finished with exit code 0
No returned value, but at least it ran. But if we evaluate (-main)
in a REPL, ...
(-main)
=> "Hello World"
There.
Solution 3:[3]
Actually, It's not exactly wrong. This return is the "return of declaration".
For example, you defined a -main
in the com.playground.core
namespace.
The return is the symbol of this declaration #'com.playground.core/-main
To print the Hello world
message you need to call the function CHEESE
after the declaration.
So... about double parenthesis, it's not good, but not impact hehe. Another point is the function name, it's not good too. Consider using kebab-case.
You also consider keeping the function declaration more explicitly. Something like that;
(ns com.playground.core
(:gen-class))
(defn CHEESE [] (str "Hello World"))
(defn -main []
(CHEESE))
But also did it you're not printing the Hello world. Your only declaring a function (CHEESE) that returns a String type.
To print, you need to call a print function.
(ns com.playground.core
(:gen-class))
(defn hello [] (str "Hello World"))
(defn -main []
(print (hello)))
I did the evolution of declarations to explain better
So, you can improve the code using the let
alternative and the threading macros
Consider use the https://kimh.github.io/clojure-by-example/ and https://tryclojure.org/ to understand these options better :)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Thumbnail |
Solution 3 |