Hacker News new | past | comments | ask | show | jobs | submit | iLemming's comments login

What does that mean for Clojure?

Same thing as Java. You could use this to run python in your clojure JVM process.

Why would it mean anything for clojure?

Keyboard input currently is the most common and efficient method to create text - dictation, handwriting recognition, and mind-to-text interfaces are still in their infancy.

Faster text input is a must for anyone involved in software development, there's no question about it.

We, software engineers constantly share our ideas, our thoughts and hypotheses and the medium for that exchange 99% of the time is text - be that plain English, programming or any other natural language.

Anyone who is incredibly slow with the process would be a detriment - a slow typist is unlikely to write good, useful git commit messages; they are less likely to spend time to write coherent, descriptive Pull-Request descriptions or share convincing architectural-change proposals.

Just think about it - the average programmer over their professional lifetime writes the equivalent of 15-20 "War and Peace" books. "War and Peace" is approximately half a million words or 3.2 million characters. Assuming an average of 50 characters per line, a programmer writing 1 million lines would produce about 50 million characters. It took Leo Tolstoy around six years to finish his novel. Programmers often have to create projects twice as big in the matter of months.

On the other hand - some may argue that over-prolific, fast typists sometimes write watered-down, lengthy texts that are painfully difficult to read and they add little value beyond just increasing the entropy. Writing well is a skill, and a faster typist is most likely to achieve this mastery quicker than a slow typist.

Whenever I need to make hiring decisions I try to find the candidate's footprint - code, comments, blog posts, etc. You can tell a lot by simply skimming through what they wrote - whether it's code or plain text. Good programmers rarely are slow typists.


Same can be said about Clojure. Although Clojure usually described as an FP-language, it's not "purely FP". In general, I find that Lispers typically don't concern themselves with the popularity of certain tools or techniques; They don't care for things like MSFT marketing shoveled in your mouth. Die-hard pragmatists, they'd use an instrument if it makes sense. They don't give two shits about OOP propaganda or extreme functional purity, or the notion such as "not using static types is immoral" and shit like that, they'd use object-orientation where it makes sense; metaprogramming, where desired; constrains, if applicable; concurrency when required, etc. All that without any zealotry - just pragmatic use of the right tools for the job, embracing Clojure's flexibility and power while staying true to the only core "philosophy" - "simple made easy".


As a dyed-in-the-wool Clojurist, I appreciate leveraging the functional aspects as much as immutable by default data structures. It takes a while to stand back and realize, but once you have a large program that is mostly all passing immutable hashmaps all around to static functions, testing becomes soo much easier and reasoning about how all the code is glued together becomes far easier. You know with certainty that code doesn't have all the ordering problems that come with Objects, whether you called some random function on some object at aome time that cached some instance variable that should have been shared with some other object. Reasoning about that is nuts, and the status quo for most OO code I've seen. If you know that most code only is implemented with pure functions with immutable data, then the ordering questions are nearly completely gone. You can now refactor so much easier as well without risk of subtle ordering related breakage. And then Clojure has atoms and channels which are very nice, thread-safe constructs that also are far easier to know your code won't have memory safety issues. I have dabbled at learning Rust or Haskell or Swift but Clojure gets so much so right.


> You know with certainty that code doesn't have all the ...

You have this certainty to the extent that the compiler enforces it.

If you like language X because it's 'pragmatic' instead of 'religious', then you make the pragmatic choice of not knowing with certainty.


I know, right? It may feel weird at first - with immutability, parentheses and prefix notation, but once you grok REPL-driven interactivity and structural editing - so much about programming becomes intuitively simpler.


I have the same experience. I learned Haskell because of the aura of prestige around it, and must admit I still love the syntax, but moved over to Clojure as my daily-driver as the practicality of "just use maps" is incredible.

IMO the article misses the point there. Immutability is the "thing" in FP.


Yes! I spent months (maybe even years) trying to understand Haskell, and for the love of god, I just couldn't wrap my head around so many things. I just wanted to build stuff with it, but it felt like becoming a doctor - getting a bachelor's, passing MCAT, then four years in medical school, then residency program, then getting a license and a board certification. All that for the sake of knowing how to properly apply a band-aid (or something). Except, with Haskell, there's no rigid structure, there's no single, proven, 100% guaranteed path to glory - it's all blur. There's no "10 steps to build a website with Haskell". And then I picked up Clojure, and OMG! everything suddenly started making so... much... sense... All the things in Haskell, for which I had either no clue or had some shallow understanding - that all became so much more intuitive.


