Fork me on GitHub
#beginners
<
2022-03-27
>
John Bradens01:03:33

I'm following a tutorial & trying to connect to a repl. In my terminal I cd into the directory, type in clj then do

user=> (web.core/-main)
and get
Execution error (ClassNotFoundException) at java.net.URLClassLoader/findClass (URLClassLoader.java:433).
web.core
What am I missing?

practicalli-johnny11:03:59

A namespace should be required before it can be used. In a terminal UI for the REPL, then an explicit require expression is required https://practical.li/clojure/clojure-cli/repl/coding-in-the-repl.html

ahungry01:03:26

clj loads files based on their directory paths/names - do you have a directory/filepath similar to src/web/core.clj , where you have set the (ns web.core) at the top of the file?

John Bradens01:03:05

I have src/clj/web/core.clj which has (ns web.core). Do you know if there's any other common errors I might have made?

dpsutton01:03:12

It's not clear if you've required the namespace before attempting to use it

ahungry01:03:29

@bradj4333 if I do this, it will work with your structure - you need the require as mentioned, and also need to fix the directory/ns mappings I think - at least, I tend to keep them matched up 1 to 1 (you can keep your original ns though and just change the second -e in here to the web.core as you had it originally, but I tend to see the path mirror the ns in most projects)

ahungry01:03:53

clj -e "(require '[clj.web.core])" -e '(clj.web.core/-main)'
❯ cat src/clj/web/core.clj
(ns clj.web.core)
(defn -main [& xs] 32)

John Bradens01:03:08

I try this and I get

user=> (require '[clj.web.core])
Execution error (FileNotFoundException) at user/eval1 (REPL:1).
Could not locate clj/web/core__init.class, clj/web/core.clj or clj/web/core.cljc on classpath.

ahungry02:03:12

did you launch the repl with clj or with clojure? did you try the lines I pasted as is? (in the same dir that holds 'src') - from the dir you launched it - does ls clj/web/core* show anything?

John Bradens02:03:46

I get

No such namespace: src
Now I'm thinking I must be in the wrong directory? I'm just in the main project folder. Should I be in src? I used clj btw!

John Bradens02:03:26

When I type in your command

clj -e "(require '[web.core])" -e '(web.core/-main)'
I get some errors that some things failed to load, but then the -main function does get called, so it looks like it ends up working okay :thinking_face:

John Bradens02:03:56

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See  for further details.
these are the errors I get, before the -main function is called. Not sure what it means? Can I safely ignore this?

practicalli-johnny11:03:15

Yes. These warnings are because a specific implementation of SLF4J logger was not added (as a dependency) so it's using the default noop version

🙌 1
practicalli-johnny11:03:47

Add the following as a project dependency to get rid of the warning message (or use a specific logger dependency if you prefer)

org.slf4j/slf4j-nop     {:mvn/version "1.7.36"}

🙌 1
E. Kevin Hall M.D.13:03:35

Is there a better way to think about this? I'm trying to filter strings and find those that contain ALL substrings in a collection. The first version works fine for just two strings, but in trying to expand this function to an arbitrary number of strings I'm sending a sequence of function to every-pred and that obviously doesn't work:

(defn individually-contains-both-tokens
  "Iteratively refines given list of cancer criteria for
  those which contain all given tokens."
  [tokens criteria-list]
  (let [s1 #(str/includes? % (str/lower-case (first tokens)))
        s2 #(str/includes? % (str/lower-case (second tokens)))]
    (filter (every-pred s1 s2) (map str/lower-case criteria-list))))

(comment
  (count (individually-contains-both-tokens ["who" "grade"] dl/lgg-criteria-list))
  (dl/write-seq-to-file "output/who-grade.csv" (individually-contains-both-tokens ["who" "grade"] dl/lgg-criteria-list)))

(defn individually-contains-all-tokens
  [tokens criteria-list]
  (let [predicates (for [t tokens]
                     #(str/includes? % (str/lower-case t)))]
    (filter (every-pred predicates) (map str/lower-case criteria-list))))

(comment
  (individually-contains-all-tokens ["who" "grade"] dl/lgg-criteria-list))

Martin Půda13:03:32

(->> ["who grades foo bar" "who foo bar" "foo bar"]
     (filter #(every? (fn [substring] (str/includes? % substring))
                      ["who" "grade"])))
=> ("who grades foo bar")

❤️ 1
Apple15:03:17

(every-pred s1 s2) vs (every-pred [...]) i think this is the problem

❤️ 1
sheluchin17:03:00

I have a large number of items for which I need to query a db, transform the result, and then write the xformed result back to the db. I should use transduce for this, yeah? Should it be something like (transduce (comp partition-item-list run-query xform-results save-xformed) ...)? Does that logic sound right?

Ferdinand Beyer07:03:11

You can reuse transduce, but who is saying you should? Use whatever works for you and produces the simplest result. Breaking your job into the functions you describe is already a good start. Whether to use transducers or simply thread some functions together is more about optimisation.

ahungry17:03:59

yea, transduce is to avoid iterating the coll n times where n is number of fns you would tend to map, and instead iterate 1 time applying each fn together, but i don't think trans or comp makes a big difference for most cases

sheluchin17:03:52

It is an optimization I am after. I have it working normally, but it gets a little heavy at times, although after looking at it some more, I'm not sure transduce would help because the queries are just plain heavy. I also found this thread on transducers yesterday https://clojurians.slack.com/archives/C03S1KBA2/p1629991519027200?thread_ts=1629924688.380100&amp;cid=C03S1KBA2. It looks like I should generally avoid doing IO right inside the transducer, and instead run the query in the input function, and do the saving in the reducing function. That's my understanding of it, at least.

Ferdinand Beyer07:03:40

@UPWHQK562 - as you said, I would not expect any gain from optimizing the iteration with transducers, as the runtime is very likely dominated by the I/O. If you need speed, maybe you could look into parallelisation with pmap etc?

💯 1