Live data from Hacker News

Clojure, the Good Parts

rasterize.io

61–70 of 96 posts

Re: Clojure, the Good Parts

#62

Why Clojure instead of Racket (or even Common Lisp)? Is it because of Java interop?

Sometimes it's for Java/Javascript interop or access to the large variety of libs in those languages, but other possible reasons you might pick Clojure instead of another Lisp are:

1. immutable by default 2. strong focus on concurrency/parallelism 3. well-thought-out design of core library (one of the most cohesive I've ever seen) 4. largest single Lisp community (just going by GitHub, Clojure has ~18k repos, CL has 10k, Racket has 5.5k, Scheme has 7.5k) 5. unified syntactic sugar for common data structures like maps/arrays

The above are just factors that distinguish it from other Lisp-based languages. If you're coming from Java/C/C++/Ruby/Python/PHP/etc, there's way more reasons than that.

Re: Clojure, the Good Parts

#63
post #43

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

If you're just looking for a starter kit with everything included, consider Luminus. It gather a bunch of libs together and shows you how they interoperate to handle web requests.

Re: Clojure, the Good Parts

#64
post #8

I don't agree on a few points. Global atoms provide a good way to confine state into a single place. In my applications they serve as a in-memory database while everything persistent is written to disk in the form of a log (kafka, file append, you name it). Agents provide a good way to serialise events akin to a transactor. Not every problem requires the parallelism or the concurrency gained by smearing it out into a…

> Global atoms provide a good way to confine state into a single place.

I think it's simpler to pass state as an argument to your functions instead. That's less complex and easier to test.

> Last but not least, transducers make it onto my list of things to avoid... They are incredibly complex, even brought the spawn of the devil, volatile, into the language. Just for a bit of speedup and core.async integration.

Transducers are not just for performance and core.async. They're a hugely useful tool that allows the various collection functions to be applied to sources that are not easily seq-able.

For instance, say I have some source of events, and I can register a callback to receive events. With transducers I can still use all the standard collection functions, even though there isn't an obvious collection to use them on.

Re: Clojure, the Good Parts

#65

Why Clojure instead of Racket (or even Common Lisp)? Is it because of Java interop?

Besides the excellent reasons 'KingMob provided, I'd add that it's easier to sneak it into a Java project bottom-up.

I wonder why Clojure vs. ABCL (Common Lisp on JVM) though.

Re: Clojure, the Good Parts

#66
It would be great if the author of the post expounded on the good libraries to use. In the couple of false starts I have had with clojure I spent most of my time evaluating libraries instead of writing code.

Also: Seeing what clojure considers bad parts makes me laugh since I spend most of my day writing python and javascript.

More language orthogonality more problems I guess..

Re: Clojure, the Good Parts

#67
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?

no, they're just data being passed in. at least thats what it sounds like to me.

obviously this data has ways to manipulate the world, because an app that did nothing would be pointless. but it's no different than any other param.

what would be bad, which is pretty much the opposite of this situation, is if you had global resources that werent passed in as params and caused side affects and you had to access a global variable to get to it (because it wasn't passed in).

Re: Clojure, the Good Parts

#68
post #8

I don't agree on a few points. Global atoms provide a good way to confine state into a single place. In my applications they serve as a in-memory database while everything persistent is written to disk in the form of a log (kafka, file append, you name it). Agents provide a good way to serialise events akin to a transactor. Not every problem requires the parallelism or the concurrency gained by smearing it out into a…

What's so complex about transducers? (let [my-xf (comp (filter even?) (map inc))] (sequence my-xf [1 2 3 4 5])) => (3 5)

Re: Clojure, the Good Parts

#69

Use raw Java concurrency instead. Back to square one.

Um, not really.

The main feature that Clojure provides for concurrency is immutability, not just the possibility of using existing data structures in an immutable manner, but an entire suite of immutable data types and data structures. This makes concurrency, even using Java's primitives, like Thread, (which was the original way Clojure was intended to be used anyway,) with Clojure's data structures is a win over using Java's if you want safe, predictable behaviour in a concurrent program.

Post reply on HN