How can I include my utility functions available for import?

Hi,

I am new to Clojure. Currently trying to learn the language by reading books and trying to build a scraping tool using Clojure.

In the book ‘On Lisp’ Paul Graham advises a lisp programmer to keep some useful utility functions handy while working various projects. I was wondering how I can achieve this.

Thanks.

Excellent question.

Step 1: Create a utility library.
Step 2: Require it in your app.

Nothing sets a utility library apart from any other type of library. They’re all libraries.
Here is a list of utility libraries authored by experienced Clojurians:

Personally, I tend to separate them according to their dependencies. For example, utility functions that don’t require any dependency, that are pure Clojure, go into a general-purpose utility library with no dependencies. Functions that are more specific to a line of applications go into a separate library. For example, I have a small utility library devoted to ring applications, with a dependency on ring.
Here is a quick overview of how I organize things, but remember that there is a lot of leeway and utlimately it’s up to you.

Hi Daniel,

Thanks for the answer. I will check these out.

If I were to develop my own utility library how would I require it to my other projects? Do I have to upload it to clojars?

Can I do it without clojars using my local repo? Is there any way to require it without manually copying it to each and every project?

Have a look here: https://clojure.org/guides/deps_and_cli#_using_local_libraries

2 Likes

If you’re using Clojure CLI / deps.edn then this is very straightforward. You can add it as an alias to your projects.deps.edn, or even as a global alias in ~/.clojure/deps.edn. You can use :local/root to simply point at the directory with your project, or reference it by git coordinates. No need to push to Clojars.

{:aliases
 {:my-util
  {:extra-deps {foo/my-util {:local/root "/home/foo/my-util"}}}}}
clj -A:my-util

If you’re on Leiningen then it’s not as straightforward.

Yes I am using Leiningen and was wondering how to achieve this with it.

I have found somewhere that
‘lein install’ and ‘checkouts’ together will facilitate development using local libraries.

Have to check it out.

Checkouts are more intended for when you’re developing interdependent libraries at the same time. I never found them particularly handy to work with. Just doing a lein install of your utility project should work though, then you just include it as any other dependency (probably under a profile).

Things you might want to consider

1 Like

The simplest thing is to put your favorite functions in user.clj, which needs to be on the classpath so Clojure can find it. If you use Leiningen, put it at dev/user.clj relative to the directory with your project.clj.

Adding to this, it turns out Clojure has a little function called load-file here https://clojuredocs.org/clojure.core/load-file

So you can actually separate your user file into mutliple files and load-file them together.

That said, this is more of a dev/messing around approach. If you plan to bundle or release programs which depend on your utility lib, I think having a separate repo with your personal utility lib in it, that you lein install might be best.

I tried Jitpack. It worked like a charm.

The only thing is that, how would I make new changes in utility library available to other projects?
I will have to first publish it to github. Pull it using ‘lein deps’.
Is there any other better way?