Fork me on GitHub
#beginners
<
2022-01-22
>
JohnJ01:01:16

spot the difference

JohnJ01:01:51

(defn remove-nils [r]
  (mapv #(into {} (remove (fn [m] (nil? (val m)))) %) r))

(defn remove-nils [r]
  (mapv #(into {}  (remove (fn [m] (nil? (val m))) %)) r))

JohnJ01:01:45

Ok, I was going to say that the introduction of tranducers made the language more confusing to read but now that I think about it it doesn't 😉 - I doubt they are used for single transformations and normally comp will signal thay there might be transducers

noisesmith01:01:37

comp is not transducer specific, it's a function that composes functions

noisesmith01:01:11

and transducers are used standalone quite frequently

noisesmith01:01:10

and your two functions do the same thing (one is just more optimized than the other)

JohnJ01:01:56

oh I thought the performance of both would be the same since there is only one transformation

noisesmith01:01:05

one creates a lazy-seq that isn't strictly needed, the other doesn't

noisesmith01:01:05

I think it's easy to find examples of code that gets confusing or ambiguous if you put 5 function calls on one line

JohnJ01:01:25

remove doesn't create the lazy-seq in the non-transducer version?

noisesmith01:01:49

the transducer version doesn't create a lazy-seq, the non-transducing version does create one. in both cases a vector is returned and any intermediate allocations are just gc churn.

noisesmith02:01:25

by "strictly needed" I meant that you don't need the lazy-seq in order to build the vector. remove creates one anyway. clojure isn't the kind of "smart compiler" that other languages offer, it is actually quite naiive in terms of translating your code structure, and relies on jvm hotspot for most optimization.

JohnJ02:01:57

remove creates a vector or did you meant mapv?

seancorfield02:01:45

"`remove` creates one anyway" -- "one" = "lazy-seq" here, not "vector".

JohnJ02:01:10

ah gotcha

noisesmith01:01:00

I do agree that transducers can make things harder on beginners because they make the error you get when you put a paren in the wrong place harder to debug

noisesmith01:01:18

but there are a lot of ways to break code by moving parens

noisesmith01:01:46

(or forgetting args)

JohnJ01:01:36

yeah, it does feel a bit hacky (and adds cognitive overhead)

noisesmith01:01:37

I think the cognitive overhead is a lot smaller if you know more about the design decisions

noisesmith01:01:19

one of the primary reasons for having transducers, is that operations like map, filter, etc. were being re-implemented for various non-collection contexts (eg. core.async channels)

noisesmith01:01:02

with transducers, instead of needing to make core.async/map you can provide (map f) as an argument to a core.async channel, and it provides "mapping"

JohnJ02:01:28

ok, how I understand the Because transducers are decoupled from input or output sources, they can be used in many different processes - collections, streams, channels, observables part

JohnJ02:01:57

its primary usecase

JohnJ02:01:22

was core.async modified to accept transducers?

noisesmith22:01:16

yes, and the original versions of map, filter etc. in core.async were deprecated

noisesmith01:01:22

so now most of the lazy collection operations each get a new function arity, omitting the collection argument and returning a function building block - the transducer

noisesmith01:01:46

this is all done via application and composition of higher order functions, rather than a new syntax or API

Nedeljko Radovanovic23:01:31

Hello everyone, Can someone please recommend learning path or maybe e-book or two for me, I want to be able to make something as soon as possible using clojure, clojurescript and datomic.. I have done some Advent of Code by using Clojure but tasks got too difficult at some point so i have some basic knowledge... I am new here so it would mean a lot to me... Thank you for your time.. 😊

sova-soars-the-sora00:01:29

Welcome @U02US0AS16K! Clojure is a fantastic language and ecosystem, and the community is top notch. You've found a great place to ask questions and learn! There are now over a dozen Clojure books out there, I think each member here will have their own recommendations. I personally love "The Joy of Clojure" as a thorough primer. Then, you will want to start working on your own project right away. That will be most satisfying and the best way to learn. As far as your project goes: my recommendation is 1. use Ring with Compojure or Pedestal for the back-end server. 2. Use tonsky/rum (Rum) with Shadowcljs to take clojurescript and output reactive html (single page application / clientside). 3. Use rum on the backend server as well to generate static HTML that you can hydrate 4. You achieve homoiconicity or isomorphic data between server (.clj) and client (.cljs) by using .cljc files w/ reader conditionals that can selectively return clojure or clojurescript depending on invoking context/namespace. 5. Tie datomic in to your backend server that is running pedestal or ring with compojure. 6. Ask questions and answer questions of other beginners 😄

Arthur16:01:33

Sova’s answer is pretty good. I’d just like to add that IMO you shouldn’t spend too much time doing AoC/exercism stuff or else you’ll probably just get bored quickly. There are a few paid courses by Jacek Schae that could help you on this route, but if you’re not willing to pay for courses right now I’d just start by creating a simple Compojure/Reitit app and learning it’s basics. As soon as you’re able to build a server and handle the requests you can probably throw datomic into the mix. There are a number of resources to learn datomic and datalog: • a website learn called datalog today • datascript’s documentation • datomic’s documentation • many blog posts you can find googling There is also Luminus, which is a a web framework that should get you up and running quite fast. The framework’s author has written a book called Web development with Clojure, which talks about most stuff you’re looking for (except for datomic iirc) If you’re looking to build your client’s as SPAs I’d also talke a look at Reagent and Re-frame.

Nedeljko Radovanovic18:01:52

Thank you both for quick response, will do me best, and AoC didn't bore me at all, it was actually fun but required time for me to solve one task has gone up and I ended up losing time (effectiveness), I hope that on next AoC i will be able to keep up. Cheers. 😄

practicalli-johnny12:01:24

https://practical.li/ has a range of free books on practical Clojure development, along with video guides, which you may find interesting

☝️ 1
✔️ 1
Nedeljko Radovanovic16:01:06

I found your study group on YT (aprox. 100 hours of video content ) and your books, that is by far most complete documentation about Clojure and Clojurescript that i found to this date. I will most certainly use it to learn as much as possible, thank you very much for that, keep up the good work. Cheers. 🙌

practicalli-johnny17:01:25

Thank you. I still have lots more to add 😁

🤞 1