Earlier quoted context omitted.
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 b…
Clojure: A Lisp that wants to spread
271–280 of 306 posts
Re: Clojure: A Lisp that wants to spread
#272Earlier 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…
Thank you so much for the response! Number 3 has me totally stoked; since that's incredibly valuable-- or like a dream to me to be honest, could you speak more about how that works? Is it just from using re-frame (which I'm looking at as I write this)? Is it able to test for visual regressions because of the pure-data UI? Or like how have you found that testing functionality in practice has it been saving y'all a lot…
The visual part of Re-frame is handled by reagent, which is a minimalist React wrapper that represents React components as pure functions, JSX as built-in Clojure data structures literals (hiccup), and state transformations using Clojure's idiomatic atom data structure. Re-frame builds on top of this base, by enforcing that a single atom (called db) holds all of the state and providing a DSL to create cursors into parts of it.
Like most things in Clojure, Re-frame's initial setup is not a straitjacket and you can swap out the state atom with e.g. an in-memory datalog database using posh/re-posh and make the data retrieval completely declarative too.
Re: Clojure: A Lisp that wants to spread
#273Earlier quoted context omitted.
Thank you so much for the response! Number 3 has me totally stoked; since that's incredibly valuable-- or like a dream to me to be honest, could you speak more about how that works? Is it just from using re-frame (which I'm looking at as I write this)? Is it able to test for visual regressions because of the pure-data UI? Or like how have you found that testing functionality in practice has it been saving y'all a lot…
Agreed... would love to hear more about this as well....
Re: Clojure: A Lisp that wants to spread
#274Earlier quoted context omitted.
Clojure seems like an odd choice for command line tools. I can see why a committed Clojure programmer would want to reuse their existing skills for a slightly mismatching domain. But Rust/Go (even C) would seem like a more obvious choice if you weren't setting off from Clojure as a starting point.
A command-line tool is nothing more than a script that maybe parses some input from the program's arguments or from stdin and then does something useful. Naturally you want to have the libraries you're used to available and the best language for CLI tools is the one you already know. Building CLI tools in C/C++ is silly. If you like Rust/Go, sure, knock yourself out. But the obvious choices are the scripting language…
Idk - If I wrote a tool in any of those languages and used state-of-the-art features then you would not be able to use them with the system interpreter and you’re back to square one.
Re: Clojure: A Lisp that wants to spread
#275Earlier quoted context omitted.
Clojure seems like an odd choice for command line tools. I can see why a committed Clojure programmer would want to reuse their existing skills for a slightly mismatching domain. But Rust/Go (even C) would seem like a more obvious choice if you weren't setting off from Clojure as a starting point.
A command-line tool is nothing more than a script that maybe parses some input from the program's arguments or from stdin and then does something useful. Naturally you want to have the libraries you're used to available and the best language for CLI tools is the one you already know. Building CLI tools in C/C++ is silly. If you like Rust/Go, sure, knock yourself out. But the obvious choices are the scripting language…
Re: Clojure: A Lisp that wants to spread
#276Startup 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 an…
If I could make my own language and stack, I too would be mega-productive. However, others likely wouldn't like it and be confused by it, even though it's dirt obvious to me. Roll-your-own has limits. Sometimes 2 or 3 like-minded Lisp developers connect and roll for a while, but over time they will find it a lucky match-up that the real-world can't repeatedly recreate. Lightning in a bottle evaporates easily.
The bottleneck of "paycheck" programming productivity is communicating between human beings, who may shift over time. Cranking out compact code fast is secondary to this. Program for people, not machines and not cleverness graders.
Re: Clojure: A Lisp that wants to spread
#277Earlier quoted context omitted.
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…
You might have a biased sample of Clojurists, in my vicinity ~50% use Cursive. Not sure where you get the disrepair part, Cursive is alive and well and seems to be a sustainable business for the author, and Calva also seems to do be doing well. It's true that there have been various open source IDE efforts that are dead now (Counterclockwise for Eclipse went the way of Eclipse, Lighttable and Nightcode were probably…
I did use Eclipse and Counterclockwise for quite a while and enjoyed it very much.
Re: Clojure: A Lisp that wants to spread
#278Earlier quoted context omitted.
> In practice, it's better to avoid positional arguments and extensively use maps and destructuring We can agree to disagree I guess. In my experience, especially in the context of refactoring, extensive use of maps as arguments causes quite a lot of problems. Linters also do nothing for that. Positional arguments have the benefit of being compile errors if called with wrong arity. I actually consider extensive use o…
For example if you have something like: (study [student age] ,,,) And inside it calls a bunch of auxiliary functions where you pass either `student` or `age` depending on what those functions do, then someone says: "oh we need to also add an address", and have address verification in the midst of that pipeline. And instinctively programmer would add another positional argument. And to all auxiliary functions that req…
In your case, you're defining a domain entity, and a function which interacts on it.
Domain entities should definitely be modeled as maps, I agree there, and probably have an accompanying spec.
That said, still, I feel the function should make it clear what subset of the entity it actually needs to operate over. That can be a doc-string, though ideally I'd prefer it is either destructuring and not using the `:as` directive, or it is exposing a function spec with an input that specifies the exact keys it's using.
Also, I wouldn't want this function to pass down the entity further. Like if study needs keys a,b but it then calls pass-exam which also needs c and d. This gets confusing fast, and hard to refactor. Because now the scope of study grows ever larger, and you can't easily tell if it needs a student with key/value c and d to be present or not.
But still, I feel since it's called "study", it feels like a side-effecting function. And I don't like those operating over domain entities. So I personally would probably use positional args or named parameters and wouldn't actually take the entity as input. So if study needs a student-id and an age, I'd just have it take that as input.
For non side-effecting fns, I'd have them take the entity and return a modified entity.
That's just my personal preference. I like to limit entity coupling. So things that don't strictly transform an entity and nothing else I generally don't have them take the entity as input, but instead specify what values they need to do whatever else they are doing. This means when I modify the entity, I have very little code to refactor, since almost nothing depends on the shape and structure of the entity.
Re: Clojure: A Lisp that wants to spread
#279Earlier quoted context omitted.
That's not quite it. The client/server distinction was removed from the JVM many years ago. These days the JVM switches between modes on the fly on a per-method basis, this is called tiered compilation, so the optimisations are in effect on by default. Back in 2006 yes it may have made a big difference but it wouldn't have made startup magically instant. IIRC Clojure apps are slow to start because they do a lot of fi…
I understand, but either way, the example Rich Hickey used to execute the sample Clojure application in less than a millisecond seems impossible? In other words, if Rich' example is real and recent, what could possibly be the environment in which this worked?
Re: Clojure: A Lisp that wants to spread
#280I think everyone using Clojure JVM, ClojureScript, or Clojure CLR should be doing this.