'Unable to resolve symbol: Example in this context clojure 1.10

I am a beginner with Clojure and I received this error while trying to write code in Clojure:

; Syntax error compiling at (src/com/playground/core.clj:17:1).
; Unable to resolve symbol: Example in this context

Here is my code

(ns com.playground.core
  (:gen-class))

;; This program displays Hello World
(defn Example []
   ;; The below code declares a integer variable
  (def x 1)

   ;; The below code declares a float variable
  (def y 1.25)

   ;; The below code declares a string variable
  (def str1 "Hello")
  (println x)
  (println y)
  (println str1))
(Example)

I pulled this directly from tutorialspoint and tried to find other people who had the same error but could not find anybody else.



Solution 1:[1]

I guess you didn't evaluate that function. Open REPL for this project, evaluate definition for Example and then evaluate (Example).

As you can already see in comments, this code is very bad and you shouldn't learn from that tutorial. But from a beginner point of view, it may be helpful to see what exactly is wrong:

  • naming conventions: names of functions should be dash-separated-lowercase-words, so no Example, but example.
  • already mentioned def inside defn. Def creates a global variable, don't use it inside any other definitions. If you need to create some variables inside function, use let.
  • integer variable and float variable. Clojure uses long and double and created variables will have exactly these types- you can check it yourself with function type.
  • repeated println (it'll work, but you can also use clojure.string/join with vector and only one println to get the same result)

Improved code:

(defn example []
  (let [x 1
        y 1.25
        str1 "Hello"]
    (println (clojure.string/join
               "\n"
               [x (type x) y (type y) str1]))))

(example)

=>

1
class java.lang.Long
1.25
class java.lang.Double
Hello

Solution 2:[2]

You can't declare a definition inside a function.

You need to declare these symbols (variable in other langs) outside. Something like that.

(ns com.play

ground.core
  (:gen-class))

(def x 1)
(def y 1.25)
(def str1 "Hello")

(defn Example []
  (println x)
  (println y)
  (println str1))

(Example)

So, when you do it, you're declaring x y and str1 as global and it's not a good practice.

To keep the context of these symbols only inside the function, you need to use the let approach.

(ns com.playground.core
  (:gen-class))

(defn Example []
  (let [x 1
        y 1.25
        str1 "Hello"]
    (println x)
    (println y)
    (println str1)))

(Example)

An extra tip is to avoid using camel-case as a way of declaration naming. Consider to use kebab-case :)

(ns com.playground.core
  (:gen-class))

(defn example-function []
  (let [x 1
        y 1.25
        str1 "Hello"]
    (println x)
    (println y)
    (println str1)))

(example-function)

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 Martin Půda
Solution 2 Marco Paulo Ollivier