Fork me on GitHub
#beginners
<
2020-12-10
>
mzuppichin12:12:57

Hello everybody, Clojure noob here. I have been kicked off 4Clojure Android app and can't login to my user anymore, however credentials are correct and he browser access goes smooth as usual. Has anyone experienced the same behaviour? Thanks sincerely in advance!

roelof13:12:48

oke, and another problem

(defn isPrime? [n known]
  (loop [cnt (dec (count known)) acc []]
    (if (< cnt 0) (not (any? acc))
        (recur (dec cnt) (concat acc [(zero? (mod n (nth known cnt)))])))))


(defn my_primes
  "my version to print out primes to a certain number"
   [limit]
   (map #(isPrime? % []) (range 2 .. limit ))
  )

roelof13:12:08

error :

; Syntax error compiling at (chapter4.clj:32:26).
; Can't take value of a macro: #'clojure.core/..

manutter5113:12:17

You don't need the .. in your range function, and in fact .. means something else in Clojure

manutter5113:12:12

Just do (range 2 limit)

roelof13:12:59

and there is another error. I was hoping on seeing all the prime-numbers but I see now a collection of false 😢

ryan echternacht13:12:42

you want filter not map

manutter5113:12:48

I would say test your isPrime? function first and make sure it returns true when you give it a prime number and false (or nil) when you give it a non-prime number.

roelof13:12:16

I tried that one also but then I see a empty collection. So I assume my isPrime is wrong.

roelof13:12:27

yep, that one is not good. It gives false on (isPrime 3 [])

roelof13:12:49

so back to the drawing board how I can test if a number is a prime

roelof13:12:26

what do you think of my solutions . I did only study the 4 first chapters of the Clojure from the ground up site

manutter5113:12:47

The code looks good overall. A couple style points: you are using partial correctly, but there was a discussion recently about using (partial foo) versus using #(foo %) and a lot of folks favor using #(foo %) in most cases because it’s more versatile and also slightly more efficient. Also it’s idiomatic to use shorter names like coll and pred instead of spelling out collection and predicate (though I favor using longer, more explicit names personally, except for really common terms like coll and pred).

roelof13:12:33

so If I understand you well I could change this (partial divisible? n) to #(divisible? n) ?

manutter5113:12:56

You need to add the % at the end

manutter5113:12:23

but yeah, that’s what I was referring to

roelof13:12:49

oke, so #(divisible? n %) ?

manutter5113:12:42

Oh, and it’s also conventional to use dashes in names instead of underscore.

manutter5113:12:16

so count-occurences instead of count_occurences, and my-filter and my-primes

manutter5113:12:49

Clojure folks are too lazy to hold down the shift key 😄

roelof13:12:55

thanks, changed also

roelof13:12:37

I know there are also languages who use countOccurences . I do not like that

roelof13:12:25

but clojure folks love parentheses 😛

manutter5114:12:02

It’s actually the same number of parens in a lot of cases, it’s just that the first paren comes to the left of the function name instead of to the right.

manutter5114:12:32

Just like HTML does with < and >.

roelof14:12:46

now take a break and tomorrow macros seems to be a difficult subject

roelof14:12:08

im following the plan which clojurefarm has made

roelof14:12:28

I hope i once learn as much clojure I can make a website with it and solved the difficult challenges of Advent of Code or exercism

manutter5114:12:16

Macros can be really hard to wrap your head around, but honestly I've been using Clojure for years and years, and I've written maybe 3 macros total (not counting "let's write a macro!" exercises)

roelof14:12:07

I have read that you almost never write a macro

roelof14:12:35

but there are three challenges at the end that you challenge to write a macro I think

roelof14:12:39

Using the threading macros, find how many numbers from 0 to 9999 are palindromes: identical when written forwards and backwards. 121 is a palindrome, as is 7447 and 5, but not 12 or 953.

Write a macro id which takes a function and a list of args: (id f a b c), and returns an expression which calls that function with the given args: (f a b c).

Write a macro log which uses a var, logging-enabled, to determine whether or not to print an expression to the console at compile time. If logging-enabled is false, (log :hi) should macroexpand to nil. If logging-enabled is true, (log :hi) should macroexpand to (prn :hi). Why would you want to do this check during compilation, instead of when running the program? What might you lose?

manutter5114:12:42

Yeah most of the time a good function is all you ever need. Plus you can't pass a macro around like you can a function.

manutter5114:12:41

Two of those require you to write your own macro; the first one just wants you to use some of the built-in macros.

manutter5114:12:33

Just remember: macros write code, they don't do anything to your runtime data.

manutter5114:12:58

A macro is a tiny program that writes bits of other programs.

roelof14:12:22

we see tomorrow. I hope I can ask for help here if needed or for a review. I hope I will not ask for help too much but the error messages are for me not always clear and as I said im totally new in Clojure so I think I need a lot of help to learn it wel

manutter5114:12:18

Yeah, the error messages are a sore spot but they're getting better, and after a while you kind of get to recognize patterns of "Oh, I got this kind of error message, I should check, that"

manutter5114:12:29

but some of them stump even the best of us.

roelof14:12:31

so this one makes the function (f a b c) ??

manutter5114:12:46

Yeah, that's a good use for a macro.

manutter5114:12:13

"Build Your Own defn" 🙂

roelof14:12:27

sorry I mean this one :

Write a macro id which takes a function and a list of args: (id f a b c), and returns an expression which calls that function with the given args: (f a b c).

roelof14:12:30

it schould look like this It hink

(defmacro id [fun a b c]
  (fun a b c)

manutter5114:12:36

You’ll need to add some macro-specific syntax to that so that it doesn’t just execute (fun a b c) when you call it, but that’s actually a good start: you’ve written out what you want the end result to be when your macro executes, and now you just have to convert it into the body of an actual macro.

roelof14:12:16

hmm, the only thing I can find it to change it into this :

(defmacro id [fun a b c] (fun a b c)``

manutter5114:12:56

You’re short a ) at the end, but once you add that, try running in your REPL with (macroexpand '(id foo a b c))

manutter5114:12:48

Then try (macroexpand '(id + 1 2 3))

roelof14:12:34

on both I see this in repl

clj::chapter4=> 
(chapter4/fun chapter4/a chapter4/b chapter4/c)

roelof14:12:45

no idea if this is allright

manutter5114:12:06

For the second one you should see (+ 1 2 3), (possibly with the clojure namespace attached to the + symbol). So there’s something not quite right with your macro.

roelof14:12:52

I think so

Alex Miller (Clojure team)15:12:38

you are currently putting a literal symbol a b c in the expanded code

roelof15:12:48

then I think I also need to unquote the fun

☝️ 3
roelof15:12:23

(defmacro id [fun a b c]
  `(fun ~a ~b ~c))
gives now with :
(macroexpand '(id + 1 2 3))

roelof15:12:37

clj::chapter4=> 
(chapter4/fun 1 2 3)

manutter5115:12:15

You’re getting closer

roelof15:12:21

yep, unquote everything does the job

roelof15:12:35

(defmacro id [fun a b c]
  `(~fun ~a ~b ~c))

roelof15:12:39

is the solution

roelof15:12:13

I learn here more then on the clojurefarm channel 🙂

manutter5115:12:36

If you want a challenge, you could try to modify your id macro so that it takes zero or more arguments.

bronsa15:12:21

or not to use syntax-quote

manutter5115:12:52

A macro without a syntax quote?? 😱

bronsa15:12:16

syntax quote is never needed

manutter5115:12:35

Heh, I can see how to do that but still 😱

roelof15:12:34

with variable amount of arguments

roelof15:12:38

(defmacro id [fun & args]
  `(~fun ~args))

manutter5115:12:57

Close, you need a slightly different unquote for the args bit

roelof15:12:42

chips , I see

clj::chapter4=> 
(+ (1 2 3))

manutter5115:12:02

Do you have a reference/tutorial for defmacro? It should show you the list of unquote symbols.

roelof15:12:30

I tried rhis :

(defmacro id [fun & args]
  `(~fun ~& args))

roelof15:12:44

but that one gives a syntax error

Darin Douglass15:12:30

have you tried ~@args?

Darin Douglass15:12:02

the @ essentially is apply for macros

roelof15:12:19

also a syntax error :

(defmacro id [fun & args]
  `(~fun ~&args))

manutter5115:12:36

That’s the “unquote-splice” symbol, btw, and notice it’s @ not &

Alex Miller (Clojure team)15:12:28

a macro is literally just a function that takes code (as a data structure) and returns replacement code (as a data structure)

roelof15:12:42

yes, this does it :

(defmacro id [fun & args]
  `(~fun ~@args))

roelof15:12:04

without the unquote I do not have a idea how to make that work as a beginner

Alex Miller (Clojure team)15:12:49

so you just want a function that does: (id + 1 2 3) -> (+ 1 2 3)

roelof15:12:16

yep, that is I the challenge as I understand it

Alex Miller (Clojure team)15:12:17

args is a seq (1 2 3) so you're almost there. how do you prepend something to a list?

Alex Miller (Clojure team)15:12:33

(defmacro id [fun & args]
  (conj args fun))

roelof15:12:58

that simple. I was overthinking it

Alex Miller (Clojure team)15:12:59

or

(defmacro id [fun & args]
  (cons fun args))    ;; order is different

bronsa15:12:44

people often think that macros are this special thing in clojure that needs syntax-quote and vice versa, but macros are literally just functions, and syntax-quote is literally just a templating syntax for data

roelof15:12:48

Time to make a lot of notes and take a break. Tomorrow further on this for me unknown territory

Alex Miller (Clojure team)15:12:36

you can find examples of both styles in clojure core

Alex Miller (Clojure team)15:12:08

look at (source when) or (source and) for a couple good examples to study

roelof15:12:56

hmm, in your examples source is unknown when I do it in repl @alexmiller

bronsa15:12:05

a good exercise is also to forget about defmacro and just implement normal functions with defn , and just invoke the function with quoted arguments manually (e.g. (foo 'bar '1 '[1 2 3]) instead of (foo bar 1 [1 2 3]))

bronsa15:12:21

then to turn foo into a macro you just need to remove the quotes from the invocation and replace defn with defmacro

Alex Miller (Clojure team)15:12:01

you might need to (use 'clojure.repl) if you're not in user namespace

Alex Miller (Clojure team)15:12:35

source is in clojure.repl

roelof15:12:43

This help from this channel gives me hope. I maybe can learn clojure

roelof15:12:51

Time for a break

roelof15:12:47

but im impressed by the speed

roelof15:12:39

maybe somewhere in 2021 I will be able to try to solve AOC challenges on my own

roelof15:12:54

but till I be there I have a lot to learn

roelof15:12:24

What do you think of the brave book

Alex Miller (Clojure team)15:12:38

it's all just more functions

roelof15:12:05

almost done. I m now busy for 2 days.

manutter5115:12:06

Most people who have used the Brave & True book have been pleased with it

manutter5115:12:25

there’s also a #braveandtrue channel here specifically for that book/website

roelof15:12:28

Can image I know now enough to do exercism or AOC puzzles

roelof15:12:10

and I have to learn a framework if I want to make websites and learn how to store something in a database

roelof15:12:42

I cannot image that I now almost done , sorry

manutter5115:12:18

It took me a few months to get really comfortable with Clojure, but that was back before Slack and also I was new to the whole “functional programming” thing.

Lars Nilsson15:12:58

I tried to start using Clojure when it was really new, but the lack of leiningen, etc., at the time made it too painful to be productive, and gave it up for a couple of years. Then came back to it when the tooling was much improved.

manutter5115:12:21

Yeah, leiningen was a big help at the time.

roelof15:12:25

im comimng from ruby and haskell so the functional part is not new to me

roelof15:12:01

I have to get used to the parentheses and the polish notation as they call it

Lars Nilsson15:12:22

I had been using Ocaml quite a bit before Clojure, so same here regarding the functional aspect.

roelof15:12:51

I think in the future I will have the most problems when I want to use something as reframe. Never wrote javascript or react or something before

roelof15:12:02

but we see when we get there

manutter5115:12:06

I love re-frame, but yeah react does have a few quirks, and also cljs isn’t 100% identical to clj, so there’s bits that may bite the unwary. I’m working full time doing clj+cljs+re-frame tho, so there’s more than plenty enough to get a decent web app up and running.

roelof15:12:44

im thinking if and when I got to that point to make a website which uses the Rijksmuseaum api . where someone sees a page and in the same time the images are downloaded and they replace the placeholders

manutter5115:12:34

Hmm, I’ve done that in straight JS back in the day, never tried to do in cljs :thinking_face:

manutter5115:12:02

replace placeholder images with hi-res versions that is

roelof15:12:05

is there then a big difference in cjs and reframe. The way the clojurefarm is teaching us clojure is using reframe

manutter5115:12:09

Re-frame is a library that uses CLJS. It’s not part of Clojure or CLJS, it’s just popular.

clyfe15:12:31

What is clojurefarm?

manutter5115:12:27

Basically, React exists in the world of JS, and someone wrote a CLJS library named “reagent” to make it easier to use React in CLJS, and then someone else wrote a library named “re-frame” on top of reagent.

roelof15:12:46

oke, I see when I get there

roelof15:12:39

first this "book", then the brave book and then 4 clojure and then I think things like reframe i have to learn

roelof15:12:00

and im not in a hurry because this is a hobby of mine and not for a job

roelof15:12:20

no idea if there are clojure jobs in the Netherlands

roelof16:12:39

maybe I come tomorrow or later back to see how to solve this one :

Advanced) Using the rationalize function, write a macro exact which rewrites any use of +, -, *, or / to force the use of ratios instead of floating-point numbers. (* 2452.45 100) returns 245244.99999999997, but (exact (* 2452.45 100)) should return 245245N

Zor16:12:52

Greetings! Can't find an elegant way to do a partial flatten, by which I mean a function that accepts any nesting of sequences and returns a sequence of the innermost sequences ; e.g. (partial-flatten [[[1 2]] [[[3 4]]]]) => ([1 2] [3 4]. Could a kind puzzle-inclined person help me out?

hiredman16:12:55

This is exactly why using flatten of any stripe is a bad idea

Zor17:12:11

Care to elaborate?

hiredman17:12:24

because you always end up with "I want to flatten this, but...."

hiredman17:12:54

but I only want to flatten n levels, I only want to flatten when the lists don't contain x, etc

hiredman17:12:30

in general flatten get used when you write a program of the form 1. do some stuff that builds up some nested list 2. flatten things out

hiredman17:12:48

but while step #1 is a generally steeped in context, by the time you get to step #2 the context has been thrown away, so determining how and where to flatten has to be done all over again

hiredman17:12:19

while if you just applied concat here and there while doing #1, you had the context right there to easily make the decisions

Zor17:12:55

Fair point. In this instance, the nesting comes from using (for) in a (loop ...) which ends up nesting the results arbitrarily - or rather, in an input dependent, yet useless way. It would be indeed better not to use flatten-but-x to solve this. OTOH, using for [ ... :let ... :when ... ] is super terse and expressive.

hiredman17:12:34

for doesn't arbitrarily nest things

hiredman17:12:52

you are recursively calling a function which uses for

Zor17:12:22

for nests things once. the recursion over it can be n-deep with varying ns

Zor17:12:44

it's a for [ ... ] recur

hiredman17:12:56

the context here is you know when you recur, so unwrap it there

Zor17:12:10

I tried to do that, but probably got it wrong. I'll do more attempts rn.

hiredman17:12:39

for example, if you have (for [i (f x)] i) and (f x) returns a lists of lists then do (for [i (f x) ii i] ii)

Zor17:12:36

it's more like (defn f [a prefix] (comment omitted termination code)) (for [n (magic a)] (f (drop n a) (conj prefix (first a))))). (magic) returns a small number.

hiredman17:12:21

right, so shift the recursive call up into the for

hiredman17:12:05

(defn f [...] ... (for [... i (f ...)] i))

hiredman17:12:37

that will concat one level of lists for every recursive call, so in your base case you may need to add a second layer of lists if your lists is meant to be a list of lists

hiredman17:12:28

the recursive call chain ends up being exactly the context information you would need to recover in your "flatten, but..."

Zor17:12:37

that worked.

hiredman17:12:10

it better, I am a big fan of recursive fors like that

Zor17:12:25

I followed your instructions and that made it work. I don't understand how or why it works tho thinking-face

hiredman17:12:16

for is a combination of a lot of difference sequence functions, include map and mapcat

hiredman17:12:59

(for [i x] (f i)) => (map f x)

Zor17:12:53

so far so good.

hiredman17:12:33

(for [i x ii (f i)] (g ii)) => (map g (mapcat f x))

Zor17:12:20

(for [x xs y ys] [x y]) => ([x0 y0] [x0 y1] .. [x0 yN] [x1 y0] .. [xN yN]) - cartesian product I believe

hiredman17:12:30

(for [x xs y ys] [x y]) => (mapcat (fn [x] (map (fn [y] [x y]) ys)) xs)

Zor17:12:20

[ processing intensifies ... ]

hiredman17:12:46

any for that doesn't use any of the keyword stuff (:when, :while, etc) can be transformed into an expression of nested mapcats around an inner map, you can do the keyword stuff to you just have to sprinkle in some calls to filter and take-while

hiredman17:12:50

(and of course (map f x) <=> (mapcat (comp list f) x) )

Zor17:12:12

eloquently put.

Zor17:12:23

this belongs to clojuredocs!

Zor18:12:48

(macroexpand '(for [x xs y ys] [x y])) is significantly harder to grok thank your explanations 🙂

Zor18:12:12

Thank you very much for your time and eloquent explanation

Alex Miller (Clojure team)17:12:44

you could do it with either tree-seq (save only colls that don't contain colls) or postwalk (concat any colls that only contain colls)

roelof17:12:11

Are there here people who are doing the AOC challenges ?

🖐️ 12
dorab17:12:06

@roelof See the #adventofcode channel in this Slack.

roelof19:12:05

is there a easy way to make this work :

(ns chapter5)

(defn schedule
  "Using the control flow constructs we've learned, write a schedule 
   function which, given an hour of the day, returns what you'll be 
   doing at that time. (schedule 18), for me, returns :dinner."
  [my-time]
  (cond
    (<= "0:00" my-time "07.00")   :sleeping
    (== "07:00" my-time)          :breakfast
    (<= "07:01" my-time "12:00")  :work
    (= "12:00" my-time)                  :lunch 
    (<= "12:01" my-time "18:00")  :more-work
    (<=  "18:01" my-time "19:00") :dinner
    (<= "19:01" my-time "23:59")  :watching-tv    
    ))

roelof19:12:56

is there a way I can convert the given time and the comparisaion to a time object

salam20:12:35

this is so far the best date-time api i've ever worked with. so if you want to do it right (like how you would do it in a real-world project), i would suggest taking a look at this api.

roelof20:12:47

so I can do (localtime my_time) to convert the given time to a time object

roelof20:12:02

so I have to that for all the times

salam20:12:29

(java.time.LocalTime/parse "07:00")
#object[java.time.LocalTime 0x2b87581 "07:00"]
(str *1)
"07:00"

roelof20:12:27

oke, and then I can use isbefore and isafter to check if its in the interval

roelof20:12:35

Time to play with this idea

salam20:12:00

just as an example, for the first clause in your cond:

(def midnight (java.time.LocalTime/MIDNIGHT))
#'user/midnight

(def breakfast-time (java.time.LocalTime/parse "07:00"))
#'user/morning

(def my-time (java.time.LocalTime/parse "06:30"))
#'user/my-time

(and (.isAfter my-time midnight)
     (.isBefore my-time breakfast-time))
true

roelof20:12:15

oke I was trying another idea but get errors

(ns chapter5)

(defn parse-time
  "Parse a string to a time object"
   [time-string]
   (java.time.LocalTime/parse time-string))

(defn schedule
  "Using the control flow constructs we've learned, write a schedule 
   function which, given an hour of the day, returns what you'll be 
   doing at that time. (schedule 18), for me, returns :dinner."
  [my-time]
  (cond
    (<= (parse-time "00:00") (parse-time(str my-time)) (parse-time "07:00") )   :sleeping
    ))

(schedule "03:00")
error :
; Execution error (ClassCastException) at chapter5/schedule (form-init11789170975546566471.clj:9).
; class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')

salam20:12:32

oh, you cannot use <= with times...

salam20:12:55

it's simply not overridden for those java time types...

salam20:12:26

take a look at the example for how to do date-time comparison that i posted above....

roelof20:12:49

oke, thanks , I will play with it tomorrow. its too late

salam20:12:55

rule of thumb for when dealing with time: don't roll your own solutions because time is hard. 😉

roelof21:12:45

I never try to roll my own solution when there is something for it

salam21:12:12

one exception is when your objective is learning how to do it. 🙂

roelof21:12:51

yep, as one of the challenge was to make my own filter method

roelof19:12:33

Right now I only have studied the first 5 chapters of the "Clojure from the ground up " tutorial

manutter5120:12:49

I find java time tricky to work with, I think for this particular exercise I’d convert the numeric input to a string

dorab20:12:09

@roelof take a look at the compare function. For just this limited set of string comparisons, it should be adequate.

noisesmith20:12:35

isn't compare what &lt;= is using already? never mind, it only works on numbers

roelof20:12:49

Hmm, have to think how compare could help me

roelof20:12:19

@manutter51 the trick to make it all string could help

👍 3
noisesmith20:12:48

@roelof

(compare "0:00" "07:00") => 3

noisesmith20:12:02

you can do two comparisons per case, or if you feel clever do a binary search

roelof20:12:03

?? I want to check if the given time is between two other times

noisesmith20:12:19

right, and using compare twice can tell you if it is

noisesmith20:12:44

if they are strings

enforser20:12:22

Why not just represent time of day in minutes as a number? No need to introduce string comparisons here

(defn time-as-minutes [hour minute] (+ minute (* 60 hour))

(defn schedule [my-time-in-minutes] 
  (cond 
    (<= (time-as-minutes 0 0) my-time-in-minutes (time-as-minutes 7 0)) :sleeping
    ;; add the rest of the cases
    ))

👍 3
noisesmith20:12:23

for a given pair of times, you'd want the first compare to return positive or zero, and the second compare to return negative or zero

roelof20:12:59

@trailcapital that is also a good idea

dharrigan20:12:10

If you wanted to use the built-in (jvm) time library, perhaps this might be suitable...

dharrigan20:12:21

(ns foo
  (:import [java.time LocalTime]))

(defn parse
  [my-time]
  (LocalTime/parse my-time))

(def breakfast (parse "07:00"))
(def midday (parse "12:00"))
(def nearly-dinner (parse "18:00"))
(def dinner (parse "19:00"))
(def late-night (parse "23:59"))

(defn schedule
  "Using the control flow constructs we've learned, write a schedule
   function which, given an hour of the day, returns what you'll be
   doing at that time. (schedule 18), for me, returns :dinner."
  [my-time]
  (let [my-time' (parse my-time)]
    (cond
     (.isBefore my-time' breakfast) :sleeping
     (= my-time' breakfast) :breakfast
     (.isBefore my-time' midday) :work
     (= my-time' midday) :lunch
     (.isBefore my-time' nearly-dinner) :more-work
     (.isBefore my-time' dinner) :dinner
     (.isBefore my-time' late-night) :watching-tv)))

(schedule "06:00")
(schedule "07:00")
(schedule "11:00")
(schedule "12:00")
(schedule "15:00")
(schedule "18:00")
(schedule "19:30")
(schedule "00:00")

roelof20:12:31

Could also be working

roelof20:12:46

I will play tomorrow with both ideas

roelof21:12:46

why do I get this error:

(ns chapter5
  (:import [java.time LocalTime]))

(defn parse
  [my-time]
  (LocalTime/parse my-time))

(def breakfast (parse "07:00"))
(def midday (parse "12:00"))
(def nearly-dinner (parse "18:00"))
(def dinner (parse "19:00"))
(def late-night (parse "23:59"))

(defn schedule
  "Using the control flow constructs we've learned, write a schedule 
   function which, given an hour of the day, returns what you'll be 
   doing at that time. (schedule 18), for me, returns :dinner."
   [my-time] 
   let [my-time' (parse my-time)]
    (cond
     (.isBefore my-time' breakfast) :sleeping ))

(schedule "03:00")
error :
unresolved symbol my-time'

Lars Nilsson21:12:05

Need parens for the let?

dharrigan21:12:07

yes, you're missing a parens just before the let, i.e., (let...

roelof21:12:57

now another one :

Could not locate chapter4__init.class, chapter4.clj or chapter4.cljc on classpath.

roelof21:12:29

which do not make sense because chapter4.cjs in another file in the same directory

dpsutton21:12:34

how did you trigger this error?

roelof21:12:12

re-opened vs code and then do crtl-alt-c crtl-alt-j to start up a calva repl

Alex Miller (Clojure team)21:12:32

I feel like you are not the first person here with this same error, wonder if maybe whatever repo you're using is not set up well

dpsutton21:12:57

what command does ctrl-alt-c ctrl-alt-j run?

roelof21:12:16

could be. I can push all my code to github so you can look ?

Alex Miller (Clojure team)21:12:22

but it's saying exactly the problem - you're trying to load chapter4 ns but it's not on your classpath. presumably you have the file so it's something with the config of the classpath

dpsutton21:12:57

this is what the maintainer and creator of calva mentioned yesterday to you

pez21:12:17

@roelof I’d be happy to try your project out from the Calva perspective of things.

pez21:12:29

As @alexmiller mentions, this problem shows up now and then. Might be a problematic project template, but also might be a Ux issue with Calva.

roelof21:12:27

I know but calva did not even start up

dpsutton21:12:38

your classpath is by default "src" so requiring chapter4 will look for src/chapter4.clj but that file is located at src/ground_up/chapter4.clj

roelof21:12:08

oke, I can do that

dpsutton21:12:30

the namespace needs to be ground-up.chapter4 or the file can be moved out of the ground_up directory to just src or you can add src/ground_up onto your classpath and leave the namespaces alone

roelof21:12:42

I did this because the next step in the course is the brave book and I do not want two chapter 3 in the repo

roelof21:12:19

thanks, everything is working fine now

roelof21:12:31

Gn , really time to sleep

💤 3