beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
valerauko 2021-05-17T02:46:09.312200Z

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 Koz 2021-05-17T02:54:39.312900Z

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

Ivan Koz 2021-05-17T02:55:02.313400Z

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

Juλian (he/him) 2021-05-17T12:18:38.315100Z

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

NoahTheDuke 2021-05-17T12:43:03.316700Z

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) 2021-05-17T12:56:13.317200Z

and when should I use or not use a protocol?

Juλian (he/him) 2021-05-17T13:00:22.317800Z

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

NoahTheDuke 2021-05-17T13:05:58.318100Z

https://clojure.org/reference/datatypes

NoahTheDuke 2021-05-17T13:06:03.318300Z

that's a good intro to the topic

NoahTheDuke 2021-05-17T13:08:18.318500Z

and then https://clojure.org/reference/protocols for protocols

pithyless 2021-05-17T13:20:03.320500Z

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: https://leanpub.com/clojurepolymorphism

👀 4
stagmoose 2021-05-17T15:54:45.323300Z

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 https://clojuredocs.org/clojure.core/-%3E 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?

2021-05-17T15:56:31.323800Z

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

2021-05-17T15:57:40.324700Z

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

dpsutton 2021-05-17T15:58:14.325500Z

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.

🍻 1
2021-05-17T15:59:00.326400Z

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

stagmoose 2021-05-17T15:59:51.327400Z

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

2021-05-17T15:59:56.327600Z

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

stagmoose 2021-05-17T16:01:12.327800Z

Thanks!

stagmoose 2021-05-17T16:02:12.328Z

gocha, thanks!

Franco Gasperino 2021-05-17T18:19:45.337200Z

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?

seancorfield 2021-05-17T18:23:21.338900Z

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

👆 1
seancorfield 2021-05-17T18:24:04.339800Z

See https://stuartsierra.com/tag/dos-and-donts — and the various posts about threading macros.

🙌 1
seancorfield 2021-05-17T18:24:47.340800Z

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

Franco Gasperino 2021-05-17T18:33:50.343Z

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

seancorfield 2021-05-17T18:36:00.343200Z

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

Franco Gasperino 2021-05-17T18:36:52.343400Z

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

Franco Gasperino 2021-05-17T18:37:15.343600Z

threading the map, main argument becomes the keyseq

Franco Gasperino 2021-05-17T18:39:32.343800Z

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

seancorfield 2021-05-17T19:55:30.344500Z

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) 2021-05-17T20:41:33.348400Z

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)
  (read))
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?

seancorfield 2021-05-17T20:45:04.349400Z

@julian608 You need flush:

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

ghadi 2021-05-17T20:45:04.349500Z

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

Juλian (he/him) 2021-05-17T20:47:28.350900Z

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

2021-05-18T13:05:39.022800Z

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

orpheus 2021-05-17T22:38:35.354900Z

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

2021-05-18T13:07:09.023Z

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

orpheus 2021-05-18T15:37:15.026900Z

@noisesmith could you share an example please?

2021-05-18T16:21:23.030Z

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

phronmophobic 2021-05-17T22:44:06.355100Z

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

orpheus 2021-05-17T22:45:46.355300Z

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

phronmophobic 2021-05-17T22:51:57.355600Z

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"}))

phronmophobic 2021-05-17T22:52:20.355800Z

not the best example, but hopefully shows the idea

orpheus 2021-05-17T22:57:16.356Z

fantastic thank you