Did you try to do this (i.e. make properties read-only)? You hinted at a way (which does not work as is) and the spec is not clear and I can't get it to work (because [[Writable]] is an internal property).
I believe the appropriate method is:
15.2.3.6 Object.defineProperty ( O, P, Attributes )
This isn't supported by V8 (not ECMAScript 5), but will be supported by our compiler, thus, when we can bootstrap ourselves, we can take advantage of it.
You did not answer this important question: how will a *client* module know that mem is a namespace with read-only fields (thus enabling the compiler to perform direct jumps)?
There are many ways to achieve this. One is a naive analysis. Only one write to mem.foo + no evals + we trust our own code, means a single point of definition.
Another is to have the compiler detect patterns such as defineProperty(mem, "foo", {writable: false}) (I'm not sure of the actual syntax). We could even have a shorthand method to make attributes read-only in our compiler. defReadOnly(obj, field, val) or makeReadOnly(obj, field).
A third way is annotations. Have some JsDoc-style comment @readonly, or something, just above things we want to be read-only.
If it sorts by name then all the mem_xxx functions will be together. What's the problem?
It's still annoying to have to browse a huge file.
It is not an issue with mem_xxx. But with mem.xxx you will be calling methods in the mem object before the fields are made read-only. How will tachyon deal with such a case (a namespace being used in the middle of its initialization)?
mem.xxx = function() {} makeReadOnly(mem, "xxx");
// Use xxx after this point
This will cause problems with the static analysis. In other words, how will the compiler know which fields of the namespace object have been defined when the code reaches the call mem.xxx ? Also, where will the field "xxx" be in the mem object, after all we are incrementally adding fields to a hash-table, so the hash-table may have to be resized, which will move the fields around during the initialization. Not a good thing!
If we have some kind of mechanism to indicate that mem.xxx will not be redefined, any call to mem.xxx can be resolved to whatever mem.xxx points to at the point of the call.
That's true, but lets put things into perspective... We are talking about a single character in the "function name", either a "_" or a ".". This is not exactly a big change in style! On the other hand we can expect a factor of 2 speed difference between "_" and ".". That's significant.
1. We can easily make sure this speed difference does not occur in Tachyon.
2. We should not prematurely optimize. Performance is hardly an issue when we don't even have a remotely working compiler.
3. We aren't just talking about this one issue. There are plenty of other cases where I'm sure you'll advocate a more "old-school", procedural, C-like design. Using JavaScript this way takes us away from the main benefit of using JavsScript: simpler, more readable code.
The mem_xxx style is clearly more KISS than the mem.xxx style.
I disagree. JavaScript is an OOP language. Using an OOP language in the most procedural way possible because you're worried that our optimizations will be so weak they won't be able to inline such trivial cases, even when we can guarantee that our compilee *will* in fact optimize these cases (because we can force it to, *if needed*), clearly goes against the KISS principle.
*Premature optimization is also not KISS*... And this is clearly your main argument here, avoiding OOP/dynamic features as much as possible because you're worried about performance and want to constrain our design when we aren't remotely near the point where we can even run any benchmarks.
I say, let's write simple, organized code, using the sensible features of the language. There are some obvious compromises I'm willing to make (no eval, for example), but please, let us organize the code nicely and tidily, let us benefits from some of the most useful JavaScript features, and let us refactor for performance and/or add annotations to the Tachyon code only if/when performance issues surface.
- Maxime