views:

198

answers:

4

The question is from a language design perspective.

I should explain a little about the situation. I am working on a javascript variant which does not support prototypes, however it is overdue a decent type system (most importantly support for instanceof). The ecmascript spec is not important, so i have the freedom to implement something different and better suited.

In the variant:-

  • You do not declare constructors with function foo(), rather constructors are declared in template files, which means constructors exist in a namespace (detirmined by the path of the file)
  • Currently all inheritance of behaviour is done by applying templates which means all shared functions are copied to each individual object (there are no prototypes afterall).

Never having been a web developer, this puts me in the slightly bizarre position of never having used prototypes in anger. Though this hasn't stopped me having opinions on them.

My principal issues with the prototype model as i understand it are

  • unnecessary littering of object namespace, obj.prototype, obj.constructor (is this an immature objection, trying to retain ability to treat objects as maps, which perhaps they are not?)
  • ability to change shared behaviour at runtime seems unnecessary, when directly using an extra level of indirection would be more straight forward obj.shared.foo(). Particularly it is quite a big implementation headache
  • people do not seem to understand prototypes very well generally e.g. the distinction between a prototype and a constructor.

So to get around these my idea is to have a special operator constructorsof. Basically the principal is that each object has a list of constructors, which occasionally you will want access to.

var x = new com.acme.X();
com.acme.Y(x,[]);      // apply y

(constructorsof x) // [com.acme.Y,com.acme.X,Object];

x instanceof com.acme.X;   // true
x instanceof com.acme.Y;   // true

All feedback appreciated, I appreciate it maybe difficult to appreciate my POV as there is a lot i am trying to convey, but its an important decision and an expert opinion could be invaluable.

  • anything that can improve my understanding of the prototype model, the good and the bad.
  • thoughts on my proposal

thanks,

mike

edit: proposal hopefully makes sense now.

+4  A: 

Steve Yegge has written a good technical article about the prototype model.

MrValdez
Thanks, that was definitely quite enlightening
mike g
[sarcasm] If I get the enlightening badge, then I would know you were enlightened. ;) [/sarcasm] Anyways, good luck on your code. :D
MrValdez
A: 

It might just be easier to try a few things with practical code. Create the language with one simple syntax, whatever that is, and implement something in that language. Then, after a few iterations of refactoring, identify the features that are obstacles to reading and writing the code. Add, alter or remove what you need to improve the language. Do this a few times.

Be sure your test-code really exercises all parts of your language, even with some bits that really try to break it. Try to do everything wrong in your tests (as well as everything right)

TokenMacGuy
A: 

Reading up on "self", the language that pioneered the prototype model, will probably help you more than just thinking of it in terms of javascript (especially since you seem to associate that, as many do, with "web programming"). A few links to get you started:

http://selflanguage.org/
http://www.self-support.com/

Remember, those who fail to learn history are doomed to reimplement it.

MarkusQ
I absolutely don't think its web programming :P - given that i work with js outside of the browser. I have done some reading on self, and its only a 2nd hand conclusion, but i did read that its inheritance model seem tacked on or rushed, for what that is worth.
mike g
+1  A: 

I don't think your issues with the prototype model are valid:

  • unnecessary littering of object namespace, obj.prototype, obj.constructor

prototype is a property of the contructor function, not the object instance. Also, the problem isn't as bad as it sounds because of the [[DontEnum]] attribute, which unfortunately can't be set programatically. Some of the perceived problems would go away if you could.

is this an immature objection, trying to retain ability to treat objects as maps, which perhaps they are not?

There's no problem with using objects as maps as long as the keys are strings and you check hasOwnProperty().

  • ability to change shared behaviour at runtime seems unnecessary, when directly using an extra level of indirection would be more straight forward obj.shared.foo(). Particularly it is quite a big implementation headache

I don't see where the big implementation headache in implementning the prototype chain lies. In fact, I consider prototypical inheritance conceptually simpler than class-based inheritance, which doesn't offer any benefits in languages with late-binding.

  • people do not seem to understand prototypes very well generally e.g. the distinction between a prototype and a constructor.

People who only know class-based oo languages like Java and C++ don't understand JavaScript's inheritance system, news at 11.

In addition to MarkusQ's suggestions, you might also want to check out Io.

Christoph
Thanks, I appreciate the answers, wasn't aware of hasOwnProperty() and was unclear on the exact taxonomy w.r.t obj/constructor/prototype that you've cleared up. The need for hasOwnProperty() though does makes me think that prototypes are inherrently a bit messy, but thats the price you pay, i guess.
mike g