Hi Cevat and others,
"...because RestrictedOO is based on classification."
While not directly related to what you wrote Cevat, this phrase made me think of something.
Becaue my language of choice forces me to delare types (for parameters, arguments, variables, fields, etc), I find myself often thinking of roles in terms of their interfaces. Implicitly, this means I am classifying roles, doesn't it?
But I don't feel this hinders anyone.
Yes, so for the role classification to not be inhibiting, the language (or framework?) needs to be dynamic. We must not be forced to define a priori what roles objects will play, but rather be able to assign them dynamically at runtime.
But none of that has much to do with using a typed name to refer to a role player. In fact sometimes that can be an advantage. For example it can assist tools in offering support like code completion and refactoring.
> On 24.09.2011 10:31, rune funch wrote:
>> But how are you going to bind something of a DIFFERENT type to that? Of course I know your answer. You're not. You're going to create a new object of a different type and assign that object therefor creating a need to think in terms of those types. The intellisense can be accomplished with out the type declaration we've already been there.
>
> You clearly don't know my answer, because it differs from the one you
> suggested ;-)
Well in the rest of the code you're doing exactly that. You are not
binding your role player to the typed local. You can't Java won't let
you because the role player is not of that type. You assign an object
that has a reference to the role player.
> If I were to write code like this, *it would surprise the reader*:
>
> public void doSomething(var myCar){
> myCar.fly(); //cars can't fly!! surprised!
> }
>
I agree. You've chosen a very misleading name for something that flies :)
> Now, to the other question:
> How can intellisense work with this code snippet:
>
> public void doSomething(var myObject){
> ... I'm editing here
> }
How would I know I don't even know which language it's written in.
As I wrote the other day in F# you try to avoid type declarations.
That doesn't mean there's no intellisense. Just mean than the compiler
does a tremendous job figuring out what type each local/parameter has
> That is why
> that code is illegal in C#
Nope that's not why it's illegal. Depending on how you write. Code
it's entirely possible to write a compiler that can figure out the
type in most cases and let you specify the type if it can't that's
_exactly_ what the F# compiler does.
The C# team decided that the type should be decidable from the
statement declaring the storage location and not from later usage
(which is what F# allows). Similar you can't use var on fields. That's
not because you can't write a compiler that infers the type. It's a
choice made to make it easier to write the C# compiler
>
> Cheers,
> Ant
role SourceAccount{
requires void decreaseBalance(decimal amount);
requires void log(string message);
transaction void transfer(decimal amount){
SourceAccount.decreaseBalance(amount);
SourceAccount.log("decreased balance with " + amount);
DestinationAccount.increaseBalance(amount);
}
}
The role has no type. Any type that has the to methods defined in the
require clauses can be used as role player and intellisense is able to
tell you which members are available on the role and the role player.
The role method is marked as transaction which goes to the discussion
about removing tech stuff from the UC code
-Rune
> On Sep 24, 9:06 pm, rune funch <funchsolt...@gmail.com> wrote:
>> What if the role didn't have a type. What if the name of the role and
>> role methods was all there was to it?
>>
>> role SourceAccount{
>> requires void decreaseBalance(decimal amount);
>> requires void log(string message);
>>
>> transaction void transfer(decimal amount){
>> SourceAccount.decreaseBalance(amount);
>> SourceAccount.log("decreased balance with " + amount);
>> DestinationAccount.increaseBalance(amount);
>> }
>>
>> }
>>
>> The role has no type. Any type that has the to methods defined in the
>> require clauses can be used as role player and intellisense is able to
>> tell you which members are available on the role and the
>> It is how you assign the role to an object.
I might be the confused one here but I don't assign a role to an
object I bind and object to a role. All the code you wrote in your
mail, I thought that was about binding an object to a role
-Rune
> On Sep 24, 3:26 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
>> One sign of a dysfunctional language is that you need to know the class of an object to be able to talk to it.
>
> Here is a Javascript object which I once created in a UI. Please name at least one method you can call on it:
>
> viewModel
That is not an object. That is potentially an identifier.
>> One common analog is that you can't talk to an object unless you created it.
>
> That makes no sense - what languages do that?!
Just about all of them. To be able to operate on an object you either have to have created it or received a token to the object from the one one who did create it. DCI is different, in that I can describe the operations on objects in terms of operations of roles. Those operations, and their mutual invocations, have nothing to do with the class of the created object.
So it does make sense.
>> That amounts to prematurely binding the role to the class. It's not DCI — DCI set out explicitly to solve this problem.
>
> What amounts to prematurely binding the role to the class?
Inheritance would be one way of prematurely binding roles to classes, because it depends on the compile-time type system. That is thinking in classes rather than thinking in objects, as is most thinking in terms of compile-time type checking.
> I don't understand.
I know. This is hard. But it's fundamental to what differentiates DCI from class-oriented programming, a.k.a. Restricted OO.
> The only time I ever use a type declaration for a role is
> at the point I am assigning an object a role, or thereafter.
I said nothing about type declarations for roles. My comment was about classes.
> Cheers,
> Ant
Rune, maybe you can help, as you seem to be able to cut to the quick with your comments.
On Sep 24, 2011, at 1:35 , Ant Kutschera wrote:
> On Sep 24, 3:31 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
>> Right — the compile-time type is that of the role, not of the object. But that's a gloss that isn't central to DCI.
>>
>> There has been much talk on the object-composition list of strongly typed or statically typed languages, and the relationship of that typing to DCI. I just don't get it.
>
> Me neither! From my perspective, this all started a few weeks ago, when you challenged us to show how wrappers could be used to implement DCI solution like your Ruby solution for Dijkstra's Algorithm.
>
> I presented a solution, and listed what I had to do in order to make it work [1]. There were a number of things which were unsatisfactory in the wrapper solution.
Yes, that's right.
> You criticised the wrapper solution [2] & [3]. Your criticisms partly seemed to relate to the use of a merged-interface.
Yes.
> I wasn't sure if you were saying the choice of interface name (Mega) was bad, or that having to declare the type was bad? Perhaps you could answer that directly, to clear this up for me?
Let's start with the name. Think of a good name. What would you have named it, given another chance? Much of DCI is about supporting readable code. By that, I don't mean indentation, but semantics and hermeneutics. Your code fails at the hermeneutic level because of the limitations of the technology you chose.
> If you were criticising the name, then what I have posted above at dci-evolution today, or what I posted at [4] should clear that up.
> Today, with what I quoted just above, you seem to be saying you don't care if one has to delcare the type?
The type of what?
> Then I ask you to read the code I posted at [4], using a different name for the merged interface, and
> highlight the exact lines which disturb you so much,
"Lines"? It isn't about individual lines. It's about a mental model.
> because when I compare that code, and your ruby code, I see almost exactly the same thing. Which means wrappers are a suitable way to implement DCI!
No, the last statement is too much of a leap: that one condition is necessary but certainly not sufficient.
>> I have often suggested to Trygve that we need some good type theory research behind DCI. That has very little to do with compile-time type checking, however. As has always been known by great object-oriented programmers, compile-time typing's software engineering advantages are often offset by how it harms expressiveness. I think DCI makes that explicit for those who are using it in an informed way.
>
> Oh... and now you're again saying that you don't like type
> declarations. Now I don't get it :-/
Did I say that? I don't remember saying that. And I can see that you don't get it.
This discussion depends on issues far more subtle than the arguments address here. That is why I am at a loss as how to respond. Addressing the questions on the table here doesn't go to the core issues of DCI. I don't think this is the right level of discussion to be having. I think I can show, at a lower level of discourse, why these issues are problematic, but I am concerned that it would be talking at cross-purposes to your line of argumentation.
As I have pleaded before, the only concrete arguments that can be persuasive in the end must be in program code. I am not eager to tool up for any Java environment on my machine as I want to keep it as free from any Java code as possible. At such time as I have the funds and time available to buy a machine and start a research program on why these solutions don't work, I'll announce it. In the mean time it's important that the arguments here proceed with more academic rigour than they have so far. So if you want to demonstrate that wrapper solutions work, convince me with a proof using retract theory.
>> If I were to write code like this, *it would surprise the reader*:
>>
>> public void doSomething(var myCar){
>> myCar.fly(); //cars can't fly!! surprised!
>> }
>>
> I agree. You've chosen a very misleading name for something that flies :)
Yes, that's right. I find Ant's argument in this case to be specious. I can just as easily say:
Airplane *chevrolet = new Boeing747;
chevrolet.fly(); // car's can't fly! suprised!
That is, the arguments I've seen here are not at the level of computational semantics but of syntax. While DCI supports a good syntax, it does so at the level of computational semantics — not just syntax for its own sake. There can be a link between a name and its semantic in DCI that is difficult or impossible in Restricted OO. If you try to simulate it in Restricted OO you end up with names like "Mega."
There is a rich compile-time type model, and richer run-time type model, behind these semantics. With regard to DCI, that is where the interesting arguments lie.
The above argument is not one of them.
The difference I was pointing out was not about assigning/binding as
much as about the direction but now that you point it out I find I
don't like assigning. To me assigning is the operation of assigning a
value to a storage location not attaching (aka binding) some value to
another value. So rephrasing what you said "binding the role to the
object" I think it turns things upside down. You should bind the
object to the role. The object is the one restricted to play one or
more specific roles at a given time in a given context. The role
doesn't even need to know of the object.
Den 24/09/2011 kl. 23.27 skrev Ant Kutschera <ant.ku...@gmail.com>:
> On Sep 24, 8:49 pm, rune funch <funchsolt...@gmail.com> wrote:
>> Well in the rest of the code you're doing exactly that. You are not
>> binding your role player to the typed local. You can't Java won't let
>> you because the role player is not of that type. You assign an object
>> that has a reference to the role player.
>
> You mean you don't like this:
>
> Plane aPlane = myCart assign Plane;
>
> Because you would rather have this:
>
> myCart assign Plane;
>
> Well, then you have a problem, because often, the name will be wrong.
> You'll write code like this:
>
> myCart.fly(); // surprise! I didnt know carts could fly
Why on earth would you call the role myCart if it's a plane? Looks
like you're mixing up a name that refers to the data outside the plane
context and the role name. The former is not valid inside the context.
> I am simply not convinced that it really makes such a huge difference
> to the code that it means I cannot do DCI if I have to do such type
> declarations like I do in Java.
I'm not talking about declarations. I'm saying I think it makes a l
LOT of a difference if you need to think of role players in respect to
types. To me it seems as if you are thinking in terms of data types
(cart) and role types (plane) I don't believe that to be DCI. We have
classifications of data in what-the-system is. Types are good for
that. We have a different kind of classification in
what-the-system-does.
Limiting this classification to what can be done with a type system
that was created to support the former classification just seem
unfortunate. If all you have is a hammer, well that doesn't make
everything a nail
> Are you really saying that in order
> to gain DCI certification, languages must not be allowed to require
> type declaration unless it is absolutely necessary?
Nope I'm saying this list is not about language but about DCI and no
language was build to support DCI so if we constrain the discussion to
a language discussion we are unnecessarily constraining the
discussion.
>
>> Depending on how you write. Code
>> it's entirely possible to write a compiler that can figure out the
>> type in most cases and let you specify the type if it can't
>
> Exactly, so there will be times when type declarations might be
> required.
Yes data.
> Does that mean that a language requiring them (whether its
> always, or sometimes) does not support DCI? I don't think so at all.
Yes that's what I'm saying the current classification is
"pre-renesance" it classifies objects as slaves/peasants/nobles which
is exactly what we need for data and is ill-suited (read can't) to
classify based on capabilities.
-Rune
• My wrapper object is of a type that has the methods from the role
and from the wrapped object
• In the definition of my role type I can find the role methods and
on the type of my data I can find the methods of the data class.
I wish we could discus DCI and not how various language build for
restrictedOO suck at it. We would discus how cars are worthless as the
foundation for a plain if this group was about inventing the airplane.
> On Sep 25, 10:50 am, rune funch <funchsolt...@gmail.com> wrote:
>> The difference I was pointing out was not about assigning/binding as
>> much as about the direction but now that you point it out I find I
>> don't like assigning. To me assigning is the operation of assigning a
>> value to a storage location not attaching (aka binding) some value to
>> another value. So rephrasing what you said "binding the role to the
>> object" I think it turns things upside down. You should bind the
>> object to the role. The object is the one restricted to play one or
>> more specific roles at a given time in a given context. The role
>> doesn't even need to know of the object.
>
> The tricky part of binding is to have the right name on the object,
> before you bind a role.
An object doesn't have a name. What do you mean?
>
> As an example:
>
> basket = ... //a plain object with data like a list of products
> basket.extend(Printer);
> basket.print(); //I personally don't like that. during analysis
> and design, and in the mental model, it is not the basket which
> prints, but the printer
I can't see how this relates to the discussion.
You either have a very bad name for your role (basket seems very odd
if the role is printer) or you are accessing an identifier that
shouldn't be available internally in you context. Binding is a
responsibility of the context so what is "basket" doing there? I'm
very confused about the code above. It look's like code from outside
the context based on the basket identifier and from inside because you
bind.
>
> "assignment" as we have called it above solves that problem (if you
> have the problem, like I do), because it forces you to start using the
> role name,
No DCI force you to use the role name in the context that's the only
valid identifier for the RolePlayer
> If we don't use "assignment" and just use "binding", then we don't
> have methodless roles anymore...
The term was bind when I first encountered DCI and we indeed had
methodless roles at that time.
Den 25/09/2011 kl. 12.26 skrev Ant Kutschera <ant.ku...@gmail.com>:
> I haven't called any role "myCart". Where did I do that?
myCart.fly(). If myCart is not the role then fly() (a role method as I
read your code) is out of scope.
>>> Does that mean that a language requiring them (whether its
>>> always, or sometimes) does not support DCI? I don't think so at all.
>>
>> Yes that's what I'm saying the current classification is
>> "pre-renesance" it classifies objects as slaves/peasants/nobles which
>> is exactly what we need for data and is ill-suited (read can't) to
>> classify based on capabilities.
>
> OK, so there is an important point here: while objects and roles are
> classifications, they are very different kinds of classification. For
> me, that statement is a keeper.
I'm sure you meant "while _types_ and roles are classifications"
On Sep 25, 3:03 am, "James O. Coplien" <jcopl...@gmail.com> wrote:I wasn't sure if you were saying the choice of interface name (Mega) was bad, or that having to declare the type was bad? Perhaps you could answer that directly, to clear this up for me?Let's start with the name. Think of a good name. What would you have named it, given another chance? Much of DCI is about supporting readable code. By that, I don't mean indentation, but semantics and hermeneutics. Your code fails at the hermeneutic level because of the limitations of the technology you chose.
I gave myself another chance, in that I posted the code again [4], and
replaced the name Mega with "Node" (albeit a different namespace,
which is basically what qi4J does [5]).
> An object doesn't have a name. What do you mean?
Technically, it does: its address. But that isn't germane to DCI.
In the bigger picture, this is a different way of saying what I said in my longer mail. Interesting that we both came to the same conclusion from different angles.
> It might at times sound like I am trying to force you all to believe
> that Java is 100% DCI certifiable, but I know it is not. But I do
> find it useful to look at where languages fail to be DCI certifiable,
> in order to see how languages must evolve, or how new languages must
> be written, in order to be DCI conform.
Regarding Java, I think we have a pretty clear picture of that in Qi4j.
If you are serious about this paragraph, let me challenge you to define a longitudinal research program that measured indicators such as coupling and cohesion in your implementation, as compared with the Qi4j results. Such analyses skirt syntactic details. That would make a good result suitable for peer review outside this community as well.
> In fact, isn't a methodless role, the variable name "printer", in the
> following role assignment:
I believe this to be a statement of thoughts constraint by how you are
trying to do DCI in java using wrappers forcing you to creat a new
object instead of simply binding one to a role. Who says that there's
a role variable at all. A variable is a named storage location and a
role is an identifier. If the identifier is an alias for the name of a
variable why would you need another variable?
That of course ties in with the discussion of identity and wrappers
just as the classification discussion does
> OK I entirely agree. So I in my role as a programmer I want to use
> that identifier in my code - where do I go look to see what methods I
> can call? What I do today in OO is go look at it's class, and perhaps
> super classes.
>
> But if I am using DCI, I go look at the roles which it is playing, as
> well as the class of the plain object.
I don't know how this paragraph relates to the next one.
> Maybe I am kidding myself, but I seem to be able to do this in Java,
> which means Java is not a dysfunctional language.
Java does well what Java does well. It is Turing complete. Dysfunctional is relative to a context, comparing the other languages to which it is compared and the purpose to which it is applied.
DCI entails more than the ability of objects to play roles.
I have yet to see evidence that it functionally supports DCI, while most other contemporary languages support it in large degree
> So, in my Till example, I think this property is missing when I think
> of things such as Printer - although I am not sure. What do you think?
Ask yourself does my context display the interobject activities? By
making the basket a printer does you show the relation and interaction
between the items bought and the receipt? Or would roles such as line
item and receipt make that more visible within a print context where
each item in the basket is in turn bound to line item?
> Is this in-between-ness an essential, fundamental property of good roles?
I think you're on to something here. It does conflict with another
Idea I have for a more generalized application of contexts but it
feels as if it's the idea that's unfinished and that I now have an
hint to what's missing
-Rune
“The name of the song is called`Haddock's Eyes’.”
“Oh, that's the name of the song, is it?” Alice said, trying to feel interested.
“No, you don't understand,” the Knight said, looking a little vexed. “That's what the name is called. The name really is `The Aged, Aged Man.'”
“Then I ought to have said, 'That's what the song is called'?” Alice corrected herself.
“No, you oughtn't; that's quite another thing! The song is called `Ways and Means'; but that's only what it's called, you know!”
“Well, what is the song, then?” said Alice, who was by this time completely bewildered.
“I was coming to that,” the Knight said. “The song really is `A-sitting on a Gate'; and the tune's my own invention.''
“But the tune isn't his own invention,” she said to herself; “it's `I give thee all, I can no more.'”
> "Basket" has nothing to do with class-oriented thinking.
>
> The basket is an object in my mental model, which contains, amongst
> other things, a list of products, which have been scanned by the sales
> person. The sale isn't complete, but the basket holds those
> products. Its just data.
That, by definition, is class-oriented thinking.
Role-oriented thinking is about:
- behavior (not data)
- relationships (not a thing in its own right)
If you have to say "contains" you are thinking data (as you say). Data are represented in classes — NOT in roles.
Your statement clarifies to me, irrefutably, that this reflects what I view as class-oriented thinking.
> So, in my Till example, I think this property is missing when I think
> of things such as Printer - although I am not sure. What do you think?
To me, at least at first blush, a Printer is not a role played by something. If someone says "Printer" to me in conversation I think of a specific object. There are many kinds of Printers in the world, by many manufacturers, that do many things, but those just form a CLASS hierarchy. I usually think of a Printer without thinking of the thing printed.
Objects of that class may play some role, and you have me thinking here, because I have a hard time thinking of any other name of that role other than "Printer." I guess that a Printer as a role prints something that is given to it... But there is some kind of confusion in my mind about this.
Thoughts?
Funny that you brought service up. When I wrote the about line items I
had exactly the same thought that basket/printer had a service feel to
it.
-Rune
Mvh
Rune
Den 25/09/2011 kl. 19.52 skrev Ant Kutschera <ant.ku...@gmail.com>:
Hint: Think of roles in terms of their relationships to other roles and see if that helps. I am getting a hunch that there is something really key to that.
Give it a try after a good night's sleep :-)
Pretend there is no computer: just people, things for sale, and pieces of paper. Good computer programs automate manual processes that work well. The computer isn't part of the problem space: it's part of the solution space. I don't want it as an actor in the use case. Given that, identify the actors. Write steps of the form:
Actor: action
Actor2: action2
. . .
Once that's done we can shape it into a use case scenario.
Then we'll figure out where the computer fits in.
Then the roles should just fall out of the wash.
On Sep 26, 2011, at 8:41 , Ant Kutschera wrote:
> - The till calls the payment partner to get an electronic payment
> authorisation.
That it is electronic is a low-level implementation detail, and that the till does the calling is, too. What human agent (role) initiates this?
Then we can use the till as a data object to implement that role.
> - The till creates a sales order in the sales order database.
Would a till create a sales order, or would a person (in some role) use a till (a machine) to create a sales order?
> - The till writes the sales log.
Probably a person, some kind of clerk or checkout person, who uses the till to do this.
> - The till prints the receipt.
But probably only at the behest of some human agent, who appears to be missing here.
> - The till empties the basket.
Do tills empty baskets?
Yes, that prevents you thinking about technical details in use case definition.
Furthermore, it clearly shows that your use case is not complete, but more like user story or a part of a use case.
How often did you go to the shop just either for completing payment or for picking up goods? Back in 1935 or 2011, only shoplifters go to shop just for picking things up. Also who goes to the shop just for payment?
I suggest that the whole "buy books from the bookstore" is the whole use case.
Btw. Does "add books into basket" use case have a business value? As a shopkeeper I would go nuts with "customers" just picking up books and never completing the sale either by paying things and leaving or returning books due to insufficient funds or other reason. I am unsure here, but my answer to that question is that "add books into basket" does not have business value and therefore isn't a use case, but maybe a habit.
-Risto
Having even more of these (that explore different contexts, variants of behavior, etc.) is even better.
I'm in a class right now but when I break free I'll take a crack at giving you some guidance to distill this into a use case.
Yes, so for the role classification to not be inhibiting, the language (or framework?) needs to be dynamic. We must not be forced to define a priori what roles objects will play, but rather be able to assign them dynamically at runtime.
But none of that has much to do with using a typed name to refer to a role player. In fact sometimes that can be an advantage. For example it can assist tools in offering support like code completion and refactoring.
----- Reply message -----
From: "rune funch" <funchs...@gmail.com>
To: <dci-ev...@googlegroups.com>
Subject: FullOO (a.k.a. DCI) Summit in Oslo
Date: Sat, Sep 24, 2011 09:58
2011/9/23 ant.ku...@gmail.com <ant.ku...@gmail.com>
Hi Cevat and others,
"...because RestrictedOO is based on classification."
While not directly related to what you wrote Cevat, this phrase made me think of something.
Becaue my language of choice forces me to delare types (for parameters, arguments, variables, fields, etc), I find myself often thinking of roles in terms of their interfaces. Implicitly, this means I am classifying roles, doesn't it?
But I don't feel this hinders anyone.Thinking of roles in terms of an explicit interface actually does hinder me at the moment. I have a side project where I'm developing an application for mobile platforms. I'm using MonoToiuch and MonoDroid. Most of the code I write is going to be platform independent but some stuff is going to be platform dependent. I can't change the interfaces the types implement, and even if I could I would want to be cause those changes would disappear with the next release of MonTouch/Droid. If the context where these objects plays a role was based on interfaces I would have to implement them once for each platform. Now I can reuse them as long as the potential roleplayers have methods signatures/properties that match. In this case method signatures that match is not very likely and I have to adapt them but for a text label to have a property called Text or similar is very likely.
I agree that DCI classifies as well but in a different manner. For lack of better terms I'd say you could talk about inhibiting and facilitating classifications. An inhibiting classification would be the classes societies a few hundred years back. Up north where I'm from we had "trælle" (kind of a slave) "bønder" (peasants) and "herremænd" (nobles). Those were classifications of the people of Scnadinavia a few hundred years back. You were born into one of those classes a with a high probability you'd die in the same. That classification inhibits you from becoming anything else.Today we have other kinds of classifications e.g. we classify people as a pilot if they are flying a plane. We expect them to have all the required abilities to fly the plane but leave it to some one else to verify that.
To me using interfaces on data to determine what roles they can play lands in the inhibiting classification style. They can only play those roles and more importantly those types that does not implement those interfaces are inhibited from playing those roles and there's nothing you can do about it as in my example above.
Classifying objects based on what they are doing (roles) is different. As long as the object is playing the role of a pilot the object is a pilot. When implementing the class of the object you don't need to know what roles they are going to play. It won't limit which roles they can play. The abilities of the class determines what roles the objects of said class can play and if a new role comes along the same applies if the behavior is there the object can play the role, you have to change nothing. Having to change nothing is a big difference when the role player is implemented in a library you can't or won't change
-Rune
Trygve Reenskaug mailto: try...@ifi.uio.no
Morgedalsvn. 5A http://folk.uio.no/trygver/
N-0378 Oslo Tel: (+47) 22 49 57 27
Norway
On Sep 25, 2011, at 4:17 , Ant Kutschera wrote:So, in my Till example, I think this property is missing when I think of things such as Printer - although I am not sure. What do you think?
To me, at least at first blush, a Printer is not a role played by something. If someone says "Printer" to me in conversation I think of a specific object. There are many kinds of Printers in the world, by many manufacturers, that do many things, but those just form a CLASS hierarchy. I usually think of a Printer without thinking of the thing printed. Objects of that class may play some role, and you have me thinking here, because I have a hard time thinking of any other name of that role other than "Printer." I guess that a Printer as a role prints something that is given to it... But there is some kind of confusion in my mind about this. Thoughts?
User narratives tend to personate the User, which is in this case "a customer".
How often did you go to the shop just either for completing payment or for picking up goods? Back in 1935 or 2011, only shoplifters go to shop just for picking things up. Also who goes to the shop just for payment?
I suggest that the whole "buy books from the bookstore" is the whole use case.
I don't think the goal is to create as many roles (or anything) as possible. An important part of mental modeling is chunking. We have engineering rules like Occam's Razor, the 5 +/– 2 rule of short-term memory, and other heuristics that help make code understandable.
The 7 +/1 2 number is one of the most widely promulgated myths in psychology, based largely on web-assisted mass propagation of research dating from the mid-1950s. Even if you stretch the original research to believe in the popular number 7, that result applies to letters rather than to higher-order concepts, for which the number is much lower. And even then, there are newer research results using better research methods, and those conclude that the magic number is closer to 5 +/- 2. See, for example, http://www.mdjunction.com/forums/bipolar-type-ii-discussions/general-support/3021312-short-term-memory, http://tastyresearch.com/2006/08/30/debunking-the-seven-plus-or-minus-two-myth/, http://en.wikipedia.org/wiki/George_Armitage_Miller, http://www.usc.edu/CSSF/History/2003/Projects/S0309.pdf.
These myths tend to propagate in part because they take on social mythological proportions. But they also propagate because of poorly Shepherdized citation in academia — also one of the main reasons that the object community was never able to shed many of the myths that came in the early days of OO and persisted, even though subsequent research debunked them. For that reason people still believe that object-orientation is all about polymorphism, productivity and reuse. The fundamental notions of mental models and object identity become lost in the ignorance of modern publication. This is probably the greatest enemy of DCI today.
But so it is with any paradigm shift.