mem.xxx = function() {} makeReadOnly(mem, "xxx");
// Use xxx after this point
And you argue that this is simpler than the mem_xxx naming scheme? If programmers have to type it, it clearly isn't. If the compiler takes care of it, it introduces complexity in the compiler that shouldn't be there.
As I've been arguing, I don't think that we should even be making those fields read only for now. That would be a fallback if our compiler can't optimize the code, if we establish that we somehow can't inline some functions and that is a performance issue. I suggest writing simple code and seeing how things go.
Granted, we can introduce mechanisms to address this problem, but at a cost in terms of "clean" design, as I argued above.
Please also note: for bootstrapping, it might be useful to do things of this sort:
for (name in namespace) if (name isinstance Function()) copyFunctionIntoBootStrapCode()
Do you think Mark's solution of recognizing prefixes in compiler function names is cleaner than what I propose?
As Marc said many times, we could always switch to using namespaces later if we really want to. It would be very easy to automate the conversion.
But the reverse argument holds too. We could go from . to _ with scripts as well.
There's a difference between OO code and your namespace proposal. The namespaces are not objects per say, they don't represent the same abstractions objects normally do. There are no brownie points for using this so-called object syntax in arbitrary situations.
My proposal allows to treat namespaces as objects (which they are), and to have nested namespaces. This is useful if we ever need to enforce properties for code in a given namespace. Mark has made the argument before that we should avoid the object method notation x.foo(v) and use global methods someclass_foo(x, v) whenever possible, again, for "performance" reasons. I feel that he wants us to adopt avoid many JS features that would be helpful for productivity, thereby negating alot of the benefits of doing this in a dynamic language to begin with. Don't forget I wanted to write this VM in C++ at the start. Performance is one of my main concerns too, but not in this case. Here, I say productivity first.
Moreover, there's also a difference between believing that tachyon will eventually be able to optimize such code and completely eliminate the performance hit, and placing ourselves voluntarily in a situation where we have to do it before tachyon can be really useful.
I'm not sure what Mark even believes in terms of performance anyways. I gave a system to *guarantee* non-rewritability and inlining *if needed*, he thinks we should stick to global methods why? Because "simple analyses" will automatically guarantee inlining of global methods? Please consider:
d8> function foo() { return 2; } d8> foo() 2 d8> function getglob() { return this; } d8> g = getglob() [object global] d8> g["f" + "o" + "o"] = 3 3 d8> foo(2) Uncaught: "TypeError: Property 'foo' of object [object global] is not a function", (d8) line 1 column 1 foo(2)
The performance guarantees mark seems to imply are potentially illusory (see example above) and based on a premature worry about performance (there may well be no cost with proper optimizations in place). Hacks will be needed to prevent method redefinition at the global scope without ECMAScript 5 annotations as I suggested before.
There are other features of the language that we will avoid using for similar reasons, I don't see this one as being special in any way.
Some features, like eval, are notoriously hard to optimize unnecessary almost all the time, and should definitely be avoided. Others, like classes, methods on objects, etc., are just convenient OOP practices.
That being said, if you have really compelling arguments in favour of
namespaces, I'll gladly reconsider my position.
1. It's the common JavaScript way. 2. Nested namespaces are possible. 3, No need for namespace prefix hacks. We have an implicit list of the members of each namespace on which we can iterate. 4. Read-only flag can be set if ever needed, where needed. 5. Nobody will want to switch to namespaces a year from now, with a large codebase. Programmer lazyness will prevent it from happening. 6. Performance is something we should mostly worry about in terms of how we design the VM's optimizations, IR, stack frame and object layout, etc. Not in terms of premature optimizations that impair productivity.
Hence, we could just do it the JavaScript way, and change it later *if it doesn't work well*, instead of imposing ourselves constraints based on nearsighted fear.
- Maxime