He goes over some rough edges and explains why they might be rough. He uses the word unfortunately here on purpose, to distinct it from bad, or weird or whatever.
Concluding he writes about how some of the unfortunate parts are needed to make typescript great.
That is confusing to me, he's talking about teaching, and using these examples for future teachers to think about in their field. Reading the comments here, they all seem to discuss the examples. I'm sitting here, thinking did I missing something, should I be discussing the examples? As someone that written many lines of code in different language. I can ignore the idiosyncrasies. But when you are new, it's really hard.
Similar that is why I'm always in awe of clojure/lisps. It's so minimal and predictable. you don't have to learn 100 million different syntaxes or exceptions. S-expressions, maps bools, data and go.
1. I can live with NaN. When the source of something becomes difficult to track, use a debugger.
2. Map vs map? Just another homograph, like there are hundreds in all spoken languages, yet most people manage to communicate.
3. The overhead of negative indices might be acceptable in JavaScript, but most languages probably don't benefit from having them. I think negative indices are actually hurtful, they tend to hide bugs which would otherwise be caught very early at runtime.
4. This is actually a serious issue. I don't get why so many people are in awe with TypeScript type system. Anything based on duck typing is a red flag to me. But still, better than no typing at all...
> {a: 1, b: 2}['c']
undefined
> {1: 1, 3: 2}[2]
undefined
If you're arguing that JS objects shouldn't be like that, you do have a point. But taking JS basic semantics as a given, I don't see what other behavior you would expect.BUT if you set/access arr[0] it's just like an array...
arr = []
arr[-1] = 'neg-one-pos'
arr[0] = 'zero-pos'
arr[1] = 'one-pos'
arr # => ["zero-pos", "one-pos", -1: "neg-one-pos"]
That was quite unexpected for me. arr = []
arr[-1] = 'neg-one-key'
arr[0] = 'zero-pos'
arr[1] = 'one-pos'
arr[2] = 'two-pos'
arr[-2] = 'neg-two-key'
arr[3] = 'three-pos'
arr // => ["zero-pos", "one-pos", "two-pos", "three-pos", -1: "neg-one-key", -2: "neg-two-key"]
arr.splice(2, 1)
arr // => ["zero-pos", "one-pos", "three-pos", -1: "neg-one-key", -2: "neg-two-key"]
arr[3] // => undefined
Incredibly weird for me.It's such a distracting downer to lead with the warts and edge cases, but it also sucks to leave them off, and I end up feeling like I'm on the defensive and apologizing for whatever I'm explaining when they run into each issue themselves.
You do NOT want to START a course/topic by predisposing students negatively. Whether that is in relation to a topic, or inadvertently in terms of your perceived ability to teach it.
You may think that "apologising" on behalf of a technology (or yourself) might attract sympathy and establish rapport, but typically it backfires and achieves the opposite.
To make the example concrete, if you start the lecture with "why NaN sucks" in order to get students to sympathise and appreciate that you're showing them the pitfalls, is more than likely going to backfire and create a general feeling of resentment along the lines of "why are we even using it, why am I wasting my time here". Not to mention the risk of "great, I'm paying $Xk/y so that some random disgruntled guy can teach me hacks to circumvent shitty technology".
There are much better ways to approach this subject (linguistically), which would make it far more interesting and scientifically engaging.
Note, I'm not saying this person is "teaching it wrong" - it sounds like they've put a lot of thought in their work. But generally one should aim to refrain from 'negative' language. You could do exactly the same syllabus with positive, non-apologetic language.
How is this going against what the post claims? It sounds like you are in violent agreement.
> As authors, we could try to head this off with "OK, this technology has a ton of problems... in fact, it's pretty bad, but here we go, let's learn it!" That sets the learner up for demotivation from the start... It's better to describe the good parts, then tell the learner that, unfortunately, ...
The reason is that it was a workaround for the limitations of 1980s hardware that has been mindlessly cargo-culted ever since. Silent NaN-propagation is a second billion dollar mistake and equally worth avoiding in new languages.
(Since you mention billion-dollar mistakes: you can remove null pointers from a language at no runtime cost, in a few different ways—e.g. require that types be explicitly nullable, or Rust-style Option<T> optimised to squeeze the None/Some discriminant into any spare space in T, so that for sized T, &T and Option<&T> both take only one word.)
Back in the PowerPC days, something along these lines happened with Java. Java mandates that integer divide-by-zero throws an exception, but PowerPC doesn't have a mechanism to signal that a divide-by-zero occurred (1/0 == 0, as far as PowerPC is concerned). This forced the JVM to wrap every integer divide with an explicit test for a zero divisor, which put a significant drag on JVM performance...
We are probably talking about single-digit percent increases in run time. For some software that's relevant, but not for most.
> And JavaScript has always had a map method on arrays, which transforms the array's values into other values.
This isn't true. We only officially got this with ES5, which only came out in 2009. And we couldn't meaningfully use them until IE9 was released with ES5 support in 2011. And even then folks still had to support old IE for quite a while: it wasn't until around 2013 (after IE11's release) that ES5 use really picked up. Until then, we had Underscore.js and jQuerys' map methods, and various polyfills/shims.
Looking at the web today, you'd be forgiven for forgetting that most of the "cool" stuff is less than ten years old.
Im running a newish version of safari that does have wasm support.. what could this website possibly be using that I dont have on my phone? Does no one else see this message?
We run the entirety of SQLite, compiled to wasm, in the browser, among other things. It depends on the course, but our version checks are site-wide because it's all one app.
I’m still in agreement that negative indices make it more confusing than just calculating based off the length, but I get why they exist.
If you are going to have negative indexing, there isn't really a better alternative than 1 based indexes; since you can't exactly do arr[-0]
> Object.is(0, -0)
false1. I'd want TS to show an error on the line where the aliasing occurs, encouraging me to clone the list if I want to change its type from a distance.
The main reason behind accepting it is that it is very useful and safe in certain situations that the type system is too weak to define strictly: if a function takes an (string|number)[] and only reads from it, it is perfectly safe to pass in a string[].
'When explaining Javascript, we have to decide how to approach its shortcomings. There are mistakes in its design, and it has usability problems, and it is unreliable. How do we approach these and how much emphasis do we place on them?
One approach is: "Javascript has a lot of problems, but we'll show you how to avoid them." That can demotivate the learner: "Why am I learning Javascript if it has so many problems?"'
The answer is: "You need to know Javascript because it is the heart of web programming and one of the most widely-used programming languages in existence."
Javascript was designed and implemented in 10 days and became ubiquitous through the world wide web, despite its laughably bad flaws and shortcomings.
Gary Bernhardt's WAT talk shows just how non-sensical Javascript can be:
https://www.destroyallsoftware.com/talks/wat
I love you, Javascript, but it's Stockholm syndrome.
As a former boot camp instructor, I can say there are many, many people who call it a first language, and a significant subset of these people that worship intricate knowledge of it's faults as if they were features.
I tried very hard while instructing JavaScript to understand why the faults were there and how to avoid them and why detailed knowledge was no longer relevant thanks to many smart people spending lots of energy to make them not matter any more, e.g.: q: "when should I use var?" a: "never, use let or const to avoid hoisting"
Unfortunately, I think one just has to learn a few more languages before they can take an objective view of their 1st.
Unfortunately it seems like JS developers will likely never know this joy.
But yes, a good addition to the blog post might be to include some more stuff to motivate the learner why the topic is useful.
2. This is not a serious issue. I think it is unfortunate that you can't use a built-in function to map over a Map, but this isn't what the article is saying.
4. This could absolutely be fixed? The reason we "can't" fix the NaN issue is because we don't want to break JavaScript backwards compatibility. TypeScript version 3 could outright ban this action and it would be totally "fine" (modulo migration pains in existing codebases). Fixing this wouldn't affect backwards compatibility with the emitted Javascript at all.
For every soundness-related bug that sneaks through, TypeScript will probably save you from hundreds of "cannot read property of undefined" errors.
Vs
type NonEmptyArray<T> = [T, ...T[]];
Or if you need to check if the array has exactly 3 items. How would you do that in TS?
Like that: https://www.typescriptlang.org/play?#code/C4TwDgpgBAKgFgJwhA...
No. Their names are clearly NOT identical.
Arrays have the method "map()" and there also exists the global class "Map".
"Map" !== "map"
The fact that they are similarly named is NOT an unfortunate accident of history because yes they are conceptually related. They both are about "mapping" things to other things. So because they are conceptually related one would assume that their names are somewhat similar as well.
What is unfortunate I think is that JavaScript Object does not have the method "map()" like Array does. Therefore you can not "map() over Maps" (or Objects in general).
(Edit: Perhaps we need a clearer model of the student that is material is meant for. Novices will need a “just do it this way” approach, while experienced programmers will need more detailed explanations.)
Not necessarily. Teaching too much, too fast can distract a student from mastering each step; from properly “leveling up”. Teaching materials (including online courses like this) need to start with a theory of the learner in order to select and tailor materials for best effect.
This is false. Array.map has been only available since 2011 in Ecmascript and has been usable without polyfills since only around 2016. You have to be a newbie in the language not to know this... If anyone older than me ever said that to me I would judge them.