Why are we so afraid to call trash "trash"? It's not attacking the creator, but just how can we make progress if things are not perceived as they are?
Why are we so afraid to call trash "trash"? It's not attacking the creator, but just how can we make progress if things are not perceived as they are?
JavaScript has a bunch of quirks, but it's still great. In the StackOverflow survey, JS reliably ranks highly in the list of "most loved" languages. https://insights.stackoverflow.com/survey/2020#technology-mo...
Node.js is a thing because people liked JS so much that they wanted to use it on the server side. You may think they're all fools, but it's actually pretty nice. I like the latest version of Node better than working in Python (mostly because node_modules are better than virtualenvs, IMO.)
You can use TypeScript to address many of the quirks described in TFA, but you can also reliably avoid them just by never using == and always preferring ===, using String() before using + to concatenate, and using Number() before subtracting.
I basically never encounter situations like the ones depicted in TFA in real code, because I never try to add two arrays or subtract two strings or what have you.
“Admitting like this has a bunch of quirks, but it’s still great.” (not arguing for it though)
Criticism is a driving force behind change to the better. Calling something “great” without pointing out great sides I find… pointless and harmful.
To name a few great points, distinct from other languages:
JS has a pretty shameless object model, where you (usually) have ordered keys, and every key is a property with an {enumerable, writable, configurable, get, set} descriptor. It is much more usable and practical than in almost all other languages. (They do that for “efficiency”, but that’s non-sequitur)
JS has very useful destructuring syntax, which many languages lack of and that leads to assignment bloating and boredom. Also, jit optimizes out temporary objects, so foo({x, y}) / function foo({x, y}) works almost at the same speed as foo(x, y).
JS has a nice Function type, which allows easier metaprogramming and substitution of ‘this’ object. Functions are objects, so you can function foo() {}; foo.x = 1; console.log(foo.name, foo.x).
JS bare objects may have methods and properties: t={_x:1, get_x(){return this._x}, …}
JS doesn’t treat syntactic lists in a last-value-only way, so you can expect foo(…a, …b, c) to work, and to work as intended. E.g. Lua cannot do that, and python (afair) requires you to collect items into a single array (not sure, correct me if I’m wrong).
But what people usually mean by “great” is “it generally works”. I know it is an american thing, but some aspects of js, including those you meet everyday, are really just trashy. It would be nice to not have them at all.
I don't understand what this actually contributes to the discussion beyond it being a tired, beaten-down programming meme.
It's ES3 API is missing a few things, like Object.keys, etc. I still happily code for browsers in ES5 with a few polyfill functions.
JS works fine for it's core competency: manipulating DOM elements and local data representations.
It's not JS's fault that the browser is the way it is and that HTTP is the way it is and that using a remote directory "browsing" protocol via a specialized file browser that renders hypertext isn't a 2-way bound GUI framework...
Seems like you had a bad experience with espruino / jerryscript or something and are projecting based on that?
Dynamic languages are easier to program in. That’s a fact, and why they are so popular.
> Dynamic languages are easier to program in.
Only if you don't care about writing correct and maintainable programs. The only thing that dynamic languages make easier is writing code. Or, more specifically, the first couple of versions of it. That's not what typical programming as a process mostly consists of.
Your browser has an embedded scripting engine. Embedded, meaning, the source code for your browser includes the scripting language engine, and JS can run on that and script various permitted things via the browser API.
ES6 may have been ratified six years ago, but it's not the target code your front-end build chain spits out, is it... browsers don't uniformly support it yet. fun facts.
Look, I've been programming JS since it was invented. I'm not impressed by "classes" that don't exist, arrow functions, async/await, futures, promises, fibers, and assorted hacks that don't mirror the actual CODE (what computers execute) a JS engine actually is based upon. I don't need these tools, why should I use something that I need to transpile when I can code directly for browsers as they are in 2021, including legacy browsers? I don't find ES6 "easier" in any way..
Regarding dynamic languages on microcontrollers: Dynamic languages cannot directly control memory allocation and manipulation, typically are heap based and have no concept of a stack frame, and are basically just a computer program written whose corresponding code instructions (machine code) and execution path is scripted by your high-level language. Read a JS engines source code, study embedded C, and get back to me as to how suitable you find it for timing deterministic embedded programming. LOL
Types are directly related to memory size allocations.
Study the recent crop of LLVM languages, including some very interesting ones like LuaJIT, which should be right up your alley, and note the role Garbage Collection (check the Boehm implementation, for example) plays in many of the object-oriented languages, as well as Go.
Look at the actual assembler instructions you require a computer to perform as a result of your high level specification.
I am NOT speaking gibberish.
I agree that dynamic languages are considered easier to program in.
When speaking of programming languages, they are not all on the same level. One cannot say "oh assembler is fine and all but i prefer lua", as it's like comparing apples and atoms.
there's a reason that you can implement a lisp in c, but that the contrary is not viable nor makes any sense. (although metaprogramming c with lisp makes a lot of sense :D)
> JS = a single threaded event loop, ON PURPOSE. That directly affected Node.js as an implementation.
That's not a criticism. It's not different to desktop app dev where you try to keep your processing away from the main thread, only it provides an easier interface through async programming. Synchronous = main thread; async = other thread.
Amazingly intuitive model.
> ES6 may have been ratified six years ago, but it's not the target code your front-end build chain spits out
C++14 may have been ratified 7 years ago but it's not the target code your build chain spits out
> Look, I've been programming JS since it was invented...
You're free to write pure assembly, and you don't.
> Regarding dynamic languages on microcontrollers
Python in particular has made this kind of programming mainstream
> Read a JS engines source code, study embedded C, and get back to me as to how suitable you find it for timing deterministic embedded programming. LOL
You're gatekeeping, and that's also your ego. You need to work on that.
> there's a reason that you can implement a lisp in c, but that the contrary is not viable nor makes any sense.
What!? I can build C in Lisp as much as I can build any other language. I parse the syntax, create machine code, and output a binary. How the hell do you think languages are built? How do you think C was built?
Just stop, man. It's not gibberish but it's bullshit.
Do you think Arduino would have had any success at all if you had to write C or Assembly to use it?
> Not a comp sci major eh?
I guess you're a comp sci major.
Do you know what a Pointer is?
Do you know what passing by reference means?
Do you know what a heap allocation is vs pushing something into the stack?
Do you know what code and bss segments are and what they are for?
This is not about being right or wrong, I just can’t stand to watch total nonsense go unchallenged.
No, you cannot write a hardware device driver in a dynamic language, which is not to preclude code generation approaches, but to point out what low level hardware programming actually consists of: manipulating memory, registers included
2) I saw your comment below. You cannot write device drivers in the language of your choice on any of todays popular operating systems, nor on any embedded devices. Device drivers must have low level access to things like memory locations and cpu registers. Such things are not exposed to Javascript and not available. This is not even speaking about performance and garbage collection etc.
Look, Javascript is someones computer program. It can be implemented in very little code: here's an example: https://github.com/cesanta/v7
Languages are not all equal nor do they all function in the same way, and that's not my opinion.
Javascript syntax itself is one thing, and you can certainly feel free to Javascriptify some C++ libraries and make it all look a certain way for specific tasks, while managing things behind the scenes, up to a point... but there is no getting around the fact that SOMEONE and some languages are needed to implement low level systems functionality.
the power of Cython or the Python C FFI is that it allows you to script/glue modular native code.
You then state "C++14 may have been ratified 7 years ago but it's not the target code your build chain spits out"
no, a C++ COMPILER spits out assembler code that then gets assembled and linked into an executable.
The C++ or C code corresponds directly to a given set of assembler instructions which correspond directly to CPU instructions.
You claim that Python programming of microcontrollers is mainstream, but this is not true nor possible. Python SCRIPTING of code modules (that cannot be written in Python) is certainly one way to assemble a system from pre-built legos.
If you refer to knowing what I'm talking about as gatekeeping and egoism, might I suggest that you insist less forcefully in the correctness of incorrect things you state? we could be done with this spat in short order if YOU would refrain from speaking falsehoods. lies.untrue things.
I look forward to your lisp c compiler. make sure that it's 100% lisp from the bottom up, or I'll consider you're having ceded my point. Consider that the lisp you author in has a garbage collection system that lisp cannot have written originally, nor has any semantics for the underlying memory structures of, but hey, I guess if one is committed to pretending that all languages are equal for all tasks, who am I to question ones self-identification with a given language.
You couldn’t have picked a worse example - your CS major seems to be needing a refresh. NodeJS came to be precisely because V8, single threaded and using an event loop, was GREAT at a high volume web servers. It massively reduced the overhead vs multi-process or thread based web servers and absolutely dominated performance benchmarks and concurrency. We started playing with 1M concurrent connections while you might barely get 100 on Apache a few years earlier. There were other async servers at the time (Tornado, Puma, Netty..) but the async-by-default ecosystem in node was a unique advantage.
Fast forward to today, it’s not an accident that the majority of high-performance web servers now are asynchronous and/or using cooperative multitasking (or even libuv directly, a spin-off of nodejs development): VertX, Actix, h2o, Jetty, go with goroutines, etc. It’s a much more efficient model.
2) "you couldn't have picked a worse example" HAAAA! You are wrong. wrong wrong. A) Do you even know what a memory leak IS and why/how it occurs? B) Did you understand what I said regarding stack allocation and out-of-scope equals "memory gone" and how that fundamentally differs from heap-based allocation as ALL JS OBJECTS ARE!??? you are wasting my time, friend.
you are straight up copying marketing lines from node.js with no apparent understand of what a single threaded event loop even is! (it is a gui system. almost all windows-style apps since 199whatever have an event loops as ONE of it's threads. Open X-code or Visual Studio and make a generic desktop app, and add a button and make it's click handler call a method of something or other. Check a moderately complex audio visual production application for clues on just how many threads one uses and for what purposes are they separate threads, etc.)
You then mention VERTX AND GOROUTINES RIGHT AFTER EXTOLLING THE VIRTUES OF A SINGLE THREADED EVENT LOOP. GO LOOK UP WHAT THOSE 2 SPECIFIC TECHNOLOGIES USE AND DO, VERSUS A SINGLE THREADED EVENT LOOP.
Do note why single core limits exist for single hardware thread execution worlds and stop saying that interleaving tasks on a single execution core is superior to architecting synchronized activity across all cores, and do note that you are primarily referring to CRUD web-dev while positing very erm controversial positions on programming language use-cases.
Node JS is a terrible high-volume web server as all of the alleged virtues you extol are workarounds from the single threaded execution model of what was never designed to be a server language. I will say it again: HTTP is a stateless protocol involving a request (method call) and response (what it returns) it then goes out of scope and disappears. no memory leaks. no heap memory allocation. no malloc. no new, etc. it's just poof gone. got it? this was done on purpose by smart computer people. If you want to run each request as a separate OS process, don't blame HTTP, but the primitives were designed for efficiency.
please DO look up what heap vs stack allocation is. please DO look up what a register vm vs a stack vm is. please DO not confuse scripting or glue code with machine code, as the machine code of your javascript program is precisely the javascript runtime with it's execution paths being puppeted by your script language. you are literally pushing someone elses buttons and calling it computer programming. no offense, that's why it's a high level language not a low one.
when you resort to reductio ad absurdum suggesting assembler as the tool for all programming, you are not engaging with anything I have said or written here, as tools have purposes, not everything is a hammer/nail
in a way, you are not wrong, as a macro-assembler, or C or C++ or Rust or Zig or Nim etc (non garbage collected compiled language capable of outputting machine code as the final target) is the next level up from asm.
Why do you suppose that Chrome is not written in JS but rather largely in C++?
I don’t know what you’re excited about yelling in caps - VertX uses and event loop. Goroutines are cooperative scheduling. Yes, they can also coordinate over multiple threads (guess what, node can too) but the underlying architecture for processing requests is the same.
> Node JS is a terrible high-volume web server
Again, why would that be? Node was invented precisely to be a high performance server. It’s literally it’s purpose, and it delivers. Check out any benchmarks like TechEmpower and guess which platforms you’ll find near the top. I’m not saying it’s the best choice but just stating facts. Nothing else to say here - you obviously have strong opinions but zero hands-on knowledge on this area.
It didn’t “affect” node, it was the whole reason it came to exist: its cooperative multitasking was a good way to tackle concurrency (remember c10k), and V8 was available and easily embeddable. Without the event loop there would have been no reason to choose JS.
so that's what it's called.
There could definitely be improvements, but trash seems to be taking things too far.
As an experienced Python programmer learning JavaScript, this isn’t true for me yet but I hope it becomes true. I think JS will be much more useful to me than Python.
> Which is fairly easily banned with a linter.
Any particular recommendations?
https://github.com/standard/eslint-config-standard
I would start with that and tweak what you don't like
TypeScript.
It's odd, there are developers who make the language they work part of their identity and see attacks on that language as attacks on their identity.
I don't get it, but it is what it is. If you call javascript trash, you will offend people.
JS is a great programming language with a lot of quirks and footguns, most of them easily avoidable by enforcing good coding styles, using easily available and widespread tooling.
And most language have linters or compilers that issue coding-style related warnings, including C, so this is not specific to Javascript.
There are also great things about it: the ease at which one can write in a functional style code, anonymous functions (vs Python), closures (vs Java), immutable strings, the fact that there is not a shitload of classes to instantiate to achieve anything (vs Java), block-scoped variable definitions, sane default function parameter handling (vs Python).
Javascript engines are also very fast nowadays because of the ton of engineering going into them.
I'd say, above all arguments, you can rapidly build very fast, lightweight and program programs with it.
Sure, you can pull a shitload of pointless dependencies and write bloatware that re-render the world on each keypress, and that's what many people do. And to make things worse, they wrap their shit with an entire browser that uses a lot of ram and processing power. But you are not forced to do that. You can also write efficient server code that does not show up in top, has few dependencies if at all, consume a negligible amount of memory and run without failure for months. That's possible too. Frontend-wise, you have amazing frameworks like Svelte that do wonders and would allow you to build very lightweight apps rapidly.
That said I would often pick TypeScript so your program is statically type-checked and your code is documented through types, especially for more-than-one-person / non-trivial projects.
I also use and like other languages like Python and D (and a bit of Rust) that have good stuff which JS doesn't have (list comprehension, borrowing, traits, named parameter, sane coercion to False…), or bad stuff which JS has. Javascript is not always the best answer, or even a good answers, but it can be one.
Basically, it was meant to be a dialect of Scheme, but with map and array data structures at the bottom, as opposed to lists (hello, Clojure!). Suddenly, the last-minute decision was made to add Java-like syntax and OOP to this language and rebrand it as 'JavaScript'. Brendan Eich did the best he could in the limited timeframe to implement this. Then in 2015 'design-by-committee' approach was accepted and horrible feature creep started. We can then investigate every feature and how it pushed individual company's agendas while compromising the integrity and vision of the language, but that's a typical design-by-committee story.
> how can we make progress if things are not perceived as they are?
People aren't blind to JavaScript's failings. The evolution of JavaScript has been a mix of adding new features and fixing what they got wrong before, e.g. the way it has two different isNaN functions. [0]
[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Python has an interesting C FFI interface, among other approaches, that can at least allow CPU and memory-bound tasks to be accomplished inside of a native code module. You see a lot of domain specific work in Python due to these approaches, cython, etc..
Crystal lang is what I would urge all Ruby devs to look at. (an LLVM-based compiled language that has HTTP in it's standard library, for one thing...I'd pit it against Go, for example.)
As I see large front-end teams frequently pushing JS from a typescript base lately, I'm not sure that even the JS community supports "everything JS" anymore. At the point one does backend Node.js work with typescript or other more rigidly typed systems, I have to wonder if targeting V8 is really the desired option any more, and if the programmer would not be better off switching to a high-performance and feature-complete typed backend language system. (the single-threaded JS execution model being a needless constraint at this point, for example. It's great as an event loop)
Given how close typescript is to javascript, wouldn't it be more appropriate to treat it as just a dialect of javascript (like coffescript was) rather than a different language like python or go would be?
1) TS to WEBASM (once JS is out of the picture, might be awhile, lol...)
2) TS as an LLVM IR frontend (compiled TS on the server)
which is basically predicated upon industry familiarity as it's selling point, so yeah, I could see where it's also just a JS industry side-effect. A wart remover, lol
I've never used it but reading about it I kept going ohh, ahhh and wow! In stead of my standard: ** ** *k * ** *sh?!?
I've never used Elixir so can't say whether the criticisms are justified.