Kind of disappointing to read the comments here. The introduction talks about semantics of teaching. How phrasing can demotivate the students.<p>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.<p>Concluding he writes about how some of the unfortunate parts are needed to make typescript great.<p>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.<p>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.
Each point doesn't really bear the same level of "unsoundness". Most are actually not problems at all the way I see it.<p>1. I can live with NaN. When the source of something becomes difficult to track, use a debugger.<p>2. Map vs map? Just another homograph, like there are hundreds in all spoken languages, yet most people manage to communicate.<p>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.<p>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...
#3 is interesting because you can assign arr[-1] and it's valid. But it goes from being a pure array to a mixed array+hash/dict where "-1" is the key.<p>BUT if you set/access arr[0] it's just like an array...<p><pre><code> arr = []
arr[-1] = 'neg-one-pos'
arr[0] = 'zero-pos'
arr[1] = 'one-pos'
arr # => ["zero-pos", "one-pos", -1: "neg-one-pos"]
</code></pre>
That was quite unexpected for me.
The class name “Map” is a noun (because it’s a class), the method name “map” is a verb (because it’s a method), and the conceptual relationship between that noun and verb is exactly the conceptual relationship between the class and the method. There’s nothing “unfortunate” about it at all. It’s elegant, in fact. (And if you know some math, it’s even familiar.)
This advice seems excellent. I find myself running into this type of thing all the time when I introduce someone to something -- anything -- that's new to them and that I have a lot of experience with, whether it's technology or a board game or other.<p>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.
I have a big red flag that goes against what this post claims (I've written about this to a similar point <a href="https://academia.stackexchange.com/a/129673/58645" rel="nofollow">https://academia.stackexchange.com/a/129673/58645</a> )<p>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.<p>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.<p>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".<p>There are much better ways to approach this subject (linguistically), which would make it far more interesting and scientifically engaging.<p>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.
> NaN itself is part of the IEEE 754 floating point standard. It behaves the way it does for a reason.<p>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.
Excellent technique, and one of the main ones I use for a Bash course & other material. I feel like being upfront about caveats is a good way to enable non-expert users to choose between languages based on their shortcomings rather than just feature lists. <i>Having</i> a feature is very different from <i>nailing</i> a feature. See for example PHP's early OO support, Python's impressive but still incomplete typing support, open source reverse engineered graphics drivers/formats.
Some pedantry:<p>> And JavaScript has always had a map method on arrays, which transforms the array's values into other values.<p>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.<p>Looking at the web today, you'd be forgiven for forgetting that most of the "cool" stuff is less than ten years old.
> You're running an outdated browser that we don't support. We use many new browser features, including WASM, so we require very recent browsers. We maintain support current versions of Chrome, Safari, Firefox, and Edge. Sorry for the inconvenience!<p>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?
I think I might disagree with #3. I find that having arr[-1] point towards the last element of the array can hide accidental off-by-one errors. It's also a bit weird how the arrays are zero-based if you access them normaly but one-based if you access them backwards. IMO it's more consistent to make the negative indexes behave the same way as an out of bounds access like arr[arr.length + 1]
It seems to me like TypeScript's soundness hole in #4 could be fixed.<p>1. 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.
Under what circumstance do you end up with a negative array index? Eg. Why do you omit bound checks?
And should accessing any gap in an array result in error, and why are there gaps in the array?
Since the focus of this article is Javascript they should have written:<p>'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?<p>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?"'<p>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."<p>Javascript was designed and implemented in 10 days and became ubiquitous through the world wide web, despite its laughably bad flaws and shortcomings.<p>Gary Bernhardt's WAT talk shows just how non-sensical Javascript can be:<p><a href="https://www.destroyallsoftware.com/talks/wat" rel="nofollow">https://www.destroyallsoftware.com/talks/wat</a><p>I love you, Javascript, but it's Stockholm syndrome.
I agree about points 1 and 3 (especially writing to negative indexes being very weird), but I disagree about the other half.<p>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.<p>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.
As the full lesson says:<p>For every soundness-related bug that sneaks through, TypeScript will probably save you from hundreds of "cannot read property of undefined" errors.
About map() vs. Map
> Their identical names are just an unfortunate accident of history.<p>No. Their names are clearly NOT identical.<p>Arrays have the method "map()" and there also exists the global class "Map".<p>"Map" !== "map"<p>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.<p>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).
I’m not sure what benefit I, the learner, get when the author makes editorial comments about how “unfortunate” certain features of a language are. It seems to me that that I’m better served by just quickly acknowledging that something <i>different</i> happens under certain circumstances, and then I’m taught the techniques that professionals use when those circumstances arise.<p>(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.)
A lot of people are shocked by Javascript behavior, but the truth is, Javascript became successful BECAUSE it's a language that is(or was) incredibly forgiving thanks to its very weak typing and syntax and its behavior, trying to do everything in its power not to yield errors, or if an error happens in the browser, not propagate it so that an app that is 10% buggy can still run without blowing up (thanks to the event loop). In my book, that's certainly an achievement. IF I recall things correctly VBscript was stricter than Javascript, thus harder to write for people who didn't know what they were doing.
> And JavaScript has always had a map method on arrays, which transforms the array's values into other values.<p>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.