Live data from Hacker News

Clojure, the Good Parts

rasterize.io

51–60 of 96 posts

Re: Clojure, the Good Parts

#52
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…

Difficult? I have a few lines in a namespace that grabs `git describe --tags` and a few other things and places them in a json file. This is served up internally by all http-speaking applications as `GET /_internal/build-info`.

https://gist.github.com/emidln/8f5993a37ff300e36897debe9c5bf...

Re: Clojure, the Good Parts

#53

Earlier quoted context omitted.

There's plenty of reason: you can put any code you like inside of `with-read-txn`, including closures that are evaluated lazily. If you dislike the duplication, create a syntactic form that allows less, like this: (transaction-> db-name (put! ...) ...) This doesn't lend itself to every kind of action, but it is narrower. Alternately, create a variadic version of `put!` which guarantees eager evaluation inside of a tr…

Ok I see your point. I am curious how that would happen though - essentially you'll need to bind the txn to a different transaction from the one intended and the whole thing locks up. I am curious how to guarantee eager evaluation - dorun, doall and run! are all sequence-oriented right?

It's not that hard to imagine: map a `get` over a series of keys inside a transaction, return that lazy sequence, and use the results to do another series of operations within a different transaction.

Libraries typically can't guarantee eager evaluation, since that's a property of the top-level execution. That's why libraries shouldn't use `binding`.

Re: Clojure, the Good Parts

#54
post #43

Any recommendations for routing / handling web requests? The article doesn't mention anything in this category.

Compojure is pretty standard for routing on top of the simple Ring abstraction.

I start projects with the template:

    lein new compojure my-app
Ring quickstart: https://github.com/ring-clojure/ring/wiki

Ring API docs: http://ring-clojure.github.io/ring/

Re: Clojure, the Good Parts

#55

Earlier quoted context omitted.

Aren't atoms a part of STM in clojure?

Nope, atoms are based on simple CAS (Compare And Swap) operation that replaces the reference value. They are pretty much a sugar around AtomicReference in Java (in case of JVM implementation of course). It is pretty much as like this 1. Dereference a variable and keep the old reference. 2. Create a new modified variable. 3. Use CAS on old reference and new variable to update the reference to point to the new vairable…

Interesting. I've never needed anything other than the occasional atom.

Re: Clojure, the Good Parts

#56
I like the write-up, but I disagree with the reasoning to avoid STM. It sounds a lot like "avoid ConcurrentHashMap in Java". It's true that web applications mostly persist their data in a database or some other persistent structure, and obviously an STM or a ConcurrentHashMap would not do you any good for that. However; if you are working with in-memory data, then STM is a very valuable tool just like ConcurrenthHashMap is.

Re: Clojure, the Good Parts

#57

Earlier quoted context omitted.

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…

This really only makes sense for service-oriented software. Not all uses of clojure attempt to saturate use of available resources, and here STM is a win.

But the OP implicitly assumed everyone was writing "production" software, assumably as part of a commercial service offering.

Re: Clojure, the Good Parts

#58

Earlier quoted context omitted.

Ok I see your point. I am curious how that would happen though - essentially you'll need to bind the txn to a different transaction from the one intended and the whole thing locks up. I am curious how to guarantee eager evaluation - dorun, doall and run! are all sequence-oriented right?

It's not that hard to imagine: map a `get` over a series of keys inside a transaction, return that lazy sequence, and use the results to do another series of operations within a different transaction. Libraries typically can't guarantee eager evaluation, since that's a property of the top-level execution. That's why libraries shouldn't use `binding`.

Wow I am not sure how I missed that - thanks for pointing it out. The (transaction-> ###) pattern looks a lot nicer to me. Really appreciate the help.

Re: Clojure, the Good Parts

#60

Earlier quoted context omitted.

Ok I see your point. I am curious how that would happen though - essentially you'll need to bind the txn to a different transaction from the one intended and the whole thing locks up. I am curious how to guarantee eager evaluation - dorun, doall and run! are all sequence-oriented right?

It's not that hard to imagine: map a `get` over a series of keys inside a transaction, return that lazy sequence, and use the results to do another series of operations within a different transaction. Libraries typically can't guarantee eager evaluation, since that's a property of the top-level execution. That's why libraries shouldn't use `binding`.

Funnily enough, I think I picked up this habit from Korma source: https://github.com/korma/Korma/blob/master/src/korma/db.clj#...
Post reply on HN