I don't know if this is part of the standards but there was a backwards incompatible change in the way regex worked around firefox 73 and a bunch of sites crash in older firefox now.
I'd like to say it's a testament to the original design; but I can't overlook the hundreds of millions of dollars, perhaps more, that has been spent to improve the language.
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.
I don't have any numbers to back this up, but I'm pretty sure that between Google, Mozilla, MicroSoft, etc. more resources (both people and money) have been put towards improving JavaScript (language and performance) than any other language in the history of programming. Now I hope someone will provide numbers to show why I'm wrong.
Huge amounts of inspiration came from coffeescript. The biggest advantage of JS has often been going last and executing what is already proven to be a great idea.
Yes, indeed. It is really pleasant compared to how it was 10 years ago, and still -- code written 10 years ago, even code written 25 years ago still runs in modern browsers. It's amazing and wonderful.
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.
I dunno. If you walked into a sophomore-level computer science lecture 15 years ago, most of the people there would either have heard of Perl or be proficient in it themselves.
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.
Speaking as a long-time Perl monger (Perl5 has been 80%+ of my day job for most of the last 25 years):
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.
> Yes, indeed. It is really pleasant compared to how it was 10 years ago, and still -- code written 10 years ago, even code written 25 years ago still runs in modern browsers. It's amazing and wonderful.
sadly that is not true. some stuff broke over the years. most often it was not javascript itself but changes in the dom api.
Backwards compatibility is one thing. But forwards compatibility is something javascript devs have a terrible time with. The standards change fast and new features are added constantly. And unlike, say, Bash devs, javascript devs want the latest and greatest and don't care if it doesn't run on $software from 2 years ago.
Yes they do, that's the entire reason to use Babel. If there's any part of the stack where you have to go to great pains to be compatible with a wide range of completely different environments, it's the frontend. It's the dev environment that churns a lot, partly for that reason.
Bash runs on an vastly larger number of different environments yet Bash devs still manage to write forwards compatible code. It's the culture, not the language.
Programming languages are tools, what matters is if they do their job. And the current popularity of javascript means it works for most people.
But boy, how ugly and inconsistent it is. I wish I could like it.
I use both JS and Python for work and not a day goes by where I don't wish history had taken a different course and Python had ended up embedded in web browsers.
There was a strange time in the dark days of IE6 dominance 20 years ago that you actually could write page scripts in non-javascript languages. VBScript was a big option that some people used, and IIRC there was a way to get python support in IE (and Windows) script host too. When I was first learning Javascript in ~1998 I remember all the docs showed how to do stuff in both JS and VB script tags: https://stackoverflow.com/questions/17483782/vbscript-suppor...
This brand-new book on using Python (via Transcrypt) in the browser to build a React app may be helpful in that regard: https://pyreact.com. Just started reading it. Seems very good so far.
You can write Rust for the frontend right now. It's pretty neat.
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.
>If people didn’t like JavaScript for front end work, it’s not like they could just switch to python
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.
>That has nothing to do with Javascript's merits as a language though.
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.
Can’t easily write Django code in JavaScript either. In general it’s not like working programmers get to choose any programming language whatsoever for the hardware and platform they’re writing software for.
You don't have to use Django (you can choose one of the billion alternative CMSes), but everyone has to use a browser. Hell, Django itself has to write javascript.
> If people didn’t like JavaScript for front end work, it’s not like they could just switch to python
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.
Why is that not a solution? The concept of compiling/transpiling a language into the target language for the runtime is everywhere.
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 not a solution if you end up with Javascript in the end. (
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”.
The issue is that writing code that goes through a JS-transpiler is more complicated than just writing Javascript, unless the language you choose is Javascript-adjacent, whereas writing code that compiles to machine code is infinitely less complicated than just writing machine code.
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.
> It turns out that even if you accept "Python is great and JavaScript sucks" that "Python compiled to JavaScript" ends up even worse than JavaScript.
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 also have gotten DMs on Reddit from companies looking for devs since I commented on a thread 10 years ago about an obscure toy language: it doesn't mean thats a reasonable choice for technology.
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)
> however crazy you think handwritten js is, generated js is just obviously worse to try to read (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.
I would expect, given you have described an operation on 3 different data structures using different words, that it would also demand 3 different kinds of syntax/denotation no? Your own language requires as much. Why not JS?
Well in python by example you use for x in myobject to iterate and that's it, no Object.entries(myobj) vs. mymap.entries , lua is even more consistent, ..
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) {...}
I started just despising JS. But with discipline and a well-configured linter, formatter, and ideally using Typescript, I've found it to become my favourite language.
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.
So many people are bringing up TypeScript here as an example of how JavaScript isn't so bad. I kinda feel like that's cheating. Like saying eggs are absolutely delicious when baked into a cake - you're praising something after it has been turned into an entirely different product.
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.
Because it's no longer the same language. You're not programming in JavaScript, you're programming in TypeScript, which happens to be compiled to something JavaScript engines accept. All the praise towards TypeScript does not necessarily apply to JavaScript. It would be like praising Assembly while you're actually programming in C.
AFAIK, the only difference between TS and JS is types. TS doesn't give you anything that's functionally different than JS -- only types that are stripped during compilation. You can't perform any logic on types at all (e.g. you can't have conditional logic based on interfaces).
With most things, yes, if the implementation for that feature supports your operating system, and it doesn't take long enough to be noticeable, and there's no weird caching issues at any given level, then yes, it's transparent in that case.
Or you could just write the JS directly and be done with it.
People occasionally rely on compilers. I don't really see this as much different.
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.
Well yes. But as the problem solver, there is nothing better than when someone has a problem, and you have a solution ready at hand which came from lambda calculus or distributed systems tricks or some crazy shit from On Lisp. That is why they are paying you, not to cranks out good dutiful straightforward solutions but for clever ideas that are simple to implement and operate. The engineering is both awareness and skill in following processes to get great cheap and effective solutions. Otherwise you end up with 20 million lines of
code and all the aesthetically sensitive people have have to leave the company.
The code output by typescript is generally pretty readable depending on the target, and the source mapping works very well regardless. The debuggers in all major browsers and ides handle it fine.
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
Given that people are usually already using Babel, TypeScript isn't really any different than running a linter is. There's no additional transpilation step if you write your code in TS, but you can also run TypeScript to have it warn you of potential errors.
I write PHP for a living and every time I look at the JS world, I feel like they're exactly where PHP was 15 years ago, except with 20 times the amount of incomprehensible tooling.
15 years ago, PHP didn't really support any programming paradigm very well, it was a huge untyped mess, the standard library was missing a lot of stuff, reusing code meant including individual files based on filesystem paths.
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 had the impression that beside gradual typing, ES6 solved most of the mess (cleaner apis, modules) which was happening at the same time PHP (and python) accelerated their growth.
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’ve worked with PHP and JS extensively and while I could almost agree from some narrow perspectives, I think JS is nowhere near where PHP was 15 years ago in any sense.
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.
> JavaScript today has stellar tooling in comparison, and arguably less warts in its standard library than PHP still has today.
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.
This may be a little off topic but your comment piqued my interest: I am currently learning JavaScript and I was wondering if you would like to recommend any of the books you read.
It’s been a while, but I really enjoyed the “You don’t know JS” series by Kyle Simpson. It explained a lot of the details I needed to understand in order to be proficient more consistently. Whether I was working on client or server side code, I felt like I understood my tools well enough to feel a lot more confident than I did before.
I maintain systems written in Ruby, Elixir and PHP over the years. Every server side code written by me even as old as 5 years ago, works with very little modification required for today.
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.
So npm gives you warnings about vulnerabilities and that's a bad thing?
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.
Diff being you usually have like five python deeps for every hundred npm deps a d you can do the old school thing and subscribe to the security alerts for those deps. The difference in number of deps means you have the cognitive
space to understand them. Npm needed to automate because the numbers are too high. One of
python’s old selling points was “Batteries included”. And the idea is fewer large library rather than a bunch of tiny libraries.
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.)
Not OP but what I think they struggled with is fixing warnings.
JS projects are like a poorly built house, things are constantly deteriorating and need constant maintenance.
I've got a new nodejs project that a colleague wrote about 6 months ago. It's already completely broken and needed a lot of effort to get working again.
On the other hand his php project from 2011 still works, just as my perl stuff from 2006 still just works.
This doesn't sound foreign to me.
Node projects rely on a lot of dependencies (and so does their dependencies) so there is a lot of moving parts and it's prone to break.
I completely disagree. The TypeScript compiler allows you to specify a compile target against a version of JavaScript. That means you can write modern TypeScript and have it compile to ES3.
1: Trying to fix every vulnerability in any nested dependency is probably not what you want to do. In my experience only a tiny fraction has an attack surface and most are duplicates.
2: Webpack is a monster and updating webpack will always result in a lot of work. If possible use a well supported framework that incorporates Webpack, like Next.js or Nuxt.js. Updating will be a breeze.
3: Don't wait years before scanning for issues, update on a set schedule so it won't become a huge task once a critical issue is found.
Do elixir libraries just never deprecate stuff? Or just that their package managers never alert you about vulnerabilities so you can pretend like they don't exist and so never upgrade?
JavaScript is backwards compatible. What you wrote in JavaScript 10 years ago will still work today in all JavaScript engines.
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.
Yes, the language is sloppy. Like all things sloppy it’s more about knowing what not to do only after which the elegance is exposed.
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.
There's a lot to like in modern Javascript, pretty much everything in the list I appreciate.
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.
Many array looping functions have been around since ES5 and I've been personally replacing them to for-of loops with very few exceptions (.map() and .filter() remain handy)
Useful fresh additions are .find() and .includes()
As a standalone idea yes, however in practice this is not actually the case [0], mostly due to those methods having a number of extra checks, more functionality built into them etc.
Fair point, although as the answer states, it depends on use cases. Working with small datasets the performance difference is negligible, but with decently large datasets (~1-100mb) and nested loops the delta is night and day.
That is a valid opinion, I agree there are advantages to plain for loops. However, it is not a universal opinion and I would argue against the for-loop, sometimes. Some languages people love do not even have loops.
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.
A for loop is an imperative construct and can be used to do literally anything. One has to read on into the body of the loop to understand what's going on. Worse, there could be a bug and now you have no idea what the programmer intended. Array.map, on the other hand, only does one thing: turns an array into another array. The intention is clear. It makes a program much easier to understand.
In javascript, what prevents the body of the map function from doing arbitrary stuff? Don't you have to read that to know for sure, just like a for loop?
In some languages the map function may be restricted to not have side effects, in which case I'd agree, but not javascript, correct?
There is nothing more clear than code as a way to communicate, at least for me. My writing in English obviously could be better but easier just to show what I mean.
This is correct, but there are some guarantees such as the result will be an array of the same length, mapping function will be called for each element, function itself can be more easily tested in isolation and there are no imperative constructs (creating accumulator array outside of the scope, tracking the index, pushing to the accumulator array)
This lends itself very nicely to functional programming (especially with typescript IMHO)
As someone who works in a few languages I find the array methods really handy as they work similarly. It's usually a bit clearer to me what the programmer's intention was with them rather than a straight for loop.
Newbies aren't the only ones stringing them together and nesting them, even seniors like me are...to great effect, increased readability and are safer than potentially dangerous mutations.
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.
The big problem with them is that they are naive. If you string 10 of them together, you will iterate the array 10 times and generate 10 garbage arrays.
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.
I’ve always heard premature optimization used to refer to convoluted, harder to use and understand techniques that trade lots of developer time for extra performance.
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.
I just wish those methods were available on iterators (and return iterators when called on arrays) and a collect method that creates a new array (a bit like Java). That would reduce the overhead and keep the advantages of this functional style.
Sure if your entire program is only one loop that iterates over 100 things that fit in an L1 cache.
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
Some other important features and browser APIs released in the last ~10 years: Web Workers, WebGL, OffscreenCanvas, Typed Arrays, Web Audio, Web Notifications, WebRTC, Websockets.
The Winchester House was continuously added onto by a huge construction crew for many years after the death of Mrs. Winchester’s husband. She believed her psychic who told her she had to continuously add onto the house to repent for the people killed by her family’s rifles during the civil war.
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.
Most programing languages old enough have that problem: C#, php, C++.
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 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.
this is my opinion but you pick a library that clings onto an outdated programming model (markup-centric, or string-based programming as I'd like to call it), to judge modern javascript.
ES5 syntax itself has nothing particularly strange. It’s bog standard C/Java syntax. If there’s any complaints to be had, they would be the semantics of using the syntax (though maybe that’s actually what you mean). The worst feature (type coercion) was an intentional addition because many developers asked for it and Eich (to his later regret) went along.
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.
To pick up on your tangent with a tangent, I think Tim Powers's take of the Winchester House mythology, in his book Earthquake Weather, is my favourite re-interpretation of the story.
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.
The very fact that your example uses a house shows this is not limited to JavaScript, or even software for that matter. A relatively famous paper "Big Ball of Mud" by Brian Foote and Joseph Yoder discusses the effect.
JavaScript has grown a lot in the last 10 years, the last ~5 in particular with ES5/ES6.
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.
Adding existing c libraries to python is trivial, and very C like experience for memory management etc. adding existing C libraries into node engine requires more skill and delicacy due to the C++ and the relatively more complicated v8 way of doing things.
Confirmed. Every time I convert an old Node project to promises I constantly find bugs and situation that were just lost in the hell. The result is also so much cleaner that sometimes you realize you were doing something wrong entirely and you scrap the whole thing. No other JavaScript improvement comes close. Everything else is nice but only saves a few chars at most.
And they announced promises like a big improvement over callbacks :D Now that was hell! Fortunately, when I started doing serious Node.js development, callbacks were already on the way out.
It's building on top of something that developers should be using anyway; or at least have familiarity with. I'm quite glad they ended up going this route for that reason.
For me too. Only thing I sometimes struggle with, is figuring out how to place error catches.
Wrap each async functions body in a try catch? Or always attach a catch handler to the calling function? But what if I forget to do that?
Should the caller or the callee handle the errors or can both?
I'm so disapointed by the committee.
So many utterly useless or easily bootstrappable features and yet, no pattern matching and pipeline operator stage 3 proposals. 0 progress for so many years.
Lack of those roadblocks Typescript implementations.
ReasonML and KotlinJS will faster become practical general purpose web languages than committee would start doing something usefull.
First of all Typescript, is now more mainstream JS dialect than vanilla-js itself and, honestly, the only one i care about.
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.
It took 6 years to ship ES6. We've now had a new spec iteration from every year after 2015. They are moving much, much faster and, having lived through ES5 to much pain and angst, I'm completely ok with them taking their time shipping these (very nice to have) features.
10 years ago JavaScript was an ugly language, with its clunky prototypal inheritance and so on. Modern JavaScript is a beautiful language, however, especially when enhanced with static typing as in TypeScript. So much so, that Stanford has replaced Java with JavaScript for its introductory programming course [1].
Picking a language to teach programming and concepts in computer science presents an interesting conundrum. Do you pick a commercially relevant language (which most students want) or go with one that might be better for academic purposes? I probably lean mostly towards the former because time spent learning something like Eiffel feels somewhat wasted.
On the other hand, there are concepts (closures, objects, pointers) that come more naturally with some languages, and you absolutely need to learn the concepts even if you don't end up using the language.
To me, the dilemma is between a language that's easy to learn and one that is useful once you learn the language. Most languages have too many warts and footguns to be easy to learn, but learning a toy language isn't good, either, because it's not useful.
No one should have a computer science degree and not know multiple languages and multiple programming paradigms. Prolog, lisp or scheme, C, JavaScript, Haskell. The long term task of the professional software developer is to learn new stuff. Helps if your awareness of the cool things you could learn is already broad. I cannot explain how wrong it is to graduate with Java only and think that is sufficient. To be honest, I would also want people to understand the halting problem and Godel’s incompleteness theorem’s proof, as understanding the equivalence of apparent different systems that can handle the integers is very fundamental. And these days some knowledge of distributed theory is also good, the Lamport time clocks paper and so on. Unless the student is ambitious and doesn’t really like programming and just wants to program for a few years and then get into management or something like that (product? bizdev? I’d that a thing?) they will go thru many iterations of interesting new technologies. The brain that enjoys learning mind-bending shit will have a broader conceptual base and a better chance to see how lisp macro type things can help with k8s configs.
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.
No! Eiffel should be the default OOP language for any kind of course. Being forced to think about pre- and postcoditions and invariants by the language is a really good thing for beginner programmers. While the syntax is somewhat verbose (mainly because of using keywords instead of most punctuation) Not teaching about Design by Contract is yet another billion dollar mistake in computer science. There are DbC libraries or frameworks for just about any language, but only very few programmers know about its existence, which leads to criminal underutilisation of the technique in the industry.
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.
I have no idea, unfortunately. On the other hand, the trademark doesn't seem to be a problem to guys behind Racket, which has the most advanced contracts system out there; the canonical book for programming classes in Racket, "How to Design Programs", teaches you everything you need to know about DbC without ever mentioning the term itself, IIRC. Even if you don't want to touch Eiffel due to it being proprietary, there are many languages which support DbC you can choose from: already mentioned Racket, Ada, Clojure, Scala, D, Nim, Haxe, Elixir, and many more.
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.
I think there were two main reasons: choosing a popular language (JS and python happen to be among the most popular, accessible languages) and pedagogical simplicity (it's nice to avoid burdening beginners with extra syntax when they're already struggling to learn other things). Some unscientific evaluation showed that students picked up static types just fine in our second programming class (which is in C++)
Personally, I think we should be teaching static types and I pushed for Typescript, but it didn't happen.
> it's nice to avoid burdening beginners with extra syntax when they're already struggling to learn other things
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.
Well, of course, but the point is that avoiding syntax is not a great criterion for defining the fundamentals of programming. A couple orders of magnitude more important is to decide what concepts are useful for beginning programmers to know.
Is there something like DefinitelyTyped for Python? TypeScript only became useful once the ecosystem reached a critical mass of type definitions available for popular libraries.
At 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 am sure I’m absolutely nowhere near your knowledge and expertise, but please bear with me sharing my opinion :)
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.
Intro classes don’t need to overburden the student. The biggest hurdle for students is thinking like a computer. You start introducing all these extra things to just get going and it becomes even more difficult.
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...
I agree with you on the overburden part, but not on the dynamic lang part. My very minimal experience is that the hardest thing to get right as a beginner (or even as an experienced developer) is to be able to follow the flow of your code (Maybe introductory courses should employ the debugger?), and the exact state it has at a given point, eg. at an exception. Restricting the valid states imo helps understanding. As well as not having to debug at all at first, but the compiler notifying what is wrong immediately.
I think that you're right in that it's hard to compose all those parts of your program together without accidentally mistaking a `Query` for a `string`, or god knows what. I'm helping a friend learn web development, and most of the issues they get stuck for long time at are solved by making sure that functions you are calling are returning what you think they are.
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.
> 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.
C# has solved that with "top level statements" [1]. If Java added that then problem solved, right? It's a simple addition.
C# would be a better choice. In addition to top-level statements, the standard API seems much less "dogmatically" OOP. Reading a file is just one static method away. Unfortunately, it's still not possible to have top-level functions, right?
> 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
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.
> 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.
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)
Having gone the other way (starting with JS and moving into languages like Objective C), I actually disagree. Having a solid foundation in software writing helped me when I started to learn about the somewhat obtuse abstract concepts that tend to be coupled with learning strict typing.
Then, when learning Flow and Typescript, where I'm expected to have a meta understanding of typing itself, I was ready to go.
I think wrapping all your code in OOP boilerplate is probably too much for an intro course. One of the nice things about Python is that hello world is `print("Hello world")`. No `public static void main(String[] args)`, no nothing. And then on top of that, you can add your functions and classes and whatnot, but it's easier to wrap your head around a zero-fluff entry point.
> I think Java fits better as an introductory language
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?
Sun’s download page?? Also, vim is more than enough for beginners and there is hardly anything hard in javac Main.java && java Main. With a modern JDK java Main.java will compile and run it in one go even. Jars are absolutely not required.
I started programming in Lua which is dynamically typed. It allowed me to experience why a type system would be nice. I'm sure if I had started with a typed language, I would have written it off as antiquated and unnecessary.
As someone who began learning with a statically typed language then moved to a dynamically typed language, I can say that I found learning a lot simpler with a dynamic language.
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 is much more limited as an introductory language than JavaScript. JavaScript is very versatile. Need to write server-side logic? Use JavaScript and Node. Need to write a native iOS app? Use JavaScript and React Native. Need to write a command-line utility? Use JavaScript and Node again. Need to make your web page interactive? Use JavaScript in the browser. Python is versatile as well, but not to the extent of JavaScript. JavaScript, when type-checked using TypeScript also scales better to larger projects and development teams. The one area where Python shines is in machine learning, where Python is a de-facto standard. But here too, Python is facing stiff competition from Julia.
The introductory course is not taken by just CS students. In most colleges, introductory programming courses are open to all majors. For many students this will be the only programming course they will ever take. Why wouldn't you teach a language that is not only well designed, but also versatile, instead of just being a good "teaching language"?
Can confirm. As someone who never formally learn programming, the moment I learned Python I never touched C# or Javascript again at will.
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.
It's an introductory course. The goal isn't to train students to be able to do all those things. I'd wager most professional programmers aren't able to do more than a couple of them well. There's more to front-end/back-end/CLI/mobile than just the language.
> 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.
You seem to have limited visibility into python’s versatility. It’s much much more than you describe, and I’m saying that as someone who hates python with a passion (and has been gainfully employed writing python for most of my career).
Out of the use cases you mention only server-side and browser are a good fit for JavaScript, and Python does quite well on the backend. Writing mobile apps with JS is a frustrating experience at best, and requiring Node for a CLI app is not great UX, unless you bundle Node in an executable.
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).
I think that it was beautiful 10 years ago, too, if you mainly used a subset of it, relying heavily on closures and avoiding constructors and "this" as much as possible. I think that prototypal inheritance is elegant but in any case, there was never much reason to use any inheritance syntax to begin with other than perhaps in rare cases where one wanted to really maximize performance. As for static typing, while it has its uses, the idea that it makes things more beautiful is subjective.
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.
JavaScript is a great browser scripting language because it's the only browser scripting language. That's a whole realm of good times, and people can and should go nuts with it there.
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
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?
To be more specific the term is hoist which means the declarations are pushed to the top of the scope at run time for maximum availability, and var is function scoped instead of block scoped. Block scoping is often more specific because a function body is a block as well.
It's a dynamic error if you access a let-bound variable before it is actually initialized. In most other languages that have lexically-scoped declarations, it simply would not be visible. So I think JS's choice is actually a regression.
var is a terrible example of that. Just don't use it.
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.
JavaScript is different in that it use the function as the lexical scope rather then the angel brackets. This forces you to think about the code as functions, rather then blocks. And in turn helps you think of the code in three dimensions where time is one dimension, making it easier to understand code that runs asynchronously.
Because people coming from other languages find this confusing the let (and const) keyword was specified (ES6/2015) for block/angel-bracket lexical scope. Whereas var is function scoped.
There would be no point in having two ways to do the exact same thing if function-style declaration and arrow-style declaration implementations were identical. Why would they add a new feature to the language if it was purely syntactic sugar?
>> 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 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.
And those things are outweighed by things JavaScript got so incredibly wrong... like === vs == and some of the weirdness when you GASP use == as any other language would do.
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.
This comment is so weird. JavaScript got scoping completely wrong, and none of those were particularly novel when it was designed and they are almost universal now so I don't know why they would keep you hooked on JavaScript!
From my perspective (mostly a Python user), Javascript is a fine language for general-purpose scripting and server dev, and Node is more than fast enough to handle typical workflows.
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.
Like JavaScript, one can argue that the only thing wrong with node is the ecosystem/developer community. Things like npm as just not curated enough given the large number of JavaScript developers and the attendant variability in quality of output. Node itself is an almost perfect call-back driven even loop for Unix network io, which till go and go routines/channels was the conceptually simplest way to use the CPUs you are paying for, saturate the network, and have subtle threading issues. (Python gevent was also good at that, but had more implicit magic which is bad for reasoning about code).
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.
10 years ago I would have agreed with you, but in recent years Javascript (and moreso Typescript) are just exceedingly pleasant to use. I'm using Typescript in backend services despite knowing Python and C# well just because I like it.
I can imagine that the original argument does not apply to the languages which compile to JS. But IMO the fact that there is so many derived languages covering the mess which JS is only supports the argument against it.
TypeScript is just JavaScript with type annotations. The runtime semantics are identical. JavaScript itself has improved to the point where it's great to work with, and arguably the nicest of the common dynamically types "scripting" langauges (python, ruby, PHP, perl).
Completely agree. I used to work mainly in Ruby, and I guess I miss its rich standard library, but overall TypeScript is such a joy to work with that now I use it for almost everything.
Well I know plenty of people that are similar to me in that in our early years, we asked for resources and help, and the response that was constantly given was "use what you know," which was bad advice for people who made websites who were looking to program.
It's no wonder Javascript is the only thing used. I actually love React and ES because it's the first time I feel like a real programmer and not someone just writing Javascript. I don't really care about people's opinions about JS, I simply use what works.
If you hated Javascript, maybe the anit-javascript community should have wrote blogs, made videos, and created content in the same way that the Javascript community did.
> Too many people only learn JavaScript, become psychologically dependent on it, and they all collectively took it too far outside of a browser.
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.
> 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?
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.
Couldn't disagree more. I was a Java programmer for my entire career until about 2015 or so when I switched to Node, and shortly thereafter to TypeScript.
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.
> 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
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.
You are interpreting GP’s comment very uncharitably, to the point that it actually becomes a completely incorrect interpretation.
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.
> 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.”
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.
It's definitely a barrier to have to switch languages. You might be super familiar with Chrome's debugger UI (which is excellent, btw), and feel lost when suddenly getting dropped into IntelliJ's.
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.
I feel like switching languages adds extra friction too. Switching contexts is still a hurdle, but using the same language can make the hurdle shorter.
Having to write the same logic twice in two languages, and then making sure both implementations behave the same way. I don’t know if I’d use the word “barrier”, it’s certainly a significant pain in the ass.
The classic example is of course validation, but plenty of other places it can come up.
Perhaps I'm overthinking things and HTML does this naturally, but is there something for rendering that is what Swagger/OpenAPI is to APIs? Some way of specifying HTML that can be both rendered (and read back for inputs) by multiple implementations.
In theory, that's what template languages like jinja, liquid and twig are for.
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.
Learning is great. It expands horizons, potential, and current capabilities. Learning is not producing though. Learning is a cost center. If you want to increase productivity start by minimizing required learning. That exchange is called usability.
> Learning is not producing though. Learning is a cost center.
Spoken like a true MBA.
> If you want to increase productivity start by minimizing required learning.
Deciding your tech stack solely on avoiding having to train people for a few days sounds like a terrible way to organise projects. Is your employee churn so bad that you can't afford even this little familiarisation?
There are two fundamental practical problems with your thinking.
1. Employers don’t train on languages/frameworks. In most circumstances employees are expected to learn on their own or from a prior employer before applying for a job. Worse, the last place I interviewed only asked about learning from the current employer while never asking about self learning outside the office.
2. Employees, in many cases, believe they can cheat learning by using a tool or framework. That is largely due to a lack of boundaries and experience in a given environment or platform resulting in low trust of peers and the technology.
If you want to require learning then provide sufficient learning material expecting a predefined structured outcome.
We are training our employees. Learning the ropes of a new language/framework enough to make easy changes is trivial, so why wouldn't we? Much better than crippling our choices in software stacks we can use.
Deciding your tech stack solely on avoiding having to train people for a few days sounds like a terrible way to organise projects.
How often is it really only a few days, though? If you're talking about learning a different programming language, that's no small thing for a junior developer. For a senior who knows multiple languages already and has a few years of experience, learning the new language itself might only take a matter of days to be productive, as long as it's still a similar style of programming to something they've done before. But then you need to find your way around the ecosystem so you can make informed decisions, and that ecosystem might be huge and mostly low-quality, even if the good parts that you eventually want to use are not.
For similar reasons, in the case of web development specifically, I think people often have unreasonably high expectations from using JS/TS both front and back. Yes, it's the same language, more or less. Yes, sharing code can sometimes be useful. But the JS standard library is limited, and the ecosystem beyond that has almost nothing in common on the front and back ends. In practice, assuming you have some decent senior devs on your team, that ecosystem jump is still likely to be the biggest time sink even if you're running something in Node on the server.
So I kind of agree with both the parent and GP comments. It is beneficial to use familiar tools and reduce the need to learn new things before you can be productive, but you are going to have to learn new things sometimes anyway and that might require significant time no matter what you decide to do. When it comes to making fundamental architectural decisions for a new project, it's wise to keep the potential costs of using new things in mind, but it's foolish to disqualify choices that might be better in the long term because of small differences in up-front costs.
Depends entirely on what you expect the devs to do, naturally. Junior devs are IMO not supposed to make informed decisions of significance in any language, that's what you have senior devs for.
GP's use case of having frontend devs do small changes to backends and vice versa to avoid having to wait for The Other Team to have time, is very easily covered with really minimal training.
GP's use case of having frontend devs do small changes to backends and vice versa to avoid having to wait for The Other Team to have time, is very easily covered with really minimal training.
Sorry, but I can't really agree with that, certainly not for anyone below senior.
Asking juniors, who don't have much breadth of experience yet, to jump from front end to back end is a good way to end up with subtle SQL injection vulnerabilities, or passwords being hashed with non-cryptographic hashing algorithms, or secrets that should be handled at the environment level being hard-coded and committed.
Asking juniors to jump from back end to front end is a good way to end up with code that runs fine in Chrome but breaks in iOS Safari, or a subtle interaction between promises or awaits that deadlocks the whole UI if the server is unreachable, or styles that break when someone updates the theme six months later because two elements were the same blue at the time but the stand-in dev looked it up from the wrong place.
Either way, there's significantly more for them to learn if they need to know a whole new programming language as well as the specific libraries and the general principles about security and so on. And either way, The Other Team are probably going to be involved and therefore a potential bottleneck anyway, as surely at the very least someone senior from that team will be required to review code changes being requested by someone from outside the team who doesn't normally work in their part of the code.
It's never just adding a field to a structure. That data is going to be there for a reason, and someone is going to write the code to do whatever that is.
And to parse the data arriving in a request from the front end.
And to validate the parsed value.
And to perform the necessary security checks. Wait, shouldn't they have been done already?
Where do we keep the validation logic in this design, anyway?
Hang on, what type is this field? Is there a native way to represent that in this back-end language, or some convention we've adopted? Did the parser already handle that?
The scenario was a front end developer making a small back end change or vice versa. In such cases the rest of the code to be written will be in the part they're familiar with.
Sometimes the field isn't part of the request. Or maybe part of the minimal training was wrapping ValueError in BadRequest. Or maybe part of the minimal training was we have an exception handler do it automatically.
Often there aren't any new security checks.
Sometimes field types are documented. Sometimes you have an integer in the database and need the same value as an integer in the front end.
Most of the issues you brought up don't go away if you use JavaScript everywhere. Learning a little of another language is comparatively simple.
> Is there any Typescript backend framework as mature as Django?
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.
> 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...
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.
Regarding ORM, it's typically paired with Sequelize or Prisma. (I'm personally using the latter.) I've built Django apps in the past (it's actually how I learned Python in the 2.5 days), but what's nice about Node/TS is that the frameworks are more loosely coupled so you can pick/choose your best components. For example, while I mentioned the ORMs above, you can even go one step further and use a backend headless CMS like Strapi, which will get you the ORM + admin interface that you'd get from Django models.
This isn't really true though. There are plenty of open-source modules in Node which were released more than 5 years ago and are still in use today. People only move to new ones, when they are clearly better. What exactly is wrong with that?
> There are plenty of open-source modules in Node which were released more than 5 years ago and are still in use today.
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.)
On the backend, Express has had a very stable API for 5+ years. On the frontend, React has. However, stable or not there's nothing that competes with Django/Rails/Laravel in the Node ecosystem.
I'm not sure React is the best example. Although the library is backward compatible in theory, it doesn't much matter in practice because almost the entire ecosystem switched to a radically different core abstraction a couple of years ago.
There's nothing stopping you from using class component as opposed to the new functional component though. It works completely fine, as it ever was, and in fact, I know a lot of teams are still using it. The API on that front is indeed surprisingly stable. Furthermore, there haven't been any shiny new thing since hooks, and it starting to feel like boring old tech. It's not the cool kid on the block anymore.
There's nothing stopping you from doing it, but part of the reason a library like React achieves such widespread use is the ecosystem that builds up around it, and if everyone else is using hooks to expose whatever functionality they're building, you are now excluded from the benefits of all of that work.
Well sure, if you don't adopt the new technology then you don't get the benefits of the new technology. But that's true it literally every ecosystem. If you don't upgrade to a C11 compiler, then you can't use libraries using C11 features either.
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!
But that's true it literally every ecosystem. If you don't upgrade to a C11 compiler, then you can't use libraries using C11 features either.
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.
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.
The fact that you can have different coding styles and APIs in your project and it will work is proof that it is backward compatible.
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 behin...
> 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'`...
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 proje...
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 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 ...
I'm trying to respond in good faith, even though I feel you unnecessarily resorted to trying to condescend me.
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.)
I'm sorry if anything I wrote came across as condescending; that was not the intent. You seem reasonable enough, and objectively I agree with much of what you've said. However, I think we've been talking slightly at cross-purposes.
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 t...
Come on, as someone that has worked professionally with Django and Next.js, the only similarity they have is that they're both web frameworks. Django is light years ahead than Next.js is it's not even funny.
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.
The similarly named (but completely different) Nest.js is much closer to Django than Next. Still a ways behind in terms of maturity, but it seems to be more or less on the right path.
> 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, et
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.
> This is like saying a screwdriver is incredibly inferior to a impact hammer.
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?"
> code that mysteriously works only when server-side rendered or viceversa, etc.
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.
I think we are into semantics here, but I would posit if your web server is talking directly to a db other than a key-value store for tokens or what have you, your system is architected poorly. Your web server should be talking to a service written in Java or C# or something that handles the db stuff.
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.
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.
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.
Not the parent commenter, but maybe my experience saves you some time.
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.
Thanks for the information. Would you mind elaborating on what made things "really, really, really messy"?
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?
Ok, so here are a few examples of the things we didn't like:
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 + Tail...
It's a general purpose web framework, that happens to have a tight frontend integration thanks to JS and React. It's still JS + Node, and everything that enables.
There are frameworks like blitz.js(https://blitzjs.com/) coming up which build on top of next.js and provide you a full-stack development environment with react in the frontend. Far superior than what django/rails/laravel can offer.
And yet – Apollo advertises its easy Python interoperatibility right on the front page, as one of the features that makes scaling easier.¹
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.
> 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.
On the other hand I've seen JavaScript everywhere slow down back end development and increase costs with not much increase in contributions across teams.
I've seen the same. It starts off faster and then as the business grows and features are added the problems scale up. Some symptoms I've seen on projects I've been asked to look over include but aren't limited to throwing Redis around when an in-memory structure would normally suffice because Node is too slow, scaling to 200 CPU's and using up at least 200GB gigs of RAM for a single servioce, when a 25 instances with 8 CPU's, 25GB of RAM could do the same job and cost a lot less, scared to write their own data structures/algo's that may be required as their business scales, etc.
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.
idk why people mentioned Next.js which is more Front End framework than Back End, but no one mentioned Nest.js. It is not old as Django but I think Nest is nearest framework to RoR/Django in Node.js
Definitely. NextJS isn't a "backend framework", it's a server-side rendering framework that has some backend abilities to handle simple use-cases.
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.
I agree with all of what you said. Note in terms of "architecture your way out of that problem", that's exactly what we did. We have an eventing architecture that uses PubSub to publish to serverless functions that can then do heavier processing asynchronously. And for us, this wasn't a compromise, this architecture has a number of other benefits.
But again, I definitely agree with what you've written, right tool for the job.
Not op but I assume they mean: a main web server is scheduling large jobs in the background by publishing an event to whatever pub/sub system you want to use (there are many!), lambdas can be subscribed to this system so they trigger off these events and publish a corresponding event back when they're done that the web app is subscribed to etc.
For an example, you can look at how node interacts with OpenCV.
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
I would argue while it has other benefits it probably isn't as simple. Simplicity is usually the long term better choice. As the business scales since you've probably set a precedent this pattern will be copied all over the place. After enough times trying to understand who owns the data transformations, what lives where, how to support it when one part of the puzzle fails and trying to wire it all and how all these stacks couple together becomes a nightmare. Unfortunately I've experienced some of these issues coming into organizations after the original developers have left once it became too "big" of a place to work for - few people truly understand the architecture and even when they do its flaky and recovery is hard. YMMV depending on the complexity of your business and age. In the end IMO it just seems like a big workaround to keep using Node.
Typescript makes refactoring easier in what way? Can you do renames without error prone string search and replace? Can you get good autocompletions with ts? If so, that would be really nice
Yup! Especially using VsCode, which feels optimized for TS development. Click the var you want to rename, hit F2, rename it, and it renames all instances of the var. If you're renaming an import, it'll do it across all the files automagically. Moving a file? Imports get updated too!
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
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).
> 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.
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.).
The shock wave that TS sends through a JS stack is hard to ignore. It's really annoying. Every tool added TS support in a slightly different way and you always have to keep it in mind no matter what you're doing. Sadly it's just the reality we gotta face. I'm hoping Rome can live up to the hype and be helpful here.
Oh man, so true, between TS mangling and whatever framework you're using (Vue/React/etc.), the stack trace ends up being literally worthless. It's kind of funny to think about: when something goes wrong, I don't even look at the trace (which is 100% what you'd do in any sane language), but rather I just go back and look at the "last thing I changed."
You aren't using source maps to transform your stack traces then? I've had very little issue in understanding stack traces in any of the major JS frameworks.
> 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.
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.
> 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.
Note that the upgrade pain with Java was not due to typing; rather, it was due to using a library directly instead of creating a class to interface with it. In other words, inadequate abstraction.
> Note that the upgrade pain with Java was not due to typing; rather, it was due to using a library directly instead of creating a class to interface with it. In other words, inadequate abstraction.
I'd look into what Jersey actually is before you say something like this, because what you've said really doesn't make sense.
There is a reason for nominal typing though, because nominal types represent an interface contract that generally goes beyond just having the right type signature, but instead it is also about semantics. It's about the parts not covered by the type system, which the compiler therefore can't check. It depends on the kind of objects you are generally working with, but beyond pure data I find nominal typing preferable, because it makes it explicit that an implementation X conforming to interface contract Y is not just a matter of type signatures.
People are talking the other points to death but on the toolchain front, you might enjoy https://github.com/evanw/esbuild, which is rapidly gaining in popularity. Just 1 thing for bundling, transpilation etc. And its terrifically fast since its written in Go (ironic I know).
At my last company I created a few tools that became key to my org, which was front end/JS oriented. Being able to write them in JS meant anyone could contribute fixes and features trivially, with zero ramp up time. That is a really nice benefit of Node. Imagine if Rails developers couldn't use Ruby for their tooling. Node really filled a nice gap here.
It would be amazing if there were other languages available for front-end development in the browser, no? Even if you think that JS is so wonderful, then having competition would still be good, or no? Currently JavaScript has a monopoly in the browser and monopolies are always bad. Bad for innovation and everything else.
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?
> 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
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.
There’s a lot of compelling reasons to share code particularly at network boundaries. Using something like io-ts/zod/etc gives you simple, declarative, type safe validation. Being able to share that behavior is an enormous productivity boost in and of itself.
Sharing validation for forms is definitely really nice.
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.
The way it’s usually done is with a generalized language-agnostic spec like OpenAPI/JSON Schema. Because the definitions are standardized, you can effectively build tools in any language that should provide the same validation, to the extent they’re compliant and the spec is unambiguous.
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.
Mainly it has to do with teams. In most orgs there is something analogous to "a backend team" and "a frontend team", because the concerns and expertise are quite different.
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.
I've always had front-end and back-end owned by the same team, and in the same repo, despite being in separate languages. The repo has a single build script which builds all parts of the project, whatever language they are in. Implementing almost any feature involves touching both front-end and back-end code, so people stay fresh. All of this seems like table stakes to me.
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.
The first post also misses something fundamental about modern software: servers programming is becoming more browser-like.
> 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.
Your examples doesn’t really read as a prototypical server application.
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
A typical most basic website, awaiting requests and serving static/dynamic content is not a short-living process, I don’t see what is controversial about that.
So you think starting up a whole process, establishing connections to a db and serving the request would have any sort of acceptable latency and/or throughput? At that point, you could write your server in bash as well.. also, I think it would be ridiculously expensive.
Lambda is great for seldom run functions, like running some analysis/conversion on user uploaded profile pictures or the like.
Lambda containers serve multiple requests. You just write the code as if you were handling a single request. And on the contrary, Lambda latency is worst when you have spiky traffic patterns (such as for a seldom run function). Of course, if you can tolerate the cold start latency overhead, Lambda is also a cost effective solution for those seldom run functions.
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 :)
Thanks for the correction! My point was not at all to “bash” Lambdas, just to point out the (in my opinion) incorrectness of grand(grand?)parent’s comment.
Though I suppose Lambdas don’t use separate traditional OS processes to serve requests, do they?
There's many reasons why you would want the server, and reasons why you may not want it. Data structures and algorithms that as you scale give you an edge in the specialized problem domain you are in is usually one that I've seen. How many services have I've seen deployed that scale the DB to many cores and CPU's just to avoid some startup time? This is a problem I sadly see in a lot of Node stacks, and its easy to look good when you write a simple component to replace all that complexity and costs decrease as a result.
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.
Either way you try to argue this, it's hard to make the case that Java/Javascript is better at any of those things than another language. Productivity be damned, your dinky jar file will get smoked on almost every quantifiable level if you pit it against against a C++ or Rust rewrite. What GP is saying is that the only reason people praise Javascript is because it's a unique language, and I think it's a fair appraisal. Javascript is in a class of it's own, for better or worse, and since it has no real competitors, it's easy to dismiss detractors.
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.
> 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.
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.
If you’ve mainly worked in TS then it explains the blind spot, because JavaScript is chock full of awful missteps built up over the years. There’s a reason my copy of “JavaScript: The Good Parts” is extremely slim next to its sibling, “JavaScript: The Definitive Guide”.
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.
I have also stopped trying to discourage people from cargo culting facebook’s stack for their 3-person teams or even solo. If someone insists on 10x the complexity and 100x the work, let them.
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.
I find the Facebook stack to have a lot of boilerplate, but overall it's very simple rather than complex.
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 will pipe up for client-side TypeScript in conjunction with Ruby-based services. I’ve been contributing PRs for Hotwire and it is the first time in 25 years I didn’t actively resent working in JS of any dialect.
Haha ruby of all things. The language where they create aliases in standard library to make the code "read like natural language"... With a framework that promotes mixins as a service layer/code sharing abstraction and fat models/controllers.
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.
I've heard someone describe Ruby On Rails as: "lots of great magical wands that make great palaces appear out of thin air but always ends up spawning dragons you have to fight"
> There’s a reason my copy of “JavaScript: The Good Parts” is extremely slim next to its sibling, “JavaScript: The Definitive Guide”.
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).
Even as a style guide, it's unnecessarily terse in some cases. IIRC, there's a line that says (paraphrasing):
> 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.
I have a lot of experience in both python, typescript and react. I would still opt for python on the backend, simply because it's a nicer language to work with. Debugging is a joy, and it feels like the library ecosystem is more comprehensive and stable.
This is of course subjective, and maybe I'm biased due to having a lot more experience with python than JavaScript.
I didn't do much web dev but is having the same language for the front and back end a real time saver? For a skilled programmer, switching language is not a big deal. I'd say that for a front end developer to touch the back end, learning the required bits of Python or whatever is used is not the biggest problem.
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.
The piece that's really nice is being able to share your data model definitions. Not having to define your interface once in one language, the again in another language is very nice.
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
The real advantages in my opinion will be found in deno where instead of managing separate node and web implementation of everything, you can use one implementation for both b
> For a skilled programmer, switching language is not a big deal.
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.
Optimizing the common case is much more effective in my experience. Setting up an environment should be scripted anyway. And having to refresh your knowledge of Python implies a while since you needed it.
> For a skilled programmer, switching language is not a big deal.
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.
> everything is on the same tech stack ... has resulted in gargantuan productivity gains
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.
no - react is a library, and in fact people do use react on the backend (for server side rendering).
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).
If there are productivity gains to be had please share it with the hoards of nodeJS 'full stack' devs at my company who suck up all wages, dont produce anything, and make people hate digital
> switched to Node, and shortly thereafter to TypeScript
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.
> Node is not ECMAScript in a server-side ECMAScript engine, it's JavaScript in a browser JavaScript engine.
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.
My guess is the browser JS engines are optimized for quick compilation and execution. While a backend engine could optimize for longer, persist runtime.
TypeScript is a pretty good language for writing web servers, as long as you don’t need to do computationally heavy parallel computing. And you can still do that, but it’s very awkward.
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
Close, but I don't want to have to switch memory models, e.g. upload/download. What I want is the incredibly diverse numerical computing support and logical syntax of NumPY but in the same process & memory space. The W3C endeavor is something a little different. Thanks tho!!
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.
This article nails it. While Python is such an elegant language for scientific research, it falls on its face when it comes to packaged applications (and as stated in my other posts, it's awkward async support compared to Node). I realllly hope scientific computing moves into NodeJS, or, Python gets better at asyncio and cross-platform packaging.
Node does have worker threads. They’re awkward because no shared memory, lots of serialization overhead and boiler plate, but if you’ve got heavy data processing to do on say a 4-8 CPU machine, you can certainly split it up between 4-8 CPU threads.
True, but regardless, the kind of ergonomic, low overhead parallel computing available in Scala or Go just isn’t possible in Node. In Scala or Go, parallel computing is barely anymore difficult than synchronous computing, in Node it’s quite the pain in the ass once you want to start passing objects with methods and whatnot between threads.
That's process parallelism, not compute parallelism. To radically different things.
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.
ActionScript is also an ECMAScript language, and it's kinda ridiculous to see that JS still hasn't quite caught up. Out of things that modern JS lacks, AS had Java-like interfaces and you could specify types on variables.
As someone who first learned to code with AS2/3, I agree it was quite disorienting when I first tried to make a few games with HTML5/JS.
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.
NodeJS is important for more reasons than "it's just JavaScript". It is asynchronous from the bottom-up, and it is literally a challenge to force asynchronous patterns into a synchronous ones, which is almost always a hack because async requires a lot of thought. This is a boon to IIoT control, where the pejorative "web server" is literally the endpoint for 10's of thousands of IoT edge nodes. NodeJS fits in with this architecture perfectly compared to the shoehorning required to make it work with PHP, (C/C++), Python or Java. (N.B.: I am not a java programmer, but we did review using Java, too, but it was voted down for other reasons.)
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.
This. I grew up with Lisp and Smalltalk, yeah I am that old, but today I love Node to build web apps.
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.
IMHO, TypeScript is only useful if you are using a build tool because it requires so much configuration. I switched to WebPack for very large Electron projects and I'm hooked on it. The syntactic sugar protects me from myself, and the importing is cleaner. I also finally made the switch to VSCode, which while bloated and awkward to configure, is pretty dang amazing when working correctly w.r.t. linting and code inspection.
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:
[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.]
I am professional who used python, Java in my Career, and TypeScript is simply the best.
“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
> The problem started a decade or so ago with Node.
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?
Unbelievable that this is voted to the top on Hacker News. The comment literally gives not one concrete example or reason by JavaScript is "bad". I'd expect more from you all here.
This happens every time a Javascript topic comes up - hundreds of comments just regurgitating the same "Javascript is bad" memes. It's bad enough that's there's no real point in reading the comments on JS submissions since there's rarely discussion about the article.
Couldn't agree more. I started in this field as a javascript programmer. I've since expanded my toolkit to include typescript, elixir, plpgsql and now gaining proficiency in rust.
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!
The only reason I'm using node.js is because I can do this:
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 a language where it's as natural as my example above, and normally an object or array so the integer was just to simplify the example. Do you have any suggestions?
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.)
well without atomic access your state would be wrong. there are languages that allow stuff like that, but if you do it you can still have the wrong number. i.e. in c# something like you wrote is possible but when getting multiple requests, the number might be wrong at the end.
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.
I don't know what's wrong with me. I hate JavaScript. I tried learning react and redux and just gave up. All this to put a button and a field on a page. React was basically invented by John carmack to do doom 3 and copied to render web pages. Is this really required!? It's not a 3d games engine. I've worked on web apps that require a lot of page updates per minute and I still hate react. I stay the hell away from front end web Dev as it just feels like hell. Sorry drunken rant.
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.
Perhaps give it another try, but with TypeScript. Im a front end dev and yes, I feel the JS pain. I look back at how I used to do things and think "wtf". TS completely changed this and brought it back to sanity.
I’m pretty sure the real issue is backend vs UI rather than JS/HTML. If you’ve worked with a few alternatives, the web suddenly doesn’t look too bad. Sure, a couple solutions are probably nicer, but they are mostly platform locked and way slower to develop on.
UI programming is literally the fine art of handling what your most exasperating client is capable of inflicting on your UI.
at least part of the problem is that Javascript and webdev have really low barriers to entry, which is positive in the sense that anyone can do it, but the problem is that anyone can reach that unhappy valley of knowledgeable enough to do a lot of damage without realizing it.
If you put bad developers on other languages they usually end up running into some wall first but Javascript is pretty forgiving.
You should really try learning react first without redux. Redux is for managing global state. It's rarely needed but has become the defacto solution for react state for some reason.
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.
Yeah, unfortunately there's been lots of folks out there who have tried to insist that Redux should be used everywhere, all the time, and ignored the guidance we've offered over the years on when it _might_ make sense to use Redux.
"React was basically invented by John carmack to do doom 3 and copied to render web pages. "
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...?
What makes matters worse is that javascript is being pushed as the golden standard language and replacing pseudocode. In recent years I've stumbled across multiple articles on serious topics and concepts such as complex algorithms for compression or image processing and two scrolls down and I see an implementation in javascript.
The fact that you can put a 900 bhp engine in a 40 year old rusty Citroen, doesn't make it a good idea(JavaScript being the Citroen). There's a good reason why operating systems are written in low level languages and not toy languages that are meant to make sites jiggle. JavaScript is just a convenient excuse to write slow, horrible, unreadable and unmanageable code without having people pointing it out because no one expects JavaScript to be anything other than an endless mess of spaghetti. Even in the case of space x is just a tool for shiny buttons and that's it. That still doesn't make it a good idea. Some time ago I saw in a video that the Audi entertainment system is written in typescript and as much as Audis are great cars, the entertainment system feels painfully clunky compared to a cheap 120 euro Android phone. JavaScript and node are horrible technologies that should be abolished and replaced by something that doesn't require a 14-core Xeon and 32gb of RAM to run semi-decently.
So what, is that not everyone loves it. Devs shouldn’t be forced to use a language that they hate using.
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.
Don't do much JS, but this is actually what makes me the most sad. My formative programming years were during an era where there were many competing technologies on most given platforms.
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.
JavaScript does not have a monopoly in web browsers. Microsoft supported vbScript and Google made a better and faster JavaScript (Dart) which also ran natively in the browser. But neither didn't take off. You can still "compile" for the browser though, the funny thing is that a lot if not most of the code running on the most popular web sites has gone through at least one compile step. So people don't actually program in JavaScript, it has become more of a compilation target.
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.
I didn't know JS had `??` for a nil coalescing operator, or, more specifically, I thought it already had `||` for that purpose, since I've been using it for that for a decade or so without any problems. How do the two differ?
?? only coalesces nullish values (hence the name), which only includes null and undefined. || coalesces falsey values, which include false, 0, and empty strings. || might work most of the time, but it requires extra checks when falsey values are valid.
Seeing a lot of distain for JavaScript in here, but not enough examples of what's actually wrong with it. It's fine to criticize the language, there certainly are issues with it, but I'd like to see some actual constructive comments and examples from other languages where it's done better.
Most of the complaints aren't really about the language syntax or capabilities. Aside missing proper support for integers, modern Javascript is pretty nice. The complaints mostly come from developers being forced to use either Javascript (only way in the browser), or being forced to change code because of breaking changes in libraries.
Library changes aren’t what they used to be. It was once frameworks of the month. At this point, React has been undisputed king for over half a decade. Major libraries like react, moment, lodash, express, etc all have had stable APIs for years now and aren’t any worse that any other language I’ve used.
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.
> Complaints like integers come from not studying the language and not keeping up to date.
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.
besides being really insane typing wise, javascript also both really lenient and unpredictable in what it accepts as expressions. Try to guess the result of the following expressions:
> [] + []
>
> {} + []
>
> [] + {}
>
> {} + {}
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.
If your statement begins with a curly brace, that brace is a code block, NOT an object literal.
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.
The tooling and ecosystem are the main problems from my perspective. If you set yourself up with Kotlin + Gradle + IntelliJ you now already have all the tools you need.
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.
Deno is definitely trying to fix that. Single executable, no node_modules, no package.json no Webpack no Babel, built in linter, formatter, bundler, Typescript compiler...
It's definitely not there yet but they have the right idea.
Yeah but I still don't see what I get from it for server side development that isn't better on the JVM...
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.
Comparing Javascript to other dynamic languages its comparable and indeed has some nice features - e.g. self style prototypes. If you compare it to more type safe languages like Java, C, Swift, Kotlin etc then it has major flaws. The dynamic languages are great for making little scripts or small-medium size one man projects, they fall down when you need to build something larger with lots of people and lots of code. If you include the problems of javascript with running it into the limited environment of the browser then there is much room for complaint.
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.
I'm years behind on Javascript (I'm circa 'AJAX is new' in my knowledge) but I've been having good luck catching up using the Babel REPL with small snippets to just see how the new features get translated into the Javascript I know. Seeing what the compiler renames is a good way to understand the new scoping rules, etc.
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?
I don't know what the REPL you're running does with top level functions, but my guess is that an `await` needs to run within a function that is declared `async`. The reason (if so) would be that then babel could then transpile the function appropriately into a Promisory function. At the top level, what function would be translated?
Top-level await is very, very new and requires ES modules -- you can only use this feature without warnings recently in Node 15. For the foreseeable future, the final line should be replaced with:
You're right, thank you for the explanation.
My REPL runs the code in the textarea in an anonymous Async function, which is why top level async works in my examples.
Try using Array.from(arrayish).forEach() to convert the thing that looks like an array to an actual array. For instance, you can't use map() on a NodeList (document.querySelectorAll returns a NodeList), so you have to use Array.from(NodeList) to first convert it to an array.
Good point. I don't think I've run into many non-iterable arraylikes, but I understand they used to be more common (e.g., a number of standard things that are now specced as iterable arraylikes used to be just the latter) and there’s probably a lot lurking in library/legacy code.
Someone already commented that you can use `[...iterable]` to convert any iterable into an array, but if you're doing this just to call forEach on it then it's probably better to use for-of in order to avoid allocating an additional array:
for (const item of iterable) {
// do forEach stuff here
}
They are not needed for proper HTML. <html>, <head> and <body> are all defined as having optional start tags and end tags. It’s perfectly valid and reasonable to skip their start tags if you’re not putting any attributes on them. (I always skip <head> and <body>, but never skip <html> because I always have a lang attribute on it, and sometimes more, such as a class attribute. But I definitely still skip its end tag.)
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.)
That whole Node thing was a huge mistake and people are starting realize it.
Using JavaScript on the server is bad for so many reasons and the complexity Node introduces for doing the simplest of things, is just just mind-boggling.
For the future, I'm betting om Elixir with Phoenix LiveView, pushing server-side rendered HTML through WebSockets.
754 comments
[ 2.5 ms ] story [ 336 ms ] threadIt'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.
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.
[1] https://github.com/yewstack/yew
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/
[1] https://idom-docs.herokuapp.com/docs/index.html
[2] https://dash.plotly.com/
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.
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.
https://github.com/getify/You-Dont-Know-JS
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.
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()
[0] https://stackoverflow.com/q/21037888/1470607
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
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 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.
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.
As it stands it's layers of caching, state machines and complexity.
https://eligrey.com/blog/pausing-javascript-with-async-js/
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.
[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:
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.
[1] https://pypi.org/project/boto3-type-annotations/
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.
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.
It's no wonder Javascript is the only thing used. I actually love React and ES because it's the first time I feel like a real programmer and not someone just writing Javascript. I don't really care about people's opinions about JS, I simply use what works.
If you hated Javascript, maybe the anit-javascript community should have wrote blogs, made videos, and created content in the same way that the Javascript community did.
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:
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.
Spoken like a true MBA.
> If you want to increase productivity start by minimizing required learning.
Deciding your tech stack solely on avoiding having to train people for a few days sounds like a terrible way to organise projects. Is your employee churn so bad that you can't afford even this little familiarisation?
1. Employers don’t train on languages/frameworks. In most circumstances employees are expected to learn on their own or from a prior employer before applying for a job. Worse, the last place I interviewed only asked about learning from the current employer while never asking about self learning outside the office.
2. Employees, in many cases, believe they can cheat learning by using a tool or framework. That is largely due to a lack of boundaries and experience in a given environment or platform resulting in low trust of peers and the technology.
If you want to require learning then provide sufficient learning material expecting a predefined structured outcome.
How often is it really only a few days, though? If you're talking about learning a different programming language, that's no small thing for a junior developer. For a senior who knows multiple languages already and has a few years of experience, learning the new language itself might only take a matter of days to be productive, as long as it's still a similar style of programming to something they've done before. But then you need to find your way around the ecosystem so you can make informed decisions, and that ecosystem might be huge and mostly low-quality, even if the good parts that you eventually want to use are not.
For similar reasons, in the case of web development specifically, I think people often have unreasonably high expectations from using JS/TS both front and back. Yes, it's the same language, more or less. Yes, sharing code can sometimes be useful. But the JS standard library is limited, and the ecosystem beyond that has almost nothing in common on the front and back ends. In practice, assuming you have some decent senior devs on your team, that ecosystem jump is still likely to be the biggest time sink even if you're running something in Node on the server.
So I kind of agree with both the parent and GP comments. It is beneficial to use familiar tools and reduce the need to learn new things before you can be productive, but you are going to have to learn new things sometimes anyway and that might require significant time no matter what you decide to do. When it comes to making fundamental architectural decisions for a new project, it's wise to keep the potential costs of using new things in mind, but it's foolish to disqualify choices that might be better in the long term because of small differences in up-front costs.
Depends entirely on what you expect the devs to do, naturally. Junior devs are IMO not supposed to make informed decisions of significance in any language, that's what you have senior devs for.
GP's use case of having frontend devs do small changes to backends and vice versa to avoid having to wait for The Other Team to have time, is very easily covered with really minimal training.
Sorry, but I can't really agree with that, certainly not for anyone below senior.
Asking juniors, who don't have much breadth of experience yet, to jump from front end to back end is a good way to end up with subtle SQL injection vulnerabilities, or passwords being hashed with non-cryptographic hashing algorithms, or secrets that should be handled at the environment level being hard-coded and committed.
Asking juniors to jump from back end to front end is a good way to end up with code that runs fine in Chrome but breaks in iOS Safari, or a subtle interaction between promises or awaits that deadlocks the whole UI if the server is unreachable, or styles that break when someone updates the theme six months later because two elements were the same blue at the time but the stand-in dev looked it up from the wrong place.
Either way, there's significantly more for them to learn if they need to know a whole new programming language as well as the specific libraries and the general principles about security and so on. And either way, The Other Team are probably going to be involved and therefore a potential bottleneck anyway, as surely at the very least someone senior from that team will be required to review code changes being requested by someone from outside the team who doesn't normally work in their part of the code.
And to parse the data arriving in a request from the front end.
And to validate the parsed value.
And to perform the necessary security checks. Wait, shouldn't they have been done already?
Where do we keep the validation logic in this design, anyway?
Hang on, what type is this field? Is there a native way to represent that in this back-end language, or some convention we've adopted? Did the parser already handle that?
It's never just adding a field to a structure.
Sometimes the field isn't part of the request. Or maybe part of the minimal training was wrapping ValueError in BadRequest. Or maybe part of the minimal training was we have an exception handler do it automatically.
Often there aren't any new security checks.
Sometimes field types are documented. Sometimes you have an integer in the database and need the same value as an integer in the front end.
Most of the issues you brought up don't go away if you use JavaScript everywhere. Learning a little of another language is comparatively simple.
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 behin...
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.
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 proje...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 ...
You wrote:
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.
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.
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... 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 ...
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 t...
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 + Tail...
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!
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.
|| - returns right side operand if left side operand is any falsy value
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.
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.
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.
- Modules
- Set and Map, WeakSet and WeakMap
- String interpolation
- Private methods (# prefix)
- Template literals
- Typed arrays
- Symbol type
- Generators
- Proxy / Reflect
- Internationalization
And more...
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:
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?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:
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.
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.)
Using JavaScript on the server is bad for so many reasons and the complexity Node introduces for doing the simplest of things, is just just mind-boggling.
For the future, I'm betting om Elixir with Phoenix LiveView, pushing server-side rendered HTML through WebSockets.