HNHacker News
TopNewBestAskShowJobs

_getify

192 karma · joined April 23, 2013

Kyle Simpson is a web-oriented software engineer, widely acclaimed for his "You Don't Know JS" book series and nearly 1M hours viewed of his online courses. Kyle's superpower is asking better questions, who deeply believes in maximally using the minimally-necessary tools for any task. As a "human-centric technologist", he's passionate about bringing humans and technology together, evolving engineering organizations towards solving the right problems, in simpler ways. Kyle will always fight for the people behind the pixels.

[ my public key: https://keybase.io/getify; my proof: https://keybase.io/getify/sigs/SxqB6BQX2LQ92yiAfs1FYql_tPEhCqCGAZhnkap6tVY ]

submissionscomments
_getify··on JavaScript Coercions Grid
In JS:

  -0 + 0;   // 0
  -0 + (-0);  // -0
  -0 - 0;  // -0
I claim that the `-0 + 0` case is the strange inconsistent one, so that's the reason for my WTF label.

----

Consider the counter-argument, that it's intuitive/correct because in math `X + (-X) = 0`:

  3 + (-3);   // 0
  -3 + (3);  // 0
  -0 + (0);   // 0
  0 + (-0);  // 0
It's true that this characteristic by itself is preserved, but where it falls apart:

  X + (-X) = 0    // -->
  X = 0 - (-X)   // -->
  X = 0 + X
That final statement should be true for all X, but as demonstrated above, it's not true for -0.
_getify··on JavaScript Coercions Grid
The "WTF" label is not about correctness, it's about surprise/intuition. It doesn't really matter to me whether it's mathematically or IEEE correct. It's strange and inconsistent.

Yes, two numbers of different signs added together are supposed to be 0, but... a number is never supposed to change (sign or magnitude) when you add 0 to it, and here it does... so... it's a strange corner case that I think defies intuition.

Given the two precedences that are incompatible, I think far more people are likely to think "anything + 0 ======= anything" than they are to think "anything + -anything ========== +0". So that's why I marked it as a WTF.

_getify··on “I Don't Hate Arrow Functions” Blog Post
(self post)
_getify··on A book series on JavaScript
Just FTR: this is not accidental or lazy on my part. It's highly intentional. But I can certainly appreciate that it frustrates some learners.

There's a principle called "Cognitive Load Theory" [1] which I believe all teachers have to take seriously. Specifically, the "extraneous cognitive load". It's why I choose to introduce concepts with foo/bar style first.

I am concerned by the observations I've made over many years of teaching (JS) that many people tend to get distracted by problem domains and miss out on the underlying concepts. For example, if I am teaching about `this` but I use an example like a login system, it's far too easy for someone to get distracted by what they know -- or worse, what they don't know -- about how login systems work.

It's an overload on the cognitive side because the learner (reader) is having to juggle not only the new concepts but also their knowledge/opinions/baggage about the problem domain.

Cognitive overload is so "dangerous" not just because you might overflow someone's capacity and they stop getting anything out of the teaching, but because it has the tendency to become subtractive and actually cause them to lose what they already knew or had learned about the concept.

So... my approach in teaching, which is also reflected in the books, is to default to teaching a concept first without a problem domain, using generics like foo/bar, and THEN once I feel someone has the concepts, later, you can reinforce those with practical applications in problem domains.

IOW, I'd teach the abstract principles of `this` first, then the abstract principles of the Prototype system, then I'd start to show some examples like a login system that show how you can put those abstract concepts together into a real thing.

Anyway, I understand it doesn't meet your preference, but I just wanted to explain the reasoning behind it from my side.

[1] https://en.wikipedia.org/wiki/Cognitive_load

_getify··on A book series on JavaScript
First, I think it's disingenuous for an author to revel only in the positive reviews and "just ignore" the negative. An author should take all feedback and do the best with it he/she can. I read all reviews, and try to find anything I can in there to get better. That's why I'm sending this reply.

You probably think I should just "ignore the trolls" and you probably also think that anyone's negative expression is "freedom of speech" and that it shouldn't be countered.

I don't see it that way. The public ratings on my books are how a lot of people figure out if the books are worth looking at. No matter how legitimate or crazy a negative review may be, the one star hurts my overall rating exactly the same.

Furthermore, if I let a negative review go unanswered, I've lost an opportunity to show other readers a different perspective, and I've also lost the opportunity to (perhaps) engage in productive discussion that helps either that reviewer, or myself, or both, get better. Yes, this has actually happened before on a couple of occasions.

I don't think I'm reacting poorly by trying to find useful stuff even in the negative reviews. And I also don't think it's wrong to point out that unhelpful reviews are unhelpful.

I'm sorry this comes across as off-putting. But it's because I care so deeply about improving JS education through these books.

_getify··on A Taste of JavaScript's New Parallel Primitives
I'm excited about the `SharedArrayBuffer` addition, but quite meh on the `Atomic.wait()` and `Atomic.wake()`.

I think CSP's channel-based message control is a far better fit here, especially since CSP can quite naturally be modeled inside generators and thus have only local-blocking.

That means the silliness of "the main thread of a web page is not allowed to call Atomics.wait" becomes moot, because the main thread can do `yield CSP.take(..)` and not block the main UI thread, but still simply locally wait for an atomic operation to hand it data at completion.

I already have a project that implements a bridge for CSP semantics from main UI thread to other threads, including adapters for web workers, remote web socket servers, node processes, etc: https://github.com/getify/remote-csp-channel

What's exciting, for the web workers part in particular, is the ability to wire in SharedArrayBuffer so the data interchange across those boundaries is extremely cheap, while still maintaining the CSP take/put semantics for atomic-operation control.

_getify··on Teaching: Convergence and Divergence
self submission
_getify··on Don’t Use Markdown for Documentation
YAML claims to not be markup, but it clearly is a markup for data (significant whitespace/indentation, etc). When I want to do markup, I use Markdown.

When I want to data serialization, I use JSON. It's incredibly easy to strip comments (and whitespace, for that matter) from extended JSON before transmitting and/or parsing. I wrote `JSON.minify(..)` for that years ago, and it's literally never been a problem for me since.

_getify··on Don’t Use Markdown for Documentation
I didn't mention in my comment, but I also use Markdown for all my technical documentation (READMEs) on my dozens of github OSS projects. I have lots of cross-references and I use normal links to named section anchors (sometimes that I insert manually via HTML).

It's not perfect or even ideal, by any means, but the other benefits of Markdown are more than enough to make up for the slight annoyances here.

I don't know about ReStructured text, but I can say that none of the examples in the OP swayed me that I'm missing anything of any import.

_getify··on Don’t Use Markdown for Documentation
The books were intended as source material for publishing, so I didn't embed any crosslinks in the documents.

However, I always use markdown for all my OSS project documentation (READMEs, etc), and I do lots and lots of cross-referencing in that context. I use simple markdown links to named-section anchors.

It's a tiny bit more manual than I'd like, but it's never stopped me from doing technical documentation effectively.

_getify··on Don’t Use Markdown for Documentation
I wrote a six book, 1100 page series in Markdown (all on github). I write all my blog posts in Markdown.

I'm sorry but I just can't sympathize with any of the complaints leveled against Markdown. They are so minor and compared to the massive adoption of the common bits of Markdown, there's no chance I'd ever choose to write anything in any other markup than that just for those small annoyances.

I don't need custom extensibility when I can just add HTML. HTML is pretty good at markup, and it enhances the markdown in those rare occasions where what's provided seems too limited. The very last thing I'd want to do is literally write code as an extension to my markup language. The only code in my markdown is inside nice tidy code blocks for display purposes only.

I also use JSON for configuration, even though many have tried to convince the community that YAML or some other format is better. I pre-process my JSON to strip it of "non standard" comments, and I'm quite happy that I chose the by-far-defacto-standard there instead of going off the beaten path.

_getify··on Thoughts on Thunks; How JavaScript thunks explain promises
(self post)
_getify··on “Concurrently JavaScript”; exploring concepts of concurrency, parallelism, async
self submission
_getify··on “Arrow This”: clearing up how ES6 = arrows handle 'this' and others
disclosure: self submission
_getify··on Constantly Confusing ‘const’
> If you pass a reference to the x array to a function

This notion (concern) is meaningless in JS, since when you pass any reference, it's always a reference-copy, so there's no value nor assistance that `const` provides.

_getify··on Constantly Confusing ‘const’
It's not the core argument. It was a tangential side note in the blog post.
_getify··on Constantly Confusing ‘const’
But my post did actually conclude the cases where it's useful. It seems like a lot of people here only read the first half of the post and stopped.

I don't think `const` should be removed. I just don't think we should lead with it. I'm not sure why that's not coming across except for the fact that the post isn't being read.

_getify··on Constantly Confusing ‘const’
> Your argument against using const comes down to ...

You did an absolutely horrible job of summarizing even remotely what my argument was, so I guess "I won't even try to respond to" this, since you either can't critically read or didn't care to this time. jeez.

_getify··on Constantly Confusing ‘const’
I don't think my argument was to avoid `const`. I think my argument was to pick `const` at the end rather than at the beginning. I feel those are different arguments.
_getify··on Constantly Confusing ‘const’
I would genuinely (no sarcasm) like to read a blog post that makes a stronger argument (in either direction) than mine. Most blog posts I've read about `const` cite very flimsy things like "it makes my code more readable" without any real meat as to why that's true. I tried to debunk that with careful thought. If someone has more convincing arguments besides subjective opinion, I'd love to read them.
_getify··on Constantly Confusing ‘const’
> I know that after reading a const line I don't have to check if someone rebinds this name before each use site -- it's impossible.

This turns out to be almost useless information for most of us, since the real problem is not re-assignment, but mutation of the value (in the case of non-primitives).

`const x = 2` feels great emotionally, but `const x = [2]` has the feeling of safety without any of the guarantee.

This is a classic case (quoted from Crockford regularly) of a utility that it sometimes useful and sometimes harmful (aka not useful), and there's a better option (`let`), so the better option should generally be preferred.

I only use `const` (refactor from `let`) when a piece of code is reasonably complete and I'm pretty sure re-assignment will not ever be appropriate. Guessing at that before writing the code is a premature optimization.

And guessing wrongly and having to refactor back to `let` later is more risky.

_getify··on Constantly Confusing ‘const’
Oh, I see. I just need to learn more. The problem is I just don't know JS (or other langs for that matter).

http://YouDontKnowJS.com

_getify··on Constantly Confusing ‘const’
> `var` is broken

Nonsense. Revisionism at its finest.

But that's an argument I made in a different blog post: http://davidwalsh.name/for-and-against-let

> It would be nicer to have real, deep immutability, but `const` isn't it.

Yep, agree with you on that. That was one of the main points of my post.

> Because `const` requires to be initialized at the time of definition, you know the variable is valid for its entire lifetime.

No, that's where you're mistaken. All you really know is that the variable assignment is reliable. If the assignment happens to be of an immutable value, great.

But given the choice between these two guarantees:

1. The assignment is immutable

2. The value is immutable

(1) is almost pointless -- and a quick scan of your small block where it's scoped will verify that or not.

(2) is the absolute important one.

`const` masquerades as (2) when it's really only (1). That's what I don't like about it.

_getify··on Constantly Confusing ‘const’
What you're thinking about in ES6 is called "function name inference" and only refers to certain forms, like this one, where the name -- PURELY FOR DEBUGGING -- can be inferred. Actually, it goes for all assignments, `var`, `let`, and `const`.

Otherwise, the arrow itself is anonymous and thus you don't have a name to make an inner self-reference with.

_getify··on Constantly Confusing ‘const’
Except that any variation of these doesn't produce the same thing as a declaration, since function declarations hoist and function expression assignments do not.

Most people don't like hoisting -- and I agree that variable hoisting is crazy. I'd never advocate this:

    a = 2;
    var a;
But function hoisting I find super useful. I always prefer to write my files like this:

    foo();
    bar();
    
    // ....
    
    function foo() { .. }
    
    function bar() { .. }
...because when I open a file, I don't want to go hunting for any executable code, I just want to look at the very top. Function declaration hoisting lets me put those definitions at the bottom and the code that uses them at the top.

I've found this to be much more useful in code maintenance.

_getify··on Constantly Confusing ‘const’
Yeah, see, this is exactly the problem. I think most developers assume the latter, when the former is all that's meant according to JS.

I don't think the former is all that useful, and the latter is super useful but `const` doesn't do anything to help with that.

_getify··on Constantly Confusing ‘const’
> Why not use `const` as default?

The argument I made toward the end of the post is that refactoring from `const` back to `let` is more risky than the other way around.

Moreover, surveying my own code, honestly, the vast majority of my declarations should be `var` or `let`, and only a much smaller amount being `const`. I think a lot of people are rushing blindly to `const` without realizing its full behavior.

> [`const`] has less rules ... using `let` will introduce complexity

I think this is completely backwards. `let` has no special caveats (other than the TDZ thing, which they both have), whereas `const` has this caveat that it's only about assignment bindings and not about values.

Imagine a piece of code that has `const x = 2` that you later refactor to `const x = [2]`. The complexity is, you now have to contend with the `[2]` being a mutable value where `2` wasn't, and `const` sorta pretends to keep you safe but doesn't.

That's the complexity I disfavor.

_getify··on Constantly Confusing ‘const’
disclosure: self submission
_getify··on Unimorphic Isoversal JavaScript What?
If we're gonna go that route, I still like "middle-end" JS better. :)
_getify··on Unimorphic Isoversal JavaScript What?
disclosure: self submission
Page 1 of 4Next →