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

0 votes
ago 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
ago by
selected ago 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.

ago 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
ago 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.
ago by
Do you have a minimal reproducible example?
ago 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)`.
ago 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?
ago 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.
ago 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?
ago by
You can use `(require '[howto-lein-repl.test.callme :as callme])` for that. Every key in the `ns` form has a macro alternative.
ago by
Thank you very much for your help.
...