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?
LT
My questions:
* Is this an idiomatic/good pattern for simulating protected
inheritance?
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.
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.
I'm not a huge fan of inheritance, but I find it does work well for some things, especially UI frameworks.
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.
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.
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.
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?
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).
Java protected access also involves the packages involved.
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
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...
> 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.