Re: Terms for method types?
- From: Joost Diepenmaat <joost@xxxxxxxxx>
- Date: Thu, 19 Jun 2008 01:25:59 +0200
To start off: I'm going to quote large sections here, because I think
this post won't make sense otherwise.
Anyway,
VK <schools_ring@xxxxxxxxx> writes:
On Jun 16, 3:55 pm, Joost Diepenmaat <jo...@xxxxxxxxx> wrote:
VK <schools_r...@xxxxxxxxx> writes:
This way I am thinking of unambiguous terms to denote in application
to Javascript the following types of methods:
1) The proposed term: "shared stateless". Functional similarity to
"static" in Java.
The most common type we are getting in say:
MyObject.prototype.method = function() {...}
As someone else already remarked; this is just basic prototype
inheritance.
And I am saying "thanks to everyone" for the enlightenment :-) Please
see my second post in this thread for clarifications. I don't care -
on this stage - about the exact inheritance mechanics, would it be:
function MyObject() {
// ...
}
MyObject.prototype.myMethod = function() {
// ...
}
var myInstance = new MyObject;
or
package MyClass;
sub new { bless( {}, shift ) }
sub myMethod {
# ...
}
package main;
$myInstance = MyClass->new();
or
public class MyClass {
public static void myMethod() {
// ...
}
}
myInstance = new MyClass();
or any other from the legion of implementations of the core idea "N
instances - one shared method". They all have different syntax,
internal representation and behavioral details, but it is still the
same idea. Just like the presence of "I go", "Je vais", "Ich gehe"
etc. doesn't deny the presence of the idea of the doer and the action.
I see what you're saying, but I don't agree it's the right way to go
about explaining inheritance in JS. I'll get to that general point at
the end of this post.
The method will indeed be shared by objects that share
that prototype, but wether or not that method maintains state(s)
depends on its definition
That is more interesting. Can you provide a sample from a programming
language with a single shared (Java-static) method preserving call
state(s) for individual instances?
First off, I was talking about javascript, not java. It's very easy to
do this in JS, and AFIAK not at all possible in java (I don't know
enough about java introspection to rule it out completely). How about
this (perl) example:
my %params;
sub semi_static_method {
my ($class,$param) = @_;
$params{$class} = $param;
}
Note that the $class variable has a deliberately misleading name.
(remember
*ALL* functions can access /some/ "this" object, no matter how you
call them).
Of course for Javascript - because here functions are first-class
objects. Yet we are talking about OOP, and
myInstance = new MyClass();
var foo = myInstance.myMethod;
foo();
and similar has no relation to OOP: it is just a pointless hack
syntactically allowed due to the intentionally flexible nature of
Javascript.
It's not pointless exactly. The interpretation of "this" in JS
functions/methods and the how/if inheritance is resolved is completely
defined by how the function/method is called. IMO trying to push a
class/instance view of the OO world is misleading at best.
What we are interested in is OOP domain and the concept "N instances -
one shared method".
"shared stateless" to be exact but you have mentioned the possibility
of "shared state preserving" and I would like to see a possible
implementation of it.
See above. Also, you didn't make it at all clear that you meant
per-object state and not per-class state; per-class state is easy in
most langauges. And then there are closures.
function MyObject() {
this.method = MyObject.method;
}
MyObject.method = function() {...}
This copies references around instead of sharing them, so it's not the
same thing at all and I would consider it a variant of the "own XXX"
examples below.
I say that you are making two errors here: one semantical and other
technical. The semantical one is that two different things do not
necessary mean two different concepts, just like "I go" and "Je vais"
do not. You don't say that "but they are doing all different things!
This one _goes_, other one _va_" :-)
I just don't see the point of doing this at all, unless some objects
constructed using this function do have different methods. The only
other explanation is that you're micro-optimizing for method calls.
The technical error is that of course just like with the prototype
chain we are having here one single method instance shared among all
object instances. You may check it by say:
function MyObject() {
this.shared = MyObject.shared;
this.own1 = new Function;
/* closure prone, but to be complete: */
this.own2 = function(){};
}
MyObject.shared = function(){};
var a = new MyObject;
var b = new MyObject;
window.alert(a.shared === b.shared); // true
window.alert(a.own1 === b.own1); // false
window.alert(a.own2 === b.own2); // false
Yeah I know. So why not put the method in the prototype. At the very
least it will reduce the amount of code, and will make instantiation
objects cheaper.
2) The proposed term: "own stateless"
Being created as a separate entity for each object instance
function MyObject() {
this.method = new Function(args, body);
}
Ok; create a new function object. Is there any reason you're not a
function() {} expression instead of the "eval pretending to be
something else" new Function construct?
Yes. Read the definition: "own _stateless_". In the particular
application to Javascript it means that for N object instances N
method clones are created: but each clone does not create a closure
over it so it doesn't keep in-between-calls state.
Unless the body uses "this", of course.
In my second post
in this thread I mentioned that I was planning to use this type of
method for criticism only, though in some particular cases such type
of method might be useful.
To fully answer to your question I am going to illustrate the regular
path of how an average not fully influenced in Javascript programmer
arrives to this type of method.
So taking an average John Doe who just learned that
function a() {
}
function b() {
}
is absolutely lame and that everyone from San Francisco to Tokyo over
Europe is already being cool :-) by doing
function a() {
function b() {
}
}
or
function a() {
this.m = function() {};
}
and other similar cool things which is not a shame to show to your
girl. Does John Doe want to be a loser and see his girl leaving him
for a guy doing nested function? Surely not. :-)
I'm sure I don't know what you mean. :-)
function MyObject(data) {
// do with data
// set other members
this.method = function(){};
}
var myInstance = new MyObject("a lot of data");
Now the question is what happened with "a lot of data" after the last
statement? Contrary to the common believe it did not get garbage
collected even if "a lot of data" was a literal or a function return
value or even a variable explicitly set to null after being used.
There's not much point in collecting literals.
By using the nested function expression we have created a closure for
the entire context of MyObject as it was at the end of each particular
call - and we have created as many of such closures as the amount of
object instances. Each MyObject instance will have its own copy of "a
lot of data" moreover retained by two references: by named argument
"data" and by automatically created arguments[0].
I'd have to re-read the treadment of literal strings in the specs
again to be sure about this case, but I'm quite sure that passing an
object literal doesn't necessarily mean it gets copied. In fact, a
reasonably smart compiler/interpreter should see that no variables are
captured by your function(){} "closure" just by static
analysis. That's one of good points of lexical scoping.
Here is the point
where "my memory is leaking on IE!" complains are coming. It is funny
that from my observations the complains are always targeted to IE even
if the testing was done under Firefox or another browser: as if IE had
some evil power to suck the memory out remotely from all other
rivals. :-)
Browsers suck. IE is just the most feckless of all the current
browsers. FTR, today's firefox 3 sucks ass too.
In this aspect "own stateless" method we started with allows to keep
method assignment within the constructor, to clone it for each
instance yet allows to avoid closures unless they are expected and
needed by the programming logic. One of simplest ways is to use
Function constructor instead of assigning function expression though
there are other ways.
function MyObject(data) {
// do with data
// set other members
this.method = new Function(args, code);
}
new Function(...) is one of the most expensive calls in all of JS. And
as I hinted above, it's completely useless unless you really *need*
eval() like construct. This does not all look like such a situation.
var myInstance = new MyObject("a lot of data");
Again, this function may or may not have state; there's no way to tell.
Right the opposite as I explained, it is very easy to tell:
this.method = new Function(args, code);
will not have state in any case unless a secondary function
augmentation which is kind of out of subject right now, and
this.method = function(){};
what about
code = "this.bla = arguments[0]";
*snipped stuff I just don't get or disagree with*
I think you're overthinking. There is only 1 thing to consider here;
where in the prototype chain the method/property is placed. This stuff
really only gets interesting when you've got more than one level of
inheritance and "instances" at different levels.
I do not agree here. Before going to prototypes, classes, their
differences and possible usage some more generic entities have to be
set and understood. Just like before learning a language it is most
useful to learn the alphabet and the distinction between different
parts of speech. IMO.
But prototypes are much *simpler* than classes and instances. AFAICT
you're pushing your java-like view of OO onto JS and it isn't a good
match. Most of OO is about instance methods, and for instance methods,
JS's prototype inheritance is simpler to explain and understand even
though it's more flexible. The issues mostly come in when with
inherited class methods, and
1) you don't really need them that often
2) they're actually relatively simple once you get a proper view of
prototypical inheritcance.
Also, classes are just performance "hacks" based on prototype
inheritance. See for a pretty good example, Paul Graham's "ANSI Common
Lisp" chapter 17, which builds a complete class/instance OO system out
of functions and structs via prototype inheritance. That's not to say
that explicit classes don't have documentation value, by the way.
--
Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
.
- Follow-Ups:
- Re: Terms for method types?
- From: VK
- Re: Terms for method types?
- From: RobG
- Re: Terms for method types?
- References:
- Terms for method types?
- From: VK
- Re: Terms for method types?
- From: Joost Diepenmaat
- Re: Terms for method types?
- From: VK
- Terms for method types?
- Prev by Date: FAQ Topic - How can I prevent access to a web page by using javascript? (2008-06-19)
- Next by Date: Re: Date in Opera 9.50
- Previous by thread: Re: Terms for method types?
- Next by thread: Re: Terms for method types?
- Index(es):
Relevant Pages
|