4 ms·
I have a copy of SICP right next to me, and it's one of my favorite computer science books. I'm not sure how I feel about this javascript edition though...
by muh_gradle 5y ago
I have a copy of SICP right next to me, and it's one of my favorite computer science books. I'm not sure how I feel about this javascript edition though...
- kazinator 5y agoI was doing some Javascript coding today. A false != x test failed for a zero-valued x; had to make it !==. WTF? I never want false and 0 to be other than different objects. Almost every twist and turn in this language is an imbecillic clusterfuck. I had one instance of a if (foo.bar = 0) typo; no warning from the implementation. Why do we want stupid C mistakes in a higher level language, without the C fixes for them? list.forEach(function (item, i) { ... }); makes my eyes bleed. JavasSript borrows the syntax of languages geared toward a form of computing at which JavaScript is poorly suited for; when you're combining functions together, it looks like dog's breakfast. To get a value out of a switch statement, you have to wrap it in a function that is immediately called? function () { switch (WTF) { } }(); the switch statement has the idiotic break with fallthrough found in C. One redeeming feature: A || B || C ... works a lot like (or A B C ...). Unfortunately, this is required for the simple task of incrementing a nonexistent dictionary key from zero: dict[key] = (dict[key] || 0) + 1; this calls for two dictionary key lookups. You want this sort of thing in a single operation. Oops! In the following, j isn't lexical: for (let i = 0, j = 0; .... I copy and pasted something like this from a StackOveflow answer into a recursive function and spotted that the j in a recursed frame was messing with the j in outer frames, there just being one j. What is "function scope" and why even have something so idiotic? Just let, or GTFO! C has function scope for goto labels, that's it; why introduce something like that. Appending together Lists has functional semantics, like Lisp: a.concatenate(b) // new thing is returned, a stays the same, so you must do a = a.concatenate(b). But a.push(b) // mutates a in place. Here is a shitshow, curently with a fitting number of upvotes: 666. https://stackoverflow.com/questions/881085/count-the-number-of-occurrences-of-a-character-in-a-string-in-javascript https://stackoverflow.com/questions/881085/count-the-number-... I accidentally wrote if (foo.bar.indexOf[key] < 0) { code } code was silently skipped even though foo.bar is an empty list. No diagnostic, nothing. Oh, indexOf is a function, which is an object. Every damned object is a dictionary with properties you can access as strings with square bracket indexing, and that is always safe: it yields undefined if the property is not found.
- kazinator 5y ago> Oops! In the following, j isn't lexical: I don't think I'm correct here. However, be that as it may, in my code, when I moved that second variable before the loop and initialized it there with a let, the behavior somehow changed.
- throwthere 5y agoNot to minimize these problems but typescript eases a lot of them.
- celroid 5y agoOnce you learn the quirks of JavaScript you get used to it. Also you should not use forEach in JS, take a quick look at this page. https://phoenix35.js.org/good-practices.html https://phoenix35.js.org/good-practices.html
- kazinator 5y agoIf forEach is not to be used, it should be deprecated and removed from the language in a timely manner. The objection that it's not functional is invalid; procedural traversal with a callback function, object or closure, is a time-honored pattern in software. Most of the other problems cited are not with forEach per se but the language in which forEach finds itself. None of the alternatives presented are more attractive than for (let i = 0; i < obj.length; i++) { let elem = obj[i]; } If we could just run this through the C preprocessor, we could have foreach (i, elem, obj) { } by way of something like: #define foreach(ivar, elvar, obj) \ for (let ivar = 0, elvar; \ ivar < obj.length && (elvar = obj[ivar], true); \ ivar++) Since Javascript is based on C syntax, it should have the preprocessor that the birthplace of C saw it fit for that language not to be without.
- hajile 5y ago> If forEach is not to be used That source is simply incorrect. forEach is perfectly fine to use as long as you realize what is happening. It iterates an array where each thing is a function that returns a promise. Of course the results aren't what they expect. ES5 array additions suffer from being a little too early (though later stuff wouldn't exist otherwise, so...). They are designed to deal with holey arrays (arrays with indexes missing). This is extremely uncommon today, but was decently common once upon a time. They were also created before the iterator protocol. The real fix is to design iterator versions that can handle things like async generator functions. > it should be deprecated and removed from the language in a timely manner. NOTHING can be removed from the language once added. Doing that would break all the older websites that depend on it (technically, a few minor breaks happened after they tested millions of sites and couldn't find anything that was adversely affected). At best, they can block older features from newer features. For example, using class syntax or a bunch of other ES6 language structures automatically makes your code shift into "use strict" mode. I hope they introduce a "use strict 2" variant that strips away more of the undesirable features than the current "use strict" does. > Since Javascript is based on C syntax, it should have the preprocessor that the birthplace of C saw it fit for that language not to be without. That pre-processor was a source of untold nightmares. Direct injection leads to bugs. If someone is going that route, full-blown macros are the only answer. There is a full-blown macro system Mozilla created a few years ago, but it's not very popular. https://www.sweetjs.org/ https://www.sweetjs.org/ There also exist some C-style pre-processors for babel too, but they should be avoided because lisp's gensym is a critical feature that they and C both lack.