Fork me on GitHub

@cddr: Is that not generally true for all tail-recursive operations? In other words, if you’re mapping across a seq, then recuring for every item in the seq, then you don’t have enough data to pop the previous frame. You need to keep ahold of the rest of the seq to finish your operation.


Or am I missing something?


The point being, you have to rearrange the algorithm so that all state is transferred in order to allow the previous frame to pop.


sooo, I just got burned by using the wrong key in a map passed to a library function


how are magic keys in maps not place-oriented programming?


e.g. (some-lib/api-fun {:url “”}), if you type :uri instead of :url, you get to chase a nil error


maybe I’m overbroadly interpreting place-oriented programming, but magic keys still seem o_O


I just wrote a post called "Decomplecting Clojure" trying to understand/explain what Clojure is about. Any feedback is welcomed!


@cfleming: this is the reason I sent you emails about debugging in the JVM.


@bensu: Nice! I’ve skimmed it over, I’ll read it more carefully tomorrow.


One thing you could mention in the sexp section - I think you’re right that paren phobia is generally a totally overrated problem, but I think prefix notation is something that a lot of people (including me) never really get used to.


@therealadam: The only solution I’ve seen to that sort of problem is some sort of type system. The problem is less about “this data is stored here” and more about “this data is accessed in this way”. PLOP is about twiddling bits of memory/storage directly, which doesn’t happen with regular old immutable values.


where “this data is stored here” == “this data is stored in this place in memory"


@cfleming: thanks, maybe add a bit about`->` helping overcome it.


Or another way to think about “this data is accessed in this way” is “this data is shaped this way”.


@bensu: Yeah, that would be good - -> and ->> are generally marvellous


@bensu: I don’t know about others, but I find comparisons particularly painful. Every single time I use < > <= >= and friends, I literally imagine the operator between the operands to see which way they need to go.


@bensu: great read, thumbs up


@mmz thanks!


@cfleming: agreed. I usually end up framing it like so: (< val1 val2) or (<= val1 val2) so that I can read it as “increases from left to right"


@cfleming: agreed! comparisons are specially hard with prefix


But I guess you can as easily read it as “decreases from left to right”… so, I guess the gist is it describes the comparables in order from left to right.


@potetm: Interesting - I find that the only thing that works for me is to imagine it in infix form, I’ve tried various other heuristics but nothing else helps much. The same should be true of division and subtraction but isn’t for some reason.


But yeah. Definitely one of the hardest things to take from infix to prefix.


Yeah it’s funny, I pretty much have to do:

(/ num
in order to see the division right.


Subtraction is not an issue for me either.


But yeah, it can be confusing. Especially with those handful of functions. Even for a veteran.


@bensu: +100 to your post. I would have saved a couple months when I started with clojure if something like that were available


@bensu: one minor thing: "taking a part a system" should be "taking a system apart"? Another (not so) minor thing: In the section about immutability you talk about the STM as the only interface to mutability. I think that's not true, for example atoms do not participate in the STM and they are closer to direct mutation. It's just that they are synchronized


@bensu: It might be a nice addition to that section if you touch on clojure supporting different models when in need of mutability. I found one answer by Arthur Ulfeldt that very succintly shows the different combinations of coordinated/uncoordinated, sync/async and thread locals with shared default value:


@bensu: But again, apart from that, I found the post super awesome!


@nberger: thanks for the feedback. you are right, atoms are not the only interface to mutability, but they are part of ATM. I'll correct my choice of words to reflect that. I don't want to be comprehensive but to convey the big picture, which is "a sane model for state management and concurrency"


@nberger: the 2x2 matrix in the SO is very good


@bensu from I read "they ensure that all actions on Refs are atomic, consistent, and isolated. Atomic means that every change to Refs made within a transaction occurs or none do". Atoms do not have the " rollback feature". Only refs have that, participating in a STM transaction


@bensu atom updates via swap! and reset! atomic, but they are not coordinated


@bensu you are right in giving a summarized view there. It's just that STM it's not the most used mutability model, it's awesome, but at the same time it's harder to understand than atoms


@nberger: after reading that again, you might be right! I always thought that atoms and agents fell under STM, but from careful reading of /refs it seems like it is not the case.


@bensu cool. To be honest, I had to check and that SO answer before giving my feedback. So we are two at least :). The thing is that STM is not really very frequently used IMO


As we are here, it would be great if anyone can point to STM usages in open source projects


@nberger: I ended up removing all reference to STM, leaving the concept that Clojure has opinions on state management


Cool, nothing to say now except keep up with the good writing. And thanks for the example.