Fork me on GitHub
Alexander Heldt11:09:34

im looking for any resource that could help me “think in clojure”, ie. change my OOP-mind into a more functional mind. articles, talks, books, whatever. thanks! this talk ( was really nice, i’d like to explore that thinking a bit more


Bear in mind that it's a very challenging book in terms of time investment if you want to solve great deal of exercises (which are very important for really absorbing the ideas)

Alexander Heldt18:09:24

Thanks for the suggestion, ill take a note of it and come back when i feel more ready


@me1243 I created a free basic resource to help people start thinking functionally. Take a look at these two sections It’s still work in progress, but hopefully should help I also have 40+ free videos on Clojure at

Alexander Heldt09:09:33

@U05254DQM awesome, thanks! i will look at that


I am always looking to improve these resources, so feel free to ask if something is not clear or you want to know more.


sorry, I missed the autocorrect when typing. its


This book is a good place to start:

Alexander Heldt17:09:44

thanks for the tip!


@me1243 maybe as a point of support as someone who has done the same and moves through paradigms, OOP and FP aren't necessarily in contention. I'll dug up a bunch of newer talks on you that brings it down into a much more simple thought process around the difference, but I'm increasingly of the mind if you are stretching your brain across academic sounding abstractions, you're heading in the wrong direction. FP and OO, at the core, I'm hypothesizing (in this statement) is more around the relationship between state and behavior, and everyone gets tripped on how that state changes as behavior acts on it.


i'll find a list of talks that back this, but even @stuarthalloway's deconstruct talk puts this in the mental space that I'm now thinking about it.


> many people are typing


but really, what you want to do to data remains the same, you just need to look at various persistent data structures to achieve the same goal. within that persistent data structure realm, we can start to talk about a lot of why that's more reasonable for representing change over time than OOP.

Alexander Heldt17:09:39

@gerred very good point, and i can see that. the talked i linked has good examples on just that.


I would just try to continue as you're going and when you hit a point when either the shape of the code you're writing looks wrong, or you're trying to stretch into shared state, etc,. you ask those specific questions and you'll get good, specific answers.

👍 1
Murshid Azher17:09:57

Hi I am new to clojure community, hence I can't the big picture of it. Like what should I concentrate on, what I should be the next step and what are the pathways/ roadmap I can take. Would anyone be kind enough to show me the big picture like this example?


I do not have a picture like that to share with you. Two questions for you: (a) what is your budget for learning materials? $0 ? $40 ? something else? (b) what would you say you already know well in terms of programming languages, versus know something but only a little, or are you new to all of programming?


This would be a worthwhile image to craft for clojure.

👏 1

Something that lays out the path from beginner to various endpoints labeled mastery


For example, if you want to limit yourself to not paying for any books, there are some one-line Clojure practice sites, and a free on-line book recommended by many others (I haven't gone through it myself) is Clojure for the Brave and True:

seancorfield18:09:17 is mostly very generic and applies to Clojure as much as anything else (Clojure is mentioned on that diagram).


Some of the sections are heavy on PHP/Node.js but I suspect only because that's what the author(s) know.

👍 1

The pathway overall is applicable to Clojure tho', except perhaps the framework sections.


@UNV5GQEJ1 a lot of the stuff on that roadmap is language-independent and is good to learn regardless of language. Clojure is a general purpose language.

👍 1

👍 to be harsher because @seancorfield is so nice...


this is a terrible and counter productive roadmap.


that optimizes you toward what somebody is selling to you rather than the problems you might want to solve.

💯 1

i started my career with a lot of this stuff but I work on infra engineering software now and haven't written a RESTful API in years, but that's because I serve the people who do.


and it's an unfair and not accessible representation of what a developer is by someone who wants to sell you something.


images like this present a view of the industry that is not accessible, or has false accessibility that grabs clicks but doesn't actually offer entry points.

Murshid Azher20:09:51

it is great to see different point of views on this matter, which lets me know this community is diverse in a good way.

Murshid Azher20:09:49

@U0CMVHBL2 I would place myself in the category of junior/ competent java developer and I would love to refer books than watch somebody else type it out for me, though I’m not particularly against it either.

Murshid Azher20:09:20

@seancorfield yes exactly, the roadmap is heavy on node/php, though most of it language-independent I believe Clojure is much more extensive than this.

Murshid Azher20:09:37

@gerred I agree with you 100% because you need to tread your path than following someone else opinion or views. But I also find the roadmap helpful for a complete Clojure novice like me, it’s like getting the overview of the Clojure community from the giant shoulder like you guys.

Murshid Azher20:09:09

Firstly, I would be able to see is this really for me from your past experiences and avoid treading on hyped technologies. Secondly, it gives a novice like me why should I use some of the technologies and when for example Reagent, reframe, red, figwheel, compojure, etc... Moreover, it would make people tryout different languages than being overwhelmed by the community buzzwords like how I’m currently am, coming from a different language community. A roadmap would make us (novice) compare and contrast the technologies we have previously experienced to the ones used in the current community. Finally, It would make language transition a bliss for a novice like me and to begin my adventure.


If you want a book on learning Clojure specifically, and are not against spending normal tech book prices for one, then either of Clojure Programming or Programming Clojure books are good choices, I think: . . Neither of those would be a complete roadmap to applying Clojure in a particular domain, but should give a solid foundation on Clojure itself.

👍 1

"I believe Clojure is much more extensive than this" -- well, any language is going to be "more extensive" than a shallow infographic like this so that's not really saying much.


Other than removing the framework sections from that backend roadmap, I don't know what would look different for Clojure vs other languages to be honest. Clojure is a general-purpose language and can be used for any backend stuff you need to build. Same with ClojureScript and frontend stuff (but I don't do any frontend stuff).


If you have specific questions about development with Clojure -- or any "community buzzwords" (no idea what you mean by that?) -- feel free to ask in #beginners and you'll get plenty of help.


"Living Clojure" and "Getting Clojure" are both excellent for learning the language. Andy's recommendation above are both solid too. If you want to compare some real world Clojure with things you've done before, "Clojure Applied" is a great follow-on from any of those.

Murshid Azher21:09:23

@seancorfield and @U0CMVHBL2 thank you so much for the recommendations, I’ll look into them. 👍


@me1243 the reason I say that is because what I've found is there's no specific answers, but that said, my Clojure these days is looking more and more like my Go, with state in different places between the two. I skip out on a lot of abstraction libs unless I really really need them and rely on clojure.core and other core libs.


my Clojure has become more robust, and the Go I have to continue writing and maintaining is becoming more and more robust.


and I try to stay at that abstraction level. i'll use @seancorfield's libraries, not an ORM, as a good example.


to finish up this convo since I have to start cooking. 🙂


@me1243 think less about FP and OOP, and more about "where are my side effects, and where do I have purity" in the sense that purity is input => output without those side effects, and drive as much purity as possible with side effects at the edges of your system.


and then FP and OOP really just kind of...go away, and if they don't, feel free to PM me.

😆 1


Alexander Heldt17:09:28

@gerred thanks so much for your input! (late answer because i ate 🙂 ) i’ll keep what you said in mind, it sounds super reasonable


no worries 😄


feel free to ask questions. there's plenty of FP topics


but there's a lot of it that is there core to "how do we make handling state nicer" and are deeper FP topics.

Alexander Heldt17:09:15

im going to try to rewrite some parts of a toy service i have (in go) to collect side-effects and state modifications to be in more designated areas, just to get a feel for that


awesome! I do mostly Go for day to day stuff since I'm working on Kubernetes (and re-writing core k8s libs in clojure right now), so happy to help you with that.

Alexander Heldt17:09:48

@gerred great! thanks for this very warm welcome 🙂 i will be happy to ask more questions when i have them

Manuel Odendahl18:09:54

hello! noob here, looking into clojurescript


Welcome @wesen! There's a #clojurescript channel in case you have technical questions you can't find answers to in this channel. You'll also find channel dedicated to various cljs build tooling like #shadow-cljs and #figwheel / #figwheel-main etc.

💯 1
Eric Ihli19:09:27

In Emacs I'm trying to connect to, evaluate forms to, and see output from an nREPL running in my terminal. I start the nREPL server with boot dev which I set up from boot dev results outputs nREPL server started on port 36299 on host - . I then type inf-clojure-connect in emacs and give it localhost and 36299. A new buffer appears but it remains empty. When I type in the new buffer and press enter, the message buffer reports "No prompt found or 'comint-prompt-regexp' not set properly." If I just hit C-c C-z the message buffer reports "Starting Clojure REPL via boot repl -C" and everything works fine. But that launches a new server. I want to connect to one that's already running.

Eric Ihli19:09:08

Hm. I see. That was quite obvious. I just needed to set the inf-clojure-cmd. (inf-clojure "boot repl -C -H localhost -p 36299") inf-clojure has all the code that handles the input/output.


@ericihli inferior mode needs a plain text repl to work with. CIDER is what you want to connect to an nREPL server.


Another option is to start a Socket REPL (and use inferior mode connected to that). You can use JVM options to have any process start a Socket REPL on a specified port.


Most people using Emacs use CIDER I think and use nREPL (I don't use either).


(at least I think you can connect inferior mode to a Socket REPL... I don't know for sure... thinking about it I suspect it would need a telnet or nc command...)


Inf-clojure works with socket repls, I'm pretty sure about that combination


I have recently used inf-clojure in Emacs to connect to socket REPLs of JVMs that I started in a terminal, for both Clojure REPLs and ClojureScript REPLs.

Eric Ihli19:09:17

Thanks. Interesting. Is my understanding correct? The "plain text repl" you're referring to would be Emacs sending keystrokes directly to STDIN of a process of printing from its STDOUT. A "socket repl" is a clojure two-process TCP server/REPL combination where the TCP STDIN just gets forwarded to the REPL stdin, etc... And an nREPL involves a client/server protocol of sending edn messages back and forth. Cider would be an nREPL client whereas inf-clojure doesn't know anything about that protocol.


If you start a JVM with Clojure, e.g. via the clj/clojure commands with the appropriate deps.edn file contents to start a socket REPL, or appropriate options on the command line, then connect to that socket REPL TCP port from Emacs inf-clojure, there is only one JVM process running, or at least there need not be two JVM processes.


If you start the JVM running the socket REPL via Leiningen, it might start one JVM process for Leiningen, and a separate JVM process for the one that runs your code and the socket REPL.


Is there a built in way to discover if a finite lazy-seq is fully realized? Calling realized? on a lazy-seq will return true if the head (or chunked 32) has been realized. But what if we want to answer the question is the finite lazy-seq fully realized? The follow up question: do we ever need to do the above? I’m thinking of realized? in terms of other deferred ops like futures/promises/delays that are ‘complete’ and cached when realized. If a lazy-seq is partially realized is that good enough?


I’d say that is not generally something you can know (unless you fully walk the seq yourself). Usually if it matters (or if you’re going to fully walk it), you shouldn’t be using lazy seqs


Thanks Alex that makes sense


Hi, I was surprised by this behavior by the >= operator in ClojureScript. I would have expected the last comparison of nil >= zero to be false like the other? (= nil 0) false (< nil 0) false (> nil 0) false (>= nil 0) true


@gis.jonor_clojurians for what it's worth, except for the = test those are all illegal in Clojure on the JVM but that's because Clojure delegates the comparisons to the host platform without checking for nil (so you get NPEs). It may be that ClojureScript just delegates to JS for those...?

💯 1

Ok, I did hope for consistency in comparing unknown with a value always returned false. There seems to be an implicit type cast to zero with >= but not with =, I don't know why.


Where = and >= differ, I would expect == to be the same as >= because = is general purpose and == and >= are number specific


Because those are number specific they tend to more closely match the host for performance, but = behaves differently because it needs to match how hashing is done for maps and sets

💯 1

Ok, thank you. I did not know there is an == operator in Cljs also, if you are not referring to Javascript.


Yes, I see there is one, I understand the difference better now, thanks.


It is a fairly subtile thing, I've been using clojure for a long time now, and I don't know that I have ever used == at work (granted I don't do a lot of number crunching)


Maybe I could swap my "not found" nil for a numerical unknown before further comparisons then (>= (or nil js/NaN) 0) 🙂


It would be better to test for that "not found" value explicitly and only do the numerical stuff if you have a real value.


(depending on what you want to do in the not found case)


(and v (some-function-of v)) or (some-> v (some-function-of)) might be good alternatives too.