1. 39

  2. 16

    “JavaScript historically didn’t have a way to intercept attribute access, which is a travesty. And by “intercept attribute access”, I mean that you couldn’t design a value foo such that evaluating foo.bar runs some code you wrote.”

    I’d call that a feature.

    1. 16

      I’m with you.

      This discussion must have happened in many language committee’s around the world:

      “Hey, I have a great idea … guys, listen … let’s hide the fact that code is being run, programmers will appreciate the clarity of not being able to see what is going on.”

      1. 9

        The argument is this: your API exposes an attribute. You want to extend that so some code has to run in addition (e.g. add logging). Can you make the change in a backwards compatible way?

        If a language has no mechanism for this (Java) guidelines emerge to always use getters and setters and never expose attributes.

        1. 3

          And the argument against is that property access doesn’t feel like something that should be able to induce side effects that you can’t possibly reason about. How much more expensive would the property access become if you add logging? How do you express the possible failure of that operation to the consumer?

          1. 2

            When exceptions are part of the function signature / contract, it becomes difficult to express. But they usually aren’t in message passing implementations of OO, like Ruby or Objective-C, where everything is like a method call.

            So stuff just needs to balance in the language as a whole.

          2. 2

            Maybe I’ll come to regret saying this when it ends up biting me, but my gut answer is that I’d prefer you just change the api rather than lie to me. This isn’t something I deal with regularly though.

            1. 2

              Yup, changing foo.bar = baz to foo.setBar(baz) when it is needed (and not before) is not really a difficult change to make. Most people don’t need such intense backwards compatibility guarantees.

        2. 2

          For back-compat reasons, the alternative to attribute access interception is to use getFoo and setFoo for every property (hiding the original properties).

          1. 2

            That’s not entirely true. defineGetter and defineSetter were a thing quite a long while ago..

            1. 2

              Do you think it’s an antifeature that you can run code? Or that you can run code with side effects?

              The code in the post is completely deterministic and is basically just a transformation of already-known values. You could do that outside the class too but it’s there for convenience. That seems like an unambiguous win to me.

              1. 4

                No, those things are fine. I want them to happen when I call functions, I don’t want them disguised as accessing a property (which I assume is looking something up in a hash at worst, but I don’t actually know what’s going on in there).

                1. 1

                  Interesting. So the mere fact that it runs code at all, regardless of whether it had side effects, is what bothers you? Because it violates assumptions about performance characteristics?

                  That seems a bit like premature optimization but maybe I don’t have the necessary “at scale” experience to comment.

            2. 7

              Those are lots of attractive new features that warm the cockles of my Python-coiled heart.

              Eevee also observes something that explains to me why my latest brush with DOM scripting felt so meh:

              The DOM APIs don’t make things much better — they seem to be designed as though the target language were Java, rarely taking advantage of any interesting JavaScript features.

              1. 7

                Indeed, because the DOM was meant to be a cross-platform object oriented API. Look familiar? :(

              2. 4

                About custom string interpolation:

                It’s a shame this feature is in JavaScript, the language where you are least likely to need it.

                I do need lit-html and pg-async!

                There’s a const now? I extremely don’t care, just name it in all caps and don’t reassign it, come on.

                Use it for every local binding you won’t reassign! That even improves performance I think.

                ES6 const is like Rust let, and ES6 let is like Rust let mut.

                1. 4

                  TypeScript is now my favourite, most productive useful language. It’s just modern JS with a fairly advanced type system that gets stripped off as it’s checked at “compile” time.

                  1. 3

                    Make sure you read the comments. There are several errors in this post, but they do get corrected below.

                    1. 3

                      Yes, arguments can have defaults now. It’s more like Sass than Python — default expressions are evaluated once per call, and later default expressions can refer to earlier arguments. I don’t know how I feel about that but whatever.

                      It’s better for performance, because your generated code doesn’t have a bunch of checks for undefined in the function preamble, it’s handled by the parser.

                      C++ does it this way too.

                      1. 1

                        The magic of Javascript is that it was an actual object oriented language. Classes have made javascript worse the same way they made smalltalk worse.

                        1. 4

                          They’re not real classes though. They’re more of a marketing gimmick to make those “not OO without classes” people shut up.

                          1. 1

                            This may be true but I am seeing code now which asserts the type before using it, throwing an error. So while they are not real classes , people are putting in extra effort to make them that way.

                            1. 2

                              People have always done that. My sense is that giving them a smokescreen class keyword might dissuade some of the atrocities previously committed when people would try to retrofit the language with some kind of class-based OO. The people who understand that class doesn’t give you what other languages call a class, and who don’t like that it’s not a class, will not be deterred by any means.