Live data from Hacker News

Try Clojure

tryclojure.org

171–180 of 404 posts

Re: Try Clojure

#171
post #79

Earlier quoted context omitted.

As a side note, I'm always amazed by people who can use a highly expressive language (Clojure, Rust, even TS) but switch to Go when they feel like it (especially pre-1.18). To me, switching to a less expressive language is painful and infuriating. I remember having to switch from Python to Java 5, and how everything started to take 3 to 5 times longer code to express. Maybe the key thing is to only write small things…

I write less boilerplate in Go than in Rust, about as much in Go (but of course different ;) as in Haskell).

That's cool! How do you manage? E.g. the `if err != nil { return err; }` stuff?

Re: Try Clojure

#172
post #118

I know many people will have problems with this post, but I am posting as information for clorjure-ophiles. Not reasons, but personal reasons why I don't do Clojure and will not try it. 1. When I read about Clojure (repeatedly) I like it. I am especially interested in transducers. I even built a half baked transducer engine in JavaScript using generators. There is clearly something here of value here. Any system that…

Running on the JVM is one of the best things about Clojure. The JVM is an impressive piece of engineering where uncounted bajillions of man-hours were invested into making a good and performant VM with modern GC. I've been using Clojure heavily for the last 9 years or so and I can't see any reasons to dislike the JVM. Also, I barely ever touch any Java. You don't need to.

And if you do need to touch Java for reasons Clojure doesn’t impose, the interoperability story is really good.

I’ve done this with internal libraries - it’s easy to get them pulled into a Clojure code base, wrap them in such a way that the ergonomics of the rest of your code aren’t ruined, and still treat them as a first class citizen for stuff like your build system, artifact stores, etc.

Re: Try Clojure

#173

> unlike full-JVM Clojure it has a very fast startup time I can't believe that after all these years Java still didn't fix their startup time.

I think, in a lot of cases when people still complain about "the slow startup time of the JVM", they're really just talking about how the big JVM GUI apps (like IDEs) struggle to get started on heavily-loaded systems. And this, I think, is mostly just due to these apps eagerly reloading the most recent workspace on startup, and so pre-allocating big chunks of memory on startup to be ready for that — which can ripple out, on systems with low free memory, as other, colder processes all bottlenecking together on the IO of having their own memory written out to swap; and/or to having dirty mmaped pages forcibly-flushed to disk en masse so that the page-cache entries they live in can be purged.

Much more rarely — mostly when talking about writing CLI tools in a JVM language — people actually are complaining about the single second-or-so it takes the JVM to start up. (Usually because they want to run this tool in a loop under xargs(1) or find(1) or something.)

This last second of startup lag is (AFAIK) quite hard to improve, as it's mostly not the JVM itself starting up, but the static methods of JVM classes being called as those classes are loaded — which can do arbitrarily much stuff before any of your own code gets control. (Due to legacy code expecting to read certain per-boot-dynamic info as static fields rather than as the results of static method calls, I believe the JRE runtime is actually required to do quite a lot of that kind of static initialization, to pre-populate all those static fields, just in case something wants to read them.)

---

You'd think that GraalVM could inherently skip most of this, because the Graal compiler does dead-code analysis. "If nothing in your code reads one of those static fields, then nothing needs to write that field, so let's not invoke the static initializer for that field." But that's not true: static initializers are exported and called by the runtime — so they're always "alive" from the compiler's perspective. The Graal compiler isn't doing full-bore data-flow analysis to determine which static members of which classes are ever read from.

I believe GraalVM does try to work around static initializers as much as it can, by pre-evaluating and snapshotting as much of JVM runtime's static initializer code as possible by default, converting it all into const data structures embedded in the class files before the native codegen step gets run on it (see: https://www.graalvm.org/latest/reference-manual/native-image...).

It's not possible to apply this pre-baking to 100% of classes, sadly — some of these data structures need environment data like env-vars or system network config threaded into them on boot.

(I wonder anyone on the Graal project is working on a fully-general static-initializer optimization pass, that does something like concolic execution to bake these initializers out into either fullly-constant data if possible, or if not, then constant "data templates" plus trivial initializer functions that just gather up the few at-boot context fragments, shove them into the "data template" using a low-level hook, and then memcpy the result out onto the heap and call it an object.)

Re: Try Clojure

#174
So here's something which I, as a Lisper, don't understand: Clojure has syntax for hash tables (the curly braces), why doesn't it use those for let-bindings, instead choosing to use vector syntax? (Of course I prefer standard Lisp syntax which can easily be extended for multiple-value and destructuring bindings:

  (let ((a 1)
        ((b c) (list 2 3))
        (d e (values 4 5)))
    `#(,a ,b ,c ,d ,e))
  ;; => #(1 2 3 4 5)

Re: Try Clojure

#175
post #22

Earlier quoted context omitted.

In my experience, the subsets of the community around clojure were one of the biggest problem with it. It's gotten better over the years, but circa 2016 - 2018 it had a spike in popularity despite being very hostile to newcomers. There was an almost apologist attitude towards rough edges or failure modes folks new to the community would fall into. I managed to work with it for a time despite that, but it left me with…

A somewhat similar thing I ran into is that existing Clojure code can be incredibly difficult to grok if you don't already know the language very well. Some of this comes from lisp's minimalist syntax, which makes it hard to even know what kind of thing you're looking at when you're encountering a new thing for the first time. But the problem is also compounded by some of Clojure's more distinctive (and powerful) fea…

If I can get clojure storm running in my project then I find a lot of code incredibly straightforward

Because there's a preference for just passing immutable data around the time travel debugger really helps me understand complex interactions

Re: Try Clojure

#176
post #149

Earlier quoted context omitted.

This is of course a popular opinion and pretty much the C++ philosophy. Unfortunately a lot of the benefits of functional programming cannot be fully realised unless you are "all in". The paper "The Curse of the Excluded Middle" is somewhat blunt but it makes some good points: https://queue.acm.org/detail.cfm?id=2611829

>a lot of the benefits cannot be fully realized unless you’re all in That is working under the assumption that “the benefits” are actual benefits. IMO, “the benefits” are measurably drawbacks, and not a technical debt I am willing to accept for no good reason.

Functional programming is basically maths, it solves the problem of how to compose software safely. I struggle to understand why anyone who really cares about their craft would not want this. In fact, many want it so badly they are willing to make sacrifices for it (performance, esoteric languages).

Re: Try Clojure

#177

Earlier quoted context omitted.

When you get into REPL-driven development, the JVM startup time (which is often under a second for me anyways) is a total non-issue. You don't continuously restart your program to see changes or run tests. You can refresh all your state instantly without exiting. But before Babashka, that was indeed a barrier to using Clojure in shell scripts. Now we have it all!

In Unix it is customary to invoke tools from the Bash shell or Bash scripts. That doesn't mix well with a separate REPL.

I see your point here... I was addressing to the feedback loop during development time. Babashka works well for Clojure in a Unix tool pipeline.

It's also possible to compile your JVM Clojure program yourself to a binary with GraalVM for even better performance than Babashka and even faster startup.

Re: Try Clojure

#178

I have to admit, several years ago, a colleague of mine advised me if not to try Clojure but at least to read the "History of Clojure": https://dl.acm.org/doi/pdf/10.1145/3386321 , which I never did. But one day I decided to watch Rich Hickey - Greatest Hits https://changelog.com/posts/rich-hickeys-greatest-hits ... I then read the "History of Clojure", and then jumped into learning it. This is probably one of the mo…

I got what you described by learning Common Lisp just a few months ago. Do you think learning Clojure would get me something in addition to that or is it roughly the same?

Depends on your style of programming CL. Clojure is immutable by default with a heavy emphasis on concurrency and strong ties to the JVM as its host environment. The differences you’ll find mostly lie in those areas.

Re: Try Clojure

#179
post #174

So here's something which I, as a Lisper, don't understand: Clojure has syntax for hash tables (the curly braces), why doesn't it use those for let-bindings, instead choosing to use vector syntax? (Of course I prefer standard Lisp syntax which can easily be extended for multiple-value and destructuring bindings: (let ((a 1) ((b c) (list 2 3)) (d e (values 4 5))) `#(,a ,b ,c ,d ,e)) ;; => #(1 2 3 4 5)

Maps are unordered, but let bindings are sequential so order matters.

Re: Try Clojure

#180
i wish it was easy to make android apps with clojure. not sure if itd be easier with jetpack compose + clojure or react native + clojurescript.
Post reply on HN