Live data from Hacker News

Clojure: A Lisp that wants to spread

simongray.github.io

141–150 of 306 posts

Re: Clojure: A Lisp that wants to spread

#141
post #23

Earlier quoted context omitted.

I do apologise. This was written mostly as a stream of consciousness, only stopping to google the github repos.

Thank you. Also, "referential transparency" doesn't mean what some FP people think it means [1]. Even though no language with macros is referentially transparent [2], Clojure, like all Lisps, is a poster child of referential opacity (opaqueness?), deriving much of its power from it. If you can quote code terms, you can't possibly be transparent with respect to reference (denotation). Saying "pure" or "without side-ef…

Could you elaborate on the part on "no language with macros is referentially transparent", specifically, do you mean that if macros can do IO, then the transparency isn't there anymore?

Re: Clojure: A Lisp that wants to spread

#142
post #2

Thats last few sentences make no sense. The argument is that uptake is stunted by the JVM's slow startup time, making it unsuitable for commandline utils or desktop apps. However thats easily fixed which was never more hillariously stated than when Rich Hickey did it a decade ago. A blogpost went viral and it was a thunderous critique of Clojure, focused on this single point of slow start up. In the comment section w…

Uhm.. I want to give the benefit of the doubt, but frankly this seems deceptive, or at least out of date, unless I'm totally missing something. Why is there no magical --client / --script option for the Clojure ClI to make startup faster, if this is such an easy solution? Also, you show system time, but the time to load dependencies is in user time, which is slow by the nature of Clojure. Example: $ time java -client…

As mentioned in other comments, the -client option is ignored on 64 bit JVMs, so it has no practical effect. Giving the benefit of doubt, Rich Hickey must have been using a 32 bit JVM.

Re: Clojure: A Lisp that wants to spread

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

Instead of just measuring how many developers adopt Clojure and how difficult/easy that is, I'd also love a measure of how many developers Clojure "puts out of business". IME Clojure is quite aggressive on that front.

In 2017 a customer wanted a set of services written in Clojure. Based on their Java experience they wanted to hire 10 devs. When I arrived they had 4, over the 1.5-year period I was there, they hired and fired 4. When I left they had 3. All 3 were not experienced in Clojure prior to the project (Java), but by 2018 each knew the entire codebase and was able to modify it and able to step in for each other. They spent less than half of their budget and all goals were met ahead of schedule.

IME learning how to put Clojure and its ecosystem in good use takes more time and effort than other languages, but its effectiveness really compensates.

Re: Clojure: A Lisp that wants to spread

#144

Earlier quoted context omitted.

I can attest that full stack (server-browser) Clojure code sharing works very-very smoothly. I've been developing web applications like that for some time now, and apart from less context swithing (because it's the same language on both sides), sizeable parts of the code are cross-compiled to run both on the browser and the JVM with very little or no extra effort. Example 1: I'm using Clojure's Spec library for valid…

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? > sizeable parts of the code are cross-compiled to run both on the browser But…

> 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 to user /network events and turning state into html. The same way it's done on server.

Re: Clojure: A Lisp that wants to spread

#146
I shifted to writing Clojure full time in November 2017 and feel that I've improved greatly as a developer.

Other languages taught me how to solve problems their way, Clojure taught me how to solve problems.

My biggest hurdle while getting started was lack of Newbie friendly resources. And the language is kinda scary at first, specially if you are like me and have spent 5 years working with Python or JS.

Dr. Fynmann said that if you want to get better at something, teach it.

Following his advice I've published multiple articles [1][2][3][4] and given a talk about Clojure at a js conf [5].

The tooling is steadily improving. I don't think it will be as widespread as JS but I doubt if it aims to be. Clojure seems to attract a certain kind of developers anyways.

---

[1] What I learned after writing Clojure for 424 days, straight https://krimlabs.com/blog/clojure-424-days

Learn Clojure by building a drug dealer api [2] https://krimlabs.com/blog/clojure-drug-dealer-part-1 [3] https://krimlabs.com/blog/clojure-drug-dealer-part-2 [4] https://krimlabs.com/blog/clojure-drug-dealer-part-3

[5] If you are going to transpile JS, why not use ClojureScript? https://www.youtube.com/watch?v=Bs44qdAX5yo

Re: Clojure: A Lisp that wants to spread

#147

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.

> Types solve 2% ....... Vastly understated in my experience. Even trivial python programs contain errors that could be prevented with a trivial type system like Go's And performance. Not being fast enough is a bug. Consuming much more energy is a bug, in my book. Sufficiently expressive type systems are better than dynamic typing. They prevent so many errors, especially in FP-inspired high level data transformation…

FYI: Clojure has types for performance, but not for static checking. They're called type hints: https://clojure.org/reference/java_interop#typehints

Re: Clojure: A Lisp that wants to spread

#148

Earlier quoted context omitted.

I think you are omitting the main reason why Clojure never succeeded: it's dynamically typed at the core. It's on the wrong side of history in that respect. I know it's trying very hard to catch up to statically typed languages now by retrofitting some type system, but it's too little, too late. Static types are where the current state of the art is, and we're not going back. Clojure missed that train and will never…

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.

My experience is the opposite. Types make code much easier to refactor, in fact almost effortlessly so and with a certain confidence the code won't be hopelessly broken afterwards.

They also make code easier to reason about since the coupling that exists because of types is the result of an explicit and thoughtful decision on the part of the author. You don't as often get into situations where the code appears to work based on superficial similarity of data, only to find out there is some deep difference which prevents it from ever working.

It's also the truth that the more expressive the type system is, the less coupling you are required to do. For instance, if the language supports type classes (traits), you can codify the fact that a part of the system requires not data of a particular type, but of any type supporting some set of operations. This is the very thing you imply is lost when coming from dynamic types, only this time it's tool-backed and not merely accidental.

Re: Clojure: A Lisp that wants to spread

#150

Earlier quoted context omitted.

Yeah, sometimes I look at some Typescript or Scala code and feel like I don't even understand what the heck they are trying to build anymore. Very often it feels like they're "elegantly" trying to solve some made-up, bullshit problems for some questionable gain. Feels like bureaucracy for the sake of bureaucracy. Totally like OOP shit that we're still trying to make sense of, like: public abstract class Ellipse2D ext…

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

This has been something I've been trying to answer and can't arrive at a conclusion.

I can't tell if I happen to have lucked out for the first time ever working with really good engineers, and that's why the Clojure code bases I currently work on are overall better. Or if it has anything to do with Clojure itself.

From my prior work experience: Scala, Java, C#, JavaScript, ActionScript 3, C++; the code bases were always kind of crap. Everything was always called "legacy code", even if it was something that we had built just the year before.

Similarly, in the open source, or even language core, things were always deprecating one after another, new release introducing breaking changes, and you had to constantly play the upgrade and refactor game to keep things working. That in turn contributed to making our own code bases so called "legacy", as the framework used even a few months back is being deprecated, or libraries you depend on that you can't upgrade to the newest release without breaking everything so you stick to outdated dependencies.

None of that happens in Clojure, things are mostly stable for decades.

Post reply on HN