Infrequently Noted

Alex Russell on browsers, standards, and the process of progress.

Comments for Thoughts on Harmony


Type annotation helps to convert generic dictionaries/objects to efficient native objects, e.g, register-based integers and floats.

Classes do not help performance but the proposed immutability of classes does. It allows to avoid run-time lookups replacing them with compile-time lookups. Right now, we have to check if some Bob the Pooch dynamically overrides constructor of Number/String/Object/whatever preventing from creating objects during the compilation, or creating object constants, basic math (like Math.min()), and generally forcing unnecessary checks and preventing inlining.

While actual type can be deduced by analyzing the code, and doing an escape analysis, it is hard to do in dynamic languages that can add functions on the fly and redefine any globals. Type annotation can help with that by avoiding this costly analysis.

"Scripting" languages are moving ahead as primary languages of modern programmers, yet Moore's law does not advance the single(*) core speed anymore. We are forced to pay attention to efficiency.

(*) JS uses a single thread model with no provisions for parallel calculations at the language level nor the library that comes with it. It can be and should be fixed, e.g., the Gears project is trying to do just that.

Hey Eugene:

So Types can help in the conversion of some things to more efficient representations, and I'm a strong proponent of ByteArray and other more efficient collections in the language. But the main value of types (as I see it) is to be able to mark off large parts of an API and say "this is what it should look like". In that sense, the like and wrap aspects of ES4's gradual-typing system were incredibly attractive to me. I understand and appreciate their runtime costs, but they give you better tools to say what you mean even when that meaning is somewhat ambiguous.

As for the efficiency of walling off classes: yes, a simple system can wall off checks at compile time, but there's lots of good research happening right now around how to get similar efficiencies at runtime without enforcing those constraints at compile time. The biggest issues (as far as I can see them) are things like ensuring that lookup points aren't required to be giant time sinks such that those runtime optimizations don't need to work so hard (or require so much memory) to check to see if they're still valid. Work like Holze + Ungar's "Optimizing Dynamically-Dispatched Calls with Run-Time Type Feedback", Tamarin Tracing's ability to JIT hot-spots without significant compiler overhead, and papers like this point to a class of optimizations that don't require forcing the class and type semantics of the originating language to make such large concessions to the runtime. The argument they make, collectively, is that instead of trying to do some guesstimating about what could be important to the performance of a program and then forcing program authors to adopt a type system notation that caters to it, you can instead substitute runtime monitoring and knowledge about what's actually expensive as a way of getting to the same answer with much better developer ergonomics.

Anyway, my biggest concerns haven't been that the new language will close things off but rather that it will do so without sufficient remuneration for programmers who depend on the dynamic nature of the language today. A truly dynamic language (like ES3) gives you the ability to build up all the missing bits. When you get syntax for them, something is traded away and something is gained. My concerns here are all about cost/benefit. Giving us classes but killing AOP-style systems in the process isn't a good tradeoff given that nearly everything in a sizable JavaScript app is event driven. Allowing us to define constants without a way to determine ahead of time of assignment to a variable will create an error is crazy. Syntax that makes type annotations more mandatory (for performance or other reasons) than they would otherwise have a right to be is a terrible tradeoff in an environment where script length (in bytes) is a key bottleneck. A final keyword is a nutty semantic for browser-hosted scripting language to take on, particularly with such a simple and easy to misuse API (it should be an onnerous and intentional protocol, think seal()).

The Harmony announcement shows that TC39 is paying attention to the real-world dynamics of script authoring and not falling prey to old ideas about what can (or should) make JS go fast.

Regards

by alex at
I agree with your points, but I think one thing is missing: sometimes we do have concrete types in mind (e.g., a number, a string) for our algorithms when other logical types just don't make sense in some particular piece of code. Why don't we reflect it explicitly when we can? I don't want us to be sucked in OOP swamp, yet simple way to convey our intent to readers (and compiler) would be nice on many levels. Especially for basic types.

Right now I feel that "history repeats itself, first as tragedy, second as farce" (c) Karl Marx --- we started programming in essentially typeless assembler with bytes and words, invented countless programming languages, and now back programming with "vars" treating almost everything like dictionaries. And we invent ways to do structured comments in JavaScript annotating that this var is String, and that var is Number, and so on. :-) Let's admit that we are already annotating. Just not for the compiler.

So what you say is exactly what I meant when I wrote:
Classes are for ... managing complexity. Types are for saying something about code ... VMs are for speed.

Types are great in that they let us define the interface to something in a way that an interpreter or a compiler can help us enforce when such enforcement makes sense. Annotation, I think, is the right way to think about it: in a sense, we're saying something which we wish others to know by way of providing clarification. It's not key to getting the point if the person comes from the same "culture" of code, but when they don't, it is information that can be invaluable in discerning the landscape. That level of annotation is where I see big hopes for typing in an eventual ECMAScript.Next. It's a feature I want...just not one I want in the way that most people reflexively reach for types.

Regards

by alex at
@Eugene Lazutkin > Type annotation helps to convert generic dictionaries/objects to efficient native objects, e.g, register-based integers and floats.

Can, but non necessarily do, especially with JIT techniques: I've read an account that Strongtalk (a high-performance Smalltalk VM with optional type annotation) only uses the annotations for static type checking, it throws them out of the runtime and uses solely JIT. Likewise, the HotSpot JVM doesn't do much with its types, mostly it ignores them and optimizes the way a dynamic VM would (purely through JIT). In fact, the javac compiler is one of the stupidest compiler ever (which is quite annoying).

by Masklinn at