Simulating protected inheritance and function member var questions.

319 views
Skip to first unread message

Rhys van der Waerden

unread,
May 18, 2012, 10:49:34 PM5/18/12
to General Dart Discussion
Hi,
I have a couple of questions regarding function members and also my
approach to this problem. What I'm trying to do here is simulate
protected inheritance, so that I my library may allow an external
class to inherit and override private functionality. I achieve this by
passing the function as an argument to the base constructor and
assigning it to a private function variable.
Here is my code example:

/* ---- child.dart ---- */
#library('child');
#import('other.dart');

void main() {
Child child = new Child();
child.talk();
}

class Child extends Other {
Child() : super.withSpeech(() => "child says hello");
}


/* ---- other.dart ---- */

#library('other');
#import('dart:core');

class Other {
// (B):
Function _speech;

// (A):
//Other() : _speech = () => "other says hello";
Other.withSpeech(Function speech) : _speech = speech;

void talk() => print(_speech());
}


This seems like a nice way to get around the lack of protected
inheritance between packages.
My questions:
* Is this an idiomatic/good pattern for simulating protected
inheritance?

* Why do I get the error " Unexpected token ')' " on the line marked
(A) above? Are function literals not allowed as initializers?

* And this is the one I'm most interested in - how do I enforce
return type and arguments on the function member variable? In my
example the function signature is 'String _speech()'. If I replace the
line (marked (B)) with this signature I get a syntax error: 'A non-
abstract method must have a body'. This error makes sense, of course -
but is there a way to do this?

Ladislav Thon

unread,
May 19, 2012, 12:08:16 PM5/19/12
to Rhys van der Waerden, General Dart Discussion
Hi,

class Other {
 // (B):
 Function _speech;
}

 * And this is the one I'm most interested in - how do I enforce
return type and arguments on the function member variable? In my
example the function signature is 'String _speech()'. If I replace the
line (marked (B)) with this signature I get a syntax error: 'A non-
abstract method must have a body'. This error makes sense, of course -
but is there a way to do this?

you can't really enforce anything, since Dart is fundamentally dynamically typed, but other than that, your problem comes from the fact that Dart uses the same syntax for function types and function values. And if I understand correctly, that was the ultimate reason for adding typedefs.

So you can't write

class Other {
  String _speech();
}

but you can write

typedef String SpeechFunction();

class Other {
  SpeechFunction _speech;
}


I'm not sure about your problem with (A), and with regards to protected inheritance, I would just say that inheritance a terrible idea anyway :-) Hope that I helped at least with (B).

LT

Florian Loitsch

unread,
May 19, 2012, 2:06:19 PM5/19/12
to Ladislav Thon, Rhys van der Waerden, General Dart Discussion
Wrt to (A):
The reason you get this warning is to avoid infinite look-ahead. Take for example:
1) A() : f = (foo) { ... };
2) A() : f = (foo) { ... }
In this case one would need to look at the very last character (";") of (1) to know that f is assigned with a closure and not just with "foo" as is the case in (2).
Could be that there are even cases with ambiguities (where even infinite look-ahead is not enough), but I don't see any right now. I could ask the parser guys, though.

In any case: if you want to assign a closure you need to wrap it in parenthesis.

That said: dart2js does not implement closures in initializer lists. Furthermore you would not be allowed to access 'this' there. Otherwise you could circumvent the restriction that 'this' is not available in the initializer list as follows:
A() : x = (() => this.y)();  // where the closure is invoked right away.

Also note that there is a push to disallow closures in initializer lists all together (for the mentioned reasons).

As a consequence I would just assign the member inside the constructor body and not in the initializer list.

// florian
 

LT



--
Give a man a fire and he's warm for the whole day,
but set fire to him and he's warm for the rest of his life. - Terry Pratchett

Bob Nystrom

unread,
May 21, 2012, 12:07:15 PM5/21/12
to Rhys van der Waerden, General Dart Discussion
On Fri, May 18, 2012 at 7:49 PM, Rhys van der Waerden <rhys...@gmail.com> wrote:
My questions:
 * Is this an idiomatic/good pattern for simulating protected
inheritance?

Not that I'm aware of. Your pattern is probably about the best you can do.

As far as idiomatic goes, I think our current style is to just make them public and mention in the documentation that it shouldn't be called directly. I think this is more or less the approach other dynamic languages take.