It definitely took me at least 3 years of reading and practicing to be able to get to -at least think- understand it, and I still think I would be considered pretty incompetent by people that do Haskell daily.

There is no doubt in my mind that the Purity concept in Haskell is taken to an impractical degree. I happen to like it, but it does not make developing software with it any less of a troubled experience. The defining concept in comparing Haskell and Clojure for me is the pareto principle :D Clojure gets 80+% of the way there, without 80% of the self flagellation.

There is also a consideration of static typing vs dynamic but that's a whole other can of worms.

Simply, in Haskell all mutability is delegated to the runtime while in clojure one has the freedom and responsibility to manage it directly, and boy does it gain in simplicity for it!

I know I am preaching to the choir but it's pleasant to find a similar experience and share thoughts!


vterm works nicely. My only gripe that Evil support in vterm isn't great, but that's irrelevant in this context.


Structural editing commands are like 'slurp' - swallows an expression inside another one; 'barf' - spits out a thing out of an expression; You can also do it from the left or right side. 'wrap' - wraps a selection into an expression; 'unwrap' - does the opposite; 'transpose' - swaps two expressions at point, and there are more commands.

Once you learn the basic structural editing commands, writing code becomes like composing poetry out of haiku pieces. Instead of thinking like: "how do I grab these vars used inside this function and refactor it to be them in their own unit?...", you'd just grab some expressions and move them around, like bricks or lego pieces. It is extremely satisfying way of writing programs. The only drawback of that approach is that later it becomes harder to work with "more traditional" PLs, you just can't easily manipulate code the same way in Python, JS/TS, Kotlin, Java, C++, etc. - you need a "structured", homoiconic, lispy language for that trick to work. Treesitter makes an effort to improve the process, but it still not on the same level of simplicity.


Well, first of all, JVM, even though it still gets a lot of bad rap (mainly due to Java) turns out to be really nice piece of tech, especially if the aim is to scale CPU-intensive tasks.

Besides - Clojure is not JVM-only, Clojure is a hosted language, it can work a top of different platforms: JS engine - Clojurescript; Flutter - ClojureDart; Native Code scripting - Babashka; NodeJS - nbb; .Net - Clojure CLR; Fennel even though technically is not a Clojure, is a lovely little language very similar to it and it works on Lua. There's also jank-lang, currently in development that works on top of LLVM. There are a bunch of other Clojure dialects - for Rust, Go, Python, Erlang, etc.


Clojure codebases may be easier or more difficult to maintain depending on factors such as team experience, project complexity, and code quality. The ease of tracking down bugs varies across programming languages and is influenced by development practices and tooling. Clojure codebases are not more difficult to maintain than any other PLs.

- Clojure has strong type inference, catching many errors at compile-time.

- The REPL provides immediate feedback and testing capabilities.

- Clojure's immutability and functional paradigms reduce bug-prone code.

- Tools like core.spec offer runtime type checking and data validation.

- IDEs like Cursive provide advanced static analysis and refactoring support.

- Clojure's simplicity and consistency make bugs easier to spot and fix.

- You also completely ignoring Clojure's rich ecosystem of testing frameworks and tools.


> IDEs like Cursive provide advanced static analysis and refactoring support.

Can you give an example? Would these tools allow you to define a custom type with fields and ensure it is correct everywhere at compile time like a static language?


While Clojure is dynamically typed, tools like clj-kondo, Cursive and clojure-lsp can offer some static analysis benefit like warning about undefined vars or functions. There isn't "true" static checking, but you can use Spec and Malli for runtime checking. That doesn't provide same level of compile-time guaranties as statically type language, yet it offers some unique capabilities that many statically typed languages struggle to match, like

- Dynamic predicates - Spec allows you to define types using arbitrary predicates, which can be more expressive than traditional static type systems;

- Runtime generative testing - Spec can automatically generate test data based on your specifications, which is powerful for property-based testing;

- Flexible validation - You can validate complex nested data structures and apply specs selectively, which is often more flexible than static type checking;

- Extensibility - Specs can be added to existing types without modifying their source, and data-driven nature of it - Specs are just data and can be manipulated programmatically.


Yep, I'd add these advantages that schema systems have:

- Power - you can do arbitrary checks on the data, static type systems are quite weak in what kind of properties they can verify (far from turing complete)

