that means increasing encapsulation of Data Object.Only injected Role Methods can call Data Object Methods (declared as private or protected not public)
It is about:- RoleA calls RoleB's object's method.not RoleA calls its own object's method. ( since the method is public, any one can call it)
sorry if I did not make it clear.
/quang
On Friday, February 27, 2015 at 9:11:26 PM UTC+8, Matthew Browne wrote:I don't see a problem with allowing any role being able to call the role player's instance methods, as long as those instance methods are public. The whole point of role binding is that you can add role methods but still be able to call the object's own methods. I don't understand why you're concerned about this (I was a little confused by your explanation).
On Thursday, February 26, 2015 at 11:32:20 PM UTC-5, Hai Quang Kim wrote:I have this question while working on the interaction diagram.
I saw 2 kind of interaction links from one Role to another Role: from Role Method to Role Method, from Role Method to Data Object Methodexample:
Role A:Role Method X()RoleB.RoleMethod Y() // this is OKRoleB.DataObjectMethodXYZ() // is this OK?
Role B:Role Method Y()DataObjectB:DataObjectMethodXYZ();
I think if we restrict this then the Role A should know RoleB's RoleMethod, but we have more Role Method as wrapper just for calling Data Object's method.If we don't the Role A will know all kind of method from Role B which makes the Role Concept not very clear:- what Role B can do with Data Object B can be done by Role A as well.
/quang
--
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/Zc-aVmFpIgA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and all its topics, send an email to object-composition+unsub...@googlegroups.com.
should the role-object contract be exposed to the Role that the object will play or any other Role?
In traditional class-based programming, “storing” and “processing” code is placed together in the same class, and the code for “communicating” (communication between objects) is often scattered across many different classes. DCI is more truly “object-oriented”: objects still contain both data and behavior at runtime, but DCI avoids the often incorrect assumption that system behavior shares the same structure as the data model.I think the fact that the role player is one cohesive object at runtime is critical to understanding DCI. Once the role binding happens, the set of methods available when calling that role player is the instance methods + the role methods. All of these methods are public, and they're all available from anywhere in the Context. Before binding a data object to a role, I doubt you'd complain about calling its public methods from a Context method, so why is it an issue to call the same method after role binding from outside the role? For example:
--
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/Zc-aVmFpIgA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.
--You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
On 28 Feb 2015, at 01:17, Matthew Browne <mbro...@gmail.com> wrote:
I'm calling foo() from the Context's constructor - not even from a role method. If it's OK to do it here, why should it not also be OK to call MyRole.foo() from any other role?
On 28 Feb 2015, at 04:50, Risto Välimäki <risto.v...@gmail.com> wrote:It's not only possible, but also I think it's quite common that you'll have some Roles acting just as identifiers in your Contexts, without having any role methods.
Sendt fra min iPhoneDen 28/02/2015 kl. 01.17 skrev Matthew Browne <mbro...@gmail.com>: Once the role binding happens, the set of methods available when calling that role player is the instance methods + the role methods.Nicely put. Not quite right, though, because of the possibility of an object playing multiple roles from one or more Contexts. Its not really class composition: objects accumulate methods over time.
The problem arises when the name space for these spaces collide. I say: the fix is to disallow such collisions.
@Matthew, in your example, the object contract is for both Context and Role, is that intended?
What if I just want that contact to be available in Role Method only not in Context's system operation or constructor.How can we do that? (or do we need that?)
/quang
On Saturday, February 28, 2015 at 6:45:52 AM UTC+8, Cope wrote:
Sendt fra min iPhone
> Den 28/02/2015 kl. 01.17 skrev Matthew Browne <mbro...@gmail.com>:
>
> Once the role binding happens, the set of methods available when calling that role player is the instance methods + the role methods.
Nicely put. Not quite right, though, because of the possibility of an object playing multiple roles from one or more Contexts. Its not really class composition: objects accumulate methods over time.
The problem arises when the name space for these spaces collide. I say: the fix is to disallow such collisions.
My mental model is that the objects carry these methods. I don't need compile-time context (small "c") to clutter my mental model.
--
The problem arises when the name space for these spaces collide. I say: the fix is to disallow such collisions.
On 28 Feb 2015, at 13:43, Matthew Browne <mbro...@gmail.com> wrote:I was talking about the methods that are available when calling methods on a role player within a particular Context.
Technically the role methods still exist on the object until the role is unbound (or at least that's the illusion) even if the execution flow returns to the environment or moves to another Context.
But they're inaccessible from outside the Context to which the role(s) belong, so from a practical standpoint it's as though they don't exist anywhere else.
By allowing duplication of method names, the system becomes an order of magnitude or so more complex with a system of epicycles and implementation arguments that protect against bad things happening in the case of name collisions.
Technically the role methods still exist on the object until the role is unbound (or at least that's the illusion) even if the execution flow returns to the environment or moves to another Context."Technically." Powerful word. Dangerous word. So: do they exist or not?
On 28 Feb 2015, at 15:51, Risto Välimäki <risto.v...@gmail.com> wrote:In my opinion, what should happen instead is that you should never be able to call role methods from instance methods.
On 28 Feb 2015, at 16:24, Risto Välimäki <risto.v...@gmail.com> wrote:I strongly disagree on this if we are talking about injectionless implementations. It's simply guaranteed that there are no surprises, no accidental polymorphism or method overriding, even if methods with same signature are used in all classes and all roles.
On 28 Feb 2015, at 16:24, Risto Välimäki <risto.v...@gmail.com> wrote:
All in all, no convention whatsoever can ever make you safe here.
The serious downside is that thos encourages thinking in terms Of classes and roles instead of objects.
I have this question while working on the interaction diagram.
I saw 2 kind of interaction links from one Role to another Role: from Role Method to Role Method, from Role Method to Data Object Methodexample:
Role A:Role Method X()RoleB.RoleMethod Y() // this is OKRoleB.DataObjectMethodXYZ() // is this OK?
Role B:Role Method Y()DataObjectB:DataObjectMethodXYZ();
I think if we restrict this then the Role A should know RoleB's RoleMethod, but we have more Role Method as wrapper just for calling Data Object's method.If we don't the Role A will know all kind of method from Role B which makes the Role Concept not very clear:- what Role B can do with Data Object B can be done by Role A as well.
/quang
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.
The essence of object orientation is
that objects collaborate to achieve a
goal.
Trygve Reenskaug mailto: try...@ifi.uio.no
Morgedalsvn.
5A http://folk.uio.no/trygver/
N-0378
Oslo http://fullOO.info
Norway Tel:
(+47) 22 49 57 27
It is about:- RoleA calls RoleB's object's method.not RoleA calls its own object's method. ( since the method is public, any one can call it)
should the role-object contract be exposed to the Role that the object will play or any other Role?
RoleB's choice of roleplayerLast time I look the context was responsible for choosing role player for both A and B
On 27.02.2015 17:05, Hai Quang Kim wrote:
should the role-object contract be exposed to the Role that the object will play or any other Role?
In a context, objects are accessed through their names, i.e., the roles they play. Do you see another way for 'any other role' to access an arbitrary rtheyoleplayer without using its name (ie. a role it is playing)?
RoleB's choice of roleplayer
Last time I look the context was responsible for choosing role player for both A and B --You are right. I should have phrased it differently.
Technically the role methods still exist on the object until the role is unbound (or at least that's the illusion) even if the execution flow returns to the environment or moves to another Context.
"Technically." Powerful word. Dangerous word. So: do they exist or not?
But they're inaccessible from outside the Context to which the role(s) belong, so from a practical standpoint it's as though they don't exist anywhere else.
So let's explore this in detail. If I have access to the object through a MOP, does the MOP carry any information about the presence of this method? That is, is the "as if they don't exist" air-tight and intended for cooperative communicating programmers, or are they an inviolate guarantees?
But I agree that you are also safe by disallowing all the name clashes that is:
1. There should be exactly one role method of the same signature. That is, if you have already method foo() in Bar context, you are not able to have context Baz with method foo().
2. There should be never role method called foo() given that any of possible role players has instance method foo() defined on their class abstraction.
For real, big applications I see this seriously limiting and resulting not only overly verbose, but also long or randomly prefixed methods. One possibility is of course use the context name as a prefix, but in my opinion, this is not neat at all. Yet I admit that I could live with this limitation, if there was no other alternative over this. But as said, there is a way over the hill, and I would rather take that way than feel myself being on prison.
My answer is Yes we should. As I say at length in a recent post, my SqueakContext has two words for identifying the roleplayer. A message sent to 'self' goes directly to the roleplayer. A message sent to <ROLENAME> is intercepted at the input. A role method is executed if it exists, otherwise the message is forwarded to the roleplayer.
On 27.02.2015 05:32, Hai Quang Kim wrote:
--I have this question while working on the interaction diagram.
I saw 2 kind of interaction links from one Role to another Role: from Role Method to Role Method, from Role Method to Data Object Methodexample:
Role A:Role Method X()RoleB.RoleMethod Y() // this is OKRoleB.DataObjectMethodXYZ() // is this OK?
Role B:Role Method Y()DataObjectB:DataObjectMethodXYZ();
I think if we restrict this then the Role A should know RoleB's RoleMethod, but we have more Role Method as wrapper just for calling Data Object's method.If we don't the Role A will know all kind of method from Role B which makes the Role Concept not very clear:- what Role B can do with Data Object B can be done by Role A as well.
/quang
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composition+unsub...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
On 28.02.2015 12:21, Rune Funch Søltoft wrote:
You are right. I should have phrased it differently.
RoleB's choice of roleplayerLast time I look the context was responsible for choosing role player for both A and B --
And to me that makes quite a difference. The context is responsible for picking suitable players that fulfill the requirements and worrying about how the object acquired method doesn't sound awfully object oriented but rather more class oriented
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/Zc-aVmFpIgA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.
To unsubscribe from this group and all its topics, send an email to object-composition+unsub...@googlegroups.com.
Comment below.
On 28.02.2015 16:59, Rune Funch Søltoft wrote:
On 28.02.2015 12:21, Rune Funch Søltoft wrote:
You are right. I should have phrased it differently.
RoleB's choice of roleplayerLast time I look the context was responsible for choosing role player for both A and B --
Of course. That's what I agreed on. Here's a rephrase:
And to me that makes quite a difference. The context is responsible for picking suitable players that fulfill the requirements and worrying about how the object acquired method doesn't sound awfully object oriented but rather more class oriented
It doesn't make sense for RoleA to call RoleB's object's method because it breaks the encapsulation of roles. RoleA shouldn't be aware of RoleB's roleplayer or how the context has chosen it.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composition+unsub...@googlegroups.com.
On 02 Mar 2015, at 11:14, Hai Quang Kim <wan...@gmail.com> wrote:"longstanding principles of linguistics, be minimal"Thanks for this very good point.
On 02 Mar 2015, at 22:43, Matthew Browne <mbro...@gmail.com> wrote:For example, there's a dialect of Inuit that has about 50 words for snow:
On 02 Mar 2015, at 22:43, Matthew Browne <mbro...@gmail.com> wrote:
For example, there's a dialect of Inuit that has about 50 words for snow:
Well... yes and no. The "word" structure was imposed by Western linguists (and Boas wasn't even acting as an anthropologist in his "research" behind this myth — more as a tourist — let alone as a linguist), so it may be more appropriate to say that there are 50 phrases for snow. Inuit doesn't sharply delineate between words and phrases. I daresay that such a number compares favourably with Danish or with the union of regional and vernacular words in American English.
There is also a slight problem with cultural relativism in this comparison. It may be better to say that they have 50 words for "particulate frozen water," one of which is archetypical English-language "snow."
In that vein, it's kind of like saying that computer scientists have 100 ways to say "X" where "X" comprises the four primitive operations of a Turing machine. All of computing can be reduced to less than a handful of verbs. So all constructs of all computing languages can be reduced to less than 10, and they are all formally equivalent. No one would say that these constructs should be interpreted (hermenuetics) in the same way. Whether they mean the same thing (semantics) is a matter of minor debate about contextualisation. In epistemology and hermeneutics, contextualisation is everything.
Word length as a measure applies in an almost entirely uncontextualized setting, whereas meaning (as for "snow").
Context is everything...
On 02 Mar 2015, at 22:43, Matthew Browne <mbro...@gmail.com> wrote:For example, there's a dialect of Inuit that has about 50 words for snow:Well... yes and no. The "word" structure was imposed by Western linguists (and Boas wasn't even acting as an anthropologist in his "research" behind this myth — more as a tourist — let alone as a linguist), so it may be more appropriate to say that there are 50 phrases for snow. Inuit doesn't sharply delineate between words and phrases. I daresay that such a number compares favourably with Danish or with the union of regional and vernacular words in American English.There is also a slight problem with cultural relativism in this comparison. It may be better to say that they have 50 words for "particulate frozen water," one of which is archetypical English-language "snow."
In that vein, it's kind of like saying that computer scientists have 100 ways to say "X" where "X" comprises the four primitive operations of a Turing machine. All of computing can be reduced to less than a handful of verbs. So all constructs of all computing languages can be reduced to less than 10, and they are all formally equivalent. No one would say that these constructs should be interpreted (hermenuetics) in the same way. Whether they mean the same thing (semantics) is a matter of minor debate about contextualisation. In epistemology and hermeneutics, contextualisation is everything.Word length as a measure applies in an almost entirely uncontextualized setting, whereas meaning (as for "snow").Context is everything...
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
On 03 Mar 2015, at 19:01, Risto Välimäki <risto.v...@gmail.com> wrote:Trust me, it's useful to have several words for snow, if you have to live with that element, since different kind of snow behave so differently under your skis, on your rooftops or when you need (or want) a quinzhee for temporary shelter.
And to me that makes quite a difference. The context is responsible for picking suitable players that fulfill the requirements and worrying about how the object acquired method doesn't sound awfully object oriented but rather more class orientedOf course. That's what I agreed on. Here's a rephrase:
It doesn't make sense for RoleA to call RoleB's object's method because it breaks the encapsulation of roles. RoleA shouldn't be aware of RoleB's roleplayer or how the context has chosen it.
And to me that makes quite a difference. The context is responsible for picking suitable players that fulfill the requirements and worrying about how the object acquired method doesn't sound awfully object oriented but rather more class orientedOf course. That's what I agreed on. Here's a rephrase:
It doesn't make sense for RoleA to call RoleB's object's method because it breaks the encapsulation of roles. RoleA shouldn't be aware of RoleB's roleplayer or how the context has chosen it.So are we at a standoff about this currently? It's quite an explicit rule that only "self" should access the RoleObjectInterface, and I'm intrigued by it since I thought that a Role type should always be RoleMethods + RoleObjectInterface. It forced me to think even harder about good method names, and put the functionality when it belongs. Or did I misunderstand something?
I went through my example code anyway and about 75% of the code is following this rule anyway. But here's a tricky one, similar to what Quang talks about. With this rule I must create a RoleMethod on destinationAccount that will have a dubious name. Deposit is already taken by the roleplayer, but what if the use case specifies "deposit"?/Andreas
And to me that makes quite a difference. The context is responsible for picking suitable players that fulfill the requirements and worrying about how the object acquired method doesn't sound awfully object oriented but rather more class orientedOf course. That's what I agreed on. Here's a rephrase:
It doesn't make sense for RoleA to call RoleB's object's method because it breaks the encapsulation of roles. RoleA shouldn't be aware of RoleB's roleplayer or how the context has chosen it.So are we at a standoff about this currently? It's quite an explicit rule that only "self" should access the RoleObjectInterface, and I'm intrigued by it since I thought that a Role type should always be RoleMethods + RoleObjectInterface. It forced me to think even harder about good method names, and put the functionality when it belongs. Or did I misunderstand something?I think that the idea of not treating the objects as the objects they are but as the roles they play breaks Kay's notion of a system of interconnected systems. It is would instead of objects being connect be the roles that were connected as if roles were some virtual wrapper around the objects.
true
, false
, nil
, self
, super
, and thisContext
Different objects may invoke different methods for the same message, this is called polymorphism.Does that not suggest that 2 different roles that may be played by the same object can both have a method with the same name? I have previously explained why I think role methods should be able to override instance methods as well - and of course we also discussed the more practical point that you don't want a single small update (the addition of a new method) to a 3rd party library class to break your existing code.
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/Zc-aVmFpIgA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.
Just a note on that "self"-thing. I regard that as the greatest of misunderstandings of the history of DCI. In Smalltalk-80 there were exactly six keywords, namely:true
,false
,nil
,self
,super
, andthisContext
So in class-abstraction Smalltalk uses "self" keyword to refer the current object itself. "Super", in other hand refers to superclass in class-abstraction. So when Trygve added the role-abstraction to enhance objects when needed, he obviously used the "self" keyword to refer the current object also in role-abstraction. Nothing mystical here. On the other hand, there is no need for "super" keyword in DCI role-abstraction, since there is no need for inheriting Role Methods and then overriding them, and thus need to access the "super role".
To sum up above paragraph, in Smalltalk/Squeak with added DCI-support by Trygve, "self" keyword is used on both abstractions for objects: class-abstraction (~D) and role-abstractions (C & I), and in both cases it works identically: It provides access to the object itself (and therefore, naturally also access to instance and role methods, which are currently bound to that object).
When other object-oriented / class-oriented languages emerged, such as C++ and Java, for reasons unknown to me, they did not take the "self" keyword from Smalltalk, but instead introduced a new keyword "this", that means exactly the same thing. Keyword "this" refers to the object.
What happened then was that all of us Smalltalk-illiterates took Trygve's notification of "self" when referring to object from Role methods as something completely new idea, instead of just using that very same "self" from class-abstraction in role-abstraction. That resulted so that in most non-Smalltalk takes on DCI used "this" for "this" in class-abstraction, but "self" for "this" in role-abstraction. That's not just confusing but also wrong. It's really shame that we can't read Smalltalk and are not willing to take the time for learning that language to better understand Trygve's ideas.
I think in general that most of the injectionless implementation ( Trygve's being the exception) all have one thing in common. If you write an expression that evaluates to the role player and invoke a method on the result of the expression it will call an instance method.
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/Zc-aVmFpIgA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.
There are two topics being discussed on this thread:
1. Quang's original question about two roles, role A and B in the same context, and whether role A should be allowed to call role B's instance methods directly.
2. Whether to allow role methods to override or shadow instance methods -- or whether to even allow method name conflicts among different roles played by the same object.
Regarding #1, if the programmer knows enough to call a role by its name, then he/she should also be aware of its Context and the role-object contract for that role. The idea that Role B's instance methods (the ones exposed in the role-object contract) should be hidden from Role A is at best a weak illusion; and as Rune put it, it replaces class-based thinking with role-based thinking instead of object-oriented thinking.
Regarding #2, I'm currently reading the latest draft DCI paper, which says this about encapsulation on page 6:
Different objects may invoke different methods for the same message, this is called polymorphism.Does that not suggest that 2 different roles that may be played by the same object can both have a method with the same name?
// Data classclass Obj {
def foo = "FOO" def bar = "BAR"
}
// Topic #2@context class Context2(a: Obj) { def resolve = a.foo role a { def foo = self.bar + a.bar // (could say `bar` instead of `a.bar`) Doesn't feel like one object, hm... def bar = "bar" }}new Context2(new Obj).resolve === "BARbar" // expected?
// Topic #1 (and #2)// An object plays different roles with same role method names@context class Context1(a: Obj) {
// Role players: val A = a val B = a
def resolve = A.foo + B.foo // role methods only
role A { def foo = self.bar + B.bar // Can't call instance method with `B.self.bar` }
role B { def bar = foo def foo = "foo" }}new Context1(new Obj).resolve === "BARfoofoo" // expected?
I have previously explained why I think role methods should be able to override instance methods as well - and of course we also discussed the more practical point that you don't want a single small update (the addition of a new method) to a 3rd party library class to break your existing code.
On 08 Mar 2015, at 09:09, Risto Välimäki <risto.v...@gmail.com> wrote:What happened then was that all of us Smalltalk-illiterates took Trygve's notification of "self" when referring to object from Role methods as something completely new idea, instead of just using that very same "self" from class-abstraction in role-abstraction.
On 08 Mar 2015, at 14:01, Matthew Browne <mbro...@gmail.com> wrote:Does that not suggest that 2 different roles that may be played by the same object can both have a method with the same name?
On 09 Mar 2015, at 13:52, Rune Funch Søltoft <funchs...@gmail.com> wrote:How one would confuse the form with the later I don't know.
On 09 Mar 2015, at 15:38, Trygve Reenskaug <try...@ifi.uio.no> wrote:Homonyms should be avoided not only in contexts but everywhere.
In computer terms, Smalltalk is a recursion on the notion of computer itself. Instead of dividing "computer stuff" into things each less strong than the whole--like data structures, procedures, and functions which are the usual paraphernalia of programming languages--each Smalltalk object is a recursion on the entire possibilities of the computer. Thus its semantics are a bit like having thousands and thousands of computer all hooked together by a very fast network. Questions of concrete representation can thus be postponed almost indefinitely because we are mainly concerned that the computers behave appropriately, and are interested in particular strategies only if the results are off or come back too slowly.This definition doesn't give any details about the communication. DCI fills in these details by specifying the interaction.
--
On 09 Mar 2015, at 16:59, Trygve Reenskaug <try...@ifi.uio.no> wrote:My mental model is that an object is like a computer.
On 09 Mar 2015, at 17:11, Trygve Reenskaug <try...@ifi.uio.no> wrote:I can't see how it can be enforced.
On 09 Mar 2015, at 17:16, Rune Funch Søltoft <funchs...@gmail.com> wrote:
Your argument has been that it is confusing.
I claime the code that I and Trygve has posted is not confusing.
Might there be other reasons. Perhaps but I don't buy that it per se is confusing
--
I don't like that Marvin is role oriented and not truly object oriented. It does make the code easier to reason but there's a discrepancy between the code and the object oriented runtime
On 09 Mar 2015, at 17:40, Rune Funch Søltoft <funchs...@gmail.com> wrote:And in that Line of reasoning I think we are closer to agreeing. I don't like that Marvin is role oriented and not truly object oriented. It does make the code easier to reason but there's a discrepancy between the code and the object oriented runtime
On 09 Mar 2015, at 18:06, Marc Grue <marc...@gmail.com> wrote:If everything was possible, how could more object oriented code look like?
WINDOW.open() => WINDOW.windowopen()
FILE.open() => FILE.fileopen()
On 09 Mar 2015, at 18:39, Trygve Reenskaug <try...@ifi.uio.no> wrote:I don't follow your arguments.
You haven't answered if you prefer to change my simple snippet from a role method:WINDOW.open() => WINDOW.windowopen()
FILE.open() => FILE.fileopen()
On Sunday, March 8, 2015 at 2:01:06 PM UTC+1, Matthew Browne wrote:There are two topics being discussed on this thread:
1. Quang's original question about two roles, role A and B in the same context, and whether role A should be allowed to call role B's instance methods directly.
2. Whether to allow role methods to override or shadow instance methods -- or whether to even allow method name conflicts among different roles played by the same object.
Regarding #1, if the programmer knows enough to call a role by its name, then he/she should also be aware of its Context and the role-object contract for that role. The idea that Role B's instance methods (the ones exposed in the role-object contract) should be hidden from Role A is at best a weak illusion; and as Rune put it, it replaces class-based thinking with role-based thinking instead of object-oriented thinking.
Regarding #2, I'm currently reading the latest draft DCI paper, which says this about encapsulation on page 6:
Different objects may invoke different methods for the same message, this is called polymorphism.Does that not suggest that 2 different roles that may be played by the same object can both have a method with the same name?
Hi all,
I hope to participate a bit again here if that's ok...
The questions raised in this thread are of course very relevant to ScalaDCI too, and I'm not sure I got method resolution right. So maybe I could ask you to consider the following examples? Are they covering some of the various concerns that Matt/Quang mentions? And are the interaction outcomes matching your expectations?:
// Data classclass Obj {def foo = "FOO"def bar = "BAR"}
// Topic #2@context class Context2(a: Obj) {def resolve = a.foorole a {def foo = self.bar + a.bar // (could say `bar` instead of `a.bar`) Doesn't feel like one object, hm...def bar = "bar"}}new Context2(new Obj).resolve === "BARbar" // expected?
// Topic #1 (and #2)// An object plays different roles with same role method names@context class Context1(a: Obj) {
// Role players:val A = aval B = a
def resolve = A.foo + B.foo // role methods only
role A {def foo = self.bar + B.bar // Can't call instance method with `B.self.bar`}
role B {def bar = foodef foo = "foo"}}new Context1(new Obj).resolve === "BARfoofoo" // expected?
In Marvin this is an alias for the role. Not specifying anything is accessing properties of the context (other roles usually) to access an instance method you can do several different things. All of which boils down to any expression that has the RolePlayer as the resulting value and is not the expression 'this' or 'role'. Eg assigning the RolePlayer to a variable and accessing a method on the variable would only look for instance methods. An inline cast would have the same effect. Of course this is only needed if you have a role method named the same as an instance method because in all other case you could just use the role or 'this'
As you see in my comments, to call both self.bar and a.bar on the same object in Context2 seems somehow "schizophrenic" as though they were two different things. Isn't that some kind of violation of comprehensiveness? I wonder if this touches upon some of the same concerns you had in this post, Cope?
In the bigger example ("Context1" - referring to #1 that Matt listed) I tried to code the simplest case I could imagine of an object playing 2 different roles having clashing role method names. Object `a` plays both a role A and B. I'm not sure if you would consider this "at the same time" since `B.foo` is evaluated sequentially after `A.foo` at runtime (or how it's correctly put). If this is not considered an example of an object playing two roles at the "same time" I wonder what that could be, maybe a recursive Context? - I don't know. Wouldn't only multi-threading be really at "the same time" and single-thread execution always "sequential"? Well that's a whole big other question...
If we were to disallow having role methods overriding instance methods conceptually and practically in code, couldn't we then unify instance/object method calls to only RoleName.roleMethod? We could consider a "unified object" - a RolePlayer with a set of unique methods that are all accessible on the same object through the same identifier. Yes, some defined in a Data class, and some in the role definition. But we would only consider the object as one RolePlayer and not a RolePlayer with "two faces".
Couldn't we say that these "two faces" of a RolePlayer causes us to switch back and forth between two different mental models of either an object with "instance methods" or "role methods"? That seems more like class thinking to me (Data class or Role definition). The runtime object has no differentiation between instance/object methods - it simply "has methods" as far as I understand. It would be nice if our mental model and code was relieved of this "split" too if we can call it that.
Technically I could disallow role/instance name clashes in ScalaDCI either with warnings or blocking errors - if all this is desireable in some form.
It could be left optional if one would refer to the RolePlayer with RoleName, `self` or `this`, not as a references to a subset of instance methods but a "full reference" to the object.
This would be quite a big departure from the current meaning of self/this, but maybe a valuable unifying one?! I'm afraid this could cause big technical challenges in some implementations, but maybe you can start viewing it from a comprehensive perspective first before considering the technical implications?
I have previously explained why I think role methods should be able to override instance methods as well - and of course we also discussed the more practical point that you don't want a single small update (the addition of a new method) to a 3rd party library class to break your existing code.
Isn't that impossible to guard against? The best you can do is to have really weird or heavily namespaced role method names... ;-)
--Cheers,Marc
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/Zc-aVmFpIgA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.
Looks like something from the Department of Redundancy Department. It reminds me of what used to disparagingly be called Hungarian Notation: a sign of an overly weak type system, for which the programmer consciously had to compensate. That's roughly what I see happening here.On 09 Mar 2015, at 18:39, Trygve Reenskaug <try...@ifi.uio.no> wrote:
I don't follow your arguments.
We may need to take this up in person. It's subtle. I think Rune now understands what I'm trying to get at — see his most recent mail. "Role-oriented" is not "object-oriented."
You haven't answered if you prefer to change my simple snippet from a role method:
WINDOW.open() => WINDOW.windowopen()
FILE.open() => FILE.fileopen()
I better liked your pronouncement that homonyms should be avoided.
From my perspective open is just another baz, because in reality it would likely be an instance method and hardly ever a Role method.
--
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/Zc-aVmFpIgA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.
role Salesman {
calculateSalary() {...}
}
role Engineer {
calculateSalary() {...}
}
Both roles could be played by the same type of object, e.g. a User or Person class.
Hi Marc,
Good to have you back on the group (whether just for this discussion or for others as well)...Comments below.
On 3/8/15 2:55 PM, Marc Grue wrote:I would have expected this to result in "barbar". I don't think there should be any difference between 'self.bar' and 'a.bar' when inside role a.And are the interaction outcomes matching your expectations?:
// Data classclass Obj {def foo = "FOO"def bar = "BAR"}
// Topic #2@context class Context2(a: Obj) {def resolve = a.foorole a {def foo = self.bar + a.bar // (could say `bar` instead of `a.bar`) Doesn't feel like one object, hm...def bar = "bar"}}new Context2(new Obj).resolve === "BARbar" // expected?
The Squeak implementation of a DCI Context provides two ways of accessing an object: <self> in a role method refers to the current roleplayer directly. <ROLE NAME> refers to the object as seen from the inter-object space and a message may be intercepted by a role method.
I would prefer a different mechanism to be able to explicitly call the instance method, e.g. casting to the type of the role player as Rune suggested. I also think that in ScalaDCI, calling 'this' should have the same effect as calling 'self', although I realize there are probably technical challenges with making that happen.
The output matches my expectation in this case, but after an earlier discussion with Rune I now think that both instance and role methods should always be prefixed by either the role name, 'self', or 'this'.
// Topic #1 (and #2)// An object plays different roles with same role method names@context class Context1(a: Obj) {
// Role players:val A = aval B = a
def resolve = A.foo + B.foo // role methods only
role A {def foo = self.bar + B.bar // Can't call instance method with `B.self.bar`}
role B {def bar = foodef foo = "foo"}}new Context1(new Obj).resolve === "BARfoofoo" // expected?
Otherwise it gets confusing, because other role players can be accessed without a prefix,
and in most implementations, Context methods can also be accessed without a prefix. So it's much more consistent if unprefixed variable names always refer to something in the Context, and within a role you have to use 'self' or 'this' (or use the name of the current role explicitly). Actually, having re-read Rune's earlier comment I realized it's quite relevant to this discussion so I'll quote it here:
In Marvin this is an alias for the role. Not specifying anything is accessing properties of the context (other roles usually) to access an instance method you can do several different things. All of which boils down to any expression that has the RolePlayer as the resulting value and is not the expression 'this' or 'role'. Eg assigning the RolePlayer to a variable and accessing a method on the variable would only look for instance methods. An inline cast would have the same effect. Of course this is only needed if you have a role method named the same as an instance method because in all other case you could just use the role or 'this'
On 3/8/15 2:55 PM, Marc Grue wrote:
If the aim is for more consistency, then I prefer using 'self', mainly because it's more succinct, especially for long role names. But I would argue that explicitly calling the role name should work too, since that should work from anywhere within the Context.As you see in my comments, to call both self.bar and a.bar on the same object in Context2 seems somehow "schizophrenic" as though they were two different things. Isn't that some kind of violation of comprehensiveness? I wonder if this touches upon some of the same concerns you had in this post, Cope?
My understanding of "at the same time" as we've been discussing it here is an object that is bound to a first role, and then is bound to a second role that also has a method with the same name
In the bigger example ("Context1" - referring to #1 that Matt listed) I tried to code the simplest case I could imagine of an object playing 2 different roles having clashing role method names. Object `a` plays both a role A and B. I'm not sure if you would consider this "at the same time" since `B.foo` is evaluated sequentially after `A.foo` at runtime (or how it's correctly put). If this is not considered an example of an object playing two roles at the "same time" I wonder what that could be, maybe a recursive Context? - I don't know. Wouldn't only multi-threading be really at "the same time" and single-thread execution always "sequential"? Well that's a whole big other question...
-- before the first role is unbound.
The two roles might both belong to the same context, or not. Even though the role methods aren't being called at the same time, they're still both bound to the same object at the same time. That's where the potential for reduced code comprehension comes up.
I think Cope may be taking that line of thinking a bit too far, but I definitely agree that such naming conflicts are potentially confusing in many cases.
This is how I always thought it was supposed to work, and still do - it's just different identifiers for the same object.If we were to disallow having role methods overriding instance methods conceptually and practically in code, couldn't we then unify instance/object method calls to only RoleName.roleMethod? We could consider a "unified object" - a RolePlayer with a set of unique methods that are all accessible on the same object through the same identifier. Yes, some defined in a Data class, and some in the role definition. But we would only consider the object as one RolePlayer and not a RolePlayer with "two faces".
Couldn't we say that these "two faces" of a RolePlayer causes us to switch back and forth between two different mental models of either an object with "instance methods" or "role methods"? That seems more like class thinking to me (Data class or Role definition). The runtime object has no differentiation between instance/object methods - it simply "has methods" as far as I understand. It would be nice if our mental model and code was relieved of this "split" too if we can call it that.
Technically I could disallow role/instance name clashes in ScalaDCI either with warnings or blocking errors - if all this is desireable in some form.
It could be left optional if one would refer to the RolePlayer with RoleName, `self` or `this`, not as a references to a subset of instance methods but a "full reference" to the object.
Object-oriented rather than class-oriented / role-oriented, as Rune has been saying.
"Really weird or heavily namespaced role method names.." are one of the things I want to avoid, and one of the potential drawbacks I see with Cope's position.This would be quite a big departure from the current meaning of self/this, but maybe a valuable unifying one?! I'm afraid this could cause big technical challenges in some implementations, but maybe you can start viewing it from a comprehensive perspective first before considering the technical implications?
I have previously explained why I think role methods should be able to override instance methods as well - and of course we also discussed the more practical point that you don't want a single small update (the addition of a new method) to a 3rd party library class to break your existing code.
Isn't that impossible to guard against? The best you can do is to have really weird or heavily namespaced role method names... ;-)
With regard to library classes, if role methods are allowed to override instance methods, then the introduction of a new method to a library class is not a problem for existing code. The existing code can remain blissfully ignorant of the addition of the new method (assuming you don't have any current need for it).
On the other hand, if overriding is forbidden, then if you have a role method 'foo' played by a MyLibraryClass object and you upgrade to the next version of MyLibraryClass which happens to have a new method called 'foo', then it will break your existing code.
On 10 Mar 2015, at 10:20, Risto Välimäki <risto.v...@gmail.com> wrote:Source code may be object oriented, but the running program in memory and CPU is not