Modern Javascript: Everything you missed over the last 10 years (2020)
turriate.com
turriate.com
I agree with your overall point 100%, but to be honest nothing in React was / is innovative except for the virtual DOM diffing, but even that is becoming increasingly irrelevant as apps are moving towards more and more reactive architecture. React made a huge impact on web dev and deservingly so, but all of the other ideas have been implemented and used on the web before.
Of course it's great that React is bringing some of these good ideas to mainstream, but they've been there way before they have been distributed along with a VDOM algo.
Is this true? I've worked in web dev for like 6 yrs now and React has provided a significant number of concepts and technologies I'd never seen before and still dont see elsewhere.
For example, JSX. Yes, it originated in php but React was its first time being implemented in the frontend.
Also the concept of hooks and functional components. The fact that you explicitly define side-effects in the render of a function, with memoization or execution dependent on arbitrary state, is a new invention as far as I'm concerned.
Transpiling, hooks and components have all been done (and done better) before React came along, but often they were laughed out as esoteric toys that have nothing to with "real programming". It's just hard to teach these concepts until you actually use them, and it's hard to get people to use these concepts unless they are included in something else that you need.
The same happened early with React, both JSX and VDOM were laughed at by many developers because "they looked stupid" to people who didn't understand them and were used to one way of doing things. MVC+jQuery+templates was the flavour of the day.
Same thing with TypeScript, FRP and so on.
Most likely, whatever concept is gaining momentum today, it's an exact or approximate copy, or in rare cases a novel remix of what has been researched 10-20 years ago, and used in production for 5 years before you heard about it on HN
These people who like to apply category theory etc. in programming have heard this mocking of their work as stupid esoteric fantasy (and then seeing them become mainstream later) so often that they literally called one of their specs "Fantasy Land" https://github.com/fantasyland/fantasy-land
There's still lot of work to be done. JavaScript doesn't even have proper immutable data structures natively, which would be a REAL low hanging fruit.
The compiler is quite mature and used by countless apps in production right now.
I've been using it myself and it doesn't feel academic at all. The Svelte Kit toolkit, a successor to the Sapper frameworks is also ready to use but it's not 1.0 yet so might be a bit unstable. But if you're worried about having to figure things out then you can use Sapper+Svelte or just Svelte just fine, and they're very robust and well documented.
On another note, a React component in FP is just any regular old JS function with a signature: `(state) => HTML string`. React is such a simple concept that it wouldn't have needed any sort of library, if it weren't for the performance and DOM reset issues.
They may predate React, but React made them easy.
Good luck explaining how lenses work.
Rx? it took the author of RxJava months to understand the concept. And he had the author of Rx.net there to explain stuff to him. [1]
> there's no single "React but better and made earlier".
Yes. And that is precisely the point
> React made a huge impact on web dev and deservingly so
The VDOM was revolutionary, no question about it. The comment I was replying to didn't even mention it.
--- start quote ---
All of these concepts are variations of what has been done before in a number of ways. Mostly by "FP academics" who "live in fantasy land", until everyone else starts using them too.
Transpiling, hooks and components have all been done (and done better) before React came along
--- end quote ---
When asked about the emphasized part, you mentioned Svelte for some reason. When called out on that, you went and listed a bunch of things, ... none of which are really better, and are quite esoteric. To the point that it took the authors of some implementations months to understand the concepts.
React (pre-hooks) could be picked up in less than a day, and just worked. Re-creating React concepts from scratch was a three-page tutorial.
Of course this would cause problems that I've described in this thread before (scroll/form state resets, performance problems etc.), so the VDOM was the missing piece of the puzzle. Overall the concept of declarative UI was incredibly simple and predated React, but the VDOM was a great thing that solved the problems people were having with declarative DOM manipulation. If React had shipped just with the VDOM implementation, it wouldn't have needed to expand into a full-fledged framework and introduce a bunch of band-aids on top it. React deservedly skyrocketed, and the VDOM was an incredible thing to introduce at the time, but every part of React is quickly becoming outdated as more FP concepts from the past are introduced into the mainstream.
So all in all, React shaked things up in a good way, and finally people are ready to move on to make their apps actually reactive and taking a serious look on things that have been "academic" before.
I don't
> I don't know what bone you have to pick with any technology other than React
I don't have a bone to pick.
> but achieving declarative DOM manipulation pre-React was as simple as
Yes, it was possibly achievable. Did anyone achieve it? You claimed that evertyhing React has was done better before React. When asked about examples, you answered first with Svelte (which appeared after React), and then with disparate technologies which are are at best esoteric and at worst extremely complex.
> That was definitely easier than learning React, and by building a component structure with vanilla javascript functions, you could have all the functionality and expressiveness of JSX without a compile step or external libraries.
You probably could, but did you? Oh, wait, you didn't. The hot tech du jour when React was released were knockout.js and backbone.js.
And, once again, the etirety of "learning React" took less than a day. And "building a component structure using vanilla javascript functions" was literally a three-page tutorial if you wanted it.
Compare this to Rx that you gave as an example of something "better than React". The author of the original Rx.Net sat by the author of RxJava, and it still took the author of RxJava several months to understand the concept. Lens, another of your examples, is esoteric even in Haskell.
But sure, "everything was done better before React came along" :-\
> React shaked things up in a good way
Indeed, it did.
Funnily enough, you start with "Transpiling, hooks and components have all been done (and done better) before React came along" and then continue with "there's no single 'React but better and made earlier'."
I did. It's kind of funny to hear that you cannot even entertain the idea that people actually did declarative UIs before React with plain old vanilla JS, because that was my bread and butter back in the day. That's precisely how I did frontend until React came along, and so did many others. We sometimes sprinkled in some CoffeeScript to get nicer function syntax, before () => {} and babel existed, but it wasn't necessary if we wanted to avoid a compile step.
Just because some frameworks were prevalent at the time didn't mean that everyone used them. Large portion of seasoned developers rejected all frameworks and still do today. They had shot themselves in the foot with MVC/"trying to do everything" -frameworks enough times to learn that not all answers come from a single framework that encompasses your whole application. This is nothing new or esoteric, and still today a good lesson to learn for new developers. Instead many people continue to use "the standard" framework, fighting against it when it fails to fit the domain logic of their app, and waiting for a new framework to arrive to save the day. Frameworks have gotten much more flexible about this today, but React wasn't anything revolutionary on the framework side of things.
It's not as simple as "React bad/React good". A framework/library can be good in certain aspects and bad in others. I loved React when it came out, because of the VDOM. Wasn't a fan of everything else though, and especially not a fan of how it was used as "the new standard framework to tightly couple your application into". This is not a contradiction, it's just non black-and-white thinking.
By you I meant "collective you". I don't care what individual developers did that no one knows about.
> Just because some frameworks were prevalent at the time didn't mean that everyone used them.
define: prevalent
1 : generally or widely accepted, practiced, or favored : widespread
2 : being in ascendancy : dominant
> Large portion .. upto ... flexible about this todayBears little to no relevance on the discussion
> React wasn't anything revolutionary on the framework side of things.
Except, it was. It upended the prevalent way of doing things and ushered in a new prevalent way of doing things.
define: reovultionary
1 c : constituting or bringing about a major or fundamental change
I did bring about a fundamental change: the prevalent way of doing things on the web changed.> It's not as simple as "React bad/React good".
Of course it's not. But we're not discussing whether it's bad or good.
> it's just non black-and-white thinking.
So far your "non black and white thinking" is "everything React has was done better befroe React, but I can't show anything to prove this except some disparate things that are both complex and esoteric, and I can also go on a prolonged discourse about how some developers don't use frameworks and may have done things a la React before React".
What devs can implement on their own beyond frameworks, and what frameworks mean to how the community as a whole operates.
"Defaults matter."
for context, I wrote the first web frp+vdom and helped inspire the creation of rxLinq and related systems, and we even did a whacky thing back then that predicted Parse/Firebase/redux/graphql/falcor, including some basic features they still don't have (should have spun out a startup instead of getting a PhD!). our group even did the first lenses for the web, though that one ended up much less usable. I think we did all that around 2003, while the alternatives were PrototypeJS, jQuery, and a couple other more sugar-level things
however.... react with hooks, jsx, and the various css modes nowadays is pretty awesome, and eliminates most of the needs for streams. main lack there is more for rich animation, than web apps. graphql, redux, and friends are all still clearly clunky technologies with limited shelf lives, so I'd focus more there than react for basic abstractions
at the same time, nowadays I think more about synthesis, ml, end-to-end GPU computing (actually proposed that back then too!) and other more powerful ideas than revisiting frp/lenses/etc...
No, React was first. It was in production, if internally, for more than a year before Elm came onto the scene.
When the complex reality of JS applications was reached in React, React shortcoming became more and more apparent.
There's no free lunch.
The easier to mentally digest appeal of 'redraw the whole thing every-time'* was fantastic but performance was always going to take a massive hit past an easily reached point.
* The difference this time was the diff engine was going to be smarter than before but it was not good enough.
One of the early criticisms of React was: “You can’t do HTML in Javascript. You shouldn’t be styling in JS! That violates the separation of concerns.” React skyrocketed productivity and allowed scaling without spaghetti. That’s why it won.
CSSZenGarden was fun, but how many companies seriously did redesigns by just swapping a style sheet? Only repeat the dogma if it makes sense....
I think React won because it had a more gradual learning curve than Angular and a didn’t drastically change between versions.
And the idea that HTML/CSS/JS are non-isolated is over-thinking it. It only applies to the world of Webapps. HTML can be published and served all day without CSS or JavaScript. And you can do a lot with HTML and CSS alone.
JSX is not magical which is what I appreciate the most about it.
The ability to type `children` alone makes a world of difference.
Both Opa and JSX were created in 2011. Opa had other innovations as well, such having the same code base run on both client and server (like Next.js). Unfortunately it didn't get traction and was abandoned by the creators.
After all, like you suggest, things like functional programming and monads have existed for quite some time. The thing that makes React special is how rabidly people adopted it, and continue to adopt their major updates.
Taking the example of hooks, React has hooks because it was released with a bunch other stuff in addition to the VDOM, people started using those things as a (poor) framework, shot themselves in the foot repeatedly and finally hooks had to be introduced as a fix on top of that.
Calling that band-aid "revolutionary" or cutting edge technology, kind of sounds wrong. They never would have been there and wouldn't have been needed if it weren't for the bloated original release.
But of course, even if that band-aid makes people think differently about building apps, it's all good. That's why I mentioned in the post that it's a great thing. But calling it "revolutionary" when a large fraction of programmers have been doing it that way for ages is a bit of a stretch.
Could you expand on this? What was it that necessitated DOM diffing before, and which architectural changes are making it irrelevant?
If you tried to solve this problem by redrawing the DOM every time your app state changed somewhere in the code, the browser would freeze and all your form elements would be defocused on every update, scroll states would be reset etc. etc.
React solved this by the diff algorithm and doing surgical updates of the dom based on the components state. It does this by manually reading the state, keeping a virtual DOM in its memory and doing diff calculations.
But if your whole app is reactive by design, there's no need to read the app state, doing diffing or figuring out which DOM node to update which one not to update. The DOM update operations flow naturally by the declarations given by the programmer. Frameworks such as Svelte are moving into this direction and they're already seeing quite significant performance improvements compared to VDOM implementations.
If you can do declarative rendering without keeping a virtual representation of the DOM and diffing it against the real DOM then "the virtual DOM is overhead" (https://svelte.dev/blog/virtual-dom-is-pure-overhead).
Maybe there wasn't much academically innovative in React, but it certainly brought declarative, functional UI programming to the masses. Its innovation was in making that as easy and accessible as possible with a tiny API.
I feel saying React wasn't innovative is so dismissive and ignores the massive paradigm shift that's happened in web development because of it.
But I'm not even talking about academic really. There were plenty of people who didn't buy into the "MVC/jQuery/templates" thing, and we were writing apps into production for actual customers. I've never been taught academically, but I realized that writing my DOM operations as declaratively as possible made my code much easier to maintain. So I started creating and updating my DOM in JS way before React, when it was considered "heresy" by people who didn't know better. And there were plenty of programmers like me, who never got academically trained or looking up category theory. They had just shot themselves in the foot with the silly MVC stuff too many times to care anymore about what other programmers think.
For me, and people like me React was a GODSEND. We started immediately hyping it, but there was huge resistance early on to adopt it. React was a great improvement from the status quo. But then later on we realized that people started using it as a framework just like they had with "templates+jquery+backbone+whatever" and although the DOM things are a bit easier now, many people don't understand any better why or how React is good and when it's bad to use...
Its innovative in the same way as the iPhone was. All of the concepts existed before, but nobody made them practical and cheap
Kinda like hyping iPhones innovation without ever mentioning touch screens.
A concept that also has existed before, but with XState, I think a lot of developers will latch onto this paradigm.
The ability to think or plan a feature/apps states in the beginning rather than imperitavely or as an afterthought during development is really valuable. And perhaps if we're dealing with something more visual at the beginning, its easier to demonstrate what will happen if I click "X". and then it becomes easier to spec out & to involve PMs/designers and QA.
Your comment was very insightful, but I feel like you've left me on a cliffhanger. I'm someone who got into the industry right when React was reaching enterprise levels, so I missed out on what came before it. I got my job, was told to learn React, and have gone from there.
Is there any way you might be able to expand on the problems you were solving with your declarative approach, why it was useful, and how you think React should be used in modern day web development?
- application is in one state and the UI is in another state
- jQuery operations mutating the DOM causing weird edge cases after several user interactions
- the template language (handlebars, mustache etc.) was getting in the way because it lacked the expressivity of javascript
- application state was split all over the place between Models, Views and Controllers. instead, if you put as much state as possible in a single place in your application, it's much easier to just create declarative functions that take in an immutable state and output a DOM node object: `(state object) => DOMNode`
Right now I'd use React only for projects that require it as legacy or as a part of a framework. If you want to get things done quick, Next.js is pretty good framework for greenfield projects that uses React under the hood and I don't mind it being there too much. But similar things to React can be achieved with Svelte or Lit without having to ship and manage a VDOM implementation or JSX with its quirks (e.g. className).
So in summary, I'd stay away from all features of React other than VDOM, and even skip that if possible. And as a general rule, don't use any frameworks unless you can say why your project specifically really needs it. Surprisingly much can be done with basic HTML, JS and CSS. People who say "just use X" are trying to force simple answers to a field that is inherently complex and needs good judgment on which tools to use and when not to use them.
jQuery is a good tool for simple one page applications but not designed for complex web apps. It is harder to code cleanly in it as compared to React.
Because it seems to me that around the time React really gained popularity there were lots of options that did largely the same thing. Knockout, Ember etc.
Personally I only see it as the real proof that VDom could work for large applications.
For an example of stuff people have built with them, here's a Robot Inventor-based Rubik's cube solver: https://www.youtube.com/watch?v=_cl2Wur8waY
Being able to just run Linux on the thing sounds like a god send.
https://www.st.com/en/evaluation-tools/p-nucleo-ihm001.html
For $35 you get a little motor, a motor control board, and an ARM micro-controller board. ST includes some software for motor control. If you want to do precision motor control, out of the box it is missing an encoder (a device that tells you the position of the motor). The STM32 chips usually have some inputs you can use with a quadrature encoder, so you could add one if you needed to. It does include a current sensor and the software uses the for field-oriented control (FOC), so you can efficiently and smoothly control the speed of the motor. To learn more about motor commutation and FOC, check out this document:
https://www.actronic-solutions.de/files/actronic/FTPROOT/Fie...
Are we looking at the same web technologies here or are you from an alternative universe?
Edit: The React repo is 3 million+ lines of code, written in its own niche language...
I have a theory that the people who go on about how the web ecosystem is too complicated are either 1) web developers who are nostalgic for the jQuery days (and have selective memories about those days), or 2) non-GUI developers who enjoy the theoretical virtues of a QT or a GTK but have never actually had to work on a complex GUI, and so can't appreciate the incredible benefits the web has over those other platforms.
https://github.com/facebook/react/graphs/contributors
It doesn't seem possible for this to add up to 3M lines of code?
I got pretty tired of chasing the fad explosion. Here's what I build everything with these days:
HTML, CSS, JavaScript, Go or PHP, Redis, MySQL or Postgres, Ubuntu & Nginx. Occasionally I'll make use of an ancient version of Sphinx for easy, fast search. I also sometimes mess with Vue for fun, as I happen to be fond of it, but I never find that I need it.
No frameworks. No containers. It's all mostly boring and ancient. I use DigitalOcean for about 95% of everything hosting wise (and rarely AWS). Works beautifully, everything is simple, blazing fast, light on bloat and rock solid.
The simplicity is still out there, if you don't have to care about what anybody else thinks, if you're not trying to earn a living doing web development (everything I work on is self-determined). That's a big if unfortunately. If you are trying to earn a living doing web development it's understood that chasing the latest thing isn't optional, as you can't afford to miss an inflection.
I seriously doubt you're going to do a better job at security than the AaaS systems out there. I couldn't, and no-one I know could. It's a ludicrously complex and subtle field.
If there ever was a red flag in what you're saying, this is it.
Auth isn't "scary". But it is hard. You need to know what you're doing in order to implement it from scratch. If you think it wasn't hard, odds are you did it wrong.
I've experimented with just about every approach. Lately I've dumped all forms of social auth (the past couple of years). I won't allow FB or Twitter login, none of them deserve to be trusted with that.
I'm a big fan of try (the service) before you have to sign up, but I always find that among the most challenging aspects to get right.
I know everyone has a different opinion on auth, but I find it routine to do after all this time. The part I find most annoying is probably throttling / controlling abuse attempts vs legitimate users (balancing it well), it's tedious.
I’ve spent 14 years working for a small agency building these sorts of systems. I kept up with all the cool new stuff that’s come out and played with it but all we ever needed was 2 load balanced app servers with a single instance Postgres database and we ran some pretty chunky systems.
I’m now looking for a new position and this attitude has come up to bite me. I’ve always been dismissive of the new dangled complexity but turns out there are systems out there that churn through so much data that mongodb makes sense, and large teams of devs where splitting systems into separate services and writing reusable components is required which is where frameworks and inter process communication tools come in.
Most things exist because there is a need for them.
Currently working on a couple of trading systems (for physical objects, not financial). That's in the ecommerce sphere technically, although they're not monetary transaction based. The first one will hopefully launch in June. I might Show HN it.
Both work perfectly with the setup I described. I build in my wheelhouse though. I can build services like Stack Exchange, Quora, Wikipedia or Reddit (or most things in standard ecommerce, ecommerce platforms). I know what my stack is good at, and what it's not appropriate for. And at this point in my life I know well what I'm good at and what I enjoy, so I look for opportunities there.
I don't want to dismiss this without any arguments but please do the basic research before you choose the db for your next project.
The "promised efficiency" of any system is a complex question. The dynamic schema approach of MongoDB makes it trivial to update schema design on the fly so I am confused by "no real easy way to correct once deployed".
BTW : The recommended production setup is three nodes (one primary, two secondaries). This is what you get by default in MongoDB Atlas (you can't go smaller).
(I work for MongoDB)
If I want to gain a relative 100% increase in concurrent read/write access and transparent session failover to my application I have to procure two servers(with roughly the same performance lets put it at rawPerf=1.0 for simplicity) and a SAN/NAS with SCSI HBA and that would be it. All the necessary components will be running on those two servers and the application will have access to almost all capabilities of a single instance with a roughly twice the performance and fault tolerance. To do that in Mongo, I would have to procure 2 replica sets with 3 instances each(bare minimum to get the fault tolerance and not use arbiters which according to Mongo University is a bad idea) for the actual data and another RS for the configuration meta-data, which is another 3 instances. I will also need instances where I can run my "mongos" to route/consolidate my requests and to have fault tolerance I will need at least two of those. Now to do a break down of the different instances. From the two replica sets for data, I can use only 2 of the instances for writes and the remaining four only for consistent reads and that is only with the appropriate write concern. And while I have two instances for writes I am not guaranteed to get a consistent increase in write operations unless the data is at least somewhat evenly distributed. I will need six rawPerf 0.5 servers(assuming 0.5 rawPerf is capable to handle roughly half the data), that is a total of 3.0 so far. The configuration RS while not as demanding as the actual data RS will still require resources so I count it as roughly between 0.5-1.0 total for all three instances. And finally I have the "mongos" instances which although will not need disk space will need some CPU and the same amount of RAM as a regular instance in case the queries and not optimized, so I will have to give it 0.5 per instance. And the total amount of resources comes to 3.0+0.5+1.0=4.5. On the other hand with the Oracle RAC I would've needed 2.0.
As for the schema flexibility, from the Mongo documentation I take it that once the shard key is created it can't be changed arbitrarily. It can only be further fine-grained by adding more keys to it, however this is available from version 4.4. In order to change it cardinally, I would have to recreate the collection.
I'm sure you are well aware of all this, however I'm just stating my experience with MongoDB so far.
I am not familiar with Oracle RAC architecture but casual mention of a SAN fails to recognise the cost and complexity of even the smallest SAN. On the other hand MongoDB can run on dumb disks without a SAN or RAID required (though RAID can help with performance).
With you two node system loss of a node results in a 50% loss in performance whereas with MongoDB loss of a node will result in a secondary taking over the primary role with no loss in performance. You get what you pay for.
Setting up such clusters used to be a PITA until the advent of MongoDB Atlas. Now you can set them up with a few mouse clicks.
As regards shard keys. Yes, they are immutable, but the documents they index are not. So dynamic schema properties are preserved in a sharded cluster.
Postgre clusters can be configured in similar fashion.
I'm not saying that Mongo doesn't have it's strengths. However using the full potential of your environment requires much more planing and has a lot more pitfalls.
I was particularly discussing the implications on what the relative immutability of the shard key has on the data distribution and that it is not that easy to change.
Devops is in a similar state! There is growing consensus that "Container orchestration" is something like the right problem to solve, and people seem to like Kubernetes, but tools like Puppet, Ansible, Salt are still in heavy usage, and are still very useful, but they solve a different problem. Even within k8s there is debate about the proper container runtime (Docker has fallen out of favor for containerd). But all of this assumes total mastery of linux, ssh, bash, systemd, vim, sudo, mount, ps, and all the distribution variations.
Java is in a similar state! Widely considered "boring technology", Java (lang) 8 introduced streams and lamdas, which is a very different way to code (and hence, to think), and emphasizes functional style over object-oriented programming. Then you get to pick which Java you want (Oracle, RedHat, ?), and how you want it installed (installer, brew, unzip, docker), and now your build tool (Maven, gradle, play, ?) Then if you're making a "typical" webapp you have to choose your VCS (git, mercurial, svn, cvs), code hosting provider (github, gitlab), your starting point - Spring, Spring Boot, Dropwizard - which assumes you want REST, when in fact you may want to try GraphQL, which may lead you to nodejs, and it's complexity.
Picking system dependencies is similarly complicated. Components we can choose from - message queues (rabbitmq, kafka, activemq, ?), caches, proxies (nginx, httpd), and here we have to balance many considerations, such as "is there a widely trusted image I can configure and use as is?", and your options, and the details used to deploy them, will depend on every other decision you've made. In fact, all of these choices are made in away that affects some or all of the others, in a way that is complex and difficult to articulate. This is certainly why certain combinations get acronyms (LAMP, Jamstack, etc[0]), and why its very hard to have an intuitive picture.
Make that web devs, if at all. In many other places where software is written, it's closer to the opposite: Managers tend to be minimalists, and the more "adventurous" developers lobby for adopting newer libraries, or use a new language for some side-project.
Listing a stack of dependencies as a starting requirement is arguably not simple.
Simple to you personally because you’re proficient in each of these. But how long did it take for you to become proficient?
The relative simplicity is in that the stack is quite set and restricted, with no unnecessary pieces. I don't add to it just because the industry finds a new flavor of the week or something loses/gains popularity. Each part of the stack has a job to do and I don't add to it constantly or constantly turn over what's in it. That stack could remain entirely unchanged for five or more years easily. Where it can be avoided I don't use unnecessary incrementals that add dependencies or complexity (which will often resurface in the loss of reliability/predictability). I often don't use the latest versions of anything unless there's a very good reason to switch sooner than later. I might stick with Ubuntu 16.04 or 18.04 for the next decade if it were a safe thing to do from a security perspective. In that approach, I can place as much of my energy and focus on what I'm building as possible (since everything I build is mine, that's where my priority and interest is).
Web development was always a means to an end for me. It enables me to build things that I want to see exist. I don't love web development unto itself (I'm rather neutral on it), I love what it enables me to do. I grew up in the middle of nowhere Appalachia. An atheist, social liberal in a typical conservative region that was intellectually unfulfilling, uninspiring, non-ambitious, slow (it was also peaceful, green, and with very little crime). The Internet (and Web) showed up there around 1993-1994 and it was like something from another planet, my teenaged brain could see immediately what could be done with the open canvas and from then forward all I wanted to do was build on it. You're telling me there's this always expanding virtual space, seemingly infinite, and I can just build, and build, and build anything that I can think of? And it connects me up to millions (later billions) of other people? And it's not even very expensive to mess with? Holy shit, let's go.
So what I primarily care about is the thing being constructed, and I want my stack to be very reliable, fast and without many frills or unnecessary complexities. I don't want it to get in the way. I don't want to have to fight with it every time I begin a new project, I want to immediately get to building, with the stack being the 'ol reliable companion that just does its job.
If there's something far better nearby (that is reliable + low on complexity) with minimal learning curve, I'll consider it; I switched to PHP 7 very rapidly for example because the speed increase was such a considerable gain and it required very little time/effort to switch. I started utilizing Go because it was easy to learn, simple and fast (I worked with Java in the 1990s, and never wanted to go through that again); Redis is much the same story, I use it for all sorts of things (from caching to various throttling tasks) and it was pretty ridiculously easy to start using vs the enormous value I derive from it. I'd be happy to keep using my current version of Redis for the rest of this decade. I've been using Photoshop 7 since 2002 because it just works and handles ~95% of everything I need in that space (and they can't do anything to force me to upgrade).
It's also worth noting that I handle every aspect of building and operating a service in the beginning. So this adds emphasis on not shaking the stack unnecessarily, the time costs can become large fast.
Despite all the mess, I have an easier time getting buttons on a screen and doing things sanely (once all the fuss is set up) compared to trying to get the ball rolling in Qt/GTK/etc (especially if you're not using Java or C++)
But then the Qt UI:
* needs to be (re)compiled for each platform
* needs to be re-shipped on each change
* is not a client-server application (all runs on the client)
* has "desktop styling" by default
I think of it like democracy. It is ugly and terrible, but still better than all the other options.
HTML is simply a terrible GUI base, JS is quite great nowadays and CSS would be great, but has to provide way too much of what HTML should be doing. But the web ui frameworks are just barely getting at the level of where native frameworks have been in a decade.
And there are plenty of other “layouting primitives”, all of which are quite cumbersome. And due to HTML encoding some form of semantic meaning only (though seldom used even for that), drag n drop tools can’t generate easy to read/modify output. Also, without js frameworks, you can’t really just embed another component into it trivially.
And I’m not trying to shit on web tech, JS has absolutely overcome its shitty past, and is quite a likable language nowadays, and CSS is an extremely powerful and expressive system (though this latter is due in part to how shitty html is). My only gripe is with HTML that is simply not fit for the task (as it was never meant for that).
If by structure you mean things like hbox/vbox then no, html is not supposed to do that. HTML should only represent the semantic structure.
Swing, Qt, et al do not have great answers to this problem, and definitely not superior ones than css.
but I agree in general with your statement.
There are a couple of exceptions for interfaces that are genuinely unconventional, or that deal with multiple spacial dimensions, or that are primarily representing graphs and visual/audio data. But most interfaces should be representable in pure text.
This argument that "the web is only for documents" is missing the point that most applications are just interactive documents when you really break down their UI. A labeled tree is a fine way to represent user-facing state for most apps, and most apps would benefit from exposing a more semantic interface to users that was easier for them to manipulate and read programmatically.
If I had to pick a stack to do a new web app entirely in canvas, I'd probably choose to port a ton of interface components from AS3 into PixiJS... but the point is, where have we gotten? Ten years from now we'll be writing apps the way they were written in 2010 -- inside a black box in a canvas or VM. The HTML5/JS revolution has been a sham from the start, just a way for one corporation to dismantle another with the side benefit of forcing all of us to rewrite our code from scratch in a crappier language.
Anyway, that's not very important.
What web apps never had is a visual app builder as popular as the first Visual Basic for Windows 3. We had some tools like that (example Jwt [2]) but none of them got a critical mass of users. Maybe it's difficult to match Visual Basic's success because Microsoft controlled the tool, the operating system and the language. If this is the case the only current candidate is Google, because of Chrome. They are investing on Flutter and Dart now but making them prosper on the web looks like a uphill battle. Much easier on Android.
Like I wouldn't want to have to deal with an interfrace like facebook in native stuff. I don't think it's impossible, but I feel like it would require a lot more up-front design and correct engineering.
You're right about XML being a medium, just kinda my memories of working with this stuff.
Yeah, its true — though you can leave an area empty where you will dynamically load one from a set of already drag’n’drop created layouts.
CSS:
.vbox, .hbox { display: flex }
.vbox { flex-direction: column }
.vbox > *, .hbox > * { flex-grow: 1 }
HTML: <div class="hbox">
<div class="vbox">
<button>Top left</button>
<button>Bottom left</button>
</div>
<div class="vbox">
<button>Top right</button>
<button>Bottom right</button>
</div>
</div>
Or was that a rhetorical question?ah, yes, the famous difficulty of getting buttons on a screen in Qt https://streamable.com/bs5fxk
By the way - Qt and GTK are super-outdated ways to do GUI in C++. Popular, but outdated.
As an aside, do "modern" developers still write GUI applications at all, since everything is on the web anyway these days?
I even write terminal user interfaces sometimes to interact with servers that don't have a desktop environment installed.
The films you watch on TV or at the cinema were not created (edited, VFX) using a web browser for a start, and the User Interfaces to those applications are pretty Graphical by anyone's definition...
to add on this, the reference UI toolkit for building VFX tools is Qt. Maya, DaVinci, Lightworks, Nuke... are all Qt-based.
Not disagreeing with what you said, but "not having anything to do with the web" isn't as clear cut as it used to be and web technologies are increasingly showing up in unexpected places.
You want to be utilizing the features C++11, C++14 and maybe even newer versions of the standard allow you to use, to avoid unnecessary boilerplate, repetition, and arcane-ness of syntax and semantics.
Similarly, the GUI toolkit should not be based on C-like or C++98-like design patterns, when newer versions of the standard allow replacing them with more convenient patterns.
Here's one example, from the Nana C++ GUI toolkit:
#include <nana/gui.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/widgets/button.hpp>
int main() {
nana::form form;
nana::label label{form, "Hello, <bold blue size=16>Nana C++ Library</>"};
label.format(true);
nana::button button{form, "Quit"};
button.events().click( [&form]{ form.close(); } );
form.div("vert <><<><weight=80% text><>><><weight=24<><button><>><>");
form["text"] << label;
form["button"] << button;
form.collocate();
form.show();
//Start to event loop process, it blocks until the form is closed.
nana::exec();
}
This is not perfect IMHO; for example, I don't really like the confusing div string with the many < and > signs. But you can put this in a text editor, build it with `g++ -I/path/to/nana/includes -L/path/to/nana/libs -lnana` - and it will just work, on various platforms. No secret sauce, no need for a bunch of IDE dialogs or any special configuration or action. #include <QtWidgets>
int main(int argc, char **argv) {
QApplication app{argc, argv};
QWidget widg;
QVBoxLayout form{&widg};
QLabel label{
R"(Hello, <span style="font-weight: 600; font-size: 16pt; color: blue;">Qt C++ Library</span>)"};
QPushButton button{"Quit"};
button.connect(&button, &QPushButton::clicked, [&widg] { widg.close(); });
form.addStretch(0.1);
form.addWidget(&label);
form.addStretch(0.7);
form.addWidget(&button);
form.addStretch(0.2);
widg.show();
app.exec();
}
Builds with g++ example.cpp -I/usr/include/qt/ -I/usr/include/qt/QtWidgets -fPIC -lQt5Widgets -lQt5Core
Here's also how the two programs behave in practice: https://streamable.com/brltmctl;ds: now that I saw it in action, I know I can instantly ignore anyone who says that nana is a suitable replacement for Qt.
... could you precise that more ? I'm literally just making "new project" > design view > search for the button component > drag'n'drop it ? How can it get more simple ?
(opening a text file and writing "Button {}" is definitely more complicated if we're talking about teaching to beginners)
if teaching beginners to programming sure, if teaching a programmer beginning QT development no.
as someone who teaches programming in university, that's definitely not true, less than 1 in 20 students has the reflex of looking for any kind of documentation (even after showing it to them)
No, it does not.
CSS allows some mitigation of this problem.
Web is a large domain of knowledge. It isn't particularly hard in terms of math, algorithms or mysterious unknown proprietary APIs. But there is a lot to figure out. What parts are important, what parts can I skip.
If by basics you mean HTML, CSS and JS. Sure. Good start. But you could also start with a framework and learn from the middle and out or the top down.
Not everything has to be learned bottom up.
Either way. It is not trivial.
The numbers speak for themselves. I don't need to convince you. There are more web developers than in any other programming field. So it must have some property that makes it easy to get started or at least some kind of incentive to make people go through the initial hurdle.
Anything worth studying is slightly overwhelming at first, but to say that everything continues to be overwhelming once you know the basics is wrong. Knowing a little bit of the grammar and some words will help you understand better Mandarine. Not knowing anything about the language will make it appear as some alien technology.
No skill starts growing at the middle. Nobody teaches mathematics by starting with abstract concepts. We don't learn new spoken languages by studying literature from the get-go. So getting the pedagogics right is part of the success.
Should I hand-type static HTML to do this? Is that what modern web developers typically do? Will learning HTML, CSS, and JS teach me how to use a backend? Which backend language should I pick? Should I use a database? Which one? Or should I use AWS? Is all I need HTML, CSS, and JS?
PHP, is that a good backend starting point? That seems to be pretty fundamental, since over half of all websites use it. A LAMP stack, right? No? What about Python? Ruby? C? Rust? Arc? Elm?
Should I use Node? If so, what is the typical Node setup?
Should I use webassembly? That's a fundamental and new browser technology.
How do I compress and minify code and images to be served? A makefile, right? That's the typical way to build things in my software world.
This is a good resource that will walk you through the cutting edge web development technologies, starting from the very basics and progressing to the more complex matters in the end. Highly recommended.
Is this a React thing?
Waiting for the extra request(s) adds lag time, makes back/forward navigation clunky, interrupts what I was doing if I already began interacting with the page (eg. infamous relayout / unwanted scroll) and sometimes breaks snapshotting tools like archive.is.
I don't mind pages with javascripted controls, but their initial content should be included in the payload with the initial page load. Don't the frameworks have tools to help you do that?
The problem with that is that it pretty much requires you be running node on the back end too. If your back end is built with say PHP or Ruby, you’d need to call out to a node process, which is potentially a lot of additional complexity, time, and expertise.
Otherwise you'd be trying to implement everything once in JS and once in PHP/Ruby
An alternative is to just serve the HTML from your ruby/php and then take over in the frontend, but this is more complex and not worth it in my opinion.
This is still incredibly common for apps that are mostly server rendered but use React/Vue etc "sprinkled" through the codebase for more complex bits of UI.
That UI/UX is getting slower as everything is getting faster is a sad reality of the times. But I guess that's the price of faster iterations, easier developer flows and a building on top of the lates greatest framework.
[1] - https://css-tricks.com/say-hello-to-css-container-queries/
I’ve had pretty decent success using this library.
But the most significant feat React achieved IMO is how easy to write asynchronous hiearchical actors (from actor model) with it (kind of like erlang vm).
Context enables dependency injection and ownership management. Effect and state enables object ownership and lifetime management. Js timers, (i.e. setTimeout, setInterval, queueMicrotask, promise/async), help making an object living asynchronously as if it has its own private thread.
Yes, those are similar concept of lifetime and ownership Rust have, but instead of functions/blocks the object (value in memory) is owned by/shared with components. And of course these are not enforceable by compilers/transpilers/linters due to them not being a javascript-primitive, but at least React helps organizing those things in a lot more explicit and clear manner.
The problem started a decade or so ago with Node. Too many people only learn JavaScript, become psychologically dependent on it, and they all collectively took it too far outside of a browser.
ECMAScript is a general purpose standard, but it was invented retroactively. Node is not ECMAScript in a server-side ECMAScript engine, it's JavaScript in a browser JavaScript engine. That's just too much of a force fit, and has wasted too much potential for me to say anything positive about it.
* Lexical scope natively without syntax or conventions
* Functions as first class citizens
* Inheritance, classes, OOP are not forced on you and can be ignored/omitted entirely from your code
Those few things are what has kept me hooked on the language.
> Node is not ECMAScript in a server-side ECMAScript engine, it's JavaScript in a browser JavaScript engine.
What does that even mean? The APIs are completely unrelated and Node does different things that don’t make sense in the browser.
I assume you mean over the alternative, dynamic scoping like in e-Lisp. But you realize that JavaScript's scoping rules are entirely wonky, e.g. that "var" declarations are lifted to the function level?
[1] https://www.freecodecamp.org/news/what-is-the-temporal-dead-...
A good example would be the scoping in for loops and maybe arrow functions. For loops are goofy but virtually never an issue, and arrow functions are awesome.
What language of the last 28 years doesn't "natively" lexically scope its variables?
- `const fooFunc = () => {}` is treated differently than `function fooFunc() {}` in declaration and subsequent access.
- A function's invocation context changes depending on how it was declared (fat arrow vs. function declaration)
Don't get me wrong: I love JS, but this is not one of the things I felt made it intuitive.
>What does that even mean? The APIs are completely unrelated and Node does different things that don’t make sense in the browser.
I have taken the privilege of rewriting the quoted part of the parent comment,
Node runs javascript on the server side in an engine built for the browser. It does not run ECMAScript with an engine specially made for server side apps.
JS is like PHP... only a popular language because it's been around a long time and it's easy to get started. Otherwise, there are SOOO many better programming language out that the ONLY reason JS still has traction is it became the "default" web language.
Maybe try some other languages...
Why do you think it's not a good language for this?
Also, I see a lot of value in using a one single language that can truly do everything: frontend, server, and scripting.
I guess you could use Python or Ruby like that with Wasm, but I haven't seen evidence of people doing that.
But I am hopeful that when I finish reading the article I will not have to reuse my jquery / d3 based framework for doing quick data viz things (which I only started doing with great reluctance because people don’t go wow over tabular data even if the data is wow-ing. The first request to make it pretty, i switched to mono space fonts. But jquery is showing its age.
Because the language wasn’t planned to support all of this from the start, we just shouldn’t use it.
There’s lots of great reasons to use a full JS / TS stack. There’s lots of reasons not to.
Doesn’t mean it’s inherently bad. This is the same logic used against PHP every day yet it’s used all over.
Do you have any evidence for this? Because there's plenty of reasons why you'd share the same code in the browser and the server. Being able to do SSR and sharing validation logic are two huge and obvious reasons. Ever try to exactly duplicate validation rules between the browser and PHP? What about when they use weird regexp rules?
I have a site builder codebase that renders previews instantly as you make changes, then uses the same code on the server to render the HTML and CSS for visitors. That would be otherwise be outright impossible to do without writing the same code again in another language.
Let me give you one example:
Lets say you want to validate if a string is a valid URL. What is a good way to do this in JS?
Just for reference in Ruby for example I can do:
URI.parse(input).kind_of?(URI::HTTP)
No gems or any other engines needed.Seems like JS standard library is better than I thought.
PHP is adding support for FFI to any C ABI-compatible language, and you can run the exact same code in the browser via emscripten or a WASM polyfill. As a bonus, emscripten/WASM compiled code will also be more efficient in the browser than plain JavaScript or Typescript.
Small gains compared to the cost of implementing. 10-20%. Now you're asking your full-stack developers to know PHP, JS, C, and WASM.
I've commented this many times before, but having a system where everything is on the same tech stack (i.e. front end in TypeScript with React, back end with TypeScript on Node) has resulted in gargantuan productivity gains, especially for a small team where it's trivial for people to cross front end to back end seamlessly. For contrast, I know many teams with a backend in Python and a frontent in React/JS, and I've worked on some teams with that setup. In my opinion it's virtually all downside compared to a backend in TS, as Python and TS are quite similar from a web programming perspective (I'm not referring to Python's advantage in data science tooling), so all it basically is is a barrier to your front end folks being able to make small enhancements on the backend quickly.
Furthermore, TypeScript is a great language and I find myself being so much more productive in it than I was in Java, especially when it comes to refactoring.
JavaScript most definitely has its warts and head scratchers after being around for 25 years, but I feel like most of these oddities (truthy/falsey, typeof null === 'object', undefined vs. null, etc.) can be learned in an hour and written on a half page.
Is there any Typescript backend framework as mature as Django?
> Python and TS are quite similar from a web programming perspective (I'm not referring to Python's advantage in data science tooling), so all it basically is is a barrier to your front end folks being able to make small enhancements on the backend quickly.
So on the on hand, the languages are "quite similar", yet it cannot possibly be expected that frontend people learn more than a single language? Something doesn't add up here.
GP is pointing out that it is advantageous to have a single language on both front end and backend. And somehow you arrived at “developers cannot be expected to learn more than one language.”
There ARE big advantages to having the exact same language (as opposed to similar languages) on both client and server, especially in an SPA where you want to render something initially on the server, but then update it using the same logic later on the client.
Because he considers it a "barrier" to have to switch between languages to do backend-only changes. Which is a completely different use case than the one you're describing.
For an SPA where you're essentially doing frontend on both ends, yes, that's obviously easier when you're only doing it once.
But that's not the general case, and I'd argue that transitioning between different mental contexts for components you're not regularly touching is always going to be a hurdle to developers, regardless of the language used. Blaming it on the language is an useless red herring.
Also, what if you just have frontend developers who straight up don't know Java or vice versa? I don't see how having a shared language could ever be a bad thing.
The classic example is of course validation, but plenty of other places it can come up.
But as you can see, there's n+1 standards for it, and in practice none of them has a Javascript implementation good enough for productive use. So it's more a "what if?" scenario, had Angular/React/Vue not taken off.
No TS framework is as old as Django, and if you're looking for "Django for TS" you won't find exactly that, but Next.js is the current reigning champion for server-side frameworks right now, according to the popular "State of JavaScript" survey https://2020.stateofjs.com/en-US/technologies/back-end-frame... Next is a "both-side" framework, allowing it to do stuff you just can't do in Django.
If you want something much thinner than Next (and thus much thinner than Django), there's Express.
> yet it cannot possibly be expected that frontend people learn more than a single language?
The problem isn't learning two languages, it's interop between two languages.
So by that graph, it has a good chance of being entirely deprecated and/or abandoned in the next 3 years, what a wonderful foundation for a backend.
And it doesn't even have any support for an ORM? Neither does Express? Having to hand-write every single query and migration like it's 1999 again is hardly the cutting edge of IT stacks…
> The problem isn't learning two languages, it's interop between two languages.
How so?
For about two weeks, then one of them becomes deprecated again and you have to migrate everything all over again…
And how stable was their API over the last five years? It hardly counts if over 5 years the APIs change so much they're basically different libraries at the end.
Django's code churn for even complex projects is on the order of single digit hours per year at worst, the remaining 99.99% of time can go into delivering things customers care about.
I can't say I've seen that sort of stability in anything Javascript-related, apart from maybe jQuery projects. (Which of course have their own problems because jQuery is the wrong abstraction usually.)
But in both cases, there's little reason not to upgrade because your old code will still work fine on the new version. And indeed you're free to continue writing new code in the "old" style. Adding additional API surface after 3 years while continuing to maintain and support the old API is hardly unstable!
I don't think the situations are equivalent, at least not to any meaningful degree.
With C11, your old code continued to work, your old libraries continued to work, your tools probably required at most minor configuration changes, your new code and libraries were still mostly the same style even if you also used some of the new features, and anyone you were working with who knew one version could very quickly and easily adapt to the other.
With React, you can stop after your old code and libraries continuing to work, except that you might not be able to use those old libraries from new code any more and they might no longer be getting much ongoing development. You still effectively have to learn a whole new version of React API, and find your way around a whole new ecosystem of libraries and tools that operate alongside that new API. So does everyone you're working with. You have the backward compatibility, but only by having two completely different coding styles in the same code base, and if you're hiring new people who only know the new API and ecosystem, they now have to learn the old one as well to work on your code.
If the original point was about whether tools are stable for a long time so you don't have to worry about making major changes or learning big new things, one of these situations is not like the other.
And, this is to be expected, because the React Core team prioritises backwards compatibility as one of the key features of the library. See: https://reactjs.org/docs/faq-versioning.html#commitment-to-s...
This is why features and deprecations are announced years in advance of the changes and that when code to support a feature is eventually removed they produce a compatability polyfill in order that teams do not need to do big-bang rewrites (e.g. https://github.com/reactjs/react-lifecycles-compat).
Maybe you disagree with what backwards compatability is? It doesn't mean that new features are backported to old verions of React or that the recommended syntax/API never changes. It does mean that you can rely on modern versions of React being able to run code you wrote 5+ years ago.
I find complaints about the stability of JavaScript kind of ridiculous. Everybody is literally still transpiling down into ES5 (2009) and most only dropped IE11 this year (2013), the main libraries/frameworks tend to make expert use of semver, polyfill old APIs and release codemods to automaticallly perform syntax upgrades. I'm interested whether there are any programming language ecosystems that have done this better? As far as I can see Python 2 to 3 caused hard rewrites, etc.
I don't think anyone is disputing that React is still backward compatible with the old API. The point is that there is a difference between having two APIs that both still work and having one stable API.
Backward compatibility is implied if your API is stable, but that's only one aspect of stability and there are many other practical questions. Will documentation and tutorials from a few years ago still be relevant? Will someone joining your team need to learn anything different before they can be productive? Will other libraries you have used previously that integrate with React still work with your new code? Will new libraries you might want to use today that integrate with React work with your existing code that uses the old React API?
Having multiple integrations with different APIs or different libraries to do the same job is a form of technical debt, and sometimes it can become quite expensive.
I find complaints about the stability of JavaScript kind of ridiculous. Everybody is literally still transpiling down into ES5 (2009) and most only dropped IE11 this year (2013), the main libraries/frameworks tend to make expert use of semver, polyfill old APIs and release codemods to automaticallly perform syntax upgrades.
Well, there are a lot of things you've said there that aren't quite the whole story.
A lot of modern build processes don't just target vanilla ES5 any more. They'll target something like the most recent two versions of the evergreen browsers and any specific minimum versions of other browsers they need for their particular market. This produces more efficient production code because all major browsers now support much more recent JS natively.
There are also some modern JS APIs that you can't completely polyfill. You have to target a runtime environment that provides real support for those.
Semver is great when it works, but when your culture is to have absurdly deep trees of nested dependencies with hundreds or even thousands of indirect packages involved, things still break often enough to notice.
Major libraries might provide automatic codemods for straightforward, unambiguous changes. However, sometimes you can't divine the original developer intent automatically. Then some manual intervention is required.
I'm interested whether there are any programming language ecosystems that have done this better? As far as I can see Python 2 to 3 caused hard rewrites, etc.
Almost all of them, in my experience. JS, including the ecosystem and culture around it, has by far the worst stability story of any major language I have used.
This is partly a cultural problem. Writing code to last simply isn't part of the mindset or skill set of many people working in web development.
Many tools and libraries we rely on for the most vital functionality are FOSS with at most a small team working on them or maybe just one single person. That means even really successful and widely used projects can easily fade away as those behind them lose interest.
Much of what is built on top is written by people being paid astronomical amounts of money who will job hop in less than two years for even greater astronomical amounts of money. They might make it to senior/staff levels a few years into their careers or maybe become the CTO at a startup, never having either built a new product from scratch or maintained one for 5+ years to see where those decisions they made earlier on come back to haunt them. Then those people are the ones leading and mentoring the next generation of newbies working in the JS community, and the cycle continues.
It's also partly a technical problem. The language doesn't provide much to help with building large-scale software and maintaining it over the long term. What it does provide is relatively recent. The tooling is relatively weak, well behind the state of the art for many other popular languages, which in turn lag the more research-focussed languages where radically different ideas get explored.
I believe a big factor in these cultural and technical problems is the way that you can just change your code and push out a new version any time you want since you have complete control over the servers hosting it. It has also become the norm to depend on online APIs provided by other parties who can do the same. This means concepts like managed releases and support lifetimes and stable interfaces are given less importance.
In striking contrast to all of that, there is code I worked on professionally a couple of decades ago that was written in C and would still compile and run on any modern platform with few or no changes. Likewise, there are professionally developed libraries in ecosystems like Java and .Net, which are platforms widely used for large-scale enterprise software development, that have been around for a decade or more and are still as active as ever. Even in Python, the 2-to-3 shift took place over about a decade, taking the community and the tools and libraries along with it. The language is still mostly compatible with Python 2 code, and there were tools to mechanically update code for most of the main breaking changes, so many of the popular libraries from the Python 2 era are still available and working fine with Python 3.
The only other language I've used where instability was as awful as JS world is Haskell, and that's obviously not a mainstream language in the same sense. It's mostly used by a community who are very open to trying big new ideas and changing how they work frequently, and that's part of its attraction to those people and also probably a reason that ideas from Haskell sometimes drift into more popular use over time but the language itself remains an eccentric choice for production use.
> The point is that there is a difference between having
> two APIs that both still work and having one stable API.
This is the direct effect of high levels of backwards compatability. You can't change APIs; you have to create new APIs and then deprecate previous APIs. That's the only way of avoiding a breaking change (other than never changing something and endlessly layering leaky abstractions on top of it). > Having multiple integrations with different APIs or
> different libraries to do the same job is a form of
> technical debt, and sometimes it can become quite
> expensive.
I disagree. If you don't need to do any work to something it has zero cost. Write tests to its behavior and it can be a blackbox to your team until you truly need to deal with it. > A lot of modern build processes don't just target
> vanilla ES5 any more. They'll target something like
> the most recent two versions of the evergreen browsers
> and any specific minimum versions of other browsers
> they need for their particular market.
This isn't mainstream yet. Until very recently the majority of companies were targetting IE 11. A lot of companies changed this in 2020 (Microsoft, Atlassian, etc), and additionally due to Node finally supporting ESM and the release of Snowpack and Vite, many open-source developers are finally targetting something greater than ES5. But you're wrong to imply that it's the norm. > There are also some modern JS APIs that you can't completely polyfill.
People tended not to use these due to needing to support older browsers. But sometimes APIs could be partially polyfilled to an extent that was sufficient enough to use them (like `Proxy` with `proxy-polyfill`). > Almost all of them, in my experience. JS, including the ecosystem and
> culture around it, has by far the worst stability story of any major language
> I have used.
OK, yeah, I'm not seeing this at all. For a start, TC39 has rules against breaking the web (see "One JavaScript", etc: https://tc39wiki.calculist.org/about/faq/). It's due to this choice that we still have mistakes like `typeof null === 'object'`...Also, I don't think your opinion has wide acceptance within the industry. See comments by Kyle Simpson (https://twitter.com/getify/status/1195362162857910273) or even Yaron Minsky decrying their inability to fix old mistakes (https://twitter.com/yminsky/status/1067926815992410113).
Of course, TC39 is not perfect and there are very rare occasions that minor incompatabilities are introduced (https://tc39.es/ecma262/#sec-additions-and-changes-that-intr...) but "the worst stability story of any major language" is quite an absurd statement if you consider the minutae that has made that list.
> [...] Much of what is built on top is written by people being paid astronomical amounts
> of money who will job hop in less than two years for even greater astronomical amounts
> of money.
This is all true. But most of the products these people create are also being replaced every 2 years so it's not as big an issue as you think it is. We're able to go back to projects written in JavaScript 10+ years ago and they work in newer browsers, but the majority of projects are thrown away or rewritten for completely different reasons before this point (normally employee attrition on smaller projects is enough to lose the knowledge required to fix bugs or add features and so companies rewrite to get back that understanding).I guess a form of backwards compatability we don't have is the ability to upgrade a tooling dependency through multiple breaking changes and not find out that the configuration system has been completely overhauled. That is unfortunate. But the code will build/run when you pull it down the first time from your repository. If you then decide to make upgrades to use new tooling you have to know what you're doing -- tooling upgrades are confusing.
> The language doesn't provide much to help with building large-scale software and
> maintaining it over the long term. What it does provide is relatively recent.
> The tooling is relatively weak, well behind the state of the art for many other
> popular languages, which in turn lag the more research-focussed languages where
> radically different ideas get explored.
I disagree. It has testing frameworks, it has automated code formatters, it has linters, it has type checkers, it has tools to automate rewriting 10,000s of lines of code via the AST, it has tools to automate producing changelogs, it has tools to visualise dependencies, it has tools to improve the performance of scaling a monorepo, etc. Some of these tools are significantly worse in other programming language ecosystems or do not even exist. > Even in Python, the 2-to-3 shift took place over about a decade, taking the community
> and the tools and libraries along with it.
Are you trying to tell me that a breaking change that was so bad that it took almost a decade for the community to complete is something that we should aspire to?I don't think that JavaScript has serious backwards compatability issues at all. Certainly not in the language. Generally not in the major libraries (React, etc). It perhaps has some issues in breaking changes to the tooling which could make upgrades very confusing (e.g. Babel changed how configuration worked a few times and this was painful due to obscure error messages).
On the other hand, I will say this: it is true that the open-source JavaScript community is high on modularisation, scrappy/innovative and prone to releasing something for fun and then ghosting their consumers. In situations where the quality of the package was high enough that you don't need to change anything this presents no issues, but sometimes when you've used a package with a broad vision that the creator has later on bowed out of fulfilling or which has later on produced lots of bugs, that then leads to engineers swapping it out for newer, shinier or better maintained (for now) things... That is the 'stability' issue that we tend to have issues with and it's the reason that I (and a small minority of other people) have started to 'vendor' or inline code into our projects. As Tom MacWright recently wrote "One of my golden rules is that you shouldn’t blackbox things you don’t need to. I like to “use dependencies for efficiency, not ignorance.”" (quality article by the way: https://macwright.com/2021/03/11/vendor-by-default.html).
I don't see how that follows at all. You can't make breaking changes to APIs, but it's fine to extend them or even expose different levels of abstraction as long as the underlying model you're using stays consistent and you provide suitable defaults where necessary.
If you don't need to do any work to something it has zero cost.
This is tautological, but if we're talking about a typical web application then you are working with that code, every time you make a new build. It might sit there as an untouched black box for a while, but if it has any kind of external dependencies or it relies on anything that could change about the language, platform or other parts of your own code, then there is always a risk that it will later break, and then you'd better hope you have someone around who still knows how to fix it.
This isn't mainstream yet. Until very recently the majority of companies were targetting IE 11.
You've made several claims like that, but in the absence of data there's no way to know whether you're correct. For example, preset-env has been in production for 3+ years now and had an extended beta/RC phase before that. It's true that it defaults to ES5 if you don't configure it, but the Babel docs explicitly recommend that you do, and it is literally a one-line change in your package.json to do something more modern and efficient based on Browserslist unless you genuinely need that degree of backward compatibility.
Of course, in some cases, even quite recently, you did need that. A relatively small proportion of business customers stuck in the IE11 era could still represent significant revenue at risk if you dropped support. But it will take more than an unsupported assertion to convince me that this has been the norm for most web development for quite some time. At one of my businesses, we've had literally no-one using IE11 visit a B2C web app for years. At another that mostly does outsourced development work, we've excluded IE support contractually for a long time and no client of any size has pushed back in years. There must be many thousands of other small businesses out there like mine, and I have to assume that they have senior devs who sometimes read the docs for the tools they use too.
OK, yeah, I'm not seeing this at all.
I think that's because you persist in interpreting my comments as being about JS itself, when I've tried repeatedly to emphasize that it is the culture and surrounding ecosystem that are the bigger problems. I'm not talking about the technical committees defining the language. I'm talking about the developer experience of using it in production.
On that score, I stand by my earlier comments. After many years of programming professionally, using many different languages, I have yet to find any more flaky ecosystem than JavaScript's other than the deliberately fast-paced world of Haskell. Nothing else even comes close for how much wasted effort I've seen over the years just keeping all the plates spinning so nothing falls off and breaks.
But most of the products these people create are also being replaced every 2 years so it's not as big an issue as you think it is.
Yes, I understand the commercial argument. The bizarre economics in the web dev industry sometimes make throwing entire projects out and rewriting every 2 years affordable. That doesn't mean it's not a horribly unstable environment, which was the original point of contention, nor that disregarding traditional wisdom about the dangers of big rewrites isn't a bad idea. It just means parts of the industry are so rich that they can afford to have a toxic culture where quality is a second-class citizen and the only answer to producing so much unmaintainable junk is exactly what you said. It's much nicer working in other parts of the software industry where what you're producing is expected to work and to last, but sadly it doesn't always pay as well.
It has testing frameworks, it has automated code formatters, it has linters...
And these kinds of things are advanced tooling, in your view? We had those in our IDEs for building desktop software back in the last century. Except they were automating rewriting millions of lines of code on 2000-era PCs, not 10,000 lines of code on 2020-era PCs.
I'm not sure what other popular programming language ecosystems you think don't have these kinds of tools today or have tools significantly worse. But in web development, TS is the current hotness because the developers finally realised that explicit typing is helpful for building and maintaining more than small systems, and not so long ago build tools adopting tree shaking was being heralded as a great advance for reducing the size of builds, and before that we got the radical new concept of a module import/export system so you could write code in more than one file without jumping through crazy hoops, and before that we discovered that immediate mode UIs and declarative specs are a thing. All of these ideas were well known and widely used elsewhere in the programming world much, much earlier.
Are you trying to tell me that a breaking change that was so bad that it took almost a decade for the community to complete is something that we should aspire to?
It took that long because that backward compatibility and stability we've been talking about meant a lot of older projects didn't need to move any sooner. And yes, having a platform where you can write code and it keeps working and the ecosystem still positively supports it for another decade is definitely something we should aspire to.
Generally not in the major libraries (React, etc).
Don't tell that to anyone who uses React Router. Or who builds their app with Webpack. Or Babel, as you mentioned. And again, it's important to note that you only said backward compatibility here. If we're talking about the broader concept of stability then you also have to include high profile libraries like Moment giving way to more modern alternatives because although they still work, they don't lend themselves to modern programming styles or play so nicely with other tools.
These comments are getting long and I suspect we may have to agree to disagree on some of this, but if you haven't worked much on software in other parts of the industry, I encourage you to look at what is considered the norm and acceptable practice in fields where better quality and greater longevity are more highly valued. If we built security libraries or the embedded software controlling industrial machinery the way a lot of online companies build their web apps, we'd be lucky to survive the night.
You wrote:
> there is a difference between two APIs
> that both still work and having one
> stable API.
As I explained, "this is the direct effect of high levels of backwards compatability. You can't change APIs; you have to create new APIs and then deprecate previous APIs."I thought my point was obvious, but will explain it with more words:
If never making breaking changes to APIs is a strict requirement, all API changes must be additive. That means backwards compatibility entails the existence of more than one API to do the same thing. It seemed like you were insisting that there should be "one stable API" that never needs changes instead of "two APIs that both still work" and this is unrealistic for something that has existed and responded to changes in use for ~25 years.
> if it has any kind of external
> dependencies or it relies on anything
> that could change about the language,
> platform or other parts of your own
> code, then there is always a risk that
> it will later break
This is a useful point. For dependencies that never make breaking changes you will be OK. But if the dependencies you have are likely to change and likely to be upgraded elsewhere in the codebase and potentially might make breaking changes, we should consider them a risk to the project.I agree that this should be highlighted -- but, in the context of what you were talking about, which was with regards to code that uses old features of React, you are incorrect. As I mentioned to you, compatibility packages exist for all old React lifecycle methods and deprecated patterns. Therefore, by design, you are not being forced to upgrade the patterns in old parts of your codebase.
I am trying to make specific claims about concrete things that I can evidence. The existence of compatability packages for features that have been deprecated for 5 years invalidates a specific argument about needing to upgrade old React code due to changes in the API.
> You've made several claims like that,
> but in the absence of data there's no
> way to know whether you're correct.
> For example, preset-env has been in
> production for 3+ years now and had
> an extended beta/RC phase before that.
> It's true that it defaults to ES5 if
> you don't configure it, but the Babel
> docs explicitly recommend that you do.
> [..]
> But it will take more than an unsupported
> assertion to convince me that this has
> been the norm for most web development
> for quite some time.
If it defaults to ES5 why are you asking for me to provide evidence as to whether companies have generally targetted IE11? It is the default; it is very unlikely that there is a majority of people that are configuring it... > But it will take more than an unsupported
> assertion to convince me that this has
> been the norm for most web development
> for quite some time.
My claims are the following:1. ES5 has been the default for front-end packages published to NPM since it was released (https://twitter.com/_developit/status/1289317757146693632). (I'm linking to Jason Miller's tweets since he has been the one most obssessively pushing for this to change. The problem we've all been having is that the `package.json` fields do not make it explicit what syntax a package is using.)
2. IE11 is in rapid decline (https://twitter.com/TheRealNooshu/status/1348955568459968515) and only recently have big corporations dropped support for it (Atlassian (March 2020): https://blog.developer.atlassian.com/retiring-ie11-support-f... ; Microsoft 365 (August 2021): https://docs.microsoft.com/en-us/lifecycle/announcements/m36... ; LinkedIn, Twitter, etc (2020): https://twitter.com/swyx/status/1260627626739130369). As I said "most only dropped IE11 this year". I guess I was off by one year, but I was talking about recent announcements.
For context, this was to evidence my opinion that the JavaScript community has been very slow moving and careful to output code that is executable by old browsers to the extent that we've supported a browser released in 2013 and used a syntax released in 2009.
> And these kinds of things are advanced
> tooling, in your view?
Check back to my text and you will see that I made no such claim.You claimed that "the language doesn't provide much to help with building large-scale software and maintaining it over the long term" so I demonstrated that we have all of the necessary tooling to do so and invalidated this.
> We had those in our IDEs for building
> desktop software back in the last
> century. Except they were automating
> rewriting millions of lines of code [...]
Can you point me towards examples of the usage of AST rewriting tools that are actively being used by open-source library maintainers in other ecosystems to help their consumers do upgrades in large code-bases (e.g. I can see that `clang` has AST tooling, but I don't see examples online of this being widely used: https://devblogs.microsoft.com/cppblog/exploring-clang-tooli...).Within the JavaScript ecosystem this is quite popular (1. https://github.com/reactjs/react-codemod ; 2. https://github.com/mui-org/material-ui/tree/HEAD/packages/ma... ; 3. https://github.com/emotion-js/emotion/tree/main/packages/esl... ; etc.) Teams that maintain huge codebases have tooling to safely automate their upgrades and the best library maintainers provide their consumers with these AST transformations.
> Don't tell that to anyone who uses
> React Router. Or who builds their app
> with Webpack. Or Babel, as you mentioned.
I agree that those particular libraries haven't been maintained well (they make extraordinarily large changes in major versions to the extent that sometimes it might as well be a whole new library). > I encourage you to look at what is considered the norm
> and acceptable practice in fields where better quality
> and greater longevity are more highly valued. If we
> built security libraries or the embedded software
> controlling industrial machinery the way a lot of
> online companies build their web apps, we'd be lucky
> to survive the night.
I think your argument has been a moving target. Originally, you pointed your finger at React saying it has a stability problem, so we showed you that they've been incredibly good at keeping backwards compatibility and that you could upgrade your version of React to regain access to the ecosystem's newest libraries built on top of new APIs without needing to rewrite your legacy code through the usage of compatability packages.Then you implied that it was an overall JavaScript ecosystem stability problem, so I showed you the level of effort that TC39 and the brower maintainers go to keep backwards compatability. And I showed you that most in our ecosystem have been carefully supporting the lowest commmon demominator users for almost a decade by producing web apps that work in IE 11 and packages that first-class ES5 syntax, and gave you examples of big webapps that only recently broke from this tradition.
Now you are pointing at exceptional cases involving particular poorly maintained libraries and tools, and telling me that we lack tooling to deal with scale (which is a separate concern). If you don't think Webpack and React Router are good citizens with regard to their API stability and this annoys you because you like to be on the latest/greatest then don't use them. I and many others also specifically avoid these libraries/tools and yet don't paint the whole ecosystem with this one brush. (On the topic of tooling, it has only been very recently that we've been getting tooling that can deal with high-scale development, however it is happening now.)
* * *
I think that possibly what you're noticing is the second-order effect of more and more usages of JavaScript and web technologies causing new APIs to steadily be added to the web with the old APIs remaining forevermore. The original APIs were made to display and navigate documents. As the years have passed more and more APIs have been released to support more complex types of applications and this resulted in overall churn in user-space as library creators iterate to produce better domain-specific APIs. We provide a high-level of user-facing stability despite this.I don't think it is fair to compare what we are trying to achieve to what is important when controlling industrial machinery. The use cases of that are much more static, while in 2021 people on the Web are creating tools like Figma (https://www.figma.com/), Office 365 (https://www.office.com/), Buerli (https://buerli.io/), and Spline (https://spline.design/). This is very far diverged from where we started and the fact it has been achieved without breaking the web is impressive. It's also quite clear to me that high-quality tools like these aren't achievable without the creation of impressive and scalable tooling (some of which has been released to the public).
OK, let's agree to disagree...
I won't try to go point by point now as these comments have become very long, but overall the difference between our positions (as I intend mine and as I currently understand yours) seems to be that you're focussing on specific technologies like JavaScript or React, while I'm talking more holistically about the entire ecosystem around them.
For example, you have talked about backward compatibility being excellent within JS-the-language, and about React continuing to support its class-based API alongside the functions-and-hooks alternative. That compatibility is not in dispute.
However, when I'm talking about stability, I'm also including everything that is built around JS or around React, the libraries and tools and documentation and people. And in these respects, the JS ecosystem is much faster moving and more fragile than almost any other language I have ever used.
The kind of bifurcation of APIs we've seen with React causes a lot of churn even if the library itself is still backward compatible. If you looked at blog posts or Stack Overflow answers or Reddit discussions about React from as little as three years ago, many of them would have little relevance to the newer API that has obviously become dominant within the community since then. On the other hand, if you hired someone with a couple of years of React experience today and asked them to maintain older code in your system that used the class-based API, they might have no idea what they were looking at. And if you found a useful library to work with React components but it only provides a hook-based API, again you can't use that functionality from your older class-based components. Your old code might still build, but it's essentially unmaintainable unless developers who have come to React more recently first learn what is effectively an entirely different library from their perspective, and even then you're limited in how much you can integrate that older code with more recent contributions to the ecosystem. (This paragraph is an elaboration on the point I was trying to make when I first joined this discussion.)
For the wider JS ecosystem, we've talked about the breaking changes in major tools like Babel and Webpack and in popular libraries like React Router. You suggest that these are "exceptional cases involving particularly poorly maintained libraries and tools". I suggest that there is, unfortunately, nothing exceptional about this sort of abandonment of earlier versions and interfaces within JS world. For one thing, Babel and Webpack aren't just any tools, they are arguably the two biggest names in the JS ecosystem, so when they break, the damage is widespread. For another, they are far from isolated cases. To give another example, Angular was React's big contemporary "competition" and it too essentially abandoned one API in favour of a radical rewrite for version 2, turning any project using the older framework into legacy code almost overnight.
Before React and Angular, we had a string of moderately popular UI libraries built around various levels of data binding. These were must-know technologies in their day for anyone who wanted to work on a project using them, but none remained popular for more than a few years, again leaving all of the individual knowledge and documentation and old code bases largely obsolete.
This pattern isn't unique to UI libraries, either. For example, as JS has evolved and added support for promises and then async/await, many older libraries whose interfaces weren't designed to support that programming style have been left behind, again including some that were very well-known and widely-used.
And with tools, it's a similar picture. Although Webpack is probably the most popular tool for building web app front ends today, over the years we've used shell scripts, self-contained tools like Browserify and Babel, task runners like Gulp and Grunt (with their own surrounding package ecosystems) to co-ordinate the ever-increasing number of tools used in build processes, more comprehensive tools like Webpack (again with a big surrounding package ecosystem) to try to unify everything in one place and bring some structure back, attempts to simplify the horrendous complexity that unification had introduced (the later versions of Webpack and the likes of Parcel), and now we're swinging back towards more specialised tools but in some cases with much better performance such as esbuild, but ironically these newer and better tools may be hard for a lot of projects to adopt because so many people are boxed in by their existing tools and have to wait for someone to provide some plug-in package for those existing tools in order to integrate the new ones. And again, breakage is not unique to Webpack. For example, not long ago, Parcel pushed out a breaking change, and because the effort from the Parcel devs is mostly focussed on the still-in-beta Parcel 2 that naturally has some major limitations of its own, this left teams using Parcel with broken builds either way until they figured out what the problem was and then probably rolled back to an earlier version of Parcel 1.
So I suppose my point is that all of that disruption can and does still happen frequently within the JS ecosystem, despite the backward compatibility of JS itself and the willingness of at least some of the big libraries to continue supporting old APIs after launching new ones. Stability, in the sense I'm using the term, implies a reasonable degree of backward and forward compatibility. The converse, unfortunately, does not hold. A good compatibility story is necessary but far from sufficient for a stable, productive ecosystem.
Here's a very simple metric: Compare the Next.js documentation (https://nextjs.org/docs/getting-started) with Django's (https://docs.djangoproject.com/en/3.2/contents/) - better yet, compare the actual API reference and exported classes/methods.
Yes, Next.js is one of the better Node/Javascript frameworks, but it's incredibly inferior to any other established framework in Python, Java, PHP, Elixir, etc. — unless you only need a static page with some dynamic React components. I am in the unfortunate position of maintaining a more complex Next.JS app, using most of its "advanced" features such as dynamic routing, SSR, GraphQL, API, and it's the most painful project I have ever had the misfortune to work on, because the upstream interface and API is so woefully under-documented, buggy, changes too quickly it's hard to stay up-to-date, etc. etc. I weep every time someone on this forum suggests to start a new project with Next.js.
In theory Javascript on the server and client is a productivity boost, in practice it is not by any measure.
This is like saying a screwdriver is incredibly inferior to a impact hammer.
> In theory Javascript on the server and client is a productivity boost, in practice it is not by any measure.
This is in direct contrast to my personal experience across multiple projects and teams. In practice it IS a productivity boost, because JS does 99% of what anybody needs a web server to do.
I'm sorry, isn't the goal of web frameworks, including in this category Django, Next.js, Phoenix, Laravel, Nuxt.js to respond to HTTP requests and present users with an HTML page representing a document or a more complex web application?
> because JS does 99% of what anybody needs a web server to do
Brainfuck is Turing-complete and does 100% of what any other language can do as well. I stand by the fact that having to "know" only one language is great in theory, but in practice it's not. Node and client JS/Webpack are a leaky abstraction it's not very hard to get yourself cut with. In non trivial modules, you'll find it hard to be able to use the same code verbatim on the client and the server. Then add the complexity of server-side rendering, serialisation/hydration, React suspense, code that mysteriously works only when server-side rendered or viceversa, etc. and you'll ask yourself "is this really worth it?"
It sounds like your opinion of server-side javascript comes from experience with badly written and poorly-understood server-side javascript, because none of that jives with my experience in writing node-based web applications.
Does talking to a DB really account for just 1% of what you want a web server to do?
edit: to address your point though, yeah, I think 99% of web sites don't need to be talking to a db. That's different from web applications, of course, but most web sites aren't, and shouldn't be, web applications.
Would you give some specific examples of where you've found Next to be buggy or where it's introduced breaking changes? We're evaluating a number of possible Node-related libraries for a new project right now, including Next, and there's no substitute for hearing from people with real experience of using them in production.
Next js is awesome, and it is the best alternative in my opinion if you go the SPA route.
Now, things get really, really, really messy and complicated when you start to implement on top of it everything else a typical web application would need. Authentication, validation, i18n, acceptance testing, background tasks or queues, etc....
We started out with next and prisma 2 and wasted a lot of time, in the end we rewrote the whole thing before launch with ruby on rails and turbo, some minimal stimulus and it was awesome. So much easier and simpler, and the application felt a lot more solid and robust.
So, next is awesome if you're doing a landing or relying on an existing backend api, etc.
If you need a full CRUD app, don't waste your time with it.
Our use case is fairly typical, basically an SPA doing the heavy lifting, an API on the back end to support it, and then some largely static marketing pages. There is a potential fourth aspect if we want to customise any of those back end pages depending on who is logged in, for example to personalise help pages with the user's own details or to host some account management pages separate to the SPA.
Next is under consideration because our SPA will be React-based, so being able to share components and styles for the rest of the site could be quite a time saver. We're reasonably sure we want to use some Node-based back end for this project, because that would allow us to share substantial functionality between the SPA and API implementations, but this would still apply if we used Express or another alternative to Next.
It looks like the SPA and static pages wouldn't be a problem with Next in your experience, but maybe there could significant problems we haven't anticipated so far with using Next for the API and/or with using server-side rendered but not entirely static content?
1. We were doing SSR, and given we needed authentication we used next-auth [1], which is a great library btw, but the problem is given the architecture you buy into when you do an SPA, we had to check for authentication in three places: 1) In the frontend you need to check if the user is logged in or not and show information accordingly. In getServerSideProps you also need to check for permissions, because otherwise you'd be leaking private information in the "initial data" that gets embedded in the first's request html as json. And then you also need to check for authentication in the API pages/endpoints... each one of these has their own ways to be done (well documented in next-auth's docs) but still, you need to be careful, and it was very, very easy to make a mistake, forget to check on some place, etc. Of course you have tests for preventing this, but still... a lot more fragile than just using devise, or a "middleware" in a traditional MVC application. This is one of the things I refer as being more "solid" or "robust".
2. Validation. Oh my!!!... Prisma, again, is an awesome library. The best I've seen and I've used many similar in the past (django's ORM, ActiveRecord, etc). Prisma is up to that level in my opinion... but it is just the data access layer, on top of that you need to implement your own validation rules. We used Yup [1] for this, which, once again, it's a great library. But then we realized we needed to validate things such as already taken emails... but of course, you would not check by issuing first a get() or select and if you didn't find it you'll create it, because that could lead to race conditions... so the "proper" way to do it is to attempt an insert, and if the insert fails because of an unique index then handle the exception, generate an error message, and make it back to the frontend. All doable, and not that difficult. But still a lot of work, and it is easy to forget about corner cases, etc: fragile.
3. Then we needed to add internationalization. So we mixed in next-i18next [3], which added another axis of complexity because translations need to be available both at SSR time plus at the client side. Plus we also need to translate the error messages from the handling of the unique index exceptions from above....
4. We needed to implement some CLI tasks, (think of equivalents to runing a worker or a sync process, etc) which needed to import some domain logic... but next has its own babel and webpack so you cannot write them with plain node, so we needed to do a lot of hacks with @babel/register so that we could import this code, and then we found problems with our code relying on things such as getConfig that next sets up on boot, but this was a CLI so we were not booting next... so we needed to init the config ourselves.
5. By this point our index page was about 250k of javascript + translations + css... and we were not done yet. And the feeling of the end result was not that great.
And we all had a feeling that any of these libraries might change at any point [4], or go unmaintained, or out of fashion and we were just a team of 3.
I insist, I don't think the problems are in any of these tools, nor in JavaScript itself, nor in the ecosystem. These libraries are great, we really liked them. You would have the exact same problems if you try to use Flask, or Sinatra, or any other "lightweight" solution.... it can be done, and it can work very well for you... but it is 1) much more work, 2) requires very experienced people that really know what they're doing and 3) you'll end up re-implementing django, rails, or similar... in your own way, with less documentation and less real-world battle tested. These problems are caused, in my opinion, by the "architecture" you get in (SPA + separate backend).
We rewrote the thing in 1/4 the time with Rails + sorcery + Tailwind + delayed_job + a few other smaller gems. Just a bunch of models and some "services" (plain ruby objects), hotwire for the "spa feel" and stimulus for things such as date pickers, modals, etc.
I think also something to consider is the team size and skills. If you have, let's say, 5 backend devs, and 5 frontend devs, then it might make sense to get into the SPA + separate backend... it is more work, but it is easier to split it... if you're a small team, and/or want to stay as a small team, then nothing beats Rails (or symfony, etc... never used those others) for this.
Hope it helps, and good luck with your project!
[1] https://next-auth.js.org/ [2] https://www.npmjs.com/package/yup [3] https://www.npmjs.com/package/next-i18next [4] For example, Prisma 1 is a totally different beast from prisma 2.
Do you really want to work with a framework that has another framework on top of it? This feels a bit iffy to me.
1. The strong typing of GraphQL is a huge boon for correctness and security.
2. Easy to autogen TS types from GraphQL schema, so we can use the same types throughout our codebase, frontend and backend.
3. Apollo has lots of features that make it easy to scale projects.
GraphQL arguably makes decoupling frontend and backend languages even easier than classic REST APIs, since the GraphQL schema can serve as single source of truth across language barriers.
¹ https://www.apollographql.com/blog/graphql-python-api-comple...
> And yet – Apollo advertises its easy Python interoperatibility right on the front page
Yes, absolutely, there is great support for GraphQL in many different languages.
> , as one of the features that makes scaling easier.¹
To be clear, that is your own commentary and I didn't see anything in the Apollo site that said implementing in Python makes scaling easier. I.e you seem to be implying that somehow implementing in Python is better for scaling, but there is no background to support that.
> GraphQL arguably makes decoupling frontend and backend languages even easier than classic REST APIs, since the GraphQL schema can serve as single source of truth across language barriers.
Yes, I totally agree with that. If you are, say, providing an API to other developers GraphQL is a great choice for a number of reasons, one of which is that there is great language support across pretty much all languages.
But if you are starting a project within a company, and have the luxury of choosing technologies, having the same ecosystem on the front and back ends makes it much easier for people on either team to go across that "boundary" if necessary. This is not just me hypothesizing. For the majority of career, which really started right when web apps started taking off, there was a separate language on the backend (Java for the majority of my career, but also sizable stints where Ruby and Python were the backend languages). Yes, most backend folks understood JS and CSS, and most frontend folks could understand the backend languages, but it was still a huge barrier to people being able to contribute across teams such that it rarely happened. It's only in the past couple of years where I've been in a "TypeScript everywhere" org where I've seen the gigantic change in the team dynamic that this allows.
I hear about this dreadful "scalability" problem with GraphQL and N+1 queries and all other sorts of geysers constantly, but I see a lot more success stories than failures.
NestJS is the most full-featured Node framework, but it's lightyears behind Django. Yet I'd still use it given the choice between both, because I prefer Typescript so much better than Python and having a single language through the stack is a game changer, enough that I'm willing to compromise on the frameworak.
In a backend where you need a heavy-duty, multithreaded process to handle long-lived computations, node is probably not the way to go unless you want to pay for all the extra instances you'd need for the same amount of load. In my experience, for example, a java-based graphQL server (that spawned multiple connections to various services) needed much much less in the way of resources than the node equivalent serving the same amount of traffic - AND the latencies were generally much better with the java server, depending on the size of the JSON payloads that it was handling.
All that being said, you can certainly architect your way out of that problem and I imagine a relatively small percentages of web applications even HAVE that problem.
But again, I definitely agree with what you've written, right tool for the job.
The JS scripts together the compute heavy CV alogrithms, and you can do similar by hosting your computer heavy things behind a service call, while keeping the orchestration parts in node
Plus you've got MS's intellisense powering autocomplete. Unfortunately, I don't think it can recognize different foods, but as long as you've typed your variables the autocomplete is pretty good!
EDIT: the OP had a typo, saying food instead of good, for context as to why I made a food joke
> This biggest "aha" benefit I get from TypeScript is that it is structurally typed, while Java is nominally typed. In my experience it has proven much easier to refactor in TS because I just need to ensure my objects have all the right properties. With Java if I have a Thing1, but a library is updated to add just a single new property so now there is a Thing2 type, well now then all the places I need a Thing2 I have to completely copy over from Thing1 - I can't just add the property and be on my merry way. This happened to me many times in my Java career - I still think I have PTSD having to do a Jersey 1.x upgrade to a Jersey 2.x version across a large codebase. It was a nightmare I've never had anything come close to with Typescript.
Not so much refactoring as upgrading, but tis an example of why duck typing is kinda nice
They weren't using Java, so probably not. ZING!
But seriously... If you want to compare tooling, you shouldn't be comparing a scripting language vs a language like Java... compare Java vs C# and C#'s experience is better than Java's IMO (not REAL experienced with Java but I've done some basic stuff).
I don't really see how. TS doesn't seem to solve any annoying problems I previously had in Java. As a concrete example, it would be nice to have the concept of a DTO as a first-class language feature, but alas, I find myself constantly casting and re-casting, plucking, or writing endless wrappers to make sure properties trickle down (or up). Hell, sometimes I just give up and use `any`. I mean, this is a web-first language that has no concept of sending objects over the wire.. okay then.
TypeScript's generics system is cute, but I think it's mostly academic. And did you look at the toolchain? To get TS working, you need babel or ts-node or webpack, and like 3 different .json config files. Importing a package without TS support? You need to write some stubs yourself in types.d.ts. In fact, the best parts of TypeScript are actually JS (await/async, arrow notation, spread operator, etc.).
> Rome is designed to replace Babel, ESLint, webpack, Prettier, Jest, and others.
Afaik esbuild only intends to be a replacement for 2 out of 5 of those things. It does that well for sure, but if parent commenter's main issue is the amount of different tools, I don't think esbuild will help.
> I mean, this is a web-first language that has no concept of sending objects over the wire.. okay then.
I have no idea what you're talking about here. I use GraphQL with auto typegen of my TS types and I get typed data objects everywhere.
> TypeScript's generics system is cute, but I think it's mostly academic.
TBH this remark just makes me thing you really don't know much about TS. I use generics extensively, find them very helpful and are easy to use.
I'll give you the point on initial TS setup being non-trivial. Hopefully advances in tooling (things like Deno, which I'm not actually a huge fan of, or other projects like Rome) will make this easier, but even then I found this to be a "one and done" cost.
I'd look into what Jersey actually is before you say something like this, because what you've said really doesn't make sense.
But there is also sucrase which is fast because.. its written in TypeScript? https://github.com/alangpierce/sucrase
It would be better if there were no oddities in a language. One of the reasons why everyone hates PHP is that it is full of inconsistencies, odd design choices, weird naming and unexpected behaviour. JS has at least some of these.
If there was a second of third language available in the browser, then that too could be used to develop back-end applications and would have the benefits you describe - that you can use the same language for both stacks etc. For example - if you could front-end stuff in Python, would it be amazing or bad? Or would the current JS devs just fear for their jobs because of it?
How so? Is it just about being able to use a single set of tools, libraries, habits, etc? Or are there particular things which are easier when the language is common? Are you sharing code between front-end and back-end.
I do very lightweight front-end coding these days. It's usually some variation on populating and updating a table from a websocket, maybe with some simple filtering and toggling in response to user interaction. There, i can't think of any particular advantage to having both ends in the same language, but then mine is quite an unusual use case.
It feels like it should be possible to do that cross-language, generating some JS validation rules from Java annotations, say, but i have never seen it done.
These approaches can of course be combined, where the sorts of validators I mentioned generate (or even build their primitives around) those more verbose standards.
Oftentimes, however, a frontend dev may need some small extra bit of data or functionality from the backend, and vice versa. If the ecosystems are very different, then the amount of time it takes to set up that separate ecosystem, remind yourself of the relatively minor syntax difference e.g. between TS and Python, update your dependencies, etc. can be a big barrier, so often the answer is to just throw a ticket over to the team on the other side and wait.
If, on the other hand, you can just quickly get into the other codebase, make a small PR and get it reviewed quickly, it can drastically improve the team's overall productivity.
Maybe some organisations have separate teams working on the two parts of an application, which honestly just seems stupid, but that's not a necessary consequence of using different languages.
> Node is not ECMAScript in a server-side ECMAScript engine, it's JavaScript in a browser JavaScript engine. That's just too much of a force fit
And what makes V8 a "browser JS engine"? A focus on:
- rapid startup. Code starts running immediately, JITs quickly. The VM is designed for latency, not just for throughput.
- excellent sandboxing. The VM is designed to run untrusted code.
- no blocking code. Designed for callbacks and promises. No threading, no thread.sleep(), no mutex, etc. Makes is much easier for non-expert developers to write fast & reasonably correct code.
Now look at things like Cloudflare Edge workers, Lambda etc. Modern server environments share all of those same design goals.
Server-side JS/TS not only has the advantage of a single codebase. It also brings the design and engineering advantages of a browser VM to the server.
Rapid startup: lambda is a tiny subset, and not really server application. A server app could take minutes and would still be okay, because they are designed to run for a long time. Even in case of scaling minutes are more than okay since deploying a new instance takes a similar amount of time.
excellent sandboxing: you usually only run your own code connected to db and other very privileged services. If there is a vulnerability it is a very big problem with or without sandbox
no blocking code: i’m not up to date, but node doesn’t have a strong parallelism story at all, compared to the JVM, Go, .NET
Wby would you want to maintain a long-running server process if you don't have to? And, wny do you think you have to?
Lambda is great for seldom run functions, like running some analysis/conversion on user uploaded profile pictures or the like.
Also, specifically for Aurora, Lambda supports transparent connection pooling. It is just no longer a concern of your application code.
Disclaimer: I work on serverless services at AWS. I’m definitely biased :)
Though I suppose Lambdas don’t use separate traditional OS processes to serve requests, do they?
That's an irrelevant tautology; the question was why you believe a long-running traditional server process is necessary.
Most of the "serverless" things delegate to a server in the end anyway - whether they be a database, a managed service, etc. Something has to stay alive, be a server and own the state after all - serverless doesn't make the problem go away just passes the buck. For run of the mill small scale websites or websites that fit a particular paradigm lambda works fine. But it doesn't suit all apps, and its hard to make all problems fit it currently. As businesses scale custom solutions can scale better.
Whenever I encounter Node, issues almost always follow. Whether it's NPM's delightfully useless error messages or a stream of neverending warnings filling up stdout, it quite literally never fails to cause a problem. Maybe Node should focus on saving it's reputation, because I for one run in the other direction of it. Hell, especially in the case of Node, I hope that Deno comes to replace most of it's core functionality. Putting up with half-assed software on a half-functional runtime only leaves me with a quarter of the patience I started with.
How big of a problem is this?
At the end of the day all that really matters is that the external representations that get handed off are the same and that everyone makes the same assumptions. Given the same set of fields manipulating a POJO with Java streams is not all that different from using modern Javascript on a blob.
So you’ve come to it at a time when the syntax and capabilities have a popular subset that actually starts to fulfil the early promise. And yet, despite the article above, one may still be enormously critical of the anemic and inconsistent standard library, and don’t even get me started on the horrifying dependency shitshow of the node ecosystem that cripples maintainability of anything over 18 months old.
Just because we’re all holed up in the throne room, doesn’t mean there aren’t monsters still roaming the sewers, just a few levels down.
As for isomorphic code, I strongly encourage my competitors to write backend code in the same fashion and the same breath as the front-end, because the resulting tight coupling and special-case-driven technical debt makes them easy to outmanoeuvre when markets shift. And if they’re reading this then please also consider microservices, graphql, and nosql data stores whilst you’re at it, for the same great reasons.
JavaScript is becoming bearable but still too painful for anyone who has touched ruby for example.
Meanwhile I’m learning closure and loving every second of it.
You always know exactly how to implement what you want, without having to think very hard.
You can do something small by yourself by writing less code, but using less code makes it more complex since you have to think a lot harder to understand the code when you come back to it in a few years
I get not wanting to start with a super complex stack, but Ruby and Rails are the worst mainstream framework maintainability wise it's obvious why it fell out of favour.
The reason is that these two books don't fulfill the same goal. The Good Parts is a rather short walk through the language and reads more like a "get started quickly" guide. The other goes into much more detail. That doesn't mean the latter's size os due to it covering all the bad stuff whereas the former doesn't. It's just a clever title but it's an apples and oranges comparison and I'd suggest not using it as some sort of supporting argument.
Whether JavaScript is good or bad as a whole is a different question (I think it is), I'm simply taking issue with that meme (that originally popped up in picture form, the two books side by side, rather than text).
Because one's a style guide and one's a complete API reference?
> Don't use continue. I've never seen a loop with a continue that wouldn't be better without it.
And that's it. No examples, no objective criteria, we're just supposed to take the man at his word on this. Whether or not I agree with this particular case, I don't enjoy argument from authority in most forms, especially not in one where you are supposed to learn about a better style of programming.
This is of course subjective, and maybe I'm biased due to having a lot more experience with python than JavaScript.
Front and back do different things, have different requirements. You control the architecture on the back end for instance, not on the front. The back end deals with data modeling and processing, the front with layout, very different task, very different skills, and the language is just a small part of it.
There is some overlap, for exemple I remember having to code a clock twice, once on the back end of to show it correctly the first time, and once on the front to have it refreshed in real time, the code could have been shared, but these occurrences where code can just be copy-pasted are not that common.
And BTW, most of my web dev was JS/PHP/SQL, and I actually liked all three languages for what they did. JS, I had no choice, but it did event handling well. PHP was good at generating HTML from a database and SQL, despite its age is still king for querying databases. I wouldn't want to use these languages for anything else.
There's tools to make it easier, but using them still means you have to pull in another stack into your workings/you're stuck with whatever limitations the tool has
I disagree, but with nuance. I consider myself a skilled programmer, and I have switched languages many times throughout my career, and you are correct, it is not much of a big deal. There have also been times in my career where I've been responsible for whole swaths of an app from back to front end where the backend was in Java and the front was in HTML/CSS/"old school" JS (this was back in the JSP/server-side days). And yes, in that case it was not hard to switch back and forth.
The problem, though, is that, as you point out very well, the back and front ends have very different requirements, and so in most organizations you have separate teams focused on the front end and back end. If I'm a front end dev, I'm going to be spending day-in day-out working in Javascript and my JS ecosystem. It's not that it's hard for me to, for example, learn and use Python, the issue is that since I'm not "practicing" it every day it definitely gets rusty, and as time moves on the ecosystem moves on such that my environment likely needs some tweaking (venv vs. pipenv vs. virtualenv vs. conda - honestly it's been a while so I have no idea what is in widest use these days).
So if I'm on the front end, and I need say one extra piece of data that I know is stored in the DB exposed in some specific API call, for what is likely a trivial change for a backend dev, well now the time it takes for me to get my backend env in sync (again, which maybe I haven't bothered with in 3 months), refresh my knowledge of Python, work through any dependency update issues etc. I may have can often be longer than the time it takes to make the simple code change. So what usually happens is the front end dev just doesn't bother, they submit a ticket for the backend dev to do it and wait to sync until the next sprint.
Compare this with what happens when front and back end are both in TS - the front end dev usually has a short chat with the backend dev to make sure the changes will be OK, but since everything is immediately familiar can go and make the change just as quickly as the backend dev, without needing to wait for the backend dev to have time to do it.
I have seen this cultural change in depth over the past couple years, and it is just a pretty shocking change if you've ever experienced it if you've been used to teams that were more "siloed" between front and back ends.
Not exactly.
It is easy in web space, but switching language is a big deal if the previous and next language have huge differences in concepts and on which layer of the stack lives.
For example, switching from language that has a complete runtime and GC to a language that does not, is a bit hard. In JS we have things like Promise.all, and setTimeout, and such to control concurrent async operations. On language like c/c++/rust where you produce abstract machine, you have to choose how to operate and regulate those async operations.
i highly doubt that - i don't disagree you got productivity gains, but it's not from being the same stack, but it's from experience gained doing it.
If what you say is true, why doesn't people use GWT (google web toolkit) and java on the backend to get this productivity gain? It has existed even earlier than typescript, and is compiled to be quite fast. It's even more integrated as a stack, and anyone knowing java is able to use it fairly easily.
we are talking about tech stack - most broadly the language (and compiler). GWT is a compiler from java to javascript. it cannot be compared to react (even tho GWT has a front-end UI component - but that's optional in GWT).
Undergoing a similar path. My problem is that the moment I switch to TypeScript and start writing my code becomes very similar to Spring. And at that point I have to ask a question of why would I not just write Java. Node on the other hand feels like node.
Why would your custom ECMAScript server be any faster or more stable than any of the existing browser engines? If you look at the resources behind those engines, I don't know who would match that effort doing the same on the server.
I’ve done plenty of backend work in all of TS, Scala, Go, Python and PHP. Scala is my personal favourite, but it’s not as practical for teams as TS or Go, which are both very productive languages, with good enough type safety and performance, that new devs can learn quickly. And I’d easily choose TS over PHP or Python for a large system.
Plus, it IS pretty nice being able to use a single language everywhere. My current company is TS RESTful services with TS/React on the web, and TS/React Native on mobile, pretty hard to beat how easy it is to do full stack dev work for most ppl in this setup.
JS has no parallel computing support, so it is not an option. And when I say parallel computing, I don't mean distributed computing, I mean utilizing hundreds (thousands) of cores on a single die, like NVIDIA architectures. (It's a black art, even addition algorithms can confuse the newcomer.)
The best course is to do what every other language does when it comes to simple-parallel operations, like Gauss-Jordan elimination: use a dedicated, optimized library, like NumPY.
I really hope some day there will be a numpy for JS. NumJS is dead, and Google's TensorFlowJS is excellent for utilizing GPUs, but a dog when trying to do simple operations (the load/store async nature doesn't quite fit with most use cases.) I suspect WebAsm will facilitate the parallel nature of tensor operations without having to move
I do think that this kind of thing will be able to be built on top of WebGPU (I saw this experimental POC that did so recently: https://github.com/milhidaka/webgpu-blas). The only issue is that since JavaScript doesn't support operator overloading even if a production-level library was created the code would be a little less readable.
In truth, assemblyscript or rust running in wasm is probably the best solution going forward.
I've avoided using node worker threads in favor child.fork, which then resolves to IPC through process.on and process.send, which is like any other process management.
(Yes, I know about TypeScript.)
I do think you're not giving TypeScript enough credit -- I felt right at home the first time I used TS, and the type system is much more sophisticated than anything ActionScript ever had. As long as you're of the "favor composition over inheritance" mindset, which I'd argue is better, even for games, TypeScript is a fantastic spiritual successor to ActionScript!
Unfortunately there's no TypeScript-based game engine that makes it so easy to combine code with animations / sound. Nothing has really filled the void that Flash left behind.
If there is another asynchronous language that is as well defined as NodeJS and has as much library support, I would very much like to study it.
It’s a fantastic environment for asynchronous programming. It also has a built-in REPL for a management interface via TCP or Unix sockets. It doesn’t really need any additional packages (I hate the dependency hell that npm saddles you with, and people don’t seem to know that Node already has http, https, and websocket upgrades built in, so you often don’t need any “frameworks” or libraries).
Give me Node, and I can build an entire web app from scratch. Most of the time you don’t even need to use JS in the browser. Just html and CSS are enough. Web apps the way God intended.
I don’t use Typescript either. Its type checking isn’t worth the hassle of poor tooling and inscrutable stack traces.
Lot's of projects are popping up using ElectronJS, which is Node+Chromium. I have written many, and they are literally write-once-run-everywhere. Node serialport and node libusb have some speed issues on macOS, but require literally no alteration, utterly seamless.
The idea as "Node is just web" is dead in the water. Hugely popular ElectronJS(Node) apps are:
* Saleae - An inexpensive logic analyzer - https://www.saleae.com/
* Balena - a flash programmer for SDmicro and USB drives - https://www.balena.io/etcher/
* BetaFlight Configurator - the seminal drone (quad/hex/octo) configuration tool - https://github.com/betaflight/betaflight-configurator
[FYI: Python is far, far behind in packaging cross-platform apps and requires gigabytes of support libraries. People complain about Electron size, but they are only comparing it to native apps.]
“Too many people only learn JavaScript, become psychological dependent o it “ is simply a false narrative from people who are stuck with obsolete web dev tech stack and refuse to learn better tools
What problem, specifically? People enjoy writing Javascript. It has a ton of fantastic resources online, it is easy to debug and deploy, it's quick to pick up and forgiving of mistakes.
> Too many people only learn JavaScript, become psychologically dependent on it
You sound like Immortan Joe warning people not to become dependent on water in Mad Max. Let people enjoy the language they enjoy developing in.
> they all collectively took it too far outside of a browser.
What does this even mean? What's "too far" even mean? People want to write code, let them?
I'm continually frustrated by my colleagues refusal to step outside the javascript ecosystem. Don't get me wrong, JS certainly has its place but its not ALWAYS the best tool for the job. I see a lot of people reach for node as their go to backend tech choice simply because its the ONLY tool in their toolbox.
Unless you're building a small focused microservice where the functionality involves calling out to a library with working tested code that does what you want, I think node is honestly a poor choice. To qualify my statement, I spent the first 7 years of my professional career building software with nodejs.
The sweet spot is much smaller than the scope of projects people throw at it.
* quick MVP? rails has more libraries that are drop in.
* Performance? go and elixir have node beat for multicore perf
* websockets? compared to phoenix channels, everything in node for serving websocket apis are a toy.
Lambda functions though? yea nodejs kicks but there!
let num = 0;
route('/url').post(data => num++);
What other languages can I do this in that are better? I simply want to have a variable I can access and mutate from inside closures and let it live in memory without the need for databases or file systems.I want to declare a variable and then be able to access/modify the same variable through a closure in a callback for incoming requests, so I guess that requires it to be single-threaded.
(I'm using this for game state where it's very convenient to just declare a persistent data structure in code directly without without having to use any additional abstraction.)
you always have some tradeoffs because in your case when you would run it with a multi threaded js engine your variable would be as broken as the c# one. that's why java does not allow it by default to modify a variable inside a thread that is declared outside.
Edit: I also worked on a node app that should have been written in a staticall typed language. Bugs that could have been caught at compile time literally caused me utter misery in on call overtime. All because some guy in our team demanded we wrote it in node. This was way before type script. I actually feel physical pain thinking about.
UI programming is literally the fine art of handling what your most exasperating client is capable of inflicting on your UI.
I suspect this is the core complaint.
If you put bad developers on other languages they usually end up running into some wall first but Javascript is pretty forgiving.
React on its own is much simpler, once you grok the react compositional model. I don't know how you can do that while using redux too.
https://redux.js.org/tutorials/essentials/part-1-overview-co...
Does anyone have any reading material on this? I've never heard it and a quick Google turned up nothing, but I'd love to read about it. Unless it's a joke that went over my head...?
32 minutes in.
IE did support VBScript, and only finally "killed" it in 2019
https://blogs.windows.com/msedgedev/2019/08/02/update-disabl...
insert ragequit gif here
It's accessible, popular, easy enough to use, and ubiquitous. All the ingredients for success.
Does it belong on mission-critical spaceships? Whether you like it or not, the answer is yes, of course it does. https://os-system.com/blog/javascript-in-space-spacex-devs-h...
Thankfully WASM is a remedy for this, and over the next decade devs will be able to build full stack across web and mobile in Swift or any other language they prefer.
Now days, if I do mobile iOS, I have to do Swift, Kotlin for Android, and as you say JS for browsers. I wish we lived in a world where the platform didn't design the stack so much.
TypeScript and JSX are the most popular languages that compile to JavaScript as far as I know. They're very close to JavaScript because people learned straying too far created problems.
[1] https://web.stanford.edu/class/cs106j/handouts/01-GeneralInf...
Don't pick one, pick a healthy mix.
Or while lazy argument evaluation might not be in your language, having it in your tool box for message processing design or you know evaluation of user preference rule sets against an event might be helpful.
I can't be sure, but I think there's a lot of thought, at least, behind selecting a particular language for an introductory course on programming. I don't know which language I would choose, but I'd like something that would broaden the horizons of student as much as possible. It could be Mozart/Oz or something similar.
"Eiffel Software applied for trademark registration for Design by Contract in December 2003, and it was granted in December 2004." https://en.wikipedia.org/wiki/Design_by_contract
Is that possibly something to do with it not commonly being taught about/learnt?
Also, there's a difference between DbC and simply using contracts - it's similar to the difference between writing tests and doing TDD. Many people might not be convinced that the benefits of DbC are worth rethinking the development process, and so they dismiss all contracts as "too many asserts, don't need". But, like with tests, you can benefit from a solid test suite even if you don't do TDD; similarly, you can reap a lot of benefits from simply ensuring that precondition violations are caught at the boundary of a subroutine, because it makes it easier to find the reason beind the problem.
I'm convinced that in the next 10-15 years we will see gradual typing (with type inference) embracing contracts as a way to extend the guarantees from compile time to runtime. Maybe we will finally get the best of all worlds: rapid prototyping, great performance, and verifiable program correctness.
Personally, I think we should be teaching static types and I pushed for Typescript, but it didn't happen.
As someone that teaches college students to program (not in a CS department) that statement is correct but doesn't provide the full picture. It's good to get rid of the extra syntax if and only if you don't need it - and that means you're intentionally limiting what you're teaching them.
Yes, that’s the point. It’s an introductory class, choices have to be made about what to teach when.
Another option would be to introduce Python types:
def square(x: int) -> int:
return x*x
http://mypy-lang.org/examples.htmlAt the moment the Python community seems pretty anti-static-types, and the core scientific libraries (numpy, matplotlib, pytorch) don't export type signatures. Language server / intellisense support for type inference also has a long way to go.
I would assume as types become used more a definitely typed type project will happen on pypi.
I think Java fits better as an introductory language — it is similarly popular as JS and python, and while I’m sure static typing can be picked up easily, I think fighting the compiler for a likely-correct program in the end is a better alternative than understanding why the program failed with this given input and not with another — so my not-backed-up-by-teaching opinion is that dynamic languages are not necessarily a great fit. It also features the basic OOP concepts, and modern java can showcase plenty of FP ones as well.
On the other hand, going lower level is similarly detrimental, I’ve taken a class where C was used, and that way you get cryptic runtime errors as well, while memory management is not that hard to pick up later on.
Explaining to students what public static void main means is pretty annoying and seeing cryptic syntax littered everywhere does not help students when they’re first learning.
Dynamic languages make much more sense to beginners because the idea of what a variable represents is more abstract to them than tangible to you. To them, they don’t see the value of types because they’re not going to be building large programs where that is going to matter. They know what their functions return and take in, because they probably only have one or two. Performance and compiling is also not as much of a concern, etc...
On the other hand, I feel that most of the lessons I've learnt that have really stuck are the ones where I first do a thing wrong, and then find how to do it right. In a similar fashion, letting the student create a steaming pile of ... and then giving them a solution to their troubles in a later course feels like a good idea.
I personally have come a full circle: starting with things like Pascal and C++, then going to C# and finding type inference interesting, then getting a HUGE boost to my knowledge and skills when I found Python and JS. A few years later, my personal preference is having static type checking, and Typescript does that pretty well, in my opinion. However, every time I remember how much I managed to learn and understand about programming when I switched to Python, I think that if I had to teach someone, I'd pick something expressive, intuitive and who cares about types when you really want to maximize exposure.
C# has solved that with "top level statements" [1]. If Java added that then problem solved, right? It's a simple addition.
[1] https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csh...
In my experience (having TAed a CS1 course) I think it is better for introductory students to be able to figure out what they are doing wrong, rather than having a compiler point it out to them.
In the first class, we want to focus on computational thinking and being able to then express their ideas into programs. So we intentionally use very little of the language (JS in my case), because the language is not the point of the course.
OOP and all these models of abstraction and code organisation come later, once they have a good grasp of the fundamentals.
This particular course I taught is only taken by CS freshmen, so that other commenter's remark (that we should teach a popular language) doesn't apply here.
That’s implying they will find it out, instead of having a finished project that can randomly crash with a slightly different input.
Also, the compiler is basically just a shorter eval loop.
But I agree with you that OOP should only come later (though using objects is inevitable in most languages)
Then, when learning Flow and Typescript, where I'm expected to have a meta understanding of typing itself, I was ready to go.
Oh no, for a beginner just setting up the environment is a huge hurdle. Sun's Java downloads page is utterly confusing, and the IDEs are monstrous and complex too. Past that, they have to learn about the JVM and compiling to JARs before they can even run their first program. Leave all that housekeeping to us seasoned, soul-crushed developers ;)
If we're starting to teach compiled, boilerplate-ridden laguages to beginners, why not jump straight to C++ or Rust?
I see static typing as a nice tool to help stop you making errors; but when I was trying to wrap my head around how to program I found it easier to not have to fight a compiler and allow myself to make mistakes.
Python excels as a teaching language.
JS, and its multitude of foot-guns, is not something I would call 'well designed'.
The syntax of Python is just way, way more straightforward. I do agree it may be a disadvantage for serious software engineering, but as a hobby? I will pick Python over others all day every day.
> But here too, Python is facing stiff competition from Julia
You severely overestimate the significance of Julia in this field. It's a great language, and I wish it were more popular, but Python still dwarfs it.
Students should learn early to use the right tool for the job, not reuse the same one just because it's already familiar.
IMO Python is a better first language because it's more approachable, and doesn't have the prototypal inheritance and other quirks unique to JS (not that it doesn't have quirks of its own, but most aren't important early on).
Arrow functions really are a great bit of syntactic sugar. I know that they are more than that, but since I avoid "this" anyway, for me they may as well just be syntactic sugar. As for the "class" keyword, I find it to be utterly pointless but of course, tastes vary.
Protoypal inheritance and class-based inheritance where classes are themselves first-class objects aren’t really all that different, anyhow.
Also there have been attempts before but nothing really stuck. How many non-Googlers use Dart?
Yew [1] is one of the early Rust frameworks for client side work. It allows for multi-threaded (!) execution and javascript interop.
Not many other languages make sense as you have to pack in the whole runtime, GC, etc. Rust is pretty well positioned for WASM, and it's going to take off soon.
Sure you could. You can develop for the web in practically any language you like these days. People use JavaScript because it has native support for the DOM that nothing else can match. Until we get away from the DOM for application development, it will always be king.
Sure it does. DOM support is built into the very core of JS as a language, and that has shaped the entire history of its' development and subsequent API choices. It's not just a library that it happens to support, the way it would be with any other language.
Sure, they can, both via compile-to-JS solutions like Transcrypt [0], and via generate-the-frontend-with-backend-Python solutions like idom [1], Plotly Dash [2], and others.
[0] https://www.transcrypt.org/
Even native languages like C/C++/Rust compile their language into binary format that the platform can run. It just so happens that the web runtime format is JS instead of binary machine instructions.
That’s what sourcemaps are for; you don’t have to debug compiled instead of source format on the web just like you don't on other platforms.
It is, just as using compile-to-(or interpreted-by-a-runtime-in-)-native-code languages is a solution to “I don’t like raw x86_64 machine code for desktop applications”, even if you end up running machine code in the end.
> Also Dash is absolutely terrible, horrible documentation, horrible code.
“X is not a choice people can make” is a different claim than “One example of X is not something I personally would recommend”.
As to your second point, that's why I put it in parentheses, of course it doesn't refute your claim but if you use as example a technology that has awful documentation because of this two-language paradigm, and leads to garbage code both at the Python stage and the Javascript stage, to me it doesn't paint a good picture of the whole concept.
Clearly, there are people that disagree with this value judgement, and the existence of that disagreement is an existence proof that Python for frontend is, in fact, a choice people can make, even if it is one you find unattractive.
I think theres legitimate reasons to compile Python to JS, but "JS is bad" can't be one of them, since you still have JS that you have to worry about. It makes sense for codesharing with server code or preexisting business logic.
Over the years I've debugged js compiled from various languages, and it's seriously a terrible experience: however bad you think debugging handwritten js is, reading and debugging generated js is strictly worse (and you will have to)
Or...maybe I won’t; I’ve used plenty of compile-to-JS languages (including what starts as “js” with JSX and modern features but gets compiled to plain, and more widely supported, JS), and I spend as much time reading and debugging JS in its compiled form as I do reading and and debugging .NET or Python bytecode instead of source, which is none.
let obj = {a:1},
arr = [1],
map = new Map().set("a",1);
// Iterating over an object keys
for (let x of Object.keys(obj)) {...}
// an array
for (let x of arr) {...}
// or a map?
for (let x of map) {...}Doesn't mean I'm saying JS is inherently beautiful. But if you ignore the bad features and do a little setup, it has the potential to be wonderful.
Maybe TypeScript is great, but I just don't like the idea of depending on transpilers to not suck when creating the final code, and also having to debug that transpiled code, and then the whole transpilation step in between the standard command-S-command-tab-command-R workflow (this is also why I never use SASS/LESS if I don't have to).
Once JS itself has strict typing and real classes, and enough time has passed that I can be assured 95% of people using five-year-old browsers will be able to use it, then we can talk about the wonders of JavaScript. Until then I don't get why anyone would use it (or anything that transpiles to it) when there are so many better alternatives for server-side development.
Let's not even get started with Electron.
Comparing assembly/C to JS/TS doesn't make sense.
...but different.
> Writing C is not like writing assembly...
...it's different.
Or you could just write the JS directly and be done with it.
At the end of the day all I care about is if I build the products and solve the problems I'm hired to do. Beyond maintainability, the "engineering" stuff is a distraction we need to be careful not to obsess over.
How does this differ from trusting a compiler or interpreter?
Every language has to be translated to machine code in some way.
When was the last time you found a bug and it was the compiler or interpreter's fault?
At any rate, the big difference is debugging, as I mentioned above. How fun is it to debug code which you only kind of indirectly wrote?
I've not come across any bugs caused by typescript itself in the time I've been using it since 2014, and my point was that this is the same for c or any other language - how fun is it to debug assembly you only kind of wrote
Today, PHP offers a solid OOP experience, good gradual typing, a larger and saner standard library and code loading based on namespaced components.
Now compare today's JS to PHP back in the day. It has the exact same kinds of problems. Except with modern JS, you'll end up adding TypeScript, webpack, Babel and a dozen other tools as well as several hundred megabytes of libraries to paper over all of those problems. But by doing that, you make the build process and the code that ultimately runs in a browser completely incomprehensible and undebuggable for the average developer. And then you start adding even more tooling (source maps that barely work) to try and solve that problem...
I find it really unfair to compare es6 to php 15 years ago, es6 is really cute (the babel/transpiling part is peculiar, I admit it)
I was writing PHP 15 years ago. It wasn’t a great dev experience and the tooling was awful. JavaScript today has stellar tooling in comparison, and arguably less warts in its standard library than PHP still has today.
I really disliked JavaScript until I read some books that helped me understand what it’s doing under the hood. These days I just don’t have issues with it. Yeah, the ecosystem thrashes a lot and the tooling experience can be bad in regards to that, but otherwise it’s impressive lately. Even without TypeScript, intellisense on regular JS enables extremely streamlined navigation of references and implementations, refactoring, project navigation, tooling integration, etc. Not to mention modern profiling and debugging tools for JS are incredibly easy to use and benefit from.
PHP wasn’t at this stage even 10 years ago. The debugging story was still xdebug and tooling was improving but not great. Composer was painfully slow and buggy - nowhere near as nice as yarn and npm are now.
Yeah JS has problems, but I don’t believe it’s nearly as bad as old PHP.
There are a lot of reasons to like JavaScript as a language and NodeJS as a particular implementation. The standard library (or lack thereof) is absolutely not one of them as things stand today. I'm not even sure what you'd compare between them.
If you meant to say "package available at the other end of npm install" instead of "standard library" I could see that being a different story.
But the Javascript part is the one that always causes me hours-days worth of work into Rabbit holes. And by JS, I don't necessarily refer to the language alone. It's the entire ecosystem.
Oh, `npm install`? You just found out you got like 1000+ vulnerabilities. Alright, good thing it told me actually, let me update.
BOOM! Babel doesn't support this specification in this file anymore because it's nonsensical so you have to do something else now. Ok, BOOM! Babel deprecated that now, you have to try this workaround. Oh, wait. Actually, there is no workaround. You gotta downgrade your node version.
Ok, let me downgrade. Oops, that package isn't supported anymore on this node version. Oh, you need to replace this because it's no longer maintained.
I literally never had to go though this pain with any of my Elixir backend projects.
Fuck Javascript
You notice you have thousands of outdated dependencies and that's a bad thing?
I used to work a lot with python years ago, and the only reasons we didn't have this problems was because the packages management was so terrible that you didn't even notice you had to update dependencies or that they had vulnerabilities.
With a small number of deps where you skim the development DL, you know if there is a security issue or a cool new feature you want. Also it has more of the Unix C philosophy of don’t break stable APIs in new releases. So upgrading mostly just worked. (Stuff like deliberately breaking old SSL protocols aside). (Until python 3 of course.)
They also don't have thousands of projects depending on ridiculous packages like left pad because they actually have a standard library.
The surface of vulnerabilities and the brittleness of the entire ecosystem is the bad thing, not the warnings.
> You notice you have thousands of outdated dependencies and that's a bad thing?
This is a weird reply considering that the OP literally said those were a good thing:
> Oh, `npm install`? You just found out you got like 1000+ vulnerabilities. Alright, good thing it told me actually, let me update.
The bad things are in the lines that follow.
On the other hand his php project from 2011 still works, just as my perl stuff from 2006 still just works.
> Alright, good thing it told me actually, let me update.
Babel is the only way to use modern standard JS without excluding older browsers.
Because you mentioned Babel I suspect you actually didn't use JavaScript - but a language that compiled to JavaScript. And this complicate things a lot and is probably the root cause of your wasted hours. The time you save upfront by using some framework you pay back later in maintenance once new versions are released and things get deprecated. In JavaScript itself nothing will ever get deprecated.
That said, unfortunately, the language is much better expressing personal projects than picking up the trash in an untrained corporate environment like an over paid janitor.
It's nothing short of incredible that it is as fast as it is and as useful as it is. It shows that many hands do make light work; and money can buy that effort.
JavaScript has quite effectively managed to avoid anything the Perl 6 fiasco which greatly contributed to Perl's demise, or the Python 2 => 3 timult, which turns out will not be a kiss of death, but made for some rough years. JavaScript did almost have its own trouble of the same sort with ES4, but it was very wisely abandoned when it turned out to be too ambitious/contentious...
I don't actively use it but I followed it. It is actually a more modern language than pretty much anything else and it seems to have great community that is not a bunch of zealots. Also, it is far from dead.
At the same time Perl5 is also still alive and from the start, it was clear that the two will be maintained in parallel. Perl6 was not intended to replace it, they changed the name to Raku to clarify the situation.
So while it may be a fiasco if you consider the market share, it clearly isn't for the language. Perl5 doesn't really need change, and if you want to change it anyways, it would be for a whole new language, and that's exactly what happened.
Now? I'd be amazed if a single student had written a line of Perl, or ever heard of Raku.
That simply doesn't compare to where Python, Java, or even PHP are in the popular mind, IMO.
I would call that something of a fiasco, frankly. Market share is everything for a programming language. The game isn't zero-sum, but it's close; there's only so many developers with so many hours to create libraries, guides, new software.
Perl6 was definitely a fiasco that contributed to Perl5's demise. The active support in the ecosystem was divided between the "two Perls" and sapped the driving forces in the community.
Perl5, like any other language, needs constant maintenance and growth in order to interact with modern tools and frameworks. For example, Protobuf and gRPC only work with a particular module (Google::ProtocolBuffers::Dynamic) which requires an arcane series of dependencies.
Remember that a language is much more than just the semantics and the batteries-included libraries with the core. On the module and community side, Perl has been in free fall for the last decade.
sadly that is not true. some stuff broke over the years. most often it was not javascript itself but changes in the dom api.
The result is a sprawling, very crazy looking house that no one would have sat down and designed upfront. I think of JavaScript as the programming language equivalent of this house.
And modern js does not look crazy, it's the es5 and bellow that was a bit wacky. Typescript is much cleaner than the 3 languages I mentioned, my opinion.
Built-in method and class naming is wildly inconsistent. OO is bolted on, typing is bolted on. While not "the language," the GIL and what it means for parallelism (multiprocessing is a shit show) was a mistake.
I dont think it's something to be too proud of if the only thing nice about your language is the syntax.
Heh, read the VueJS 3 code base.
I haven't done much at the level of optimization I think is going on there, and this is Evan's third iteration so I'm guessing there is a lot of insights baked into it, but dang if it's not hard to wrap your head around. Even if you check it out and use VSCode to try to figure it out.
Individual sections of code make sense. But it's like a deconstructed hamburger and you've never seen a hamburger in your life.
The only other truly weird features came from twisting prototypal inheritance into something vaguely Java-ish. These actually became more convoluted with a whole extra layer of weirdness while once again trying to force traditional classes on top. Unfortunately, devs from other languages think they’re the same and they mostly work as expected right up into things fall apart (usually when the hole they’ve dug is massive).
In truth, the biggest mistake was not going with scheme. If they had, the rest would be easy from language extension to adding lower level abstractions to compiling various languages to it would all be easier.
As to Javascript - I like the language because it a language that fits best with my way of thinking about code. I'm not sure if that's a good thing to admit.
Complaints like integers come from not studying the language and not keeping up to date.
Asm.js type directives have offered 31-bit integers for years now on all major JITs. That is slowly not working again as wasm takes over, but BigInt has been included for quite a few browser versions now.
Perhaps, or perhaps fixing one too many bugs where someone thought floats were appropriate for all the things. Regardless, forced change, even if it is a good change, is still forced.
> [] + []
>
> {} + []
>
> [] + {}
>
> {} + {}
It means that if you feed it nonsense it does not stop you but happily carries on and explodes a few milliseconds later somewhere else. Another can of worms is the difference between null, 0,undefined, '', ....Ok, you got me worked up. I need to go for a run to blow off steam.
> "There are only two kinds of languages: the ones people complain about and the ones nobody uses".
I'm not a fan of JavaScript but I do like TypeScript.
Coercion rules are terrible, but they were only added to the language due to developer demands.
If you worry about zero or empty string, you’ll have problems in tons of other languages. Null vs undefined is less understandable along with the old ability to redefine undefined as it was a variable . In any case, I agree that one of the two shouldn’t exist.
Want to create/maintain a modern JS/TS stack? Well, you are going to need npm, webpack, probably babel, linters, need to understand how to setup source maps and get those working for debugging server side. etc.
It's a nightmare and it's all very fragile and that isn't even touching on the poor quality of the libraries outside of React/big ones.
It's definitely not there yet but they have the right idea.
Better JIT, real threads (also Loom coming which is better than async/await or Promises), better standard library, better library ecosystem, better profilers, better debuggers, better metrics/monitoring for the VM, better portability.
It seems to me that the core server-side JS benefit is isomorphic code on browser and server which is probably useful if your team is small enough to have the same people working on both but for companies of the size I generally work for this is rarely the case beyond maybe small fixes I might do in JS/TS.
For me personally this can't offset the absolutely gigantic difference in quality between say JS/TS and Kotlin/Java.
I think a lot of the arguments are due to the clash of these two opposing mindsets, people who start in javascript and build things in a browser think it's great, people who build enterprise applications with typed languages disagree, often strongly.
Great programmers and hackers don’t complain about the language as it is irrelevant. They just use whatever is available to get the job done and get it done well. The more programming languages you know well the more you understand that each has advantages and disadvantages. Part of being a pro is to know what to use under what circumstances. What’s the point of comparing apples to oranges?
Finally, you will always need a scripting language with a loose type system even when you start at the low levels. Don’t be so obsessed about type safety, etc. It only shows lack of skills to keep the program model in your head. Gaming engines are scriptable for a reason. It provides different ergonomics that are useful. There are plenty of Rust, Go and Java applications that that replace scripting with ill-conceived configuration templates that resemble scripts except that they are inferior. If you are writing a complex system in Rust, v8 is a modern, expressive scripting runtime that will help you rapidly prototype. That is not say it is better than Lua or Python. It really depends what you want to achieve. But choosing the right scripting language can also drive adoption. So choose wisely!
If you ask me, the reasons are quite uncomfortable; and has parallels to how a lot of prejudice is seen in society when upward mobility happens. JS now encroaches server-side jobs, while earlier it was relegated to the browser. JS can do scripting. JS can now do native phone apps quite well. It can be used in desktop apps. It also pays well.
Probably because it's a gatekeeper language - in order to run code in a browser, you have to use this language[1]. That means a lot of developers that dislike it enough that they would switch to another language if they could, are stuck with it because they need to target the browser. This "captive audience" is effectively forced to engage with the things they dislike on a daily basis - at that point you either develop Stockholm syndrome, or the resentment grows into hatred. Thus the "warts" that JavaScript has (by nature of having been thrown together in a couple weeks originally, and being iteratively turned into a "real" language over the following decades) have a chance to cause much stronger negative feelings than they would if people could just switch to something they liked more.
[1] I know, I know, WebAssembly may change this, and there are already niche alternatives like Scala.js, ClojureScript, Blazor and Reason - but for the most part, you still can't effectively run things in a browser without knowing JavaScript, even if just for debugging
Developers can choose to program in whichever language they want but only JavaScript is officially supported on the browser. Any other language will require a transpiler or compiler (when it comes to WASM). Similarly you can program iOS and Android apps in whichever language you like but only Objective-C/Swift and Java are officially supported. All other languages you need to support yourself. The official spoken language in UK is English whether you like it or not. You are free to speak any other language you want but social frameworks and civil services evolve around a single language.
If developers are so smart how come we cannot understand these basic principles?
I'm sure there are many other factors that play into this (just look at Gary Bernhardt's "WAT" talk), but essentially, I agree that this has to be a big part of the problem. If you've been developing backend systems and asked to hold up robustness and stability guarantees for multiple years and then run into Javascript, you will likely run into situations where you have to make up for its deficiencies in that regard.
That doesn't make it a bad language per se -- that's the case with any language in some aspects -- but since JS will be a new language to you, you're much less likely to accept that situation as a given.
Last year I finally started to dabble in Node. Though I fully understand the criticisms of Node, learning it really did open my eyes on just how far js has advanced. I'm really loving the present state of js callbacks/anonymous functions, leading to elegant solutions that I now miss when going back to Python.
I am naive to doing any professional web development, but from what I have seen, it seems like having to handle the idiosyncrasies of the four major browsers is a lot less effort than having to handle the 4 major operating systems though I could be wrong.
As it stands it's layers of caching, state machines and complexity.
It's been especially helpful for yield and async/await, but I wonder if there's a bug in Babel with async/await. Just using the code sample from the article:
function fetchUserName() {
return new Promise(resolve => setTimeout(resolve, 500))
}
async function withAsync() {
print("withAsync: fetching...")
await fetchUserName()
print("withAsync: done")
}
await withAsync()
when I set the target to be 'ie 6', so hopefully I get output that's only the Javascript that I know, most of this gets translated to (a lot of) Javascript that looks normal for 2005 Javascript - except the last 'await' line is still there. Is that a bug/limitation in Babel or was 'await' present in Javascript from years ago? withAsync()
.then(() => print("done")
.catch((err) => console.error(err);MDN is amazing, coming from games and working on a web project the level of documentation is incredible.
https://www.infoq.com/news/2017/10/microsoft-google-mozilla-...
The only thing I wish was never added is the new Array Functions, I mean, ok they are "handy" sometimes, but they seem to get abused heavily. Newbies like stringing them together and even nesting them, when they could have achieved the same with a single for loop and the same number of lines. In other words they seem to encourage people to artificially increase the complexity of a problem without any objective improvement in legibility, not to mention lots of GC work with throw away arrays... many people don't seem to even be conscious that under the hood of most of the array functions is just another iterator of some kind.
Useful fresh additions are .find() and .includes()
You never know what structure a for-loop will take, it could break early, skip items, build a new data structure, mutate a data structure, or all the above. If I see a map and a filter, I know exactly what each does.
I don't want to argue over which is better. Pros and cons. I just wanted to say that chaining and nesting array functions is not a reliable sign that someone is a "newbie", maybe they're just someone with different preferences.
Array methods convey meaning a lot better. There are some cases where performance matters, but usually the performence cost is negligible.
In some languages the map function may be restricted to not have side effects, in which case I'd agree, but not javascript, correct?
This lends itself very nicely to functional programming (especially with typescript IMHO)
I teach all my reports to lean heavily into the new array functions because, if wielded correctly, are much more powerful than using for loops while using less code.
Lodash and similar libraries are much better in this regard as they tend to use iterators internally which don't generate all the extra garbage and don't iterate multiple times. Because they don't have to handle all the weird edge cases, they tend to also execute faster too.
Computers are fast, and all browsers are really good at this stuff, so I don't tend to worry about creating a bunch of extra work for the GC.
Something something.. premature optimisation?
In this case, we’re talking about a single import and almost identical API while also gaining access to tons of additional and more advanced functions that save time too. It hardly seems comparable.
This is the most missused phrase of all. We are not talking about optimisation here, we are talking about _not_ writing slow code, there is a huge difference. Optimisation tends to add complexity with a trade off.
If you write an entire program with this thinking, a significant program, each of those "negligible performance hits" will usually add up to a poorly performing program. Back in the day people called "optimising" the application of clever algorithms and tricks to squeeze more out of a computer, today we call it ripping all the shitty slow code out of programs because devs couldn't be arsed to write things properly because "computers are fast". </ yes it's a rant, it's why lots of stuff sucks, make nice things pleeease
I’m trying to get rid of it and move to a functional language like Clojure (actively learning) or perhaps Rescript.
Meantime I found Ramda.js and so far so good. No more javascript fatigue.
Ramda, React, and Typescript looks like a good patch for the short term. On long term I definitely need something integrated.
And something integrated with the running environment. Node, Webpack, Babel are a real pain.
I think the future is bright. We’ve learnt the pain making all above work, and work together. Now something really new is coming.
Statically typed, functional (the good parts), focussing on problem solving, and leaving the quirks behind.
|| - returns right side operand if left side operand is any falsy value
> 0 ?? 1
0
> 0 || 1
1I feel like I'm doing the work of the compiler. Why can't it automatically make the function async whenever it sees an await within it?
I would still love a "20 mistakes you need to avoid when writing JS".
One of the most horrible "WHAT IS HAPPENING HERE?" moment in JS was when there was a missing semicolon after some multiline code and error messages were not helping at all. I'm wondering if JS compilers will have some linter or will one day help beginners be warned of "possible mistakes".
Isn't there a list of "good practices" or "js coding standards"?
I'm not a JS dev but isn't this something almost any IDE with a linter would help you out with?
let a = 123
({a}= {a: 10})
Prettier will reformat it like this: let a = 123(({ a } = { a: 10 }));
You could also use ESLint to enforce semicolons.The error messages when running code like this aren't very good though.
- Modules
- Set and Map, WeakSet and WeakMap
- String interpolation
- Private methods (# prefix)
- Template literals
- Typed arrays
- Symbol type
- Generators
- Proxy / Reflect
- Internationalization
And more...
There are still “fucking JavaScript” moments but those are few and far between compared to what they used to be. The “...” operator in particular has been hyper useful for neatly modifying complex objects without turning into spaghetti code.
SPA+node/express is a pretty solid stack these days because of these improvements. I no longer find myself missing Rails for Ruby’s syntactic sugar and knowing that operations on the server will work exactly the same on the client has been great for browser console debug sessions.
The holy grail would be for HPC JavaScript libraries to allow the same ease of implementation to use something like NVIDIA RAPIDS (especially RAPIDS itself) as easily as we get with Python. Given how far js has come, I don’t think that’s an unrealistic proposition.
One thing seems clear: We won't be using webpack, react or any other current tool. I'm not sure how organization can shoulder the costs associated with that kind of churn.
They are needed for proper HTML. They're just not needed for HTML.
There’s plenty of precedent for habitually skipping start tags in the HTML syntax. Few people write <tbody> if they are doing a simple table with no <thead>, because <tbody>’s start and end tags are both optional. <html>, <head> and <body> are the same.
(I’m spelling out “in the HTML syntax” here, because if you’re using the XML syntax—not common, but not unknown—no start or end tags are optional; if you write <table><tr>…</tr></table> in an XML syntax HTML document, you will get an invalid HTML document that lacks the <tbody> element.)
I wish there was such a resource for modern C++ though. I learned and used C++ in the 90s and early 2000s, and apparently the language has progressed a lot meanwhile. People say idiomatic modern C++ (C++14/17/20) can be pleasant and metaprogramming capabilities are really powerful.
Lol, I love modern JS, but that’s factually wrong. Const means the variable cannot be reassigned in the same scope. It is 100% mutable though. It “implies” nothing. Indeed, one of the few good uses of const (it’s basically useless most of the time) is Vue’s composition API, where you want to prevent rebinding but actively mutate.
That said, on some level it's all just lipstick on a pig. I just want a type-safe strongly-typed language in the browser. Maybe Java, Kotlin, Scala, etc. Mark my words: Someone will make a browser where a Java VM is a first- citizen like the JavaScript VM is, and people will start writing apps specifically for that browser.
ASI is an error correction mechanism, not a language feature. You can also do things like not using the var keyword when declaring variables or something like a = 2 < "4"; and it'll work fine. But you don't because they're all errors.
Sometimes I can use Array.forEach() and sometimes not, and I don't know why, even if I'm only using Chrome. So I just use lodash.
Spread syntax is my goto for that:
[...arrayish].forEach(...)
But, it being JavaScript, there’s probably a subtle distinction in where Array.from(arrayish) works and where [...arrayish] works.`...foo` requires `foo` to be an iterable (implements the iterator known symbol).
`Array.From()` only requires it to be array-like and not necessarily iterable.
for (const item of iterable) {
// do forEach stuff here
}Are they?
Last time I used them (some years ago) they did not came close to Class behavior I know from Java etc.
It was still prototype inheritance. Or did I missed something?
They occasionally have uses, but generally, I think they aren't hyper useful.
[...foo.filter(x => x % 2 === 0)]
rather than
[foo | where x % 2 === 0]but does it?
I think of javascript like perl. It makes things work where you need it but god I don't want to work on a codebase of more than a few files.
ReasonML and KotlinJS will faster become practical general purpose web languages than committee would start doing something usefull.
Is it JavaScript's job to improve the lives of transpiler implementers instead of improving the lives of JavaScript developers?
And i thought it's kind of obvious for anyone, that until *JS* proposals are staged far enough - Javascript won't have those features too. There is a good reason why TS waits for the stage 3.
I like JS a lot these days.