Welcome! Please see the About page for a little more info on how this works.

0 votes
in Beginner by

Clojure beginner here.

I've created a leiningen project "adventofcode" and I've created a file "src/adventofcode/2024/day7.clj" with this namespace:

(ns adventofcode.2024.day7
  (:gen-class)
  (:require
    [clojure.math]
    [clojure.math.combinatorics]
    [clojure.pprint]))

Now when I run lein repl the prompt is adventofcode.core. How can I call a function in the file above? Or switch to the namespace adventofcode.2024? Tab completion suggests that this namespace doesn't exist. Do I manually have to load the file somehow?

I'm just starting out. If I'm making my life unnecessarily hard with this project structure I wouldn't mind a comment on that too.

1 Answer

+1 vote
by
selected by
 
Best answer

Using adventofcode.2024.day7, you have to require it as adventofcode.2024.day7, not as adventofcode.2024. Tab completion might not work properly because the middle part of the namespace is a number, but I'm not sure - in any case, don't rely on tab-completion alone.

So, suppose you have a function f in that namespace. Require it as [adventofcode.2024.day7 :as day7] or with some other alias that you prefer, and call f from adventofcode.core as (day7/f), that's it.

The only problem with that naming is if you decide to use the generated classes from Java-the-language. It doesn't support numeric package segments, even though JVM does support them.

by
Unfortunately, that didn't work: [adventofcode.2024.day7 :as day7] ->
Syntax error (ClassNotFoundException) compiling at (/tmp/form-init6149621435280713369.clj:1:8977).
adventofcode.2024.day7
by
I tried to rename 2024 to test. Both the namespace in day7.clj as well as the directory the file is in. Unfortunately yielding the same result.
by
Do you have a minimal reproducible example?
by
Add `(:require [howto-lein-repl.test.callme :as callme])` to the `ns` form in the `core` namespace, add `(callme/f)` at the end of the `-main` function, start `lein repl`, execute `(-main)`.
by
Ok, this works. "success" is printed. However, what I actually wanted to do is to call f directly at the repl. Is this not possible? Can I only call functions in another file / namespace through a proxy function in core?
by
After adding the `:require` form, have you tried restarting the REPL (or reloading the `core` namespace properly) and running `(callme/f)`? Works for me.
by
Yes, that works. Thank you. Is it possible to call f without requiring the namespace in core? Thus can I somehow require the callme namespace directly at the repl?
by
You can use `(require '[howto-lein-repl.test.callme :as callme])` for that. Every key in the `ns` form has a macro alternative.
by
Thank you very much for your help.
...