News for hackers. Stuff that matters.
Re:Deep JavaScript: Theory and Techniques by azangru on Wednesday June 17, 2020 @05:50PM (#23557203)
Have you seen that Flanagan's JavaScript the Definitive Guide, the famously big book with the rhinoceros on its cover, has recently seen a new edition? I wonder how deep its JavaScript goes :-)

(https://www.amazon.co.uk/JavaScript-Definitive-Guide-David-F...)

Re:Deep JavaScript: Theory and Techniques by petercooper on Wednesday June 17, 2020 @08:55PM (#23558652)
David has written about what's new, if anyone's interested: https://davidflanagan.com/2020/05/03/changes-in-the-seventh-...

I also (briefly) interviewed him about it here: https://superhighway.dev/david-flanagan-interview

Re:Deep JavaScript: Theory and Techniques by ithrow on Wednesday June 17, 2020 @10:56PM (#23559352)
No PDF version?
Re:Deep JavaScript: Theory and Techniques by jmchuster on Wednesday June 17, 2020 @09:52PM (#23558971)
I've always enjoyed the famously small book "Javascript: The Good Parts", albeit a bit dated at this point
Re:Deep JavaScript: Theory and Techniques by mayank on Wednesday June 17, 2020 @10:59PM (#23559372)
Unfortunately, the language has changed so much in recent years that I wouldn’t necessarily recommend that book anymore. A large number of fundamental features have been introduced since 2008, including async/await, lambda functions, class and extends syntax, proxies, and a ton of builtin methods like map() and forEach() on native list types.
Re:Deep JavaScript: Theory and Techniques by jmchuster on Wednesday June 17, 2020 @11:56PM (#23559669)
For sure, these were the old days before jQuery was even considered a standard library. It was still duking it out with YUI and Prototype.
Re:Deep JavaScript: Theory and Techniques by chrstphrknwtn on Thursday June 18, 2020 @01:52AM (#23560169)
I'm fairly sure Lambda functions have always been part of javascript?
Re:Deep JavaScript: Theory and Techniques by croddin on Thursday June 18, 2020 @02:02AM (#23560208)
Anonymous functions indeed have. I think he means the arrow function syntax.
Re:Deep JavaScript: Theory and Techniques by mayank on Thursday June 18, 2020 @11:35AM (#23564043)
Yes, my bad. I meant arrow functions.
Re:Deep JavaScript: Theory and Techniques by ulucs on Thursday June 18, 2020 @02:00AM (#23560206)
function () {}'s have been there forever, but () => {}'s have different semantics and are somewhat new
Re:Deep JavaScript: Theory and Techniques by ipnon on Wednesday June 17, 2020 @01:05PM (#23553804)
I've never heard of object sealing or freezing, glancing at the Table of Contents. JavaScript keeps surprising me.

  // Levels of protection: preventing extensions, sealing, freezing
  Object.preventExtensions(obj)
  Object.seal(obj)
  Object.freeze(obj)
Re:Deep JavaScript: Theory and Techniques by DylanSp on Wednesday June 17, 2020 @01:22PM (#23554030)
From using immer[1], I learned about Object.freeze(), which immer uses under the hood.

[1] https://github.com/immerjs/immer

Re:Deep JavaScript: Theory and Techniques by cjones26 on Wednesday June 17, 2020 @08:28PM (#23558493)
Though I recommend to my team to avoid mutation if at all possible, there are times which I have found immer absolutely invaluable. Try spreading out an object 15 levels deep to replace a single property value and you'll catch my drift.
Re:Deep JavaScript: Theory and Techniques by acidbaseextract on Wednesday June 17, 2020 @09:46PM (#23558926)
My biggest challenge with immer has been that my code aesthetic taste leans functional, but immer makes code look imperative even if it is ultimately functional. Always looks a little wrong to my eye!
Re:Deep JavaScript: Theory and Techniques by wereHamster on Thursday June 18, 2020 @01:57AM (#23560187)
Writing old-style pure code to do changes in a deeply nested structure is cumbersome, both to write and read. Eventually every language will find nicer ways to allow programmers to express these mutations.

JavaScript doesn't provide a nice way to extend the language syntax, unlike some other programming languages. So most DSLs end up looking like imperative code but do pure mutations underneath. I understand, for the reader it's confusing, because unless you know that it's a DSL you never know whether the mutations are pure or not.

Compare that with Haskell, with its support for custom operators, allows for some quite succinct code to express deep mutations (cf. lens library)

Re:Deep JavaScript: Theory and Techniques by XCSme on Wednesday June 17, 2020 @01:22PM (#23554034)
This feature feels pretty new, even though it was released in ES5, and had some more fixes in ES6. It's useful for having immutable data, which was all the hype when React and Redux were introduced.
Re:Deep JavaScript: Theory and Techniques by tempodox on Wednesday June 17, 2020 @02:03PM (#23554560)
This looks like it's worth a place in an electronic bookshelf. Among other things, following a link in the contents led me to this little pearl: https://mathiasbynens.be/notes/globalthis
Re:Deep JavaScript: Theory and Techniques by ezequiel-garzon on Wednesday June 17, 2020 @07:33PM (#23558104)
He’s great! Consider https://mothereff.in/ampersands
Re:Deep JavaScript: Theory and Techniques by jacobr on Thursday June 18, 2020 @02:40AM (#23560408)
That’s horrific and amazing
Re:Deep JavaScript: Theory and Techniques by MatekCopatek on Wednesday June 17, 2020 @04:49PM (#23556560)
Love this!

Some languages are typically taught in introductory programming courses - it's a very deliberate process aimed at explaining concepts from the ground up. JS is the opposite, people mostly learn it top-down, doing web development and being forced to use it.

And like eager college graduates need to learn it's sometimes a waste of time to optimize an algorithm, DIY JS devs can greatly benefit from a bit of theory and technical depth. Resources like this are perfect for that.

I can also wholeheartedly recommend Kyle Simpson's You Don't Know JS.

Re:Deep JavaScript: Theory and Techniques by jorangreef on Wednesday June 17, 2020 @12:46PM (#23553528)
One of the things I love about JavaScript is that you can write an almost 10x faster hash table than the standard library if you take care of cache misses and GC: https://github.com/ronomon/hash-table#motivation

In fact, all the usual low-level optimization techniques like reducing branch mispredictions and expensive memory accesses apply, and make a huge difference, even though you're writing in a high-level language.

Re:Deep JavaScript: Theory and Techniques by _bxg1 on Wednesday June 17, 2020 @02:06PM (#23554605)
*for a very specific use-case where you have an ungodly amount of data to insert

Still, it's interesting that there is something to be gained under these circumstances. I'm typically skeptical of this sort of thing because the standard library is written in C++. One time I thought I was very clever and hand-wrote a more appropriate sorting algorithm for a specific use-case only to discover that, no, Array.sort() was still faster by sheer brute force.

Re:Deep JavaScript: Theory and Techniques by jorangreef on Wednesday June 17, 2020 @05:40PM (#23557103)
We actually wrote the original version in C with SIMD extensions as a Node.js binding, but the JavaScript version was still twice as fast. I kid you not. You will find the reason for this in the README, it's the last bullet point under "Fast": https://github.com/ronomon/hash-table#fast
Re:Deep JavaScript: Theory and Techniques by _bxg1 on Wednesday June 17, 2020 @08:49PM (#23558614)
Huh. Does that apply to WASM too or just to binding from Node?
Re:Deep JavaScript: Theory and Techniques by jorangreef on Thursday June 18, 2020 @04:08AM (#23560886)
I am not sure but I wouldn't think so, unless you have to serialize/deserialize or otherwise transform or inspect function call arguments in some or other way, as you need to do when binding JavaScript with C.
Re:Deep JavaScript: Theory and Techniques by austincheney on Wednesday June 17, 2020 @05:34PM (#23557057)
The algorithm for Array.sort is implementation specific, but there is an ECMAScript proposal for a standard algorithm.
Re:Deep JavaScript: Theory and Techniques by zamalek on Wednesday June 17, 2020 @02:04PM (#23554579)
It's why managed languages have such a bad rap: people think that this stuff ceases to matter.

I remember the C# DirectX billboard sample, it was something like 10x slower than the same C++ sample in the same version of the SDK. Why? C# didn't have generics yet, and a value type was being stored in a non-generic list. Something like 4MB of memory was being copied around due to boxing and unboxing.

These things always matter.

Re:Deep JavaScript: Theory and Techniques by game_the0ry on Wednesday June 17, 2020 @03:53PM (#23555952)
I do appreciate the effort the author put into that library and obviously performance is important.

However, JS doesn't primarily live in the server side world, it mostly lives in the browser world. And in the browsers, you rarely do heavy processing. If you are, you're doing it wrong - that logic needs to live on the server.

You're also doing it wrong in you are relying on server side NodeJS for tasks that involve heavy duty computations.

Still, interesting to know. I wonder if the author can make this repo a proposal to the TC39 committee.

Re:Deep JavaScript: Theory and Techniques by hombre_fatal on Wednesday June 17, 2020 @04:15PM (#23556185)
I consider this wrong on all counts and I don't see where you're coming from to make these claims. You obviously benefit from performance gains on the server and client in standard use-cases.

A Node.js server's main thread is nickel and dimed by a thousand little cuts. A faster hash implementation can reduce loop delay by a nontrivial amount. This isn't heavy processing.

Same with the client. Any sort of game could have a good reason to be doing hashtable lookups in a hot loop on the client. This isn't heavy processing in some exotic use-case, it's rather elementary. And perf trade-offs especially help slow clients. And freeing up the main thread lets you fit in more nonreducible cycles.

Also, moving work to the server because your client implementation is too slow and then generalizing that to "always do work on the server", is tautological. Where you do work is fundamentally a business logic / product design concern that is only a performance concern in the suboptimal case where you can't fit the work on the server or client. So faster implementations move what are performance concerns back into the realm of higher level product design decisions.

These aren't symptoms of "doing it wrong". This is just plain jane software engineering.

Re:Deep JavaScript: Theory and Techniques by jorangreef on Wednesday June 17, 2020 @05:42PM (#23557119)
> This is just plain jane software engineering.

Thanks, love this quote!

Re:Deep JavaScript: Theory and Techniques by game_the0ry on Wednesday June 17, 2020 @04:51PM (#23556585)
> These aren't symptoms of "doing it wrong". This is just plain jane software engineering.

To use author's example, let's assume 2 scenarios.

Processing 4M records: 1) client side 2) server side via network API over the wire

One will be faster than the other. Not sure which one, but the slower one is what I would call "wrong."

Re:Deep JavaScript: Theory and Techniques by _bxg1 on Wednesday June 17, 2020 @04:02PM (#23556043)
> And in the browsers, you rarely do heavy processing. If you are, you're doing it wrong - that logic needs to live on the server.

This is very incorrect. At my last company we had a React interface (a specialized IDE, really) that needed to juggle (sort, filter, process) and work with sometimes hundreds of thousands of entities at once, all in-memory. JavaScript did this just fine, and the user experience (and the API design) really benefitted from not having a bunch of extra round-trips to the server.

Even in this extreme use-case, the bottleneck was always the few-hundred items that were actually rendered in the DOM at a time. We virtually never had performance problems from sheer volume of underlying data.

Re:Deep JavaScript: Theory and Techniques by game_the0ry on Wednesday June 17, 2020 @04:44PM (#23556501)
> At my last company we had a React interface (a specialized IDE, really) that needed to juggle (sort, filter, process) and work with sometimes hundreds of thousands of entities at once, all in-memory.

The author's example inserts 4M elements.

> and the user experience (and the API design) really benefitted from not having a bunch of extra round-trips to the server.

Possibly, but unless you benchmarked both scenarios, this might not be the case.

Performance over networked devices often has trade offs, sometimes those trade offs are directly contradictory, eg sorting/filtering/mapping/etc data on client side versus server side via api call - sometimes one is better than the other but you wont wont know unless you benchmark.

I get the impression that your company did not go through that exercise, considering you guys are building an IDE with scripting language.[1]

[1] https://nickjanetakis.com/blog/switching-to-vscode-from-subl....

Re:Deep JavaScript: Theory and Techniques by jorangreef on Wednesday June 17, 2020 @05:34PM (#23557051)
We actually use this to insert 400M elements.

The only reason the example inserts 4M elements was because Set and Object start to become prohibitively slow at some point and crash the process with too many allocations, not to mention the stress on the GC which now has to follow so many pointers.

HashTable performance is a fundamental component of any language.

Re:Deep JavaScript: Theory and Techniques by game_the0ry on Wednesday June 17, 2020 @06:03PM (#23557317)
> HashTable performance is a fundamental component of any language.

Agreed, but why use Node if performance was so critical to your use case? Could this 400M insert logic exist in a separate service that lives outside your Node code base?

Re:Deep JavaScript: Theory and Techniques by _bxg1 on Wednesday June 17, 2020 @06:39PM (#23557643)
It's one thing to write a web service in a different language for performance; it's a much bigger question to move logic from your client to your server for the sake of performance. Both from a user experience standpoint and from an architectural complexity standpoint.
Re:Deep JavaScript: Theory and Techniques by game_the0ry on Tuesday June 23, 2020 @04:39PM (#23619920)
Not sure what you're getting at. Could you elaborate?
Re:Deep JavaScript: Theory and Techniques by ralphc on Wednesday June 17, 2020 @04:32PM (#23556383)
One of the selling points of tensorflow.js is that you do your processing on the client, for privacy reasons. This is heavy, heavy processing, and you're doing it right.
Re:Deep JavaScript: Theory and Techniques by adamc on Wednesday June 17, 2020 @01:30PM (#23554143)
Disappointed not to see a dead-tree version.
Re:Deep JavaScript: Theory and Techniques by divbzero on Thursday June 18, 2020 @02:00AM (#23560203)
A few bits of deep JavaScript that I’ve learned from Deep JavaScript:

– The % operator calculates the remainder, not the modulus, which makes difference for negative numbers.

– Constructors can return a Promise.

– Function names are stored as the .name property.

Re:Deep JavaScript: Theory and Techniques by seph-reed on Wednesday June 17, 2020 @12:50PM (#23553582)
I just think this is interesting. The following statement is true:

`(~~4.2 === 4) && (~~-3.5 === -3)`

Re:Deep JavaScript: Theory and Techniques by XCSme on Wednesday June 17, 2020 @12:58PM (#23553714)
Isn't `true` the expected result? Apart from that, who would write code like this?
Re:Deep JavaScript: Theory and Techniques by ipnon on Wednesday June 17, 2020 @01:00PM (#23553740)
Antagonistic JavaScript code golfers typically are not JavaScript users, I've found.

edit: It's like writing an intentional buffer overflow in C. You don't see it as often because it requires actually knowing how to program.

Re:Deep JavaScript: Theory and Techniques by XCSme on Wednesday June 17, 2020 @01:19PM (#23553981)
The thing is, the result above is not even specific to JavaScript (in PHP for example it also returns `true`), and it makes a lot of sense if you know what the bitwise operators do.
Re:Deep JavaScript: Theory and Techniques by mrspeaker on Wednesday June 17, 2020 @01:20PM (#23553999)
Now I'm curious what result the OP was expecting... that's how bitwise NOT should work on (IEEE 754) floating-point numbers regardless of the language, isn't it?

  (4.2).toString(2);
  > "100.00110011001100110011001100110011001100110011001101"
  (~4.2).toString(2);
  > "-101"
  (~~4.2).toString(2);
  > "100"
Perhaps the initial NOT is supposed to maintain the bits after the point? I have to go look at the spec.

[Ok, looks like that not defined in the spec, and is a language-specific behavior: I have some homework now!]

Re:Deep JavaScript: Theory and Techniques by XCSme on Wednesday June 17, 2020 @01:29PM (#23554131)
I think in C++ for example you can't even pass a floating number to the bitwise not operator.
Re:Deep JavaScript: Theory and Techniques by seph-reed on Wednesday June 17, 2020 @01:41PM (#23554280)
I wasn't intending to be antagonistic.

It's just interesting that it works.

Re:Deep JavaScript: Theory and Techniques by XCSme on Wednesday June 17, 2020 @01:46PM (#23554351)
What part is interesting or surprising? As per the spec, isn't this what the operators should do?
Re:Deep JavaScript: Theory and Techniques by seph-reed on Wednesday June 17, 2020 @04:46PM (#23556520)
I found it interesting and surprising and thought others might as well.

It appears my emotional response was not in line with everyone else's.

Re:Deep JavaScript: Theory and Techniques by ByteJockey on Wednesday June 17, 2020 @10:26PM (#23559176)
Could you maybe elaborate on what you expected?