5 ms·
This was very nice! I will make an important nit. Keep in mind this is a nit. It's text in bold in the page, but this is NOT an attack on anything else in the
by frognumber 3y ago
This was very nice!
I will make an important nit. Keep in mind this is a nit. It's text in bold in the page, but this is NOT an attack on anything else in the article, which describes good design practices.
There is no principle that one should "Choose the least powerful language suitable for a given purpose."
This would, in fact, be an incredibly stupid principle. One want the most powerful language for any purpose. However, "purpose" is broadly defined:
1) We want code to be semantic. This allows a11y tools, search engines, and various performance optimizations to understand what's going on.
2) We want clean abstractions. In a horizontally-abstracted system, we would like the content designer to be focused on the content, the UX designed to be able to focus on the UX, and the back-end engineer to be focused on the back-end. (Note that, contrary to the beliefs of most people who have only worked on database-backed web applications, vertical abstractions are okay too, and break things up completely differently).
3) We want systems to be bug-free and understandable.
This can leads to programming paradigms like functional programming + React, where no mutation is allowed. This isn't a random restriction which reduces power; to the contrary, it increases power by allowing predictable state, avoiding a whole class of bugs, and allowing debugging with time travel.
In other words, you want good design discipline. However, the point here is much more on "good design" and not "discipline."
Every one of the changes proposed can be derived from first principles from the above. But this does not come from some principle of "least power."
To make this even simpler: Think of diet discipline. The goal isn't discipline about being hungry and eating yucky food. The point is about being healthy and losing weight. That probably involves being hungry and eating yucky food, but that's not the point. Food should be as tasty as possible and people should not be hungry to the extent goals on weight, heart health, insulin resistance, etc. can be accomplished.
Same thing here. Languages should be as powerful as possible, while allowing goals around readability, introspection, a11y, abstraction, etc. to be accomplished. That requires very specific and narrow constraints on what one bans.
- deleted 3y ago[deleted]
- MaxBarraclough 3y ago> There is no principle that one should "Choose the least powerful language suitable for a given purpose." This is mistaken. https://en.wikipedia.org/wiki/Rule_of_least_power https://en.wikipedia.org/wiki/Rule_of_least_power
- davedx 3y agoIt’s a stupid rule. Why? In my career there are two types of software projects. Ones that start off using a powerful language and libraries, and those that don’t because “this is just a prototype/small project”. 9 times out of 10 the second type naturally evolves into something more complex and requirements become harder to solve with some “least powerful” language. Inevitably a costly migration is made to a more powerful toolset, be that react, Spring, or whatever. I think it’s a bit different in infrastructure where the core of what you want is a declarative set of requirements and properties. But in SWE you’re a fool to start your project with the least powerful tools.
- williamcotton 3y agoIs C more or less powerful than TypeScript?
- MaxBarraclough 3y agoMore. JavaScript is deeply constrained by design. If you're using Deno and run into the limitations of the JavaScript language/ecosystem, you use its FFI to call out to libraries written in languages like C and C++. Similarly you might address a performance issue in your C code by writing assembly code, which is the most powerful language essentially by definition, and which of course has plenty of downsides.
- kevindamm 3y agoI think it does make sense if you consider it in terms of actual language power (a la Automata Theory) as opposed to just varying kinds of Turing-complete languages as it seems you're framing it. If what you need is a configuration language, please don't express it in Python. If what you need is a regular expression matcher, please don't express it in a bespoke recursive-descent parser written in the enclosing language. If what you need is a SELECT over a large dataset, don't download all rows from the DB and then iterate/filter them on the local host. I think there are many reasons for this, not just for human readability -- also for performance and security. Berners-Lee is quoted in that wiki article as saying it helps semantic extraction, too, but I personally consider that less convincing. EDIT: automistake/grammar
- davedx 3y agoYou put it very diplomatically. In my world I’m a lot more no-nonsense about the anti-react movement: they can go spend their careers making dull static websites with progressive enhancement and I’ll work on the interesting stuff without them.
- MyFirstSass 3y agoThis is interesting. React / Vue 3 has totally destroyed the creativity involved in webdev for me after working on multiple larger projects. Having just finished a pure JS + Petit Vue project the creativity and fun came back for me, while highlighting some important parts of the larger ecosystems. I'm still anti the newer frameworks though - and i think most are like me because of the ridiculous complexity these days, the sweetspot for me was around Vue 2, Angular 1. The newer frameworks just have too much "magic" going on, way too many files, dependencies, ever changing tooling, and no one seems to understand even small parts of it fully. It becomes about reading manuals and following conventions, instead of being creative and getting things done. Sharing simple data from one div/component to another is a good example of too much complexity; from 1 minute sharing across your app/teams through window.sharedObj, to 40 intermediate steps, 100 files, 100 imports, stores, 10 dependencies, .value.value.data.data, and extremely long nonsensical errors when your data has stranded somewhere.
- sensanaty 3y ago> I'm still anti the newer frameworks though - and i think most are like me because of the ridiculous complexity these days, the sweetspot for me was around Vue 2, Angular 1. But it's the exact opposite? At least if we're talking Vue 3, literally everything about it is less complex than Vue 2 was, especially with Vite. You're telling me that Webpack is less complex than Vite? At my work our 1 Million+ LOC Vue app the Vite config is like 40 lines for Prod, Staging & local dev each, and every single line of the config is dead obvious without even needing to check the docs, especially when you compare it to the monstrosity that Webpack setups usually end up looking like. Plus there's the insane speed at which even gigantic projects get built, whereas Webpack can easily take 100x the time. Hell, even HMR would take around 15 seconds on an uber powerful machine before we made the switch to Vite, where it now takes ~500ms. Sure, there's a small bit of adaptation to be made with refs and calling `.value` outside of templates, but once you grok it it's actually a lot more logical than the magical `this.` you'd see everywhere in Vue 2, since `this` can refer to a LOT of things at any given moment, and it's never 100% clear what it is. > Sharing simple data from one div/component to another is a good example of too much complexity; from 1 minute sharing across your app/teams through window.sharedObj, to 40 intermediate steps, 100 files, 100 imports, stores, 10 dependencies, .value.value.data.data, and extremely long nonsensical errors when your data has stranded somewhere. Again, this is the complete opposite to my experience with Vue 3. In Vue 2 you had to deal with Vuex and the weird getter/mutation/state stuff, whereas with Pinia you just set some state as an object, and you can directly manipulate that state wherever you want, even with excellent devtool support. And I definitely wouldn't call sticking all your state into a random `window.` object less complex than using something like Pinia, if that's your idea of less complex then I'm happy to not be working on the same codebase as you. I'd rather you not be creative with state management like that, cause every time I've ever had to deal with some monstrosity of an untyped `window.GodObject` I've wanted to throw my laptop against the wall. Not to mention that if you opt for TS (which is like a single line in the Vite config), it's WAY more productive than Vue 2 since you now have properly typed emits and props and can actually have an overview of what data is flowing where. Plus CompAPI in general is just objectively less boilerplate and less code than the old Options API. An identical component will have much less code in 3 vs 2, especially complex ones, and ESPECIALLY once you start talking about mixins. Also, passing props hasn't changed between Vue 2 & 3. You still just pass it in the template via `:myProp="myProp"`, all the same caveats as before still apply, except now it has proper type hinting that your IDE can help out with without having to scan the file itself. If you wanna avoid prop drilling (passing data from a parent to a deeply nested grandchild component), then provide/inject (also typed) or just Pinia (which again, is dead simple in comparison to Vuex or heaven forbid some monstrosity of a `window` object) is there to help. The Vue 3 docs are also the best I've ever had to work with, and if you read through it just a single time you'll have an extremely clear understanding of how the framework actually works. No guesswork needed, and they always outline drawbacks as well as how to work around those drawbacks.