Live data from Hacker News

Clojure: A Lisp that wants to spread

simongray.github.io

241–250 of 306 posts

Re: Clojure: A Lisp that wants to spread

#241

I don’t actually get the big deal about enforced immutability. Of course, you need to constrain yourself in certain circumstances to do things immutably, but it seems like something that should be contextual (immutably ...), rather than enforcing it. In fact, sometimes it is necessary in high performance multi—threaded/multi-processor environments to use side effects judiciously. Moreover, most serious lisp programme…

You CAN create mutable data structures. This can be very useful LOCALLY. But then turn it into an immutable data structure as soon as you return it.

Example: a sieve function for primes. Pass it a range of n1 to n2. It seives that range, say from (1 million) to (1 million plus 100,000). It could use an efficient mutable data structure locally. Then return an immutable result. Especially since the result has no reason to EVER be mutable again. You're not going to find more or less primes within that range.

Re: Clojure: A Lisp that wants to spread

#242

I don’t actually get the big deal about enforced immutability. Of course, you need to constrain yourself in certain circumstances to do things immutably, but it seems like something that should be contextual (immutably ...), rather than enforcing it. In fact, sometimes it is necessary in high performance multi—threaded/multi-processor environments to use side effects judiciously. Moreover, most serious lisp programme…

It's not just about immutability. it's about the fact that you can do mutations producing a cheap copy of the data structure.

If I have an array of ten million numbers. I can alter one of those array elements, getting back a new immutable array with the modification. And fast. Yet the original array still remains without the modification. How the implementation magic works is not a concern when thinking about the abstraction. But you can read how the magic works and like any magicians trick, you end up saying "oh, so that's how it's done".

So you can modify one array element and get the performance (extremely close) to how you expect a single array element modification to perform. You the original copy of the entire array also remains if some other code has a copy of it.

Imagine a recursive algorithm searching a game board with different move possibilities. Apply a move to a board and get a new game board. Yet the original game board remains unaltered. And you didn't have to implement any magic in your search algorithm. No copying of the entire game board. You just get your new game board with the new move applied so that your recursive function can proceed.

Re: Clojure: A Lisp that wants to spread

#243
post #27

I tried Clojure but ended up hating it for reasons all stemming from its hosted implementation. Whenever I didn't know how to do something, I (and most other Clojure users) would go use some JDK class (or worse, an external Java library) instead of figuring out how to write the Lisp. For some reason this doesn't often happen with regular Lisp even though CFFI is available. There's a tendency to just reimplement it di…

While I am an experienced Java developer, and took immediately to clojure, I don't think you deserved to be downvoted for expressing that experience.

I can imagine if I were to learn a new lisp, that was hosted on a language I did not know, and various difficult things leaked through the abstraction making it more difficult for me to work. I might feel similarly.

Re: Clojure: A Lisp that wants to spread

#244
post #128

Earlier quoted context omitted.

You're aware that it's possible to write bad code in any language, even Clojure, right?

Totally agree, functional programming, and certainly the kind of programming you do with clojure, can get just as messy and far away from your goals as object oriented code. Clear, organized, well-architected code, in any language, is the skill that takes a long time to develop. I do not personally find clojure makes this any easier than in any language.

> I do not personally find clojure makes this any easier than in any language.

Surprisingly, it does for me. After using many different languages, I find myself more productive in Clojure than in any other language I have used before. Every language I used before Clojure left a dent in my mental ability to appreciate what I do. It's not a single favorite PL of mine, but most other programming languages make me feel bored and not interested after a year or so of using them. They have so many inconsistencies and quirks that you slowly succumb to the inevitable - you become a hostage. Your language of choice becomes your mental prison. Your hobby becomes this thing where you dig up yet some another poorly documented inconsistency and brag about it to your colleagues and friends. You become an expert from burning too often and too much. The language becomes your identity because you've seen too many ugly parts of it.

You have no idea how many times I had to fight my anxiety and depression and seriously thought about leaving the field for good.

Learning Clojure has liberated me; it allowed me to maintain focus and put in use all the good things and patterns I learned over the years. In other languages, sometimes you have to bend over backwards to create something clean. Sometimes you have to build this colossal cathedral that requires enormous scaffolding just to hold its own weight, and you can't even remove the scaffolding, and you call that "an elegant solution."

Re: Clojure: A Lisp that wants to spread

#245
post #180

Earlier quoted context omitted.

Static types are the new religion, like OOP was in the 90s. Types solve 2% of programming errors. They lead to coupling for the sake of the compiler, and make code harder to change, harder to write, and often needlessly constrain the utility of the code where they're applied. But they do make the IDE code-completion go, so there's that.

Can you reference "Types solve 2% of programming errors"? I've read numerous research papers and blogs on this topic and have never seen anything as low as 2%. Edit: Googled and nope, can't find anything.

