Fork me on GitHub
#beginners
<
2021-06-10
>
Angel Rojas00:06:47

hello, could you please tell me where find a tutorial for create an API REST

sova-soars-the-sora01:06:20

2 links there, one is the tutorial, one is the source code of the main core.clj file

sova-soars-the-sora01:06:31

if you need any help feel free to ask in the channel ! ^.^

Angel Rojas00:06:28

its great to be here...!😃

Chris K00:06:55

Hello I'm using doom emacs and cider for clojure and for some reason, if I run cider on certain directories, emacs will go crazy and use 100% of my cpu, the cider repl will also not open

seancorfield01:06:02

If you haven’t asked there already, you may have a better chance of getting answers in #cider and/or #doom-emacs

Chris K00:06:09

this happens only on like 1 directory and others projects are fine

Chris K02:06:19

I have a map that I need the keys to be characters like '(' or ';' but I'm not sure what's the best way to make a map with keys like this I currently have it as : {";" "SemiColon"}

jaihindhreddy03:06:17

Character literals are preceeded by a backslash in Clojure:

{\; "SemiColon" \( "OpeningParenthesis"}

Chris K03:06:37

Thanks!! Been a while also 😄

3
popeye08:06:10

I have json structure like below

{
    "fruit": "Apple",
    "size": "Large",
    "color": "Red"
}
{
    "fruit": "orange",
    "size": "Small",
    "color": "Red"
}

popeye08:06:25

How can I group like below structure

popeye08:06:27

fruit=[Apple, Large]
size=[Large,Small]

delaguardo08:06:13

(reduce
 (fn [acc {:strs [fruit size]}]
   (-> acc
       (update "fruit" (fnil conj []) fruit)
       (update "size" (fnil conj []) size)))
 {}
 [{...}])
as an example of using reduce

popeye08:06:38

What us :strs ?

delaguardo08:06:47

destructuring instruction, same as :keys but for string

👀 3
popeye08:06:45

I got update does noot found , I am using clojure 1.9

popeye08:06:15

I got {f{r{u{it{s{mango orange}}}} after using update-in

delaguardo08:06:15

update-in expect to have a sequential path provided as a second argument. I guess you have a string instead. The problem that in clojure string is also sequential data

delaguardo08:06:23

just use update

popeye08:06:38

it says update not found

delaguardo08:06:44

could you share your code?

popeye08:06:26

@U04V4KLKC

(reduce
               (fn [acc dt]
                 (-> acc
                     (update "fruits" (fnil conj []) (:fruits dt))
                     (update "size " (fnil conj []) (:size dt ))))
               {}
               data)

popeye08:06:44

oh sorry , i had the code updat eexclude above

popeye09:06:13

I have below code

(def a (interpose "," (get hellovar ":a" )))
(def b (interpose "," (get hellovar ":b" )))
(def c (interpose "," (get hellovar ":c" )))
(def d (interpose "," (get hellovar ":d" )))
Can this be improved ?

popeye09:06:43

I wrote in below way

(defn hellointepe [data]
  (reduce-kv
    (fn [acc k v]
      (assoc acc k (interpose "," v)) )
    {}
    data))

Juλian (he/him)10:06:04

you could use zipmap:

(zipmap (keys hellovar)
        (map (partial interpose ",")
             (vals hellovar)))

Juλian (he/him)10:06:04

but your reduce-kv looks fine, too

popeye11:06:37

I am trying to type cast each value like (map Integer. (get fruts :size)) this giving syntax error at Integer. any reason?

indy11:06:03

What is the value of (get fruits :size)It has to be a seq.

popeye11:06:34

it is giving 11

indy11:06:03

It has to be a sequence-like collection, example, vector, list, set...

indy11:06:21

(map (comp #(Integer/parseInt %) :size) fruits)

indy12:06:49

if your fruits is something like [{:size "90" :name "apple"} {:name "banana" :size "89"}]

2
noisesmith16:06:17

Integer. is not an object that can be passed to map, it is a syntax expanding to calling new on a class and for (IMHO foolish) domain design reasons methods are not first class citizens in java (and thus the JVM), but instead they are special operations on an object. #(Integer. %) takes that constructor invocation and puts it inside a new Object of class clojure.lang.IFn which is an obect with .invoke and .call methods, which is what map expects as its arg.

noisesmith16:06:41

finally, as Indy suggests Integer/parseInt is better than using the Integer constructor Long/parseLong is almost always better than that even because integral literals in clojure code are always Long and on modern computers there are few cases where using an Integer is better

noisesmith16:06:30

same with Float vs. Double - clojure always prefers the 64 bit type, and down casts to the smaller type for you when it's needed for method call interop

delaguardo13:06:05

This is a question of personal preferences but in my opinion honeysql is much more “clojure” than korma - https://github.com/seancorfield/honeysql

myguidingstar15:06:41

or if you want to try sql from a higher level of abstraction, there's http://walkable.gitlab.io

popeye16:06:35

That was my production code , so cannot change now

NoahTheDuke14:06:25

is there a wrapping library for clojure.string that makes the functions nil-pun?

ej16:06:53

I seem to remember reading about a project for getting better error messages in Clojure, but I can't seem to find anything when Googling right now. As far as I remember, you could add it to your project and it would look up error messages on a server and give you something more easily understandable. Does anyone know what I'm talking about?

noisesmith16:06:36

I almost made something like that but before I got motivated enough to flesh it out I just learned the internal classes / methods that keep showing up in stack traces and moved on

noisesmith16:06:04

as a brand new user I saw Long can't be cast to IFn and got confused and angry, then I went code diving and learned what IFn was and why my code would make that happen, then I started thinking that I could make a guide or program that turned that into a more intuitive message, but before that plan got fleshed out I just developed intuitions for things like IFn and seq coersion and I had other priorities

popeye16:06:26

Hi Team, I have a scenario where I have written a function where it calls the database select operation multiple times lets say 10000 times, How can I implement that function, which can be used reduce , map or pmap any suggestion?

Michael Stokley16:06:34

can you build the select operation programmatically, at run time? collapsing the 10,000 into 1

Michael Stokley16:06:47

or maybe i misunderstand the goal

noisesmith16:06:50

right, calling a db in a tight loop like that is like opening a file to write each character, then close it again, across a string

noisesmith16:06:19

it's going to have the correct result but it's never the thing that you want to do in a real app that isn't a toy

popeye16:06:56

I have to call the function multiple times, so using reduce might take more time , so how in clojure we can handle calling same function several time? may be more than >10000

popeye16:06:07

I have passed using In operation for database ( passing multiple argument at same time)

Michael Stokley16:06:09

if you want to call the same function multiple times with different arguments, map works

noisesmith16:06:21

that's what map repeatedly and run! and doseq are for, but it's a bad idea to do this with db calls

popeye16:06:37

But how calling same function multiple times is handled in clojure

noisesmith16:06:50

it depends on the context

noisesmith16:06:21

do you have args in a collection? do you have a function ready to take those args? do you need a discrete return value from each call in a new collection?

noisesmith16:06:45

the answers to those questions are how you decide between map, repeatedly, run!, doseq, iterate, etc. etc.

Michael Stokley16:06:48

(defn query-db
  [db lookup-id]
  'data)

(def lookup-ids [1 2 3])

(def db 'db)

(map (partial query-db db) lookup-ids)
;; => (data data data)

noisesmith16:06:12

but! calling map to get db results means that your db lookups are going to happen in unpredictable places at runtime, and if you already know multiple id's it's always better to do one select to get all of the ids rather than call the db in a loop

noisesmith16:06:21

there's no one size fits all answer

popeye16:06:20

do you have args in a collection? do you have a function ready to take those args? do you need a discrete return value from each call in a new collection? - Yes

sova-soars-the-sora16:06:49

is there any repetition in the calls or repetition in the result you can exploit

noisesmith18:06:15

@U01J3DB39R6 if yes to all of those, use map if it's not io / side effecting / manipulating state, and mapv if it is

Endre Bakken Stovner17:06:00

I am having trouble using taps. My tap code looks like this:

(defn tap [[type & args]]
  (let [[jobid outtype line] args
        type-color (if (= type :err) red green)
        cmdline (str/join " " [(yellow (str/join " " jobid)) (type-color type) line])]
    (println "------")
    (println cmdline)
    (println "------")
    ))

(add-tap tap)
The place where I call tap> looks like this:
(tap> [jobid type line])
Still my output looks like:
[[:bwa-map ({:sample "A", :genome "hg38"})]
 :err
 "[main] Real time: 0.853 sec; CPU: 0.646 sec"]
I.e. it seems like just println is used, not my custom tap function which calls three printlns. What might I be doing wrong?

Endre Bakken Stovner17:06:09

Doing it in the REPL works:

user> (add-tap #(println "----" % "----"))
;; => nil
user> (tap> "hi")
;; => true---- hi ----
"hi"

Endre Bakken Stovner17:06:24

I'm sure my add-tap was triggered since I added this line above it:

(println "adding tap****************")
(add-tap tap)

noisesmith18:06:12

it could be your tap function is crashing, I'm not sure you'd see a stack trace if it did

noisesmith18:06:55

you could put a try / catch with a println in the catch to check

noisesmith18:06:44

@endrebak85

Clojure 1.10.1
(cmd)user=> (add-tap (fn [& args] (/ 1 0)))
nil
(cmd)user=> (tap> nil)
true
(ins)user=> (add-tap (fn [& args] (try (/ 1 0) (catch Exception e (println "oops!\n" (pr-str e))))))
nil
(cmd)user=> (tap> nil)
true
user=> oops!
 #error {
 :cause "Divide by zero"
 :via
 [{:type java.lang.ArithmeticException
   :message "Divide by zero"
   :at [clojure.lang.Numbers divide "Numbers.java" 188]}]
 :trace
 [[clojure.lang.Numbers divide "Numbers.java" 188]
  [clojure.lang.Numbers divide "Numbers.java" 3901]
  [user$eval142$fn__143 doInvoke "NO_SOURCE_FILE" 1]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$fn__8821$fn__8822$fn__8824$fn__8831 invoke "core.clj" 7861]
  [clojure.core$fn__8821$fn__8822$fn__8824 invoke "core.clj" 7860]
  [clojure.lang.AFn run "AFn.java" 22]
  [java.lang.Thread run "Thread.java" 829]]}

manutter5118:06:56

@endrebak85 maybe you have “stale” namespaces in your REPL that work, and when you run from the command line, it builds fresh namespaces that don’t work?

noisesmith18:06:44

I'm actually surprised tap> swallows stack traces silently, that seems like a big gotcha

manutter5118:06:07

Or maybe the namespaces don’t load in the same order? I’d try putting (println ">>>> Here goes tap>") in before your tap> line and see if somehow your tap> is executing before the add-tap.

noisesmith18:06:21

I'm guessing the lack of output from tap> is because of an exception because running the app gives you different data types than the repl experiment

manutter5118:06:44

Yeah, the try/catch could be very instructive here.

noisesmith18:06:48

a simpler way to do it might be (add-tap (fn [& args] (println (try .... (catch Exception e ...))))) then you know you always get a println (unless it's an Error instead of Exception etc.)

Endre Bakken Stovner16:06:16

You were right, it was due to an error 🙂

Stuart20:06:50

Hi, Can someone help me and explain the following behaviour. I evaluate this in the repl and expect to see an error:

(let [foo [1 2 3]]
  (nth foo -1))
I get an error, which is great.
Error: No item -1 in vector of length 3
I evaluate this:
(let [foo [1 2 3]]
  (map-indexed (fn [idx i] (nth foo -1)) foo))
I see no output to the repl at all, no error and no indication its even evaluated it??? I thought it should have generated an error same as above.

alexmiller20:06:55

map-indexed is lazy

alexmiller20:06:10

nothing has tried to read the first element yet

Stuart20:06:12

ah okay! That explains it God so simple.

alexmiller20:06:25

happens to literally every beginner :)

alexmiller20:06:37

so good job getting it out of the way!

Erik B Good21:06:14

(map #({:a %1 :b %2}) [1 2 3] [10 12 12]) (map #(assoc {} :a %1 :b %2) [1 2 3] [10 12 12])

lucas severo21:06:05

in the first line you are execing the map as a function, use a do in these cases

lucas severo21:06:10

like (map #(do {:a %1 :b %2}) [1 2 3] [10 12 12])

alexmiller21:06:20

or use the hash-map constructor

alexmiller21:06:04

(map #(hash-map :a %1 :b %2) [1 2 3] [10 12 12])

Erik B Good23:06:33

Right I think I understand what you mean by execing the map as a function. Thanks both of you for your answers

Erik B Good21:06:30

Anyone know why the first line does not work while the second one does?

Chase21:06:33

Is there a way to call out to an api using curl but do so in clojure? Does that make sense? Specifically a command like this:

curl  \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"prompt": "This is a test", "max_tokens": 5}'

dpsutton21:06:40

do you mean make a request to the api from clojure or use curl from clojure?

Chase21:06:53

well I would make a request to an api but I was being lazy in figuring out how to use the java api library. There are no clojure bindings yet as far as I've found

Chase21:06:06

I haven't done that before but it would be good practice

seancorfield21:06:12

clj-http or http-kit’s client lib.

seancorfield21:06:44

(we just switched all our HTTP API calls to use the latter since it has no dependencies and a nice, simple async interface)

Chase21:06:52

I actually have those currently open on other tabs so I'm on the right path

Chase21:06:02

so is making a curl request equivalent to a "GET" request?

Chase21:06:46

I also have mdn's http docs up to try and learn some web basics here

seancorfield22:06:51

curl with -d is going to be a POST

Chase22:06:45

awesome. I'll fiddle with that. the response is going to come back as json. What lib do you recommend there. I just saw an article going over all of them

seancorfield22:06:50

(http/post "" {:headers {"content-type" "application/json", "authorization" (str "Bearer " your-api-key)} :body "{\"prompt\": \"This is a test\", \"max_tokens\": 5}"}) — something like that

seancorfield22:06:18

I recommend org.clojure/data.json since it has no dependencies. Cheshire relies on Jackson which has caused me pain.

seancorfield22:06:46

(we switched from Cheshire to data.json recently, just before we switched from clj-http to http-kit)

Chase22:06:01

awesome! I will try this out. Thanks folks