[Ometa] Python definition in OMeta
Alessandro Warth
alexwarth at gmail.com
Wed Jun 11 16:44:35 PDT 2008
Hi Dethe,
I spent some time today going through the javascript files for OMeta JS 2.0
> and I think I have a better handle on what's going on now.
>
Great... please e-mail any questions, comments, etc. on/about that code to
the list!
> There are a few comments about Javascript sucking,
heh heh :)
especially in lacking functions as first class objects. As far as I am
> aware, functions *are* first class objects. Could you elaborate on the
> problem(s) you encountered?
Sure, I'll explain.
At first glance, JavaScript seems to have a nice and simple object model in
which an object is just a dictionary that maps property names to values.
When you ask an object x for the value of property p (i.e., x.p) and the
object doesn't have a value for that property, the runtime automatically
asks the object's prototype (or parent), and so on. This is known as
delegation, and you can read more about it in this excellent paper by Henry
Lieberman<http://web.media.mit.edu/%7Elieber/Lieberary/OOP/Delegation/Deleg=
ation.html>
.
If you create an object x that delegates to y, x should behave
*exactly*like y. After that, if you want, you can specialize x's
behavior by assiging
values to some of its properties (in other words, overriding some of y's
properties).
All object-oriented programming in JavaScript is done using delegation. I'm
sure you've seen expressions like new Person(); to the implementation, this
means "create a new object that delegates to the prototypical Person, which
is stored in Person.prototype" (for completeness, after the new object is
created, the function's body is evaluated in an activation record (or
context) in which this is bound to it).
new is somewhat (arguably) convenient for pretending that JavaScript
supports classes, but it's really awkward to use if all you care about is
delegation. In that case, it makes sense to add a method to the Object
prototype (the parent of all objects) that creates a new object that
delegates to the receiver. In my own lib.js (used in OMeta/JS), this method
is called delegated. Here's a simplified version:
Object.prototype.delegated =3D function(props) {
var f =3D function() { }
f.prototype =3D this
return new f()
}
So far so good. We can do things like
x =3D {a: 1, b: 2}
y =3D x.delegated() // right now y's a is 1, and y's b is 2
y.a =3D 3 // and now y's a is 3, and y's b is 2
Now, everyone says that JavaScript is a language with first-class functions,
meaning that functions are full-blown objects. And at first glance, you
believe this. After all, they have properties, etc.
The problem is that if you create a new object that delegates to a function,
the new object is not a function! In other words, the following doesn't
work:
f =3D function(x) { return x + 1 }
g =3D f.delegated()
g(5)
So, as you can see, functions aren't as "objecty" as other objects in the
system. That's why I say they're not "first-class".
And unfortunately, there are other kinds of objects that are not quite
first-class, according to my definition. Arrays, for example. In JavaScript,
an array's length property is automatically updated whenever you assign into
it with an integer index. For example,
a =3D []
a.length =3D=3D=3D 0 // evaluates to true
a[5] =3D 1234
a.length =3D=3D=3D 6 // evaluates to true
(N.B., I'm not saying that this is the way I think arrays should work...
it's just the way they work in JS.)
Now, let's try the same with an object that delegates to an array:
a =3D []
b =3D a.delegated()
b.length =3D=3D=3D 0 // evaluates to true
b[5] =3D 1234
b.length =3D=3D=3D 6 // evaluates to false! (it's still 0)
I think you get the point, and this rant has gone on long enough. Here's the
bottom line:
(1) I really don't like that the programmer has to worry about these special
cases; it would be much nicer to free up that part of your brain to think
about the problem at hand.
(2) When you actually need to create an object that delegates to a function
or an array (as I have, in the OMeta/JS implementation), you end up having
to resort to awful kludges.
And that's why I said that it sucks.
Also on the global object not being a first class object. I don't know how
> Rhino handles the global namespace, but in the browser the "global" is ju=
st
> the window object, so for instance "var myobject =3D function(){}" is
> equivalent to "window.myobject =3D function(){}" is equivalent to
> "window['myobject'] =3D function(){}" is equivalent to "function
> myobject(){}". I suspect the problem here is that native (C or C++) obje=
cts
> in most (all?) implementations of Javascript do not have prototypes. This
> bites me most often when dealing with the DOM, where it would be really n=
ice
> to be able to extend, for instance, the Element object and have all DOM
> Elements have the new functionality, but it also applies to the Document,
> Window, and to things like embedded Flash or (in IE) ActiveX objects.
> Definitely not turtles all the way down ;-)
Exactly!
Cheers,
Alex
Thanks again for the helpful responses and this example code!
>
> --Dethe
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://vpri.org/pipermail/ometa/attachments/20080611/61dbc3b8/attachme=
nt-0001.htm
More information about the OMeta
mailing list