Look Ma, no "this" (was: ECMAScript Harmony)

Peter Michaux petermichaux at gmail.com
Mon Aug 25 16:57:14 PDT 2008


On Mon, Aug 25, 2008 at 2:01 PM, Brendan Eich <brendan at mozilla.org> wrote:
> On Aug 25, 2008, at 12:23 PM, Peter Michaux wrote:

> > Now there is another problem: differentiating between which
> > variables are local to the constructor function (that is,
> > transient and garbage collected after the constructor function
> > is returned (don't know the
> > technical name for these variables))
>
> Temporaries.
>
> > and which are properties of the
> > resulting returned object.
>
> True temporaries might need explicit block scope to avoid being
> entrained in closures.
>
> > Requiring the programmer to use both "public" and "private" as I
> > did below might be a solution (though you thought it is
> > verbose) so that it is clear which variables are part of the
> > constructed objects.
>
> But the private vars would not be temporary.

Correct. Even the temporaries might not be temporary due to closures
(see below.)

> They would need to live as long as the instance.
> It seems to me you're mixing lifetime with visibility.

I don't think I am (too) confused. This is the very issue I was trying
to raise or muddle through in my mind.

There needs to be a way(s) to distinguish which variables have which
lifetimes and visibilities.

The following is no good

class Foo() {
  var temp = 0;
  var priv = 1;
  var pub  = 2;
}

It could be

class Foo() {
  var     temp = 0;
  private priv = 1;
  public  pub  = 2;
}

In the above example, "temp" will be garbage collected and there is no
use in the private "priv" variable and it could be garbage collected
too.

The situation changes when a public method exists.

class Foo() {
  var     temp = 0;
  private priv = 1;
  public  pub  = function() temp + priv;
}

Now "temp" is captured in the closure of "pub" and so "temp" is
effectively instance-private. So the "private" keyword isn't necessary
at least in terms of lifetime as the following is the same.

class Foo() {
  var    temp = 0;
  var    priv = 1;
  public pub  = function() temp + priv;
}

This last example, no "private" keyword, works if instance-private is
desired. If class-private is desired (I hope not! as I explained
before) then the second to last example above would be required. In
which case "var" works like Ruby's "private" (instance-private),
"private" works like Ruby's "protected" (class-private) and "public"
is like everyone's "public".

So the issue may not be choosing between instance-private *or*
class-private. JavaScript will have instance-private thanks to
closures. The question becomes is class-private also desirable, worth
the extra keyword and complexity both to learn and to debug?

I favor the last example above, with no class-private, and now my gut
feeling that private-by-default is natural for JavaScript has some
concrete support.


> > No one seemed to response to my post in the thread about
> > modules but "module" should not equal "file" as HTTP is
> > still expensive and programmers want to concatenate and
> > minify their scripts.
>
> Oh, absolutely. I made the point in several posts, and Ibad picked up on it:
> addressing and loading are outside the core language. The inside part that's
> left is about how the importer names (or does not name) the module, how the
> module provides what the importer requires, how eagerly "linking" occurs,
> whether cycles are allowed (better be!), etc.
> The upshot is that stuff has to be loaded already. You can't block a script
> mid-evaluation and go service events (violating run-to-completion or else
> locking up some or all UI) to load a remote file on demand.


I think the ability to have two modules in one file means modules will
need to name themselves. That is they will need to be declared with a
name like

module foo {
  // ...
}

or

var foo = module {
  // ...
};

The importer could rename things but somehow the importer will have to
use the name "foo" to at least start importing.

By cycles you mean module A using module B which uses module A? Late
"linking" would required to allow cycles, correct? Also perhaps the
"foo" variable may reference different module objects at different
times.

> > The only unfortunate thing about "function" is they are not really
> > functions.
>
> Ok, I will bite: what are they?

Now I regret that statement because I'm in a room full of far more
qualified people than I to argue about programming language
terminology semantics. I won't chicken out though:

I'd say they are procedures because they carry out a series of steps
(a process). A function wouldn't have implicit arguments (i.e.
"this"), automatic variables (i.e. "arguments"), or be able to cause
side effects. This is why the word "function" has needed to be
fortified to "pure function" to mean "a function and we really mean an
actual function that take input and produces output without causing
any chaos in the mean time." Just to be clear, I'm not a pure
functional enthusiast. I don't understand "monads" when a simple
"print" will do just fine.

Now I will try to duck the many punches I probably deserve.


> > > Another separable point to debate: resolved, classes should
> > > freely nest (in other classes and functions) and generate
> > > new entities each time they are evaluated. Just like
> > > functions (ignoring or removing the joined function
> > > object option from ES3).
>
> > Great!
>
> I phrased this as a proposition to debate pro or con. I didn't mean to say
> it was resolved (but I hope it will be, in Harmony).

If "class" is desugaring to a constructor function then I'd hope
everyone agrees.


> > > There are deeper waters to do with types,
>
> > Yes. The parent-child windows issue both declaring the same or
> > different "class Foo" seems like an important detail. Perhaps
> > provably making nominal types useless or at least as awkward
> > as instanceof?
>
> No, nominal types have their uses. In two disjoint globals, loading code
> defining the same nominal type should result in two types, not one -- we
> don't want to trust the name, or compare the contents.

I agree they would have to be two types. I'm not very interested in
types and type checking but I don't think we want to have a situation
where people are checking if something is an array by looking for the
existence of an "obj.splice" property. Ugg that is gnarly.

> The name would simply
> be qualified by some kind of global identifier or pathname.
> Nominal type use-cases for security, which I've mentioned before, include
> auditors (http://www.erights.org/elang/kernel/auditors/) and hybrid
> information flow systems
> (http://www.ics.uci.edu/~franz/Site/pubs-pdf/C46Prepub.pdf, see figure 3).
> When you need type relations and equivalence based on name bound by special
> form, it's hard to do without. As Mark pointed out in Oslo, nominal types
> plus lexical scope let human and machine auditors know *exactly* what
> implementation(s) a class has.
> One can make nominal types via branding in a structural type system. There's
> more to say here, later.

I'll have to read up...or do some work. Hmmm?

Peter


More information about the Es-discuss mailing list