Here are some which look at GitHub for various languages and count the defect rates by analysing commit messages:

https://dev.to/danlebrero/the-broken-promise-of-static-typin...

https://www.i-programmer.info/news/98-languages/11184-which-...

https://nextjournal.com/PRL-PRG/toplas-analysis

One thing to note is that the absolute difference in terms of bugs from the worst language to the best is still minimal. So language choice doesn't seem to make or break software.

Another thing to note is that while overall static languages faired better in terms of having lower defects, Clojure did best of all.

I knew of another one but can't find it again.

Then there are a few where they had beginner programmers implement trivial programs in different programming language and checked how many errors/time it took them. But I consider those all pretty bad since the experiments are so reductionist. So I won't list them. They aren't conclusive either. Some end up saying static and dynamic are same, some say dynamic is more productive at equal defect, and some say static had less defects at equal productivity.

Re: Clojure: A Lisp that wants to spread

#246
post #88

Earlier quoted context omitted.

> sometimes it is necessary in high performance multi—threaded/multi-processor environments to use side effects judiciously The short answer is: Clojure (and other languages/frameworks that emphasize immutability) is not intended for those use-cases. The long answer is, Clojure added something called "transient data structures" as a trap-door for cases where you really absolutely need mutability for performance: http…

I haven’t really thought this through, but at the OS level we used to have the concept of reentrancy, which separated code from variables for multi-tasking. I haven’t seen this exact concept in a programming language level, although I don’t know every language, and it may exist by another name. I didn’t really think about this until now, but I naturally write reentrantly, separating the hash tables and globals For cr…

I think the idiom in Clojure is for threads to be functional, so they aren't running persistently and mutating shared state: they spin off to do nonblocking work and then return their result. While doing so they share memory so as to avoid serialization/cloning overhead, but that shared memory is an immutable data structure, so you don't really have to worry about race conditions because threads can't step on each other's toes.

Re: Clojure: A Lisp that wants to spread

#247
post #26

Startup time isn't what is holding the language back. In my opinion it's: 1. Tooling. You end up spending way more time getting your tooling setup than it should be. 2. Difficulty in learning. 3. Clear best practices and frameworks. The philosophy of composing libraries is extremely powerful, but to gain broader adoption you still need straight forward frameworks and opinionated best practices. The last point has man…

Yes, this. Tooling. If you want to get started, Clojurists will insist you learn emacs. After all it's so great you must learn it. Now I have nothing against emacs. But I don't expect to have to invest significant effort to learn a specific editor in order to use a programming language. No other programming language has this requirement. I was surprised at how many Clojure users took this as an attack upon emacs. It…

I don't think this is accurate today - while Emacs is still dominant, there are other options with growing support, and a growing recognition that foisting Emacs upon newcomers is not ideal

Re: Clojure: A Lisp that wants to spread

#248

Earlier quoted context omitted.

If you tried Clojure a few years ago, the Tooling could be a problem. But now, the tools-deps(official Clojure cli) is awesome.

How do you find it compares to Leiningen? I'm using lein for all of my side projects (and shadow-cljs) and I like it. What does tools-deps offer me?

Better dependency resolution is one highlight - Alex Miller presented on conj on this and some other pieces at the recent conj conference: https://youtu.be/7CM7Ef-dPWQ

Re: Clojure: A Lisp that wants to spread

#249
post #229
post #227

Earlier quoted context omitted.

You are making unfair and uninformed assumptions about me, someone you do not know. I've worked professionally as a full-time Clojure developer for many, many years. > you have no ability to apply the quote at all. You don't know what my abilities are.

show you github or blog, Time is not ability.

Your github is full of text and cloned repos... and you refused my earlier suggestion of sharing practical examples of your Tao, so it seems strange that you are so quick to demand proof of competency through code just to discuss with you.

Re: Clojure: A Lisp that wants to spread

#250

Earlier quoted context omitted.

> Much of the client-side code is about manipulating the DOM. Such code must assume the DOM-API exists. So such code can not run on the server unless there is some kind of ducky DOM environment there as well. And since client-side relies much on destructively manipulating the DOM, how can such code be tested on the immutable clojure server? The same way as it's done in React. Think of a client app as a loop reacting…

> Think of a client app as a loop reacting to user /network events and turning state into html. Then who, which part of the code, inserts that HTML into the DOM? Is that done by user-code or some library (when using Clojure)?

There is a library called reagent which is a wrapper for React, check it out: https://reagent-project.github.io/

It uses a the same data format as hiccup template library which can be used on server side - https://github.com/weavejester/hiccup

That's why the same code can be used on client and server. The simplicity of the process (uses pure functions to turn immutable data structures to html) means that it can be also easily unit tested.

Post reply on HN