It sounds like to me that you've taken your knowledge of your commonly used languages for granted, and assumed a new language would be just as easy. But if you watch a developer who is dipping their toe into that ecosystem for the first time you'll find them making mistakes and running into footguns you didn't know were possible.
Regardless of the language, not having a proper guide leaves devs susceptible to the incorrect blogospam that's out there, where engagement is rewarded over correctness.
Ignore all of the blogospam.
The two things you need to know:
C/C++/Java/Go/Python have all gone through changes, growth and churn just like JS.
Knowing the history of the ecosystem will go a long way towards helping you. If you understand why things have changed, then you'll know how to ignore the bad advice out there.
Here's my shortened version of number 2.
The beginning:
JS starts as a scripting language embedded into a browser
Different browsers try to copy each other but put in their own "features" pulling the language in different directions.
The amorphous blob that is JS starts to congeal and language standards are solidified. This standard is known as ECMAScript (named for legal reasons). ES1 is the first version, followed by ES2 and ES3, each adding useful features.
ES3 (released in 1999):
This is what you could consider the first long term stable baseline widely supported version of the language, where you can make anything you want.
Almost everything you can make in future versions of the language can be backported to ES3.
If you want to go by analogy, you can think of ES3 as javascript's C99.
The false start:
Work starts on ES4 with a massive feature list (including static typing, classes, modules, algebraic data types, generators, embedded xml/xhtml known as JSX/TSX today, etc...). It fails due to political infighting, and for basically being too ambitious in a single version.
This sucks up years of progress between released versions.
This version is commonly seen as being poisoned by 90's/00's Micro$oft and the dark ages of Internet Explorer
But the spirit of ES4 was released spread out over future versions anyway.
The resumption:
The v8 JS engine is released, making JS really fast and worth programming in. This is used in Chrome and Node.
ES5 (released in 2009):
Adds native json support, reflection, and a strict mode to avoid some footguns with ES3
Think of this as C11
Some developers being experimenting with a more consise syntax in CoffeeScript that compiles down to ES5.
2012: Typescript is released adding an optional and gradual typing system to JS (inspired by C# and ES4) designed for both Humans and Computers.
In effect, this brings IDE-style support for JS
ES6 (released in 2015):
With the lessons learned from CoffeeScript, a whole bunch of syntactical sugar is added to make the language more pleasant to write in.
With the lessons learned from community made modules, an official module spec is released and added to the language.
Known as ESM (EcmaScript Modules)
The community starts moving away from unofficial modules (CJS, AMD, UMD)
Babel is created to allow any developer to create and share their their own language extensions.
The faster feedback cycle from Babel allows for smaller and more frequent language updates.
Javascript moves to a yearly release cycle and ES6 is renamed ES2015
ES2016
Adds block scoping as an alternative to hoisting
ES2017
Adds async/await/Promise() syntax sugaring, to make asynchronous programming easier
ES2018
Adds ... (rest/spread operator) syntax sugaring, to make destructuring and variadic functions easier
Ryan Dhal (creator of Node) releases his famous 10 Things I Regret About Node.js talk. Announces his intention to create a "modern reset" of Node known as Deno.
Adds top level await, making asynchronous programming easier
Adds private field syntax sugaring
ES2023
Minor changes
The current state of things
Language-wise
Javascript has added a whole bunch of syntactical sugar since 2009 making it really pleasant to code in.
Typescript adds some really nice IDE support to Javascript and the vast majority of all libraries and frameworks are written in it giving that IDE support to Javascript developers.
Babel allows developers to create their own language extensions, which are frequently put forwards at for other developers to give feedback on. Useful proposals are added to the language on a yearly basis.
Runtime-wise
Node is considered the older slow-moving most-stable release of running JS outside of the browser
Think Debian
Deno is considered the friendly Node, coming with all the tools a developer needs (linter, bundler, tester, ts support, etc...). In the last 5 years it has reached almost complete feature parity and compatibility with Node.
Think Ubuntu
Bun is a brand new kid on the block prioritising speed over compatibility.
Think nightly linux
Standard workflow
Write in typescript
Let your editor check your typescript while you're typing live so you don't need to go through a compile cycle
Let your project's stack compile your typescript for you.
If you're writing a new project from scratch, Deno will run typescript for you.
If you want to build a new stack from scratch with no assistance, use the typescript project itself to check and compile your code into js, or use esbuild to strip out the typescript types to turn your typescript into js. (most developers elect to strip types since your editor/ide should be live checking your typescript anyway allowing you to skip a redundant compile check cycle)
If you're using an existing stack, your build tools will compile/strip-out typescript for you.
Tooling wise
Most projects use Vite / rollup / and other "zero-config" tools to build and bundle their applications. Some older projects still use Webpack (which does the same thing, but with a more complicated config file).
Everyone uses ESM modules now, almost no one uses the older modules.
For your simple fibonacci example:
Create your fibonacci module that exports your fibonacci function
Import module
Call function in module
Pick your endpoint:
Browser endpoint: Output result in console.log() and see result in browser's console.
Server-side endpoint: Output result in Deno.serve() and see result in network requests/responses
CLI endpoint: Output result in console.log() and see result in terminal
deno run hello.ts (time taken to run command: 0.037s)
[...] 3 different ways of specifying the files and settings you want to use [...]
3 incompatible ways to define and use a “module”
Yes, that tends to happen as ecosystems evolve over time. Typescript allows developers to use modern standards-compliant modules, while maintaining backwards compatibility for older code.
embracing duck typing means [...]
One of typescript's strengths is that its type system isn't all or nothing. Typescript will support duck typers, but it isn't forced or limited to that. You can add as much or as little typing as you want. In theory, this means that the language supports simple beginners up to experts creating turing-complete theorem solvers at compile time. In practice, this means a much smoother onboarding and porting experience.
Have a “generalized fibonacci” module taking 3 inputs [...]
I'm not sure if this is the basic problem challenge or the hello world example was. It seems a bit ambiguous as to what you really want, but it's easy to create a module that takes inputs and produces outputs while running on backend servers, in browsers, and in CLIs.
I thought I loved ts-node, since it's a good patch over some annoying issues in node.
But I retried deno a few months ago (after having first tried it when it first came out) and I realised that I only ever liked ts-node, and that I actually loved deno.
Deno just ran ts as if it was ts-node without needing a dependency, or startup time, or any prior setup, and it did it so fast I thought something was wrong. It was great.
I absolutely understand OOP, its explosion took over everything that took a long time to recover from.
The problem with OOP is that it's pushed as a cure-all both by teachers who do not the problems it solves and also do not understand its own limitations.
In almost every situation where OOP makes sense, something else makes more sense to use.
Every IDE and editor (gui and tui) I've used has always come preconfigured with a tab-size of 4.
The only thing I've ever experienced having a tab-size of 8 was github, and I thought that was just a problem with a setting from github's size that I quickly set back to 4.
It seems that tui editors come with tab-sizes of 8 only when a config isn't provided, and every environment I've used where I've used a tui editor has always come with sensible configs (for things like config location, language recognition for syntax highlighting, etc...) including a tab-size of 4.
The horizontal tabulation character moves the cursor to the next column which is a multiple of the tabulation length. See the examples here: https://en.m.wikipedia.org/wiki/Tab_key
Yes
Clearly the whitespace produced by each tab character has a different length.
No, each tab has the same size, the text rendered over the top of the tabs are not the same size.
Always remember the golden rule: Tabs for indentation, spaces for alignment.
first major release under daddy Microsoft, so things may be different
I wouldn't hold my breath:
Bethesda's management have always unvalued spending effort on engine development
Microsoft's awful mandated top-down rules are what seriously messed up Halo Infinite:
To go into this point in more detail:
343 industries hired a large amount of "temporary" contractors to work on Halo Infinite (this is standard in AAA games)
For legal reasons, any contractor who had worked on a project for 18 months is given workers protections
Microsoft mandated that each contractor be "let go" right before reaching this 18 month time-frame.
During the regular process of development, different developers would build different things, then over time either help out with any questions on how to use it, or tweak it to support a new use case.
During Microsoft's mandated development, the developer who built a tool or best knew how it worked was let go. Since it's easier to write new code rather than read existing code unassisted the developer who needs something done before a deadline has to build a new tool. After 5 years we now have 40 something tools that are all built based on different assumptions that keep overwriting each other's results in wildly expected way. No one knows how anything works anymore.
I was in it for the parkour; I didn’t really like the combat and kept being forced to fight people.
Part of the charm of the game was to make its combat unwieldy to push people into parkour-ing past/out of each encounter. The whole game was made so that you could finish it without ever picking up a gun.
It sounds like you didn't get far enough to learn this.
Mixed zoning with each new development voted on by the people who live in the area. The company that puts forward the best proposal for residents gets the contract. (e.g. Luxury high rise = no, High rise with bakery, cafe, fruit & veg, grocers on bottom floor, and rentable office space on second floor = yes)
It sounds like to me that you've taken your knowledge of your commonly used languages for granted, and assumed a new language would be just as easy. But if you watch a developer who is dipping their toe into that ecosystem for the first time you'll find them making mistakes and running into footguns you didn't know were possible.
Regardless of the language, not having a proper guide leaves devs susceptible to the incorrect blogospam that's out there, where engagement is rewarded over correctness.
Ignore all of the blogospam.
The two things you need to know:
Here's my shortened version of number 2.
The beginning:
The false start:
The resumption:
async
/await
/Promise()
syntax sugaring, to make asynchronous programming easier...
(rest/spread operator) syntax sugaring, to make destructuring and variadic functions easier??
Nullish coalescing operator syntax sugaring??=
/&&=
/||=
Logical assignment syntax sugaringThe current state of things
For your simple fibonacci example:
console.log()
and see result in browser's console.Deno.serve()
and see result in network requests/responsesconsole.log()
and see result in terminal