Live data from Hacker News

Clojure, the Good Parts

rasterize.io

21–30 of 96 posts

Re: Clojure, the Good Parts

#21
post #9
post #4

Solid advice (I've been writing Clojure for the last 6 years or so and I agree with pretty much everything). I would like to add, however: * before you decide to use Component, take a look at Mount and see which one suits you better (I settled on mount for both Clojure and ClojureScript and I'm happy so far), * use Timbre: yes. Definitely. In fact, pretty much anything by Peter Taoussanis will be a good choice (for e…

We don't use Component in production, because it's way too heavy for us. Our web store uses Datomic, PayPal and Stripe, and a few AWS services, and none of these need to be started or stopped. But we do take a tip or two from stuartsierra's "Reloadable" work flow (which he based Component on), specifically that there should be no global state, and all dependencies should be passed into functions that need them as a p…

Isn't your use of an env as a parameter just another form of global state?

If not, can you elaborate?

Re: Clojure, the Good Parts

#23
post #15

Earlier quoted context omitted.

Haskell noob here. How is STM used in Haskell? What is type-driven STM? In Clojure, I don't recommend it because it's Just Another Place To Stick State. It's cool, but provides little semantic value over compare-and-set! on an atom.

Aren't atoms a part of STM in clojure?

Nah, you can't update two atoms and make sure they both change at the same time. That being said, 99% of the time you can have one atom, a map, with two keys, and that'll do it.

Re: Clojure, the Good Parts

#24

Pretty good list that I mostly agree with. I think the only point of contention I may have is with using timbre--having tried it in the past, I found it didn't do much that clojure.tools.logging couldn't do for most use-cases, and added configuration complexity while not sparing me the trouble of dealing with logback XML configs and whatnot--Java logging seems to rears its ugly head no matter what you do, especially…

https://www.google.com/search?q=ml+OR+haskell+jvm

I wish more people (could afford to) vote with their feet, as it were.

Re: Clojure, the Good Parts

#25

Pretty good list that I mostly agree with. I think the only point of contention I may have is with using timbre--having tried it in the past, I found it didn't do much that clojure.tools.logging couldn't do for most use-cases, and added configuration complexity while not sparing me the trouble of dealing with logback XML configs and whatnot--Java logging seems to rears its ugly head no matter what you do, especially…

[deleted]

Re: Clojure, the Good Parts

#26
post #9

Earlier quoted context omitted.

We don't use Component in production, because it's way too heavy for us. Our web store uses Datomic, PayPal and Stripe, and a few AWS services, and none of these need to be started or stopped. But we do take a tip or two from stuartsierra's "Reloadable" work flow (which he based Component on), specifically that there should be no global state, and all dependencies should be passed into functions that need them as a p…

Isn't your use of an env as a parameter just another form of global state? If not, can you elaborate?

Consider unit testing. With global state, it gets harder to keep things clean; requires more "resetting" type code.

Re: Clojure, the Good Parts

#27

Programmers should know their trade-offs. It's not so much that STM should be avoided, but that the use cases it was designed for don't often present themselves in production. Same with agents, core.async, metadata, etc. So I also get a bit twitchy when I hear for wholesale use of Timbre, Component, Schema. Every one of these libraries has tradeoffs. And those tradeoffs should be understood before adopting them. As a…

The sweeping recommendation on STM was especially hollow to me since the software I work on doesn't use a database at all.

Re: Clojure, the Good Parts

#28

Hm, I've used defs and bindings together inside macros to reduce redundant args like this function here: https://github.com/shriphani/clj-lmdb/blob/master/src/clj_lm... I think brevity is far more important than being explicit all the time. When we speak, we use a lot of context to infer what is said - no reason code shouldn't look like that.

The problem with that is that if `put!` or some other function is used inside `map` or some other lazy context, it may get realized outside the context of `with-read-txn`. Making `binding` part of your public API breaks referential transparency.

So what would you recommend that function look like? I think it is bad taste to say (with-read-txn db-name (put! db-name)) - no reason you should specify again what db you are dealing with.

Re: Clojure, the Good Parts

#29
post #15
post #10

It's sad to see that STM is not recommended. It is hugely important in Haskell. I jump to believe that this is an artifact of type-driven STM, but it may be something else instead. I've recently moved from Component to Mount. It is less powerful but just a vast syntactic overhead reduction. Absolutely avoid metadata. The worst thing ever is using it like how Reagent does in ClojureScript where it actually provides im…

Haskell noob here. How is STM used in Haskell? What is type-driven STM? In Clojure, I don't recommend it because it's Just Another Place To Stick State. It's cool, but provides little semantic value over compare-and-set! on an atom.

If you're using an atom, you're already sticking state in a place; the problem with atoms is choosing granularity. If one atom has everything in it, it will become a point of contention.

If your compare-and-set returns false, what do you do?

STM resolves these issues by letting you coordinate updates to more granular, finer-scoped refs

Re: Clojure, the Good Parts

#30

Programmers should know their trade-offs. It's not so much that STM should be avoided, but that the use cases it was designed for don't often present themselves in production. Same with agents, core.async, metadata, etc. So I also get a bit twitchy when I hear for wholesale use of Timbre, Component, Schema. Every one of these libraries has tradeoffs. And those tradeoffs should be understood before adopting them. As a…

The sweeping recommendation on STM was especially hollow to me since the software I work on doesn't use a database at all.

A lot of his points say to offload to services such as a database or queue. It makes sense that if all you are doing in your Clojure application is some simple business logic then you won't need the more sophisticated tools for concurrency and shared state, but if you were trying to write those services in the first place, or if you need higher performance so that sending everything over a socket to a database isn't realistic, then you may need them.
Post reply on HN