You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/posts/2024-10-20-javascript.md
+23-3Lines changed: 23 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ tags: [javascript]
7
7
draft: true
8
8
---
9
9
10
-
Not long ago, I got into a discussion with someone who vehemently and vocally dislikes Javascript. When they voiced their dislike for it, I made the mistake of asking why, then proceeded to dig myself further into the rabbit hole until we both grew tired of the conversation. I noticed, though, that a lot of their complaints seemed to (not unlike a lot of the common complaints about PHP) come largely from a place of misunderstanding the language, and it made me still want to put out there explanations for some of those complaints.
10
+
Not long ago, I got into a discussion with someone who vehemently and vocally disliked Javascript. When they voiced their dislike for it, I made the mistake of asking why, then proceeded to dig myself further into the rabbit hole until we both grew tired of the conversation. I noticed, though, that a lot of their complaints seemed to (not unlike a lot of the common complaints about PHP) come largely from a place of misunderstanding the language, and it made me still want to write about what was behind those things they complained about.
11
11
12
12
## The Floating Point "Bug"
13
13
@@ -18,8 +18,28 @@ Let's start with the most common thing used to criticize the language, which is
18
18
>false
19
19
```
20
20
21
-
Contrary to popular belief, this isn't a bug at all, but a limitation in math itself that, in fact, *all* programming languages have. How Javascript handles it is actually (and ironically) the documented standard way [set forth by the IEEE](https://en.wikipedia.org/wiki/IEEE_754). Most other languages choose to be less compliant with the standard in favor of what they consider better development experience, and truncate or round the numbers to create results we'd normally expect (usually). Different languages handle this differently.
21
+
Contrary to popular belief, this isn't a bug at all (at least not in the usual sense), but a limitation of digital calculating of math itself that, in fact, *all* programming languages have. How Javascript handles it is actually (and ironically) the documented standard way [set forth by the IEEE](https://en.wikipedia.org/wiki/IEEE_754). Most other languages choose to be less compliant with the standard in favor of what they consider better developer experience, and truncate or round the numbers to create results we'd normally expect (usually). Different languages handle the details of this differently, but the result is typically the same: `0.1+0.2 == 0.3 -> true`.
22
22
23
23
So what is this limitation? It's an incompatibility between base 10 (decimal) and base 2 (binary), combined with how computers do math, and the necessary limitations of dealing with infinitely repeating decimals.
24
24
25
-
How do you represent \({1 \over 3}\) in decimal format? In math class, it'd be \(0.\overline{3}\), or "zero point three, repeating." That's because decimal *can't* represent \({1 \over 3}\) or any other number from an equation that doesn't divide cleanly. This is the same reason your calculator will display \({2 \over 3}\) as \(0.66667\) (or however many decimal places it displays), because it picks a limit and rounds the next place accordingly. Converting between binary and decimal has the same issue, except with different (floating point) numbers. There's a whole bunch of math used to illustrate this, but I won't bore you with those details. [Wikipedia has a good explanation](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) if you're curious.
25
+
How do you represent \({1 \over 3}\) in decimal format? In math class, it'd be \(0.\overline{3}\), or "zero point three, repeating." That's because decimal *can't* precisely represent \({1 \over 3}\) or any other number from an equation that doesn't divide cleanly. This is the same reason your calculator will display \({2 \over 3}\) as \(0.66667\) (or however many decimal places it displays), because it picks a limit and rounds the next place accordingly. Converting between binary and decimal has the same issue, except with different (floating point) numbers. There's a whole bunch of math used to illustrate this, but I won't bore you with those details. [Wikipedia has a good explanation](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) if you're curious.
26
+
27
+
## JavaScript Often Fails in Silent Ways Instead of Crashing
28
+
29
+
This is another one I've run into off and on, and was one the person I was talking to got particularly stuck on, since they worked primarily in server side and other controlled-runtime environments. This was also the underlying thing that led to basically all the rest of his criticisms of the language, particularly relating to math.
30
+
31
+
History time! Well, history and still current events, really.
32
+
33
+
### Array.sort "Can't" Sort Numbers Properly
34
+
35
+
(It can, just has a naive default that runs counter to numeric sorting -- it converts to strings and sorts alphabetically, because converting to strings preserves data. Also talk about how Python handles sorting.)
36
+
37
+
### `NaN % 2 !== 0` -> `true`
38
+
39
+
Also - `'abc' % 2 !== 0` -> `true` (basically, anything that isn't a number and can't be coerced into a number results in the same thing)
40
+
41
+
(He expected this to throw an exception (presumably type mismatch), but it's a case where JS fails gracefully rather than crashing. He claimed it was nonsensical, but...it actually isn't. `!==` is strong comparison and requires the left and right sides to also be the same type as well as equal. both `'abc' % 2` and `NaN % 2` return `NaN`, and `NaN`...is neither `0` nor the same data type...)
42
+
43
+
## The LeftPad Debacle
44
+
45
+
(Weakness of centralizd package repository, not language)
Five years ago, I decided to start keeping a "second brain" note system, in an effort to start keeping track of things...just...in general. I soon settled on [Foam](https://foambubble.github.io/foam/), a VS Code extension. I had many reasons for picking it, which I might write about eventually, but the short of it is that it keeps my notes in Markdown and on my own machines unless I choose otherwise. At the time, Obsidian wasn't an option (I think it was paid only, IIRC), and Notion failed even the aforementioned requirements, as did most other options available then.
10
+
11
+
In the past five years, the Foam team has done a ton of work on it (shout out to them! 🫶 ) and now, I'm constantly finding new goodies that it can do. Today is one such day.
12
+
13
+
I'm active in the Foam Discord, and someone asked about hierarchical notes, a feature Dendron had when it was still maintained. Though Foam uses a different paradigm and therefore doesn't officially support hierarchical notes, I did know that it happily supports folders, tags, and other organizational methods. The question got me wondering what it would do if I tried making a hierarchical tag. So...I tried it. I grabbed a note, and in the front matter, I added `tags: foo/bar`. Immediately, the hover tips recognized it as a single tag, so that was a promising start.
14
+
15
+
But it got even better when I looked at the tag explorer, and again when I opened the graph. I expected Foam to either not recognize the compound tag, or to just see it as one string and list it with all the others.
16
+
17
+
Boy, was I pleasantly surprised to find that it supported it fantastically, recognizing the slash as a hierarchical separator, nicely nesting `bar` under `foo` in the list. The graph isn't *quite* as nice, but still, there was a `foo` node, then a `foo/bar` node, then my note. Honestly, not bad for what seems to be a happy accident. I can live with that, as I don't intend on nesting them super deep and can simply skip some ancestor tags in most cases.
0 commit comments