Hacker News new | ask | show | jobs
by hugomg 2154 days ago
I always love reading more about JavaScriptCore internals although I have to confess that much of the time one of the main lessons I get from it is that life would be much easier if we had types and didn't need to speculate so much in the first place.
1 comments

Not having types is a virtue for the web, where interfaces can change in weird ways. Dynamism leads the engine and the JS code to be less tightly coupled. So, there’s more wiggle room for evolution in the engine and more wiggle room for portability defenses in JS.

So, it just depends on how important the benefits of dynamic types are versus the benefits of static types. I don’t think static types of dynamic types are better; they are just good at different things.

It wouldn't be the JS we know and love if it had been burdened with a type system designed by a committee sometime in the 90s. That said, one thing we can say for sure is that the dynamic typing doesn't make your job any easier :)
You may want to speculate even when you have precise concrete types.

For example your type system may tell you have you have an int32, but you can speculate that only the lowest bit is ever set, with a kind of synthetic type you could call int32&0x1 which isn't expressable in the type system the user uses.

> dynamic typing doesn't make your job any easier

Yeah, it makes millions of application programmers' jobs easier at the expense of a small group of experts - sounds like the right tradeoff?

> Yeah, it makes millions of application programmers' jobs easier

I don't think it's that simple. Large programs get unwieldy, no matter what language you write it in, and a large body of evidence suggests that having static types for both safety and documentation is a big win, because it makes programs more robust and ironically makes programmers more productive in the long run. As you and I both know, this is a long discussion that stretches back decades, so it probably isn't going to be productive to hash it out here.

A more important discussion which is not being had is the question of the size of the trusted computed base. Framed this way, it makes sense to minimize the size of the trusted computed base and not have a complicated dynamic language implementation on the bottom. Instead we should have layers with a very strict statically-typed target that is easy to make go fast at the bottom. This is why I want to put WebAssembly under everything. Yes, even JS. (Fil would probably not agree here :-))

> For example your type system may tell you have you have an int32, but you can speculate that only the lowest bit is ever set,

Range analysis is really important for JavaScript code because everything is a double and it is generally a win to avoid doing double math if possible, but I am duoubtful that it makes much difference for statically-typed integer code outside of array bounds checking optimizations. In my mind, range analysis on integers really only feeds branch optimizations. Maybe it's the case that optimizing integer code that is full of overflow checking benefits from range analysis (the kind of stuff you find inside the implementation of a dynamic language), but I can't really think of much else.

> a large body of evidence suggests that having static types for both safety and documentation is a big win

Citation needed. A review of studies on static vs. dynamic languages concluded "most studies find very small effects, if any". https://danluu.com/empirical-pl/

I read through all those studies and didn't think they shed any light on the subject, as this is something very hard to get numbers on:

"The summary of the summary is that most studies find very small effects, if any. However, the studies probably don't cover contexts you're actually interested in."

”Large programs get unwieldy, no matter what language you write it in, and a large body of evidence suggests that having static types for both safety and documentation is a big win“

I am beginning to think that cutting your large untyped program into pieces and typing it only at the boundaries will get you all the benefits. That probably means most, if not all, types inside those pieces can be inferred.

How about optional typing, even in some limited form (primitive types, primitive-only structs) with gradually adding more over the time?

I think there was some proposal already but it's probably dead now because I haven't heard about it for a while.

There are still ways to program to unstable interfaces in static languages though, and they tend to be safer overall because they are isolated from the rest of the language.