Fork me on GitHub
Gabriel Kovacs10:09:31

Is this the idiomatic way of defining a constant?

(def ^:const constant2 1.2)

Ben Sless10:09:54

just def, in Clojure, everything is constant by default. :const has other implications regarding compilation

Gabriel Kovacs10:09:50

as far as I understood adding :const will improve the runtime. thus best practice?

Ben Sless11:09:30

Does your code have stringent performance constraints?

Gabriel Kovacs11:09:04

No, it has not. I just wanted to learn and apply the best possible option 🙂 .

Gabriel Kovacs11:09:06

Is there a reason why I should not make use of :const ?

Ben Sless11:09:00

Yes, because some things can't be made into a const and then the code which uses them will fail and you'll scratch your head. The best possible option is to start with def Then if you build an application use direct linking Then check if you have performance issues Then profile Then realize you're probably blocking on an IO thread or non optimal algorithm, fix it and go have beer It's not that const has no use, but it's rarely required. The defaults are good :)

❤️ 1
🍻 1
Gabriel Kovacs11:09:49

Thx for the info! 🙂

Lyn Headley14:09:59

What kinds of things cannot be made into a const?

Ben Sless14:09:45

ref types, I think, java types. they can be made into a const, but every piece of code using this const will break

Drew Verlee20:09:17

You speak as if from personal experience Ben 🙂

😉 2

(defn str-count-chars [s char]
    (->> (seq s) (take-while #{char}) count))

  (str-count-prefixes "## fo" \#)

  (defn positions [pred coll]
    (keep-indexed (fn [idx val] (when (pred val) idx)) coll))

  (count (take-while (fn [[x y]] (= x y)) (map-indexed vector (positions #{\#} "## fo #"))))
2 attempts at counting the heading level in markdown. Any tips? I want to count the occurrence of a char at the beginning of a string, then I thought there must be something general with positions


(count (second (re-find #"^(#*)" s))) (count (take-while #(= \# %) s)) something like that ?


yea maybe I am overthinking it :thumbsup:

Ahmed Hassan13:09:28

(defn restargs [name & args]
    (println name args (type args))
    (let [{default :hello} args]
  (restargs "restargs hello" :hello 3000)
Why can we destructure the args, even though the type of args is clojure.lang.ArraySeq? Edit: Destructuring works, I'm curious why it works, even though the args are not a clojure.lang.PersistentArrayMap

Gabriel Kovacs13:09:52

I assume that args can be multiple things, thus due to ambiguity it does not work. just guessing :)

Ahmed Hassan14:09:04

Destructuring works, I'm curious why it works, even though the args are not a clojure.lang.PersistentArrayMap

Gabriel Kovacs14:09:30

Sorry, misread 🙃

Alex Miller (Clojure team)14:09:18

You can apply map destructuring to sequential collections (like rest args) as if those were the kvs

💯 1
Alex Miller (Clojure team)14:09:44

This is sometimes called kwarg destructuring which allows you to pass alternating keyword / value options at the end of your function call, then destructure them like a map on the rest args

💯 1
Gabriel Kovacs14:09:48

I would like to know why was the evaluation (in the REPL) of this function successful? (defn add-sales-tax [cart-item] (let [{:keys [price]} cart-item] assoc cart-item :sales-tax (* price tax-rate))) My assumption is that assoc , cart-item , :sales-tax and (* price tax-rate) are all expressions and only the evaluation of the last expression is getting returned. Am I right or is there another reason why it was successfully evaluated?


what argument did you invoke the function with?

Gabriel Kovacs14:09:52

This map

(def cart [{:name "Silicone Pancake Mold" :price 10.49}
           {:name "Small Pour-Over Coffe Maker" :price 18.96}
           {:name "Digital Kitchen Scale" :price 24.95}])


that's not a map

Ahmed Hassan14:09:28

It's seems that you are right,

(def tax-rate 3)
(add-sales-tax {:price 4}) // => 12


but your original idea is correct. a let returns its last form in the let body

Gabriel Kovacs14:09:49

was actually (map add-sales-tax cart) 🙂 And thx for the clarification!


(let [x 1] inc dec (+ x 1)) just returns the (+ x 1) form

Gabriel Kovacs14:09:07

So I have to be more careful with my parentheses 🙂 .

Eugene Mosh16:09:11

Hello friends! I'm reading book "Clojure for brave and true" and find in chapter 1 some strange mutation: after command "`lein new app clojure-noob`" Leiningen named folder like clojure_noob. Why folder name with _ not with - ? Thnx!

Gabriel Kovacs16:09:15

Java can't handle dashes thus underscores are used when defining the structure of the project.

👍 1
Ben Lieberman17:09:15

I have a small dataset (a timetable) that I originally wrote row-wise. I realized it makes a lot more sense for it to be column-wise. So I came up with this solution

(->> (-> "times.edn"
           (get-in [:weekday :southbound])
       (partition 15))
I'm wondering if nesting thread macros like this is a faux pas or if this is ok. any suggestions/improvements welcome in either case

Bob B17:09:08

it is, of course, subjective, but I sort of get the impression that it's generally frowned upon.<> explicitly calls this out as a "don't". And in this case in particular, the partition call is the only thing being "thread-lasted", so a couple viable options include just calling partition directly on the thread-firsted form (e.g. move partition 15 to replace ->> ) and using a let

Ben Lieberman17:09:29

interesting read, thank you


Not sure if this will apply to your data structure but a few times I've been able to use this really elegant way of turning rows into columns: (map apply vector my-data) I found in the clojuredocs for map: (it's the last example in this small block of examples)

🔥 1

you might be able to replace vals and then flatten with (mapcat vals) but that's a quick untested thought (edit: this wouldn't work in the thread first expression of course)

Ben Lieberman15:09:45

that map apply vector solution is beautiful