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

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

julien.rouse14:02:05

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

julien.rouse14:02:13

I heard about marginalia also

julien.rouse14:02:46

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

mattmorten14:02:36

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

julien.rouse15:02:50

cljdoc talk about it, it's in his roadmap

julien.rouse15:02:41

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

julien.rouse15:02:50

Research function based on their signature

julien.rouse15:02:01

Really cool feature for Haskell

julien.rouse15:02:34

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

mattmorten15:02:19

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

julien.rouse15:02:57

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

julien.rouse15:02:19

That could help a lot!

julien.rouse15:02:54

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

mattmorten15:02:30

Do you have this week's lottery numbers too?

ericcervin20:02:50

28 26 19 18 41 14

julien.rouse15:02:03

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

funyako.funyao15615:02:24

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

mario.cordova.86216: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.cordova.86216: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

jayzawrotny16: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.

chase-lambert20: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 "!"))

chase-lambert20: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 ^^

rodger.scott20: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?

rodger.scott20: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"]]

rodger.scott21: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

rodger.scott21: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

rodger.scott21:02:32

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

r.natarajan3522: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?

r.natarajan3522: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