1
votes

I have recently started learning Clojure and was wondering if there is a standard way of executing a simple .clj file.

I have installed Leiningen and created my first project called my-stuff using lein new app my-stuff.

To run my-stuff.core, I started with lein run:

user>lein run
Hello, World!

Next, I tried lein repl, followed by:

user=> (require 'my-stuff.core)
nil
user=> (my-stuff.core/-main)
Hello, World!
nil 

I also used lein repl to do some basic evaluations:

user=> (defn sum [x y] (+ x y))
#'user/sum
user=> (sum 1 2)
3

I tried to define this function within my-stuff.core:

(ns my-stuff.core ((:gen-class))

(defn sum [x y] (+ x y))

(defn -main
  [& args]
  (sum [1 2]))

I get the following error: clojure.lang.ArityException: Wrong number of args (1) passed to: my-stuff.core/sum

I apologize if this is a stupid question, but how would I correctly define this function within core.clj? Does it make more sense to define it in a separate file and reference it from the core.clj file?

Thank you.

Update

If the function was defined in another .clj Clojure file, what is the correct way to declare the namespace to be able to run the code from the project my-stuff?

2
I've updated my answer to address your question on calling functions from another namespace.Denis Fuenzalida

2 Answers

1
votes

I would bet there are ways to use Leiningen to create a standalone .clj file, but I don't know what it is.

I do know a way to create a standalone file that is a combination of both a bash script and a clj file that is executable, and runs as long as the system has Java and the clj CLI tools installed - https://clojure.org/guides/getting_started

It can also let you specify dependencies within the same file as the Clojure source code, even if those dependencies are not included as part of Clojure itself.

Here is an example: https://github.com/jafingerhut/dotfiles/blob/master/bin/clj-check-added-metadata

0
votes

There are no stupid questions! :-)

Let's check the function you defined:

(defn sum [x y] (+ x y))

This is a function that takes two arguments, x and y. In Clojure, function parameters are surrounded with square brackets because it helps readability.

Let's check how are you calling the function:

  (sum [1 2])

Here you are calling the function sum with just one argument, the vector [1 2] which is like a 2 item Array. The error is trying to tell you: you are calling a function that takes two arguments, but you provided only one. In this case, you'll fix the error with:

  (sum 1 2)

Edit: If you create a new namespace within your project, like this:

src
└── myapp
    ├── core.clj
    └── utils.clj

You can call functions from the other namespace by using a :require instruction in the ns declaration at the top.

Let's say that I have this function in utils.clj:

(ns myapp.utils)

(defn sum [a b]
  (+ a b))

Then you can call sum from the core namespace like this:

(ns myapp.core
  (:require [myapp.utils :refer [sum]]))

(defn -main
  [& args]
  (sum 1 2)) ;; call `sum` defined in the `myapp.utils` namespace