Fork me on GitHub

Thanks, I didn't know about arrayType. On the other hand Integer/TYPE need eval instead of resolve so not sure how I feel about that...

Ivan Koz02:05:39

@vale could bring them into a closure at function definition, so it only runs once at program start

Ivan Koz02:05:02

(let [get\\convert primitives here] (defn ..)

Juλian (he/him)12:05:38

are there tipps, when one should use defrecord or when they could be too much overhead or overcomplicate things?

Noah Bogart12:05:03

Records are good when your map is closed (no extra or missing keys), and/or when you want to implement/extend a protocol

Juλian (he/him)12:05:13

and when should I use or not use a protocol?

Juλian (he/him)13:05:22

sorry, will read more about them, maybe I'll understand it then

Noah Bogart13:05:03

that's a good intro to the topic


If someone wants to learn more about protocols/multimethods/etc. I found this booklet to be a really good summary of all the pros/cons and when you may want to use which:

👀 12

I am using d3 in my project and it is possible to show result like this (first pic): with this code (second and third pic): I am a bit confused about the -> syntax here. I know that is It said: • (-> x & forms)

Threads the expr through the forms. Inserts x as the
second item in the first form, making a list of it if it is not a
list already. If there are more forms, inserts the first form as the
second item in second form, etc.
But I want to ask why using (d3/scaleLinear) instead of d3/scaleLinear after -> Why is (d3/scaleLinear) the "x" above, not d3/scaleLinear Is it reasonable to call a methods like (d3/scaleLinear) without any given argument?


I am not familiar with d3/scaleLinear. Is it a Clojure function, perhaps?


Or from a quick Google search, perhaps it is an interop call to a JavaScript method?


it's a function from d3 that takes no arguments. Whoever made that function made it so that it cannot take arguments. So it's pretty reasonable to call it that way.

🍻 3

In Clojure, the syntax (d3/scaleLinear) is the way to call a Clojure function, or a JavaScript method via interop, that takes no arguments.


I used shadow-cljs to import d3.js installed using npm


Or to be more precise, it is one good way to do so. There are others, but that is the most commonly used.


gocha, thanks!

Franco Gasperino18:05:45

when working with threading macros and interleaving -first and -last based on the functions applied, is it more idiomatic to use the as-> macro, or wrap composed in anonymous functions to conform arg positioning?


It’s more idiomatic to not mix -> and ->> if you can avoid it.

👆 3

See — and the various posts about threading macros.

🙌 3

as-> is specifically intended for use inside -> for occasional cases where the threaded value is neither the first nor the last argument.

Franco Gasperino18:05:50

thanks. having read the thread-as post he has on that site, he claims to prefer a wrapper to arrange the args to fit thread-first or thread-last. im staring at the common interaction of the various built-ins and 'into' as an example


Rule of thumb: sequence operations use ->> because the “main argument” comes last; collection/object operations use -> because the “main argument” comes first.

Franco Gasperino18:05:52

yes. im reading that now. however, i ran into select-keys and for threading, the main argument is flipped onto its head

Franco Gasperino18:05:15

threading the map, main argument becomes the keyseq

Franco Gasperino18:05:32

"Don’t use anonymous functions to change argument position" ... i should have read this


select-keys is a collection function: it takes a collection as the first (main) argument and produces the same type of collection. That’s consistent.

Juλian (he/him)20:05:33

I'm trying to make my input function nicer by adding a prompt at the beginning, but it doesn't work like I'd expect. Here a minimal example:

(defn prompted-read [prompt]
  (print prompt)
When I try it in REPL (clj or lein repl) by calling it like this (prompted-read "Input: "), the prompt is shown only after I enter something. Is there a way to fix this?


@julian608 You need flush:

dev=> (defn prompted-read [prompt]
 #_=>   (print prompt)
 #_=>   (flush)
 #_=>   (read))
dev=> (prompted-read "Input: ")
Input: 123


@julian608 add a (flush) call after print, flushing only happens after newlines

Juλian (he/him)20:05:28

thanks, @seancorfield and @ghadi - should have known this from other programming languages facepalm


I think this is a TTY API issue and not a language issue


How do I create an object with optional and default values? I have a function that returns an invoice object

(defn invoice [account-id]
    {:account-id account-id
     :key-1 "key-1"
     :key-2 "key-2"
If sometimes I want to create an invoice and only change key-1 or only change key-2 or change key-3 and key-4 but not 1 and 2. Is there a possible way or better way to go about this? That way I don’t need to create an arity body for each possible combination


It's kind of hard to tell what types of functions you're trying to write, but probably some combination of assoc or merge?


Thank you will look into. Writing functions to create object payloads to send over http


I usually end up using merge for similar use cases. You can pass the original map as the first arg and selectively overwrite keys. Eg.

(merge payload
       ;; always add these
       {:id (next-id)}
       ;; optionally add these
       (when (:checksum? opts)
          {:checksum (calc-checksum payload)})
       ;; choose one
       (if-let [user-agent (:user-agent opts)]
          {:user-agent user-agent}
          {:user-agent "batman"}))


not the best example, but hopefully shows the idea


fantastic thank you


I always put "defaults" as the first arg to merge, that way you get the intuitive behavior that any provided keys are used as overrides


@U051SS2EU could you share an example please?


(let [defaults {:user-friendly true}] (merge defaults opts)) - if opts has a : user-friendly key, that value is used, otherwise you get the default