- Flexibility to do checking at where you want at runtime (eg check data at API boundaries)

- Ability to treat schemas as data, generate them, output them as data and share between systems (for example in databases), throug conversions possible to interop with other platforms (eg json schema)

- loose coupling to your programming language, are just libraries


> I found it impossible to read and frustrating and tedious to write.

Perhaps you've done it wrong? To read any Lisp code one needs a REPL. And you don't typically type directly in it, you connect to it and eval things from source files. Once you get connected to a REPL, you can eval any expression and sub-expression, and with practice, you'd learn to grok the code without a REPL.

And for writing Lisp, you only need structural editing support in your editor. Once you find basic commands - moving structures around is far more enjoyable process than writing things in an unstructured language.

I am far more productive using Clojure instead of Java and Clojurescript instead of Javascript, Fennel instead of Lua, etc. - it's easier to read, easier to modify, easier to maintain. But, yeah, it does require some practice, just like any other skill.


I am well aware of the benefits of a REPL, and find it pretty essential for learning any language. It didn't help me grok clojure any better, though.

I'm not sure what you mean by structural editing support. I usually find things like autocomplete or automatic parenthesis to be more of a nuisance than a help.


> find it pretty essential for learning any language

No, REPLs in other languages are not equal to REPLs in Lisp dialects. I bet what you are describing is not the same workflow that an average Clojurian would use. In other languages you typically type directly into the REPL console. With Clojure, you typically connect your editor to a running REPL instance and then manipulate things directly from the source code - you basically write the program, while living inside it - your codebase becomes a living, breathing, maleable entity.

Structural editing has little to do with autocomplete, it's just a way to manipulate expressions - move them around, raise them, transpose them, wrap/unwrap, etc.

I suppose you tried to understand Clojure by looking at the code, and that could be challenging - without proper REPL and structural editing support, it may not be the same joyful experience that many Clojurians know.


Yes, I've heard this sales pitch before. Yes, I used an actual REPL tied to an editor, among other configurations. I found it rather underwhelming. I tried a few other lisp dialects as well, but had the same experience. Interactivity is great, but it doesn't make up for the language itself.


"Underwhelming"? Seriously? I don't think you actually tried the real thing, have you? I don't know about you, I find it extremely satisfying, when you can run a basic Puppeteer or Playwright script and then explore the DOM structure directly from your editor, without having to copy/paste, move or change your code, or even using devtools (everything controlled from your editor), and then navigate the page interactively from your editor and execute pieces of code (that run in the browser) without any preliminary ritual, even without having to save the file.

Or you'd run a curl command once and continue exploring the data - parsing slicing, dicing, grouping, sorting any way you like, or even have it visualized in the Portal tool with charts and graphs.

Look, I'm currently writing tests for a thing, while my IDE is connected to a service running on a Kubernetes pod in the cloud - I can eval any function that affects the execution of the service, I can explore the db tables, change the routes and re-run the tests - all that without having to restart the pod, without having to deploy anything, without even having to save any files (if I don't have to).

Lisp REPL-driven development gives you immediate feedback, allows you to modify and debug running programs on-the-fly, allows you to experiment, it's great for understanding language features interactively, and it's a real, tangible productivity boost - it's superb for rapid prototyping.

> Interactivity is great, but it doesn't make up for the language itself.

The language is what allows that great interactivity and exploratory programming. I mean, I get it - while it may initially appear challenging to read, much like how sigma notation for loops in mathematics can be difficult to comprehend, with practice it becomes intuitive. One wouldn't go to math.stackexchange to complain about sigmas and other mathematical symbols being unintuitive, would they?


Strange, I use Lisp and type to a REPL all the time. Now you tell me that is a feature of other languages, not of Lisp?


What's cool that you can control it from your editor. It feels so nice managing YouTube video playback from Emacs, makes the note-taking so easy. elfeed-tube/elfeed-tube-fetch command lets you follow the transcript, while ignoring commercial bits. You can basically search through the text and play it from that point.


Yeah, anyone who remembers 1990s knows that MSFT is not to be trusted. I am appalled to see how they lured thousands of programmers to use VSCode.

How are people so naive to think that a colossal corporation with a capitalization comparable to the GDP of Germany is spending an enormous amount of resources to build "a free" code editor, and that they are doing so with absolutely the best and benevolent intentions?


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: