Fork me on GitHub

@dominicm That class name you mentioned sounds tailor made for Spring.

Daniel Tan03:06:38

i think learning about monads actually made me appreciate how macros work


Learning about monads can make you appreciate all sorts of things 😉


what exactly? unless you were being sarcastic, but I don't know you as a very sarcastic person ☺️


For a lot of people monads are dark and mysterious or unknowably complex, so I meant it in terms of enlightenment.


Yes, but exploring dark/mysterious/unknowably complex things is doesn't automatically results in appreciation of "all sorts" of thing, so I figured, maybe you had some specific thing in mind, and not just a general "joy of exploration", which is a kind of appreciation for epistemology, even in the end you end up in a place where you have less tools and less resources than where you started.


Exploration, no. Enlightenment, yes. And learning about monads seems to fall into the latter category for a lot of people for some reason.

Daniel Tan04:06:26

i kinda agree with this. I asked about monads in the FP slack chat and most people asked me to get “an intuition” about it when the monad design pattern is simply a set of functions and a set of laws

Daniel Tan04:06:45

in the end i realised that monads are how FP languages try to work without macros because manipulating code is not as natural in other languages as with clojure


Monads are weird. We use them all the time, but we don't talk about them. I think we know what several of them are without knowing their names. But it has become a "badge of honor" to "understand monads".


Only a few languages actually reify them. Haskell is pretty much defined by reifying monads.

Daniel Tan04:06:08

AFAIK the API for monads is basically some callback chain


"seems" "a lot of people" "for some reason", this is not the kind of talk that leads to productive discussion, I can't look this up, I can't learn this, I can believe you or I can be skeptical, but it's not something useful. I don't see what kind of enlightenment is guaranteed, I would say it's possible that you lose intellectual capabilities if you start learning too much about monads. And since it doesn't seem to be the norm to qualify or validate our words, I will not attempt to do so either 😉


@U0VQ4N5EE Why does everything need to be something you can look up and/or learn? You dismiss anything that isn't mathematical or rigorous. You need to be more flexible (and more fun).


No one is guaranteeing anything. As for "los(ing) intellectual capabilities if you start learning too much about monads"... well, I've heard that opinion voiced before and I have some sympathy. Just don't voice it around Haskell fans 🙂

🙂 12
David Pham05:06:17

I thought that monads were monoids in the space of endofunctors where the operation is composition.

David Pham05:06:08

I guess I have to start again learning monads... (I am a mathematician so I like these kind of definition).

Daniel Tan05:06:01

I was referring more to the monad design pattern in software engineering

David Pham05:06:12

Rich talks on reducers was eye opening to understand monads.

Daniel Tan05:06:32

which means we’re talking about the same thing, except I simply reduced it to using terms on the context of SE

David Pham05:06:24

The context of SE is a concretion of the abstract idea in the end.

Daniel Tan05:06:36

yep, i agree

David Pham05:06:55

You use it, because we know some properties will fall out of it for free I guess.

David Pham05:06:46

(I am not a fan of monads and proof theory at all in SE, as a mathematician when I solve real world problem, there are just to much mess and in the end you end up with an inconsistent system. So better off accepting the world is messy and use informal logic to solve problems).


And in general, I find that the stuff @U050P0ACR has written on algebra stuff (monads, monoids, and such) very useful. As @U04V70XH6 said, we use this stuff all the time, but we're not really aware of it.


We got +, merge, *, and, or, conj which are all monoids

Daniel Tan07:06:00

it’s likely that we’re using unlawful monads though


I'd argue that our seqs are functors

Daniel Tan07:06:44

in usual clojure code I dont think we really make an effort to use a monad i guess


That might be, the insight I think I've had to monads wrt to the "laws" is that a monad is an ADT + some stuff that you can't express in the type-system. This "some stuff" are the "laws"


I think that if you squint some-> is akin to a maybe-monad?

Daniel Tan07:06:09

generally what i’ve seen is that we use macros instead of monads

Daniel Tan07:06:34

some-> is a good example of macro vs monad


(reducers/monoid + (constantly 0)) seems like a terrible example (on that page) given that + is already associative and (+) returns 0...


agreed 🙂


Even so, I find it, at least interesting if not useful, to think about my operations in terms of monoids. Can we "add" two things together? If so, what's the identity value?


The whole machinery around reduce is built on monoids.


I think the problem with calling this out as "monoids" is that people then expect it to be something "special" (like a monoid function) when it's an inherent property of existing operations.


It's like the "List Monad". Which we use all the time without thinking of it as anything special.


I like Elm's approach to this, where they basically forbade use of the "M-word".

🙂 6
Daniel Tan07:06:16

just for fun but does the factory design pattern count somewhat as a “monad”


Is it associative? Does it have an identity?


Might be, but the facinating thing to me is that one school of FP seems to look at FP from this very abstract view point where everything is a Functor, Monoid, Monad etc. Then you have our school who look at FP in a more practical way, like you can (reduce conj [] (range 10)) The facinating thing to me is when you se that the everyday practial things that we use has a foundation in the abstract stuff the other camp keeps talking about.


Or perhaps more appropriately (reduce conj coll) relying on (conj) producing [] in some situations 🙂


(it's somewhat weird that reduce only ever calls (f) if the collection has zero items... it it has one item, that is returned without calling f at all, and it if has two or more, then f is only called with two arguments)


Oh, but we don't like the two-arity version of reduce, now do we 🙂


And I guess that's why Rich thinks the 2-arity of reduce was a mistake.


user> (reduce (fn [x y] x) nil)
Execution error (ArityException) at user/eval259006 (form-init1049871881092821308.clj:9213).
Wrong number of args (0) passed to: user/eval259006/fn--259007
user> (reduce (fn [x y] x) [] nil)
;; => []


Which might come and bite you at the most inopportune of times.


Absolutely. It's why next.jdbc/plan produces IReduceInit not IReduce (like


and where the monoid fn comes in handy:

user> (reduce (clojure.core.reducers/monoid (fn [x y] x) (constantly []))  nil)
;; => []


That's a cure that's worse than the disease. Just force people to provide init: (reduce (fn [x y] x) [] nil)


Agreed 🙂


anecdotically, I heard that once you learn what a monoid is, you loose the ability to describe what a monoid is to others 🙂

Daniel Tan07:06:04

i would agree that an explicit init prevents a whole host of issues


No, that's only for monads.

Daniel Tan07:06:33

im triggered by that comment because i saw it in the fp slack chat


It's still possible to explain a monoid


even if you understand them 🙂

Daniel Tan07:06:45

luckily some of them still managed to explain it to me

Daniel Tan07:06:59

because apparently most people still dont understand what is a monad


I think this is why I don't like completing. It says it take a 2-arity fn and adds a 1-arity function, but it still requires the function to be 0-arity as well.


(defn completing
  "Takes a reducing function f of 2 args and returns a fn suitable for
  transduce by adding an arity-1 signature that calls cf (default -
  identity) on the result argument."
  {:added "1.7"}
  ([f] (completing f identity))
  ([f cf]
       ([] (f))
       ([x] (cf x))
       ([x y] (f x y)))))
No mention of the silent expectation that (f) is valid.


Jira issue and patch 🙂


I wish I could learn math, but modern math is almost all about things that I find either useless, or framed in a way that makes it useless to me. If I have a chance to enroll higher education ever (I am a high school dropout, basically I left school when I realized that they are teaching stuff I have to forget later), then I will be learning something math/physics related for sure. Solid state physics and lasers are the nicest.


But higher education requires going there, not just paying a lot.


Tried to look around online for math tutors, but it's more for preparing for exams, not for number theoretical deep dives, which is what I need.


Sounds to me like you're always blaming other people for your failings @U0VQ4N5EE If you really wanted to learn that stuff, you could, with no cost. You just don't want to, and you just want to sound like a victim...


"I realized that they are teaching stuff I have to forget later" -- that is such B.S.


hmm? I never blame anyone


Everything I was taught in school I had to unlearn, I am willing to prove this to you.


obviously, you have such a low opinion of me, if you think I am blaming people, that's a complete misunderstanding, so I wouldn't be surprised if you will dismiss this as ludicrous, but this is the way of heterodox thinking, it always annoys the mainstream to no end ☺️


If I really wanted to learn, because that's all I need, right? Willpower?


and I am the one who blames people, lol


btw, the problem is when you call this a "failing", why is it a failing?


It's true, based on your posts here, I'm afraid I do have a very low opinion of you. You butt into all sorts of conversations with your weird, negative comments, derailing discussions. I wish you'd keep to purely technical stuff.

👍 4

well, I am sorry, I am a human being, not a robot


my aim is not to be technical


but what is the failing? 🙂


@U0VQ4N5EE humans can't unlearn


"I am a human being" is a very poor excuse. We're all human, and yet I don't think I've seen anyone else behaving in a similar manner.

👍 4

Monoids, (almost no) monads, sum types, product types and others concepts, explained to anyone with "high school algebra", by a clojurist ericnormand

👍 12

@U2FRKM4TW • excuse? it wasn't an excuse, it was a declaration, I do not intend to only "keep to purely technical stuff" because 1. that's key to oppression 2. no one else does it either 3. I don't even know how. • "behaving similar manner", can you be a bit more specific? What is in my behavior or mannerism that so unique to you that you claim that I am unlike any other human you have ever met?

Daniel Tan12:06:26

I’ll just include my notes on monads here: if anyone is interested

🔥 12

That's a very nice explanation @U01458A7CBX. Certainly a better topic than the parallel, thanks for sharing!


Monoids, (almost no) monads, sum types, product types and others concepts, explained to anyone with "high school algebra", by a clojurist ericnormand

👍 12

I'm curious if you folks could recommend a beginner Java resource. I'm not super interested in the language if I'm being honest (I totally respect the JVM though and why Clojure used it), but I have felt funky using Clojure without knowing a lick of Java so I am curious. From my search I've seen this MOOC recommended: and now JetBrains is offering a free course on it too: Does anyone recommend these or maybe something better? Am I just wasting time and should just keep on chugging with Clojure?


That's a very interesting question. Clojure is quite different than Java, but I value having an understanding of Java too. What is your background? Do you have experience in other languages?


I've bounced around a lot. Mostly a perpetual, tutorial doing beginner tbh. I probably know Clojure the most even but it's all a slow (albeit fun) struggle. I do struggle with understanding error messages so was thinking maybe some Java knowledge would help me there?


If I reflect harder I think my hardest thing with Clojure is understanding function inputs when reading other people's code so Java knowledge won't help me there. That makes me run to statically typed languages with annotated type signatures and helpful compilers but then I miss Clojure and come give it another shot. That is more a topic for the beginner channel I suppose.


i wish it were easier to learn what typical values are as inputs to functions as well. i resort to using various tracing, printing, debugging, etc. tools and techniques. i still find that having to change my code to learn what values are flowing through to not be ideal -- though unless using a debugger, it doesn't seem that different from many other programming languages. placing tap> in various places with it wired up appropriately can help in observing what actually passes through. if one uses rebl in combination with tap>, one can more easily browse the values. there is also the reveal tool and shadow-cljs' inspect functionality these days.


Probably 🙂


But I understand too 🙂 Reading other people's code, where the function inputs aren't clear can be hard.


naming is everything 🙂


I was thinking yesterday that maybe just shift my perspective and realize the input is probably a map or at least one of the other common data structures and the core functions can work on each would help me and go from there. Not sure it will help though. But I'll get back on (off) topic.


Usually, function inputs do follow a naming convention, like using m for map.


I think beginners can help out more 🙂


Of course, these are just recommendations, nothing official, but the names are commonly found.


definitely. I'm pretty familiar with those. It's when the parameter is just something like req or params or rules just to mention something I was perusing today.


I have no clue how to start parsing that


How common is it to find good docstrings? I know with Java there was a time when everybody was javadoc crazy, but at some point only your companies with stringent rules used it.


I kind of feel like just chugging along with Clojure is probably the best bet. Java doesn't particularly help one learn JVM-isms in my experience. I've been doing very Haskell-esque Scala for the last five years and learning Clojure now for a new job, but every time I had to go into Java-land (say to fix some old code) it didn't add anything for me. Maybe just implementing some java.* Clojure wrappers, not to share as a lib but for yourself for the sake of exposure, would be a better use of time?


Clojure is my first language and and today, after 3 years working with it, I feel comfortable to say that "I know Java"

👏 4

I appreciate it. Sounds reasonable to me for sure. I'll probably stick to Clojure projects and keep upping the challenge there


a buddy of mine is; in the Typelevel ecosystem in Scala, which tries to bring more Haskell and ML flavor to Scala, if anyone's interested simple_smile