Fork me on GitHub
#beginners
<
2019-02-21
>
Eccentric J14:02:10

What tools do people use for generating docs from clojure code?

superancetre14:02:05

cljdoc generates the documentation part automatically if you put your project on Clojar I believe

superancetre14:02:13

I heard about marginalia also

superancetre14:02:46

Never tried it, it seems to be kind of documentation generation/ literate programming type of library

butterguns14:02:36

On a tangent, I wonder if these tools could at some point make use of specs to enhance the documentation

superancetre15:02:50

cljdoc talk about it, it's in his roadmap

1
superancetre15:02:41

It's goal is to try to do something akin to Hoogle => https://www.haskell.org/hoogle/

superancetre15:02:50

Research function based on their signature

superancetre15:02:01

Really cool feature for Haskell

superancetre15:02:34

That could probably be recreated for Clojure with the help of Spec

butterguns15:02:19

So many times while browsing docs, I ask "ok, but what does this opts map look like?"

superancetre15:02:57

Martin Klepsch advocates to use table in docstring to help understand what keys goes into opts map

superancetre15:02:19

That could help a lot!

2
👍 2
superancetre15:02:54

It's funny because every questions you have here, I read about it like 2h ago

butterguns15:02:30

Do you have this week's lottery numbers too?

Eric Ervin20:02:50

28 26 19 18 41 14

superancetre15:02:03

435 4585 744 but don't tell anyone else, that'll be our secret 😉 🤑

🤫 1
fmn15:02:24

How do you compile clojure project into an uberjar using clj ?

Mario C.16:02:26

A couple days ago I came here asking for help with exception handling happening within futures. I wrote up a little code to show what I was working with and I mistakingly didn't replicate the actual code verbatim. The real code looks like this

(def list-names '("Tom" "Harry" "Richard"))

(defn throw-func
  [nme]
  (str "hello " nme)
  (throw (Exception. "I just threw you an error")))

(defn tc-test
  []
  (let [futures (map (fn [name]
                       (let [sample (fn [name]
                                      (try
                                        (println "Sanity Check")
                                        #(throw-func name)
                                        (catch Exception e
                                          (println "Got an error here!"))))]
                         (future ((sample name)))))
                     list-names)
        response (doall (map deref futures))]
    1))

(defn foo
  []
  (try
    (tc-test)
    (catch Exception e
      (println "Handling error here as well"))))
Then after talking with a co worker he points out my flaw. And it all made sense! Anyways, just in case anyone was curious or runs into a similar issue.

Mario C.16:02:33

I never saw the exception in sample because there was no exception happening when returning an anonymous function. So to fix I had to return the try-catch and call throw-func. Then everything worked as I expected it

Eccentric J16:02:04

Thanks for the doc generation links and Martin Klepsch’s article on writing good docs. I had just finished documenting a couple of functions but was curious if it would be beneficial to put the breakdown of map properties into the meta of a function and write a tool to use it to build more detailed docs. Right now it feels like a big ’ol string.

Chase20:02:23

So something like (println "hello" name "!") automatically includes a space between operands. => hello chasote ! Seemed convenient at first but how do I get rid of the space if I don't want it?

Lennart Buit20:02:41

(println (str "hello" name "!"))

Chase20:02:02

simple enough! there will be a day when I'll be like, "why can't str just put the darn space in for me!" haha

Lennart Buit20:02:39

hehe, its pretty common in other languages, JavaScript’s console.log, Pythons print(...) and such do the same ^^

RodgerDodger20:02:48

Hi All. If I have a vector of vectors (with strings as they type of each of the four elements of the individual vectors), what would be the best way to go about combing vectors that have the same first element string value?

RodgerDodger20:02:42

So [["hey" "1" "2" "3"] ["you" "4" "5" "6"] ["hey" "7" "8" "9"]] would return [["hey" "1" "2" "3" "7" 8" "9"] ["you" "4" "5" "6"]]

RodgerDodger21:02:28

I am guessing this would be a good case for a loop, any opinions?

alexmiller21:02:00

you might play with group-by first

alexmiller21:02:14

that's just a first step

RodgerDodger21:02:16

@alexmiller Thank you! I think this puts me on the right path.

Lennart Buit21:02:53

be careful, you get a map from that, so if its important to you that “hey” stays before “you”, the order of the entries in a map is not guaranteed

RodgerDodger21:02:32

Thank you for the heads-up @lennart.buit.

kaneko22:02:35

Hi guys, I was wondering if there is something along the lines of didSet in clojure? The use case I'm thinking of is: an atom is updated with a new value and then I want to fire some API request using the newValue

Lennart Buit22:02:41

I found https://clojuredocs.org/clojure.core/add-watch, haven’t used it, but maybe it helps you

noisesmith22:02:32

this is exactly what add-watch is for

noisesmith22:02:15

I forget though, does the watch fire before or after possible retries?

kaneko22:02:53

awesome thank you so much

noisesmith22:02:56

answer: after retry

(ins)user=> (def a (atom 0))
#'user/a
(ins)user=> (def retries (atom 0))
#'user/retries
(cmd)user=> (add-watch a :foo (fn [_ _ _ _] (swap! retries inc)))
#object[clojure.lang.Atom 0x2f48b3d2 {:status :ready, :val 0}]
(ins)user=> (dotimes [_ 1000] (future (swap! a inc)))
nil
(ins)user=> @a
1000
(ins)user=> @retries
1000

noisesmith22:02:28

retries should have been called tries in retrospect, but since the numbers match it clearly only fires the watch after the retry if any

Lennart Buit22:02:45

Thanks for confirming my googles, noisesmith! TIL

noisesmith22:02:04

(cmd)user=> (def a (atom 0))
#'user/a
(cmd)user=> (def tries (atom 0))
#'user/tries
(ins)user=> (dotimes [_ 1000] (future (swap! a (fn [x] (swap! tries inc) (inc x)))))
nil
(cmd)user=> @a
1000
(ins)user=> @tries
1052
- for 1000 items, 52 retries