I like the simplicity of not having protected, but if I'm wearing my framework designer hat, I definitely find the lack of it frustrating here. Many classes, especially in frameworks, have two entirely distinct APIs that they expose: one for all users of the class, and one for subclasses. Dart doesn't let you easily distinguish those.

- bob

Ladislav Thon

unread,
May 21, 2012, 12:35:34 PM5/21/12
to Bob Nystrom, Rhys van der Waerden, General Dart Discussion
I like the simplicity of not having protected, but if I'm wearing my framework designer hat, I definitely find the lack of it frustrating here. Many classes, especially in frameworks, have two entirely distinct APIs that they expose: one for all users of the class, and one for subclasses. Dart doesn't let you easily distinguish those.

And the problem doesn't lie in the language, but in those frameworks. Such classes should be split into two -- one providing the API and one providing the SPI.

Seriously, Dart's library-scoped privacy is great and I would hate to lose it for useless class-scoped privacy crap.

LT

Bob Nystrom

unread,
May 21, 2012, 12:46:41 PM5/21/12
to Ladislav Thon, Rhys van der Waerden, General Dart Discussion
On Mon, May 21, 2012 at 9:35 AM, Ladislav Thon <lad...@gmail.com> wrote:
I like the simplicity of not having protected, but if I'm wearing my framework designer hat, I definitely find the lack of it frustrating here. Many classes, especially in frameworks, have two entirely distinct APIs that they expose: one for all users of the class, and one for subclasses. Dart doesn't let you easily distinguish those.

And the problem doesn't lie in the language, but in those frameworks. Such classes should be split into two -- one providing the API and one providing the SPI.

I'm not a huge fan of inheritance, but I find it does work well for some things, especially UI frameworks. Can you show an example of how you could split classes in two like that? Start with something like:

class Widget {
  void add(Widget child) {
    children.add(child);
    child.render();
  }

  // Protected.
  void render() {}

  List<Widget> _children;
}

I can come up with ways to split that up using some combination of separate libraries, interfaces, and default classes, but it adds a ton of complexity. Do you have something better in mind?


Seriously, Dart's library-scoped privacy is great and I would hate to lose it for useless class-scoped privacy crap.

Right. I think most of us <3 library privacy and we wouldn't want to lose that.

- bob

Peter Ahé

unread,
May 21, 2012, 1:06:35 PM5/21/12
to Bob Nystrom, Ladislav Thon, Rhys van der Waerden, General Dart Discussion
On Mon, May 21, 2012 at 6:46 PM, Bob Nystrom <rnys...@google.com> wrote:
>
>
> On Mon, May 21, 2012 at 9:35 AM, Ladislav Thon <lad...@gmail.com> wrote:
>>>
>>> I like the simplicity of not having protected, but if I'm wearing my
>>> framework designer hat, I definitely find the lack of it frustrating here.
>>> Many classes, especially in frameworks, have two entirely distinct APIs that
>>> they expose: one for all users of the class, and one for subclasses. Dart
>>> doesn't let you easily distinguish those.
>>
>>
>> And the problem doesn't lie in the language, but in those frameworks. Such
>> classes should be split into two -- one providing the API and one providing
>> the SPI.
>
>
> I'm not a huge fan of inheritance, but I find it does work well for some
> things, especially UI frameworks. Can you show an example of how you could
> split classes in two like that? Start with something like:
>
> class Widget {
>   void add(Widget child) {
>     children.add(child);
>     child.render();

You assume protected access as known from Java and C#. This is based
on static types and doesn't work well in a dynamic language. One
approximation of protected access is when the compiler can tell
statically that you're calling a protected method on this, such as:

this.render(); // Explicit this.
render(); // Implicit this.

This wouldn't work:

var self = someMethodThatReturnsThis();
self.render(); // Not a send to this.

The problem is similar to why dynamic languages have object-based
privacy instead of class-based privacy. You need some way to
distinguish the call of a restricted method from a regular method
calls. This is what the _ in package privacy does.

You could add something like protected if you, for example, said that
all methods starting with __ get a unique name based on the current
class. This would work just as well as package privacy (aka library
privacy) and make it hard to create mocks, so I'm not a big fan of
this idea.

Cheers,
Peter

Ladislav Thon

unread,
May 21, 2012, 1:16:50 PM5/21/12
to Bob Nystrom, Rhys van der Waerden, General Dart Discussion
I'm not a huge fan of inheritance, but I find it does work well for some things, especially UI frameworks.

Oh, you are right with UI. Inheritance works just fine there, widget hierarchy corresponds nicely to class hierarchy (but one sometimes pray for multiple inheritance, heh).

I didn't think about UI when I was making that categorical statement, as I don't work with UI much. You could invent something like "widget renderer", but I'm not sure if it would work well. But in general, I think that it's good enough to separate API from SPI and let them both be public, enforcing privacy doesn't add much (I can even imagine someone writing his own widget renderer for stuff like checkboxes and other form elements).

LT

Christopher Wright

unread,
May 21, 2012, 2:14:22 PM5/21/12
to Peter Ahé, Bob Nystrom, Ladislav Thon, Rhys van der Waerden, General Dart Discussion
On 21 May 2012 17:06, Peter Ahé <a...@google.com> wrote:
You assume protected access as known from Java and C#. This is based
on static types and doesn't work well in a dynamic language. One
approximation of protected access is when the compiler can tell
statically that you're calling a protected method on this, such as:

this.render(); // Explicit this.
render(); // Implicit this.

This wouldn't work:

var self = someMethodThatReturnsThis();
self.render(); // Not a send to this.

The problem is similar to why dynamic languages have object-based
privacy instead of class-based privacy. You need some way to
distinguish the call of a restricted method from a regular method
calls. This is what the _ in package privacy does.

I'm curious about how that's implemented. It seems like this is a case where you need an intrusive runtime, or you have to accept type annotations having an impact beyond type checking.

Specifically, either the compiler can do static type analysis to determine that you are dealing with a type in the same library, and then allow or disallow the method call; or it can leave this to the runtime, which will have to record in each function the identity of the library in which it was defined, and check that against the runtime type information for the object it's making the call against.

I suppose you could implement both, and then you'll get a speed boost when you use more type annotations.

Though considering your further comments, it looks like name mangling came to the rescue...you rewrite a leading underscore in a method name to something including the name of the library. You end up looking for a method, say, '$myAwesomeApplication$coolFunction', when the type defines '$myTotallyRadLibrary$coolFunction'.

You could add something like protected if you, for example, said that
all methods starting with __ get a unique name based on the current
class. This would work just as well as package privacy (aka library
privacy) and make it hard to create mocks, so I'm not a big fan of
this idea.

The general consensus that I've seen is, if you get to the point where mocking part of a class seems like a good idea, you're in trouble.

Peter Ahé

unread,
May 21, 2012, 2:36:34 PM5/21/12
to Christopher Wright, Bob Nystrom, Ladislav Thon, Rhys van der Waerden, General Dart Discussion


On Monday, May 21, 2012, Christopher Wright wrote:
On 21 May 2012 17:06, Peter Ahé <a...@google.com> wrote:
You assume protected access as known from Java and C#. This is based
on static types and doesn't work well in a dynamic language. One
approximation of protected access is when the compiler can tell
statically that you're calling a protected method on this, such as:

this.render(); // Explicit this.
render(); // Implicit this.

This wouldn't work:

var self = someMethodThatReturnsThis();
self.render(); // Not a send to this.

The problem is similar to why dynamic languages have object-based
privacy instead of class-based privacy. You need some way to
distinguish the call of a restricted method from a regular method
calls. This is what the _ in package privacy does.

I'm curious about how that's implemented. It seems like this is a case where you need an intrusive runtime, or you have to accept type annotations having an impact beyond type checking.

Specifically, either the compiler can do static type analysis to determine that you are dealing with a type in the same library, and then allow or disallow the method call; or it can leave this to the runtime, which will have to record in each function the identity of the library in which it was defined, and check that against the runtime type information for the object it's making the call against.

I suppose you could implement both, and then you'll get a speed boost when you use more type annotations.

Though considering your further comments, it looks like name mangling came to the rescue...you rewrite a leading underscore in a method name to something including the name of the library. You end up looking for a method, say, '$myAwesomeApplication$coolFunction', when the type defines '$myTotallyRadLibrary$coolFunction'.

Precisely. You can see this in effect if you look at the output from dart2js.
 
You could add something like protected if you, for example, said that
all methods starting with __ get a unique name based on the current
class. This would work just as well as package privacy (aka library
privacy) and make it hard to create mocks, so I'm not a big fan of
this idea.

The general consensus that I've seen is, if you get to the point where mocking part of a class seems like a good idea, you're in trouble.

Generally, I assume you get into trouble after a few years. If you have a lot of resources and can modify all the sources of your app, abstract data types are great. But when that is not the case, you need a flexible dynamic underlying platform that lets you bypass encapsulation.

Cheers,
Peter 

Josh Gargus

unread,
May 21, 2012, 2:38:21 PM5/21/12
to Peter Ahé, Bob Nystrom, Ladislav Thon, Rhys van der Waerden, General Dart Discussion
On Mon May 21 10:06:35 GMT-700 2012, Peter Ahé <a...@google.com> wrote: 
The problem is similar to why dynamic languages have object-based
privacy instead of class-based privacy. You need some way to
distinguish the call of a restricted method from a regular method
calls. This is what the _ in package privacy does.

Interesting discussion.

Is "object-based" the standard terminology to differentiate eg: Smalltalk's concept of protected (any instance may access any superclass method/field within that same instance) from eg: Java's concept of protected (any instance  can access protected superclass methods/fields of any instance that shares that superclass)?  I'll use it as such...

I think it's interesting to consider the pros and cons of having both notions of privacy.

I grew up with object-based privacy, and it seems to more naturally support the object-capability security model: in Java, you end up making things more things private than you want so that you can avoid subclasses accessing things that they shouldn't in other instances.  This is applies not only to ocap security, but also to framework design.

On the other hand, I've come to appreciate Dart's library privacy (which is the same as Java's "package" privacy, etc.)... it allows me to write some code more clearly/concisely than if object-based privacy were enforced.

It seems like a good balance would be object-based inheritance of protected fields from a different library, and library wide-access within the library.

One concern I have is what syntax to use for this concept, and another is the additional burden for the programmer to reason about it.

However, it occurs to me that both concerns can be addressed by using the current syntax for both: any field with an underscore can be accessed from anywhere within the library, as well as from subclasses defined outside the library (but only within the same object... no touching other objects' privates).  There may be some flexibility lost by not making these concepts orthogonal, but it seems like this would support most use-cases, and is quite simple.

Thoughts?

Cheers,
Josh

Ross Smith

unread,
May 21, 2012, 2:45:44 PM5/21/12
to General Dart Discussion
> Can you show an example of how you could
> split classes in two like that? Start with something like:
> class Widget {
>  void add(Widget child) {
>    children.add(child);
>    child.render();
>  }
>  // Protected.
>  void render() {}
>  List<Widget> _children;
>}

Well, just for fun, what if Widgets were always just Widgets, but were
observed by a Renderable context?

class Widget<C extends Renderable> {
final List<Widget> _children;
final C _context;
final Event rendering;

Widget(this._context)
: _children = new List<Widget>()
, rendering = new Event() {
rendering.observe(() => _context.render);
}

void add(Widget child) {
_children.add(child);
}

void render() {
rendering.raise();
for(Widget child in _children) {
child.render();
}
}
}

On May 21, 12:46 pm, Bob Nystrom <rnyst...@google.com> wrote:

Gilad Bracha

unread,
May 21, 2012, 2:53:38 PM5/21/12
to Josh Gargus, Peter Ahé, Bob Nystrom, Ladislav Thon, Rhys van der Waerden, General Dart Discussion
On Mon, May 21, 2012 at 11:38 AM, Josh Gargus <jj...@google.com> wrote:



On Mon May 21 10:06:35 GMT-700 2012, Peter Ahé <a...@google.com> wrote: 
The problem is similar to why dynamic languages have object-based
privacy instead of class-based privacy. You need some way to
distinguish the call of a restricted method from a regular method
calls. This is what the _ in package privacy does.

Interesting discussion.

Is "object-based" the standard terminology to differentiate eg: Smalltalk's concept of protected (any instance may access any superclass method/field within that same instance) from eg: Java's concept of protected (any instance  can access protected superclass methods/fields of any instance that shares that superclass)?  I'll use it as such...

Tobe extra-finicky: Object based privacy means that the only privileged access to an object is by the object itself. That is more general than the specific rules of Smalltalk, but it does fit with the rules for instance variable access in Smalltalk (which can be viewed as "protected").  Class-based privacy is the model used in many statically typed languages, whereby privileged access is based on the classes involved. Again, this extends beyond protected (Java private is also class based). Java protected access also involves the packages involved.  I'd characterize Dart's privacy as library-based, as neither the class nor the object really matter here.

I think it's interesting to consider the pros and cons of having both notions of privacy.

I grew up with object-based privacy, and it seems to more naturally support the object-capability security model: in Java, you end up making things more things private than you want so that you can avoid subclasses accessing things that they shouldn't in other instances.  This is applies not only to ocap security, but also to framework design.

Yes.
 

On the other hand, I've come to appreciate Dart's library privacy (which is the same as Java's "package" privacy, etc.)... it allows me to write some code more clearly/concisely than if object-based privacy were enforced.

Object privacy is a strict discipline which requires very careful design.  It is more challenging to work with.

It seems like a good balance would be object-based inheritance of protected fields from a different library, and library wide-access within the library.

One concern I have is what syntax to use for this concept, and another is the additional burden for the programmer to reason about it.

However, it occurs to me that both concerns can be addressed by using the current syntax for both: any field with an underscore can be accessed from anywhere within the library, as well as from subclasses defined outside the library (but only within the same object... no touching other objects' privates).  There may be some flexibility lost by not making these concepts orthogonal, but it seems like this would support most use-cases, and is quite simple.

Thoughts?


I'd like to keep these two clearly separate. Adding a notion of object privacy as an orthogonal concept would be clean and direct. I don't like muddling things.

--
Cheers, Gilad

Josh Gargus

unread,
May 21, 2012, 3:44:44 PM5/21/12
to Gilad Bracha, Peter Ahé, Bob Nystrom, Ladislav Thon, Rhys van der Waerden, General Dart Discussion
On Mon May 21 11:53:38 GMT-700 2012, Gilad Bracha <gbr...@google.com> wrote:
On Mon, May 21, 2012 at 11:38 AM, Josh Gargus <jj...@google.com> wrote:

Tobe extra-finicky: Object based privacy means that the only privileged access to an object is by the object itself. That is more general than the specific rules of Smalltalk, but it does fit with the rules for instance variable access in Smalltalk (which can be viewed as "protected").  Class-based privacy is the model used in many statically typed languages, whereby privileged access is based on the classes involved. Again, this extends beyond protected (Java private is also class based).
 
Thanks for stating this so clearly.  I understood the generalization of what I wrote, but wasn't able to articulate it so well.

Java protected access also involves the packages involved.  

Oh, does it?  I thought that Java's "protected" was purely class-based and that "package" (the default) is package-based... the most similar to Dart's library-based privacy.  My mistake, I'm not a Java expert.
  
However, it occurs to me that both concerns can be addressed by using the current syntax for both: any field with an underscore can be accessed from anywhere within the library, as well as from subclasses defined outside the library (but only within the same object... no touching other objects' privates).  There may be some flexibility lost by not making these concepts orthogonal, but it seems like this would support most use-cases, and is quite simple.

Thoughts?


I'd like to keep these two clearly separate. Adding a notion of object privacy as an orthogonal concept would be clean and direct. I don't like muddling things.

I'll think about it some more, and will probably end up agreeing with you.

Cheers,
Josh

 

--
Cheers, Gilad

Gilad Bracha

unread,
May 21, 2012, 3:52:47 PM5/21/12
to Josh Gargus, Peter Ahé, Bob Nystrom, Ladislav Thon, Rhys van der Waerden, General Dart Discussion
On Mon, May 21, 2012 at 12:44 PM, Josh Gargus <jj...@google.com> wrote:

 
Thanks for stating this so clearly.  I understood the generalization of what I wrote, but wasn't able to articulate it so well.

Java protected access also involves the packages involved.  

Oh, does it?  I thought that Java's "protected" was purely class-based and that "package" (the default) is package-based...

That would be too simple :-).  Protected members are accessible to *all* classes in the package where they are declared.

The interaction between package and protected makes for terrific puzzlers, and has been the source of verifier bugs and academic journal articles. Consider what happens when a subclass overrides a protected member declared in a superclass in another package.  Now there are classes that cannot access the overridden method.  

These interactions can be very hard to foresee. Which is why I like to keep things orthogonal.



--
Cheers, Gilad

Eric Leese

unread,
May 21, 2012, 7:51:31 PM5/21/12
to General Dart Discussion
Agreed that protected and private cover very different scenarios, and
that for protected, object based is better than class based. Speaking
of keeping things orthogonal, it occurs to me that for object based
protection, no special naming convention is necessary to mangle names
for the Javascript translation, so the two concepts really could be
orthogonal:

// publicly visible
var foo();

// visible only within library
var _foo2();

// can only be invoked on this
protected var foo3();

// can only be invoked on this by code in this library
protected var _foo4();

I don't think I'd ever bother with the last one, but if anyone feels
library privacy isn't private enough, they could use it.

Peter Ahé

unread,
May 22, 2012, 2:54:20 AM5/22/12
to Eric Leese, General Dart Discussion
My main concern with using words like "private" and "protected" in something that looks like C++/C#/Java is that programmers will have a preconceived notion about how it works and will get confused. 

This is the reason why we didn't just add object-based privacy. For example, take your favorite Java class and translate it to Dart (I assume Point is your favorite):

// Dart with object-based privacy:
class Point {
  private var x;
  private var y;
  Point(this.x, this.y);

  operator==(o) => o is Point && x == o.x && y == o.y;
}

This doesn't work. In principle this means that you can only use private very rarely and it should only be used to implement things like ocaps.

Now here's the problem with ocaps. I've been trying to discuss this with the best expert on ocaps that I know: if you leak a capability by accident, the whole security model breaks down. 

I assume that programmers make mistakes. I know I do. So how does a feature like adding a private keyword help me prevent leaking capabilities? I don't think it does.

So I have now concluded that object-based privacy is only useful for things like ocaps, but it still doesn't solve what I consider the biggest flaw in ocaps: accidental leaks.

I can simulate object-based privacy using closures:

typedef Point MoveFunction(dx, dy);

class Point {
  final MoveFunction move;
  Point.internal(this.move);
  factory Point(var x, var y) {
    Point move(dx, dy) => new Point(x+dx, y+dy);
    return new Point.internal(move);
  }
}

But notice I can't implement a distance method nor the operator== method. In my opinion, this is more obvious in this more tedious version. 

So I don't see what adding a keyword for object-based privacy (private, not protected) would buy us. We do have something that can serve the purpose for ocaps, and I don't see it being useful for general programming. 

Cheers,
Peter

Eric Leese

unread,
May 22, 2012, 8:01:50 PM5/22/12
to General Dart Discussion
> My main concern with using words like "private" and "protected" in
> something that looks like C++/C#/Java is that programmers will have a
> preconceived notion about how it works and will get confused.

Another option could be:

var this.foo();

> This is the reason why we didn't just add object-based privacy. For
> example, take your favorite Java class and translate it to Dart (I assume
> Point is your favorite):

Point isn't a very compelling case for protected inheritance, but if
you must do something like this, then just as it is possible to have a
private field with a public getter there's no reason you couldn't make
a private field with an object-protected getter.

Typically I have seen protected inheritance used when you have a large
complicated/powerful base class that provides simple ways for
subclasses to modify its behavior. Object based protection works well
for that case.
> > On May 21, 3:52 pm, Gilad Bracha <gbra...@google.com <javascript:;>>
> > wrote:
> > > On Mon, May 21, 2012 at 12:44 PM, Josh Gargus <jj...@google.com<javascript:;>>

Peter Ahé

unread,
May 23, 2012, 3:40:19 AM5/23/12
to Eric Leese, General Dart Discussion


On Wednesday, May 23, 2012, Eric Leese wrote:
> My main concern with using words like "private" and "protected" in
> something that looks like C++/C#/Java is that programmers will have a
> preconceived notion about how it works and will get confused.

Another option could be:

var this.foo();


Brilliant, you should suggest this at dartbug.com/new. As far as I can tell, this is a new idea we haven't tried yet. 
 
> This is the reason why we didn't just add object-based privacy. For
> example, take your favorite Java class and translate it to Dart (I assume
> Point is your favorite):

Point isn't a very compelling case for protected inheritance, but if
you must do something like this, then just as it is possible to have a
private field with a public getter there's no reason you couldn't make
a private field with an object-protected getter.

Typically I have seen protected inheritance used when you have a large
complicated/powerful base class that provides simple ways for
subclasses to modify its behavior.  Object based protection works well
for that case.

Agreed. I think your syntax suggestion a new idea and it would be great to consider it for object-based "protected". If I could choose only one, I would pick protected over private. This is because if I'm worried about what a subclass would do, I can prevent subclassing with a factory and package private constructor. 

Cheers,
Peter

denis papin

unread,
Oct 20, 2012, 1:19:19 PM10/20/12
to mi...@dartlang.org, Josh Gargus, Peter Ahé, Bob Nystrom, Ladislav Thon, Rhys van der Waerden
Well, when I override a protected method from a superclass from another package, it's my responsibility to make my class to work correctly and in any case, I will not break anything that worked before.

The package issue you are invoking is only a problem of how people take care about package dependencies. If they not, it is only a design issue, not a language one.

If I want to write a piece of software made of several layers, the bottom layer could be the more abstract classes and the layer right above could be a different package containing classes that subclass the classes from the abstraction package. When a final programmer want to use my framework he does not want to see of the inner implementation, but only the useful public method. But when I code the layers, I must be able to _use_ and _redefine_ some methods from a N-th layer class to a N+1-th layer class. 

class MoreConcreteClass {
   [protected] void doThis() {
     super.doThis();
     // to more concrete things....
     ....
   }

}

This is a very powerful mechanism that allows us to reuse complex processing from a class to another without making the process as public.
Keeping my package dependencies clean is up to me.

Cheers, Denis.

denis papin

unread,
Oct 20, 2012, 1:34:25 PM10/20/12
to mi...@dartlang.org, Bob Nystrom, Rhys van der Waerden
Well, I don't think the problem lies in those framework. It is not because they don't comply with the Dart features that they are wrong. 

Being able to reuse a method from a mother class without making this method public is a powerful mechanism. If you limit this possibility to a library, it's a narrow vision of the question : I may want my own library to be used by others and also want them to be able to reuse and redefine the methods of some of my classes. It will not be the same library but the mechanism is still valid and powerful.

I love the Dart language but It's a fact that we can't do that in Dart today, no matter how long we will cast the fault to others.

- Denis

Christopher Wright

unread,
Oct 22, 2012, 2:41:26 PM10/22/12
to General Dart Discussion, Bob Nystrom, Rhys van der Waerden
You can do this with cooperation between the parent class and the child class:

class Parent {
bool _haveSetProtectedMethods = false;
Parent() { setProtectedMethods(_method1, _method2); }
_method1() => print("Method 1");
_method2() => print("Method 2");
setProtectedMethods(method1, method2) {
assert(!_haveSetProtectedMethods);
_haveSetProtectedMethods = true;
}
}

class Child extends Parent {
var _m1, _m2;
setProtectedMethods(method1, method2) {
super.setProtectedMethods(method1, method2);
_m1 = method1;
_m2 = method2;
}

foo() {
_m1();
_m2();
}
}

It's pretty ugly, though.
> --
> Consider asking HOWTO questions at Stack Overflow:
> http://stackoverflow.com/tags/dart
>
>

Hans Van den Keybus

unread,
Mar 6, 2013, 8:56:40 AM3/6/13
to mi...@dartlang.org, Bob Nystrom, Rhys van der Waerden
Sorry for picking in on this discussion so late, but I'm currently starting out with Dart, and one of the first things I've been trying to find is of course "how do I set protected methods".

To me, a good argument not to use "this" is because in a lot of languages, it has a different meaning.
It has been suggested because the keyoard "protected" can be interpreted in different ways, but then I think: "this" can't?
In AS3 "this" is class level, in JS it is even a global var, I believe.

Second, I don't think "this" is very flexible.
What if you would later on decide to change the scope of "this", or add other scopes such as "remote"?
I think using keywords is still the most flexible way.

My suggestion:
- "internal" on library level
- "private" on class level
- "protected" on class level, and only for inheritance
- "public" on ..... you know, public level
- "remote" for remote functions maybe?

I understood the reason why this was the choosen way to go is because Dart is a dynamic language, but ActionScript also is dynamic..no?

Or am I wrong?

Reply all
Reply to author
Forward
0 new messages