IWETHEY v. 0.3.0 | TODO
1,095 registered users | 0 active users | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New I just don't get OO design decisions
The "3-graph model" referenced under "Flame" ([link|http://geocities.com/tablizer/bizmod.htm)pretty|http://geocities.co...d.htm)pretty] much "encapsulates" (he he) my typical biz-app design philosophy. Define the schemas, ER diagrams (implied or explicit), then divide the problem up into "tasks", and build the liaison layers to help isolate tasks from schema changes and org. Even software-engineer-poor shops pretty much follow this formula. Their biggest problem is not factoring common behavior into subroutines or perhaps even a tablized framework in some cases. But even without the factoring of commonality, such a setup is still eazier to grok than any OOP biz design or usage I have seen. More change-friendly too IMO because the "big structure" is specified via relational and Boolean formulas, and *not* physical code organization. IOW, in p/r, patterns are a "view", and not a code structure for the most part.

Further, some OO fans still insist that "things are better organized" if you break things down into hierarchical classifications or "sub-types" (like collection taxonomy API's with stacks, queues, etc). I find almost nothing about real world change patterns that fits such structures. Yes, things can be forced into tree taxonomies, but it makes a mess because it is not fitting reality IMO. (If you don't fall into the taxonomy camp, then ignore this part.)

I just saw a book by M. Fowler the other day that suggested using one "list" of pointers (reference to object instances) to know which items were not processed yet. IOW, rather than setting a flag in a table of items, he proposed a list of references to them. This IMO is really sloppy design (and more coding). Attributes should not be specified by their physical location for the most part. Is he gonna make such lists for every potential Boolean attribute? It just seems that OO fans don't "get" tables. And Fowler, like Meyer, was a highly recommended author. (Unlike Meyer, I only glanced thru Fowler.)

(Granted, if each given user needed their own list, then a second table {collection} may indeed be needed, but I don't think this was the case in the example.)
________________
oop.ismad.com
New I believe I understand why you have a problem
You are unable to understand any OO code unless you have mentally rewritten it in terms of your favoured paradigm, at which point it is a lot uglier than it would be if written in terms of your favoured paradigm from the start.

Since you never tried to understand OO on its own terms, you are unable to manipulate its structures directly. Being unable to do that, you are unable to see how to work with things which have been set up in an OO manner. This makes you unable to understand how to use it.

Now rather than go on about how much this mental handicap costs your employer, I am going to recommend a non-OO book as a good way to understand it. That book would be Code Complete by Steve McConnell. It is all about practical coding advice to program well in a procedural environment. Whether he is talking about the One True Brace Style or discussing naming flags, he has excellent advice backed up with plenty of references to the literature.

Buried in his advice on how to modularize code there is a little section about the benefits of abstract data types. That section does a rather good job of explaining the fundamental principles that make OO a useful way to work, even though he never uses words like "Class" or "Object", and even though he talks about how to use the concept of an ADT in purely procedural code written in a purely procedural language.

Pick up that book for everything else in it. But do read that section. After you are done reading that section say the following, A class is a way of implementing an abstract data type, and having data encapsulated in objects is merely a way of keeping data associated with the appropriate abstract data type. There may be more to OO than this (a lot more) which OO people like going on about (mainly because, having learned it, they think everyone else should as well), but that simple idea, combined with the wins listed in Code Complete of using abstract data types, give about 90% of the real win from having OO designs available.

(Wins which a bad OO design can easily lose for you, but that is another issue.)

Cheers,
Ben
New Re: I believe I understand why you have a problem
Problem with "code complete" is that he describes a programmatic lifestyle that Microsoft seems not to have embraced.
"Beware of bugs in the above code; I have only proved it correct, not tried it."
-- Donald Knuth
New Well, my philosophy says...
Their failure to follow their own good advice is no reason for me not to follow it. :-)

Cheers,
Ben

PS That is, of course, if I think the advice is good. Which I do in this case.
New ADT's and Coddlets
>> You are unable to understand any OO code unless you have mentally rewritten it in terms of your favoured paradigm, at which point it is a lot uglier than it would be if written in terms of your favoured paradigm from the start. <<

I won't deny that my head tries to tablize OO structures. However, that is because tables are more grokable and structurally compact IMO. They are lined up in a clean pattern, row and column names are not repeated in each and every cell, etc. They strip out the repetitious packaging crap and are leaner meaner and cleaner. Then I mentally convert the OO relationships into SQL-like relational formulas. That is more compact and abstract than seeing each node's reference to others via a hand-built manual index, as it appears in OOP patterns.

>> Being unable to do that, you are unable to see how to work with things which have been set up in an OO manner. This makes you unable to understand how to use it. <<

It is like going back to hand tools after using powertools. IOW, building "node indexes" by hand; like stringing the wire like Xmas decorations. I have mentally reduced the complexity of GOF patterns into mere simple formulas (more or less), and you want me to go back to bricks and mortar. That is how I see this. How can manually putting up the Xmas decorations be superior to issuing a few formulas to tell the computer (how) do it?

Codd was a fricken genius (although it took a few people to clean up his ideas). He found a way to reduce complex patterns into set-based and Boolean-based relational formulas. My software and tables define the pieces (elements), then Codd's magic strings it all together with tiny, easy to change formulas. IOW, the big picture is in the "Coddlets" and *not* the code structure itself. You don't have to read the entire application to find the underlying pattern; you only have to read the Coddlets and then apply them to the good ol' stable, consistent tasks+schemas p/r model. That is a little bit of an idealistic description, but that is what my head keeps trying to achieve and I cannot make it do a U-turn.

Now, with regard to ADT's, Meyer's book had a whole section on ADT's. His primary examples showed how one could hide away the implementation of a simple collection engine (find, add, delete, count_nodes, etc.). IOW, be able to swap out the implementation without affecting the code that uses those operations. One could switch to a linked list instead of say arrays without changing the calling code.

Is Code Complete's description of ADT's superior to OOSC2's (Meyer)? If I drop by the bookstore again soon I will take a look.

I agree it is an interesting concept. However, I cannot extrapolate such into realistic projects.

I have been bathed in plenty of "OO Lore". The problem is that nobody can show me how such concepts make *better* business applications. I use tables, not arrays and not linked lists (although the post-XBase anti-nimble-table world has forced me back into arrays a little bit), so I don't have to worry about swapping between arrays and linked lists.

In custom biz apps one rarely writes different implementations of the same thing (for use at the same time). That would be a waste of money. Thus, there is nothing to "swap out" the implementation of, at least nothing that I actually code myself.

IOW, my OO training is reality-deprived. The concepts are cute (at least the first 10 times I heard them), but I cannot find applicability such that they make software more change-friendly than p/r in a demonstrate-able way (such as thru change impact analyses).
________________
oop.ismad.com
New Coddlets?
Google searc turn up nothing. Could you clarify?
New From the context: Applets + Codd = "Coddlets".
He used Codd's name repeatedly, and the parallel to "applets" is obvious -- well, if you work in a company that markets portal plug-ins as "portlets", it is...

So it must mean little snippets, not of code functionality, but of data structure (in this case, TABLE! :-) definitions... Something like that.

HTH!
   Christian R. Conrad
The Man Who Knows Fucking Everything
New And "little snippets of data structures" make no sence to me
New Me neither - but don't blame me; it's *his* concept! :-)
New Virtual Structures
>> And "little snippets of data structures" make no sence to me <<

It is not snippets of data structures themselves, but snippets of specification of the relationships between the base components.

IOW, rather than "build the tree" in code like you do in stereotypic OOP, you *define a formula* for a tree. (Hypothetical only since it is the specific views that are defined, not physical structures, and so the label "tree" is not really appropriate.)

In p/r, one is less pressured to "model" up front, because it is assumed that the structures eventually used are *virtually* created as needed. You just have to make sure that enuf info is available in the "nodes" to be able to apply a structural formula to.
________________
oop.ismad.com
New I understand all words
, but cannot make out what you're trying to say. May be an example?
New how about this then
We could compare a p/r "role pattern" to an OOP one:

[link|http://www.geocities.com/tablizer/prpats.htm#role|http://www.geocitie...ats.htm#role]

(I didn't show the OOP version. Jay posted a Java version once, but I don't remember where it is. Anybody volunteer one?)
________________
oop.ismad.com
New Odd. Not a single mention of "coddlet" anywhere.

New "A formula for a pattern or structure"
________________
oop.ismad.com
New Still odd.
The only use of word "formula" on the whole page is here:

>>>>>>>>>>>>>>>>>>>>>>>>>>>
You will note that many of my examples don't include a lot of code. This is because many of the GOF-influenced patterns are mere "viewpoints" in the relational world, created by a trivial relational or Boolean formula, and not a physical code structure. This makes them easier and less intrusive to test and change. Thus, to us table fans, GOF-like patterns appear Neanderthalic. It is better abstraction to use formulas to represent repeating patterns than to physically repeat them. For one, the same items can more easily participate in multiple patterns. Think about it.
<<<<<<<<<<<<<<<<<<<<<<<<<<<

No matter how much I thnk about it, I don't get it. Do you mean using "WHERE" clause of a SELECT (or may be a view) instead of a list or a table holding needed elements? Fine technique, when you can employ it. But not really new or deserving its own term. Or did you mean something deeper?


New Jay, where is your "Roles" link?
________________
oop.ismad.com
New I think you would prefer what Code Complete has to say
For one thing he isn't pushing OO. He isn't tying the idea of an abstract data type to a huge amount of structure, and then using it to sell a bunch of design patterns. He is trying to make a point about the value of abstraction and modularity.

For another, he elsewhere suggests using table lookups as another useful abstraction technique. :-)

As for your looking at things with tables, yes, Edgar F. Codd was a genius. His relational databases are a beautiful way to organize data into components such that people can combine, organize and extract it on the fly in very useful ways.

It is not, however, a good way to rewrite OO. For a start the abstraction that is OO is applied to itself recursively. (You build abstraction layers on abstraction layers.) This kind of recursive abstraction is something that relational databases are bad at expressing (see the complications with keeping hierarchical structures in relational databases) and while you can rewrite any particular example in a table structure, in so doing you lose sight of this central key fact.

What that means on a practical level is that you are unable to see or follow any of the transformations that make up modification and code reuse in OO. Yes, you can do both the starting and the finishing version. But you can't see how simple the change was for what it did. You can't see it as simple, and you can't see how you would do it. You are thinking relationally, and relational thinking simply sucks when it comes to modelling layering abstraction layers on top of each other. (Because that is a hierarchical action, and relational databases don't model nested hierarchies very well.)

That is when the examples are simple. When they get complex, you might as well be dealing with people who are speaking Greek. No matter how easy they seem to find understanding each other, you can't understand any of them. It just sounds like incoherent babbling. And it will continue to sound that way until you stop having to mentally translate everything to and from a language in which the basic concepts simply cannot be stated.

Cheers,
Ben
New You must think in *Russian*! Think in *RUSSIAN*!
10 LRPD Points[tm] to the first person to name the movie.

Very good points, and key I think to understanding why Bryce doesn't understand what we're talking about.

Relational sets have a very different algebra than graphs. Yes, sets are very powerful (and they have their own native means for representing hierarchical relationships, such as nested set trees), but they aren't the entire world. Being able to think in both worlds vastly expands the range of solutions one can provide.
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New Firefox, Clint Eastwood and the semi-telepathic MiG.
[link|http://us.imdb.com/Title?0083943|Tagline: His job...Steal it.]
Expand Edited by CRConrad Jan. 30, 2002, 12:17:43 PM EST
New Second, was FireFox. (book was better than movie)
-----
Steve
New Abstraction level is relative and graph-like IMO
>> He is trying to make a point about the value of abstraction and modularity. <<

Does he use *actual* examples that reflect how one would actually do it in the real world? That is what I really really need to see: actual usages of such in practice so that I can see the code structure and how it behaves under different change scenarios (change impact analysis).

>> For a start the abstraction that is OO is applied to itself recursively. (You build abstraction layers on abstraction layers.) This kind of recursive abstraction is something that relational databases are bad at expressing <<

This is another fundamental difference between us. Nested abstractions in general *don't work* in business applications IMO. To simplify (compartmentalize) things, *views* work best. The problem with levels is that what is a high-level detail from one user's perspective is a low-level detail for another. Relevancy is relative. Level is relative. (If Einstein and Codd had a baby together, he/she would know exactly how I think :-) Perhaps in other domains it works, but I don't see it in biz apps. I create abstractions per-task rather than per-level. It is a graph view of abstraction instead of a tree view of it.

I think computer scientists keep over-using nesting and trees. They are an intellectually attractive concepts, but fail to accurately reflect real-world issues. (I think hierarchical file directories are fundamentally flawed, BTW.)

>> This kind of recursive abstraction is something that relational databases are bad at expressing (see the complications with keeping hierarchical structures in relational databases) <<

I don't think they do a bad job at it. You just need to augment them a little with some standard tree-traversal operations in some cases (not that much different than IMS actually). Oracle has experimented with tree operations in SQL. Note that IBM's IMS database (born around1965) heavily used nested structures. It was found to be less than ideal and most were glad to upgrade to RDBMS.

>> What that means on a practical level is that you are unable to see or follow any of the transformations that make up modification and code reuse in OO. <<

I am not quite sure what you mean by this.

>> But you can't see how simple the change was for what it did. <<

This should be demonstrate-able, no?

________________
oop.ismad.com
New Nested abstractions do work in business
When the CEO of a company says they will have a booth at a major conference, the CEO tells people to make it so. The CEO doesn't need to know the details of who to ask to get a prefabbed both. The secretary who gets that doesn't care where the raw construction materials come from. The person who buys the raw construction materials doesn't need to know about the manufacture of plastics beyond who sells them, and how much they cost. And so on.

In short when you look at how our economy is structured, the whole thing is a series of abstraction layers. At every layer, whether it is between businesses or between people within a business, there is a hiding of details that the person asking doesn't need to know which really do need to be known to satisfy the request. That isn't theory. That is specialization in action, and was documented centuries ago by Adam Smith.

This doesn't mean that any particular business problem should be solved with nested abstractions, or that OO is the right way of abstracting things. This just means that layering abstractions on abstractions is something that businesses do all of the time. Explain it in terms of actual people doing real jobs, and you can see it in practice. (OO models the people as objects and the jobs as method calls. That is all.)

Now as for Code Complete, Steve McConnell isn't grinding any ideological axes. He gives real examples from real code. But he isn't focussed on overall design of projects. Instead his focus is on actual decisions made while coding. It is very practical and direct. One of his points happens to be relevant for this discussion, but his book is just plain good stuff to know.

Furthermore if you want to see an example of OO design in Perl, I would point to LWP. Don't try to master its internal design, that is a mistake. The point of abstracting details into interfaces is to avoid having to learn those details. Instead try to use it. Here is one:

use LWP::Simple;
print "Please name the URL: ";
chomp(my $url = <STDIN>);
getprint($url);

Try it out. Note the good old [link|http://name:password@www.whatever.com/page.hml|http://name:passwor...com/page.hml] syntax for handling names and passwords, how easy is it to modify your application to handle that? Switch the protocol from http to https to ftp, was that hard? Put a proxy server in the way, set the appropriate environment variables (eg set http_proxy to [link|http://yourproxy:proxyport/|http://yourproxy:proxyport/], ditto for https_proxy, ftp_proxy, then set no_proxy to addresses you get directly), did that do what you expect?

If you allow the base URL to be given by the user, your code doesn't ever change at all. And wouldn't change even if 15 new protocols you had never heard of were added.

What actually happens is, of course, wildly different based on what the protocol is. But you don't know, and you don't care. Because the person writing that program shouldn't have to know and shouldn't have to care. So getprint is a very simple functional wrapper around a common set of OO requests to a fully functional OO library whose design makes replacement of one protocol by another utterly trivial and straightforward.

Cheers,
Ben
New "Layers" is not appropriate for the most part
>> In short when you look at how our economy is structured, the whole thing is a series of abstraction layers. <<

Abstractions, yes. "Layers"? Not really an appropriate description IMO. The abstractions are graph-structured "views", and not so much nested "layers".

>> At every layer, whether it is between businesses or between people within a business, there is a hiding of details that the person asking doesn't need to know which really do need to be known to satisfy the request. That isn't theory. That is specialization in action, and was documented centuries ago by Adam Smith. <<

Yes, but graph (webbed) views, and *not* really layers. Roles, filters, call them whatever you want, but "layer" implies something higher or lower than the other, which is not appropriate to a relativist like me.

Some details for a secretary are not important to the boss, and visa versa. For example, the boss may see HR details of an employee he is about to fire. However, the secretary may only see a note to remove the fired dude from the mailing lists. She sees less, he sees more.

But, if she is asked to schedule a meeting, then the boss may only see the final time slot, whereas she may ponder several candidate time slots. In this case, she sees more and he sees less. (The opposite of the fire example.)

(I realize the genders used here are stereotypical, but making them PC would be more typing to make things clear.)

IOW, the "level" of details in this example is independent (orthogonal) of the employees' rank. Further, attaching behavior or detail level to rank is too heavy coupling because the tasks may be reassigned or rearranged later. Thus, one should use a very light form of coupling, such as tables of access rights, for example, instead of hard-wired "types".

Things change.

>> Explain it in terms of actual people doing real jobs, and you can see it in practice. <<

Yeah, teams temporarily or permanently coming together to solve a given task. Sounds very p/r to me.

>> What actually happens is, of course, wildly different based on what the protocol is. But you don't know, and you don't care. <<

Exactly. Whether the protocol *internally* selected is based on polymorphism, case statements, or a table lookup is hidden away from the user of such thingies. I have a whole webpage devoted to "swappable device drivers" bringing up many of these philosophical issues. I would note that in biz apps, the division between "types of drivers" may blur, as the programmer is not trying to make a commercial-grade super-generic driver or split them up into different DLL's for shipping purposes.

Thus, if two different "drivers" share enough code, then they may be merged and the differences managed with say IF/Else statements. Generally if more than 50 percent is the same, then merge them and use IF/Else statements to select the differences. However, if less than 50 percent is the same, then make them two different modules and call the shared parts.

Your example is kind of a systems software example. I would like to see more of a *business* example. (I might look at it closer during the weekend regardless.)

________________
oop.ismad.com
New That's not the kind of post I 'd like to get...
I was hoping to see how you reach a _particular_ decision, not another instruction on how to think tables.

Here is one of my own:

I have a large data structure (a tree of 4 levels). In one opf the levels, tree nodes hold large pieces of data that will be same across all subtrees. Since I may havbe 10s of 1000s of subtrees, I need to store those large pieces (let's call them OIDs for brevity) in one place, and then refer to them from the tree. In fact, those things may be so large, even 10 subtrees provide substantial savings of memory.

Now, how do I implement this?

I need a separate data structure to store OIDs. When I create a new node in my tree, I must quickly find the OID for node among existing OIDs or create a new one. Then I need a pointer to store in my node, a pointer that gives me quick access to the OID's data.

My first impulse was to create a class for OID storage. The only method for such class would be findOid(const void *data, size_t dataSize).

Then I stop. What will findOid() return? And, if nodes are removed from the tree, do I ever remove unused OIDs from OID storage?

OK, now I get a class with 2 members: "something" findOid() and releaseOid("something"). But it's still not clear what "something" is.

Another step, almost automatic - we need to have ref counts for OIDs so that we don't release something that is being used by some nodes. Since C++ has no garbage collection, it's a must.

OK, so for each OID I need to store its data and ref count. And I need to return something that would allow me to access the data and decrement ref count. What if that "somethnig" getc copied? Do I need to increment the ref count for the copy?


And then the big break comes. What if, instead of using a class to represent something "secondary" to the solution - OID storage - I use a class to represent something that I must have no matter what - a smart pointer to OID data?

Once I get this, everything flows from here. The InternedOid ("interned" comes from Java strings) will have 2 kinds of constructors: one constructor will locate or create OID in hidden global storage, others will simply pass OID pointer to new instance or create "empty" pointer. I also define = operator. All of the above manages ref count as needed. And it's totally tarnsparent for the user of the class.

Tada!



That's the kind of monologue I wanted from you. Could you try?
New Why the Tree focus?
>> I have a large data structure (a tree of 4 levels). In one opf the levels, tree nodes hold large pieces of data that will be same across all subtrees. <<

I think we should perhaps explore *why* use trees instead of how.

It is hard to propose a realistic solution and test it against change scenarios if we don't know the context anyhow.

________________
oop.ismad.com
New No tree focus.
The tree is actually irrelevant to the problem solved. You can say that I have an array , and each element contains a large OID, and OIDs are repeated in array, so I want to extract them to only store each OID once.

Also, I am not looking for better alternative for _my_ solution. I am looking for your example of _your_ problem solved. Then we could compare the way insight works for both of us, and may be we'll see why OO looks so bad for you (tables do not look bad for me :) )

Lastly, to answer your question (keep in mind, it's not important) - I am writing an SNMP poller. It polls targets (first layer). Each target has multiple objects (SNMP term, it essentially means data fields) to poll (second layer), such as time since last restart or number of octets that passed through a particular interface. Each object can be polled in different way fo rdifferent clients, so under objects I have subobjects, third layer.
Expand Edited by Arkadiy Jan. 31, 2002, 01:59:03 PM EST
New Have you thot of tables?
>> tables do not look bad for me........Lastly, to answer your question (keep in mind, it's not important) - I am writing an SNMP poller. It polls targets (first layer). Each target has multiple objects (SNMP term, it essentially means data fields) to poll (second layer), such as time since last restart or number of octets that passed through a particular interface. Each object can be polled in different way fo rdifferent clients, so under objects I have subobjects, third layer. <<

Then have you considered a table solution?

I am not sure if OID is globally unique or not in your system. However, a basic table may resemble:

Table: SNMP
-----------
TargetID
OID
Protocol
LastPollTime
PoolCount






________________
oop.ismad.com
New Not relevant.
Bryce, the quality of my solution is not relevant. I just posted it to illustrate _how_ ADTs come up in my thinking. I want to see _you_ solving _your_own_ problem. I want to see how you come up with tables. My solution was in C++ - I want to see your solution, for your problem, in real language you use every day. I want to see how you come up with your solutions. Then we'll compare thought process we use, and may be it will clarify our differences.


(To answer your (irrelevant) question, the proper table structure would be:

table OID {
int oidId
string oidData
}

table polledSubOid{
int targetId
int oidId
int pollFreq
int lastPollTime
and so on
}

But, this is all in memory, and C++ does not give me nice table API. It needs to work really fast, need to scale really well, so I stick with C++.

Again. This is not relevant. Please use your own problem and your favorite real language.
New what is wrong with them?
>> But, this is all in memory, and C++ does not give me nice table API. <<

Are you saying there is a speed or other resource constraint here? I am sure there are plenty of ways to hook C++ up to tables. I have even seen a C API set that accesses XBase tables (.DBF) somewhere on the web. I can't vouche for the quality though.

Note that once the stuff is in tables, you can use higher-level utilities like FoxPro to browse, search, summarize, report-on, etc. the data.

>> Please use your own problem and your favorite real language. <<

None of the "6 challenges" examples are sufficient for whatever analysis you wish to do? If so, may I inquire why? Can they be expanded to fit what you are looking for? The thought process is generally the same as described in the 3-graph write-up.

________________
oop.ismad.com
New Bryce, please pay attention.
Arkadiy has asked you several times now to pick a programming problem that you have solved using your programming techniques and explain the step-by-step thinking. He gave an example of how he works through such a problem; now could you please provide one of your own?

Wade.

"All around me are nothing but fakes
Come with me on the biggest fake of all!"

New seperation of concerns
>> He gave an example of how he works through such a problem; <<

I notice that his design is heavily based on how it will be used and on performance issues.

I tend to make sure that the entities have all the needed peices of information associated with them. The operations that will be done with entities is generally an independent issue, beyond making sure the "raw" information is available for later coddlet transformations.

If the entities are well designed, then I apply my "coddlets" for a given task to give the rest of the task the information it needs. The coddlet tends to isolate the task operations from the schema structure. Thus, it is sort of a seperation of concerns.

IOW, if you have a good schema system, the rest tends to flow naturally.

He seems to be coupling his class design to the immediate needs of the problem. What if vastly different needs come along for the same data?

It would be interesting for him to finish his table version and describe how he thinks it through. Perhaps he can find some assumptions that I missed on a conscience level.
________________
oop.ismad.com
New Duh!
"I notice that his design is heavily based on how it will be used and on performance issues."


Wow. Really?
New Perhaps p/r is moving above that
________________
oop.ismad.com
New Bryce, Static is right.
I didn't really want theoretical "challenges". I wanted a problem you had faced last week, solved in language you actually used to do it.

But, since you won't provide such info, I looked at [link|http://www.geocities.com/tablizer/chal01.htm|Challenge 1]. Now I have a question:

Do you consider the "re-worked p/r version" to be better code than the original p/r version?

New what is the goal?
>> I didn't really want theoretical "challenges". I wanted a problem you had faced last week, solved in language you actually used to do it. <<

For the last 2 years or so, most of the stuff I have worked on has been incremental maintenance, and not "from scratch". (Few companys are building *new* things in these tight times.) Thus, I have no fresh brain droppings to present. (The tool tracking project mentioned around here a few months ago comes to mind, but it is not done yet, and somebody else has since been assiged to design the schemas instead of me; so my schema design will likely never get tested. IMO my design was more long-term change-friendly, but theirs probably models the existing system better, and is thus considered a safer bet.)

But, my 3-graph model article is a pretty good summary of the general process I go thru. It is time-tested and works.

Further, what should be considered is how maintenance-friendly the result is, not the intellectual steps to model the first run IMO. Isn't that the goal here?

>> Do you consider the "re-worked p/r version" to be better code than the original p/r version? <<

If you mean automating the most-frequent joins, if it was built into the DB engine then it would almost certianly be worth it (I hear some engines *do* have a similar feature) unless specifying partial joins versus full joins creates more syntax than it saves. However, joins don't take up that much code in practice and thus is not worth the bother. John's example is kind of exaggerated and comparing apples-to-oranges.

Plus, the issue of product classification has not really been dealt with. Division into "types" is probably a mistake (I lean toward set membership). But, we would have to look at the actual business to model a better approach. His OOP example is shorter than his p/r example primarily because the joins are specified elsewhere and classic but misleading polymorphic hat-trick WRT polymorphic product "types".

Do you want to get into product classification here? It keeps coming up in examples anyhow, so perhaps I should byte the bullet and write about it.

________________
oop.ismad.com
New The goal is to further the discussion.
I am attempting to understand what you mean by table-oriented programming and how it's different from OO programming.

I noticed a piece of code in your example that looked familiar to me. I want to know if you consider it a better code. If you do not, we are back to square one. If you do, I have some more to say.


Here are the pieces of code I wondered about:


String query = "select *
from invoice,
customer,
sales_rep,
invoice_line,
product,
product_type
where invoice.customer_id = customer.customer_id
and invoice.sales_rep_id = sales_rep.sales_rep_id
and invoice.invoice_id = invoice_line.invoice_id
and invoice_line.product_id = product.product_id
and product.product_type_id = product_type.product_type_id
and invoice.date >= today()";
ResultSet rs = con.executeQuery(query);
while(rs.next()) {
switch( rs.getInt("product_type_id") ) {
case 1
total += base_calculation()
case 2
total += extended_calcuation()
case 3
total += special_offer_calcualation()
case
}
}




versus




// Re-worked p/r version
rs = openRS("inv2", "invoice.date >= today()")
while getNext(rs) {
total += invoice_getTotal(rs)
}





Yes, I do realize that a significant piece of second approach is missing.
New that depends
So that's the one you meant. Silly me, I did a search for "rework" instead of "re-work".

Whether it is "better code" or not depends on a few things. The second is better procedural decomposition, but it does not reduce *overall* code nor better repetition factoring (so far). And, excess procedural decomposition requires too much eye-jumping IMO. If the first had bold headlines, I might consider it equal:


// ********************************************
// Total all invoices based on a given criteria
// ********************************************

//------Get SQL------
......
//------Loop thru each invoice [or invoice detail item]---
while
. . . //-----Calc each item detail-----
. . . ......
end while


IOW, with bold headlines, you don't really need code succinctness as much. Further, the SQL is specific to the task, so routinizing it does not give us any real reuse or repetition-factoring value that I can see. (The join clauses are the best place to focus on repetitition factoring if one decides to go that route.)

Other p/r fans may have a different viewpoint. What annoys me may not annoy others. Given a choice, programmers tend to optimize code and designs for their *own* minds.
________________
oop.ismad.com
New OK, getting somewhere.
So, there is something to the second option. It is no worse than the first, and in some ways it's better.

Personally, I never use comments to replace function calls, except may be in tight loops. But in any case, the structure is there, and it's important.

I think your beef with OO is mostly syntax. I can tell you that the second variant of the code is not only good procedural decomposition, but it has beginnings of good OO decomposition. If you prefer to write invoice_getTotal(rs) instead of rs.getTotal(), that is fine with me. As long as you see that there is a bunch of functions related to invoice, and invoice is presented as a piece of data passed to those functions, you'll write good code, whether you call it OO or not.If you do not notice that there is such thing as "total" that can be computed over any "rs", you're not a good procedural programmer either.


New Now THAT is the crux....
I think your beef with OO is mostly syntax. I can tell you that the second variant of the code is not only good procedural decomposition, but it has beginnings of good OO decomposition. If you prefer to write invoice_getTotal(rs) instead of rs.getTotal(), that is fine with me. As long as you see that there is a bunch of functions related to invoice, and invoice is presented as a piece of data passed to those functions, you'll write good code, whether you call it OO or not.If you do not notice that there is such thing as "total" that can be computed over any "rs", you're not a good procedural programmer either.


From the gist of this whole message, you are beginning to see the reasoning we all end up quitting arguing with Bryce. As he just ignores relevant facts. Don't worry your "progress" will be all for naught, in the next few replies.

And Bryce, I am beginning to think you will never be able to debate these "issues" you have with OO to a reasonable level of disagreement with most of us here. You just cannot see things the way we see them. Although we most definately are seeing your way of viewing things.

greg, curley95@attbi.com -- REMEMBER ED CURRY!!!
In 2002, everyone will discover that everyone else is using linux. ** Linux: Good, fast AND cheap. ** Failure is not an option: It comes bundled with Windows. ** "Two rules to success in life: 1. Don't tell people everything you know." - Sassan Tat
New only one fact here
>> As he just ignores relevant facts. <<

What "facts" prey tell? I only see opinions and claims and cliches. I don't see it saving keystrokes or making things objectively easier to find or making less code spots that need changing, etc.

If OOP helps you PERSONALLY grok code or designs better, that is fine with me. Just DON'T extrapolate what makes your neurons comfortable onto mine UNTIL you have some externally objective demonstration.

>> You just cannot see things the way we see them <<

That is probably the *only* fact here.

>> Although we most definately are seeing your way of viewing things. <<

I question that. If it was true, then you would be able to come up with better justifications beyond cliches and authoritarianism appeals.
________________
oop.ismad.com
New I disagree
>> I think your beef with OO is mostly syntax. <<

If it was that simple and minor, then why all the pressure to get away from p/r to begin with?

>> As long as you see that there is a bunch of functions related to invoice, <<

I only see one here. Besides, totals may be able to be calculated by only looping thru the *detail* entity (invoice line items) and may never even have to touch the Invoice entity.

Tying operations tightly to entities is generally poor design IMO anyway. The entities that may be involved in a given calculation can vary widely. IOW, different nouns may be used in formulas over time.

>> If you do not notice that there is such thing as "total" that can be computed over any "rs", you're not a good procedural programmer either. <<

Conceptual only. In many cases it might take nothing more than SELECT SUM(Amt) FROM InvcDetail". In fact, one normally does not re-calculate the line-items and totals if they want to sum them: they have already been done at the point of sale. Recalculating them may give a different answer than what the customer saw and actually paid. For example, some of the coupons may have expired before the time of re-calc. Thus, SELECT SUM... may be sufficient for the vast majority of cases.

Reality keeps barfing on the clean view of polymorphism. I don't know why, it just does. (It is John's example, not mine.)

________________
oop.ismad.com
New May be.
>>>>>>>>>>>>>
If it was that simple and minor, then why all the pressure to get away from p/r to begin with?
<<<<<<<<<<<<<

I don't think there is pressure to get away from p/r. A good OO aproach has to be good procedural approach before it becomes any good at all. And anyone who uses databases has to be good with the "r" component.


>>>>>>>>>>>>
>> As long as you see that there is a bunch of functions related to invoice, <<

I only see one here. Besides, totals may be able to be calculated by only looping thru the *detail* entity (invoice line items) and may never even have to touch the Invoice entity.
<<<<<<<<<<<<


The exact details are not relevant. It is a good procedural practice to break up long functions into many calls to smaller functions. And often you end up with a bunch of functions taking some struct pointer as first parameter. That's where OO begins.

If your problem domain is simple eniugh to have "SELECT SUM(Amt) FROM InvcDetail" - more power to you. You don't need OO. You don't even need terribly good procedural programming. You only need both when things get hairy, when you end up with single function that takes 1500 lines of code. That's when you break it up (into subroutines, or into methods)

>>>>>>>>>>>>>>>
Reality keeps barfing on the clean view of polymorphism. I don't know why, it just does. (It is John's example, not mine.)
<<<<<<<<<<<<<<<

Did I mention polymorphism anywhere yet? Polymorphism comes after incapsulation. We are trying to establish the merits of encapsulation here. When and if I'll convince you that incapsulation is simply a tiny syntactical extension of good procedural programming approach, we'll move on to debate polymorphism.
New the calculation complexity may not even matter here
>> I don't think there is pressure to get away from p/r. A good OO aproach has to be good procedural approach before it becomes any good at all. <<

I am not sure what you mean.


>> If your problem domain is simple eniugh to have "SELECT SUM(Amt) FROM InvcDetail" - more power to you. <<

I did *not* assume the whole thing was simple. I am suggesting that even if the orginal price calculations require a trillion lines of code, the summary process may *still* be a relatively simple operation. Well-designed systems are often like that.

I have worked on systems with relatively complex discounting rules, yet the *end result* was still a simple number (price) in a table.


>> You only need both when things get hairy, when you end up with single function that takes 1500 lines of code. That's when you break it up (into subroutines, or into methods) <<

For the sake of argument, and to get things moving along, assume that we do break things into routines to your satisfaction.

________________
oop.ismad.com
New It does not matter indeed.
I am trying to get at ease of understanding and modification. But we are a long way off yet.


>>>>>>>>>>>>>>>>>>
>> I don't think there is pressure to get away from p/r. A good OO aproach has to be good procedural approach before it becomes any good at all. <<

I am not sure what you mean.
<<<<<<<<<<<<<<<

I meant that you have to be a good procedural programmer before you become a good OO programmer. OO does not replace good p/r programming, it is built on it.

>>>>>>>>>>>>>>>>>
For the sake of argument, and to get things moving along, assume that we do break things into routines to your satisfaction.
<<<<<<<<<<<<<<<<<

"To my satisfaction" in this context would mean that we end up having some data structures that are passed as poiners or handles (or using names and table lookup) to functions that modify/use those data structures. Do you agree that it's a common occurance in well-structured procedural programs?
Expand Edited by Arkadiy Feb. 2, 2002, 11:52:14 PM EST
New Regional Scope to the Rescue
>> "To my satisfaction" in this context would mean that we end up having some data structures that are passed as pointers or handles (or using names and table lookup) to functions that modify/use those data structures. Do you agree that it's a common occurance in well-structured procedural programs? <<

Relatively common, but *not* pivotable. At times I make them "regional" (module) scoped variables so that I don't have to keep passing them around as params. Keeps the code cleaner and simpler that way IMO. It is a form of "repetition factoring". If there is only one "main query" in a module, then passing it around intra-module generally does not buy you anything. In languages like PHP that don't have regional scope, this is not possible.

>> I am trying to get at ease of understanding and modification. But we are a long way off yet. <<

"Ease of modification" should be fairly easy to demonstrate: simply offer a set of (allegedly) typical change-scenarios that you think your version fairs better at and apply them using numerical change-point counts or whatever metric you like.

However, "ease of understanding" is relative and subjective.

________________
oop.ismad.com
New Regional Scope - ok.
I don't know what the word "pivotable" meansd to you. For me, if it happens often, it's worth consideration.

Your "regional scope" is rather good idea. So good in fact that OO provides 2 levels of it. You can have class-scoped variables, or instance-scoped variables. All that to save parameter passing.

Here is how you can look at encapsulation through "scope" lenses. Suppose you have a module that parses a string for you (substitute some sort of DB access and use if you prefer):


======================================

ParseString.h

void setStringToParse(const char *str);

void setParseMode(/*some crap describing parsing */)

const char *getFirstToken();

const char *getNextToken();


======================================

ParseString.cpp

static const char *parsedString; /* that's you regional scope, isn't it? */
static const char *currParsingPoint;

/* and so on */


/* implement the functions from .h here */

=======================================



Now, before we go any further, is that a good example of "regional scoping"?
New I think so
but my C++ is extremely rusty. May I suggest Java or Python examples instead. Java probably has the widest audience here.

I agree that classes can have a very module feel. The differences are usually when it comes to "instances" (AKA "state").
________________
oop.ismad.com
New It was really C, not C++
I'd have hard time expressing it in Java w/o using classes. And I don't know Python enough to write (barely enough to read). But, now that we established how regional scoping looks in a non-oo language, I'll proceed to use Java examples for the rest of encapsulation discussion.


You say: "I agree that classes can have a very module feel. The differences are usually when it comes to "instances" (AKA "state")."

Well, don't you have a need sometimes to "clone" a module? For example, suppose you need to keep track of parsing more than one string at a time. What you do in a procedural language is take your static, module-scoped variables and make a structure out of them. Something like

struct StringParseContext
{
const char *parseString;
const char *currParsePoint;
};

(that was my last C example, I promise)

And then you initialize and use the structure. And that "clones" your regionally-scoped vars. They became instance-scoped vars.

(BTW, unless I am wrong, Ada, which is not really an OO language, has an explicit concept of cloning modules, much as I explain above but with extra syntax support)

So, the very basic level of OO is to come up with ideal "module" for doing something to a piece of data. And then to be able to clone it as needed to work with more than one piece of data at a time.



New Welcome to Table Land
>> It was really C, not C++ <<

My C is rusty too :-) I havn't written a C program that needed header files since about 1993.

>> Well, don't you have a need sometimes to "clone" a module? For example, suppose you need to keep track of parsing more than one string at a time.... <<

This usually is where I enter Table Land. Granted, the "standard" RDBMS approach is a bit bulky for this kind of thing. However, XBase has taught me that tables can dance like a butterfly and sting like.......

If the number of "clones" can be open-ended, such as based on user input, then given a preference I turn to tables.

The standard reply from OO fans is something like, "But wouldn't you like to group the parsing operations with the structure that they operation on?". I then reply something like: If the structure is determined in code, then place the structure next to the code. However, as the application scales, often multiple modules or tasks need access to the same data structure. Building a one-interface-fits-all to such a structure can turn into a can of worms. Further, tables are already an interface as far as I am concerned. If you want some kind of "global protection", then use triggers or referential integrity or something.


________________
oop.ismad.com
New So, each clone's data is a row?
Fine with me. But you still need to act on row number, or primary key, or something. Please understand, I don't care how you store your data, as long as you agree that you need instances (clones) of data stored somehow.

For example, when you use dBase (forgive me if my syntax is crap, I've been out of dBase longer than you've been out of C):

SELECT InvoiceLines
SCAN FOR InvoiceNo = Invoice.invoiceId
Invoice.shippingCost = Invoice.shippingCost + computeShippingCost()
ENDSCAN

you may not think about it, but computeShippingCost() can be thought of as a method on InvoiceLine instance. The fact that the object has no name and its pointer is passed implicitly by setting workspace row pointer to the proper row is not that important.
It's all about how you think about stuff, not about syntax. You have to say to yourself: "How do I find the shipping cost for _one_line_of_invoice_?" Once you used a noun, you have an object, whether your syntax looks that way or not.
New Multiple Entity Association Candidates
>> as long as you agree that you need instances (clones) of data stored somehow. <<

This has been going on since at least punched cards. This seems like a trivial statement, unless you meant something I missed.

>> you may not think about it, but computeShippingCost() can be thought of as a method on InvoiceLine instance. <<

I suppose. But, what does that get me? And......


>> You have to say to yourself: "How do I find the shipping cost for _one_line_of_invoice_?" Once you used a noun, you have an object, whether your syntax looks that way or not. <<

Well, that is one way to look at it, but again, I don't see what it buys me.

The calculation of shipping costs could involve multiple entities (nouns), you should notice. For example, it might be stored at the Invoice level, not at the line-item level (but that is not the only choice). It may also reference a weight table for the various shipping services. It is like a human neuron: multiple input sources with one output (value).

Thus, there are 3 candidate entities to associate it with. Association with entities is more or less continuous and multiple and dynamic in my observation. Further, it may change. For example, we may originally store shipping costs at the Invoice level (one slot per invoice). However, we may later decide to make it another line item (invoice detail), along with other options such as Tax, Fee(s), Discount, etc. Using the You-Must-Associate-Every-Action-With-One-And-Only-One-Entity view of OOP, we have two problems:

1. There are multiple candidate entities (nouns) to associated it with.

2. We may change which entity/noun it should be associated with. This change would be less disruptive under typical p/r because we don't have to *move* any code. OOP would have to move it from one class (entity) to another.

(Your XBase is marginally better than my C :-)
________________
oop.ismad.com
New Re: Multiple Entity Association Candidates
>>>>>>>>>>>>>>>>>>>>>
>> as long as you agree that you need instances (clones) of data stored somehow. <<

This has been going on since at least punched cards. This seems like a trivial statement, unless you meant something I missed.
<<<<<<<<<<<<<<<<<<<<<

I am talking about cloning API's static data. And yes, this is an ancient idea. But not quite trivial.


Now, as far as multiple candidates for association... I don't know about you, but for me at any given moment there is only one proper association. Any other seems arbitrary or wrong (at the moment). If you can think of shipping cost computation for a line as something that belongs to whole invoice - fine. But then, at least in my mind, this method can not belong to a single line. Distribution of methods among classes is one of the finest point of OO. What does it buy you? Your code structure reflects the way you think of your problem domain. If you say: let's compute shipping cost for invoice, then your code will say so, explicitly. If you say: invoice's shipping cost is computed by summing up shipping costs of lines, your code can say that. Explicitly. By having both Invoice.computeShippingCost() and InvoiceLine.computeShippingCost(). If the invoice's shipping cost is the function of shipping method, which is the same for all lines, and total cost of invoice - you can say so, again. In your code, not in comments. Encapsulation allows for more direct translation of problem domain statements into code.

You say that moving code around is a hassle. But it's a small price to pay for keeping your code in sync with business model. If, all of a sudden, you learn that each invoice line can have its own shipping method, moving the shipping cost computation to InvoiceLine class is a small price to pay for writing down your new understanding of problem domain.



New Genericness
>> but for me at any given moment there is only one proper association. <<

To me, this appears to be a doctrine-induced habit on the part of OO followers. Or perhaps some peoples' minds are simply more comfortable with "master associations" taking precedence. Relation to a "single master entity" is a rather weak and relatively useless concept in my mind. It is too restricting and change-unfriendly IMO. Besides, one can physically group all invoice-related code together, if there is such a thing.

What if the function is designed such that the scope is open ended? Example:

criteria = "InvcID=32 and DestinationID in (85, 87, 92)"
sc = shippingCosts(criteria)

The ShippingCost function belongs to nobody! It is more or less "generic" WRT the scope it operates on. True, it probably uses invoice detail records, but the scope is not necessarily per detail record. It could cover a single detail line in some circumstances, a group of line items going to the same destination (similar to above example), the entire invoice, or a complex combination or subset.

It is achieving generic-ness that OOP often brags about, but cannot seem deliver when it over-couples operations to single, narrow entity instance.

>> Your code structure reflects the way you think of your problem domain. <<

Do you mean:

1. The way one *should* think about the problem domain?

2. The way *you* think about the problem domain?

3. The way *most* people *actually* think about the problem domain?

4. ?


>> If you say: let's compute shipping cost for invoice, then your code will say so, explicitly. <<

Yes, as a query or scope criteria. That is explicit.


>> Explicitly. By having both Invoice.computeShippingCost() and InvoiceLine.computeShippingCost(). <<

Why?

>> Encapsulation allows for more direct translation of problem domain statements into code. <<

I am sorry, but I am not seeing it. Requests often come in the form of, "if this and that, then do such and such".

>> If, all of a sudden, you learn that each invoice line can have its own shipping method, moving the shipping cost computation to InvoiceLine class is a small price to pay for writing down your new understanding of problem domain. <<

At least you are admitting to *some* "shuffling costs" of moving (and possible duplication of code). That is a start.

My approach seems more change-friendly. As far as being "self documenting", I prefer Coddlets over physical positioning to indicate what is going on. Coddlets are more multi-aspect-able. I don't want to be locked into picking one dimension at the expense of or dethroning of other perfectly valid dimensions. It is classic OO *IS-A* mentality taken too far again IMO.

The IS-A-ness of OO keeps bothering me in various incarnations. (A list of annoying IS-A-isms is at my website.) It is a theme that OO fans keep locking onto or are attracted to for some reason. They find some grokability comfort in it somehow, while I find it constricting and rather arbitrary. It is like a *bad* single parent is better for OO fans than multiple parents of varying and dynamic importance.

Both the like of it and the distaste of it seem to be an inborn head-wiring thing. If you are going to completely rewire my head, it may just take a good while.
________________
oop.ismad.com
New Expressing problem domain
I don't think associating functions with data is a habit induced by OO. I had it long before I came across OO. All well-structured APIs are built around that habit.

As to your example implementation, I find it highly ugly. What the hell does it do? Compute total of shipping cost of lines in invoice 32 that go to Zip codes 85, 87 and 82? I had to think a lot before I formed that guess.

I want _my_own_ code to reflect, as straightforwardly as possible, _my_own_ current understanding of problem domain. I _do_not_ want my code to reflect my understanding, knowlege and mastery of programming language.

Your latest object-independent code is good enough for an ad-hoc query, where all you care about is to get results quickly. If you need something more long term, you'll need to do something like:

invoice = GetInvoice(32);
properDestinations = SelectInvoiceSubset(invoice, "DestinationID in (85, 87, 92)");
sc = CalculateShippingCost(properDestinations);

I'll leave it as an exersice to the reader to demonstrate how those lines are closer to OO.


I am not using physical positions for self-documenting. I am using function names and variable names. Your coddlets may actually have another name: functions.

Yes, it may take a long time. But I hope to demonstrate that style that does not keep track of the relationship between functions and data they operate on is not good in the long run. The reason is - it tends to express your mastery of coding rather than your understanding of problem domain. And it's the second, not the first that matters in the long run.


New Misunderstanding
I should have made it clear that those were only *sample* destination numbers. I did not mean that such were hard-wired into production code. Let's say that the numbers are gathered from another operation that *dynamically* groups shipping costs based on available carriers if the customer approves of mixed shippers. If not, then one shipper is used.

>> I had [been doing] it long before I came across OO. <<

Perhaps you were born with an OO mind. OO fans often say that OO simply formalized the way they always saw programming when it came along.

>> But I hope to demonstrate that style that does not keep track of the relationship between functions and data they operate on is not good in the long run. <<

And I hope to demonstration that artificial, exaggerated, and/or forced coupling (associations) is not good in the long run.


________________
oop.ismad.com
New Actual numbers don't matter much.
It could have been a value of variable - my objection still stands. My code reflects my understanding of problem domain. Your code does not reflect your understanding of problem domain, or at least I can't deduce your understanding from it.



Nothing "artificial, exaggerated, and/or forced" is good in any run - long or short. My contention is that in addition to all artificial and forced couplings one can come up with there _always_ is at least one that is natural and proper. It is always worth the effort to find that coupling, because, when found, it has deep roots in problem domain, allowing your code ... (you heard that already).

Why do I think there always is a natural coupling? Because of the structure of our language (and, therefore, our thought process). Whenever we use a verb, there is a noun somewhere, the actor, the doer, explicit or implied. That is the natural and proper connection I struggle to make obvious in my code.
New Spoken Language?
>> Your code does not reflect your understanding of problem domain, or at least I can't deduce your understanding from it. <<

Are you suggesting that it is random?

Perhaps we are optimizing for different things. One of my ultimate goals is to make the system *change-friendly*. Mirroring the *current* problem statement as strong as possible is not at the top of my priority list, for it will *drift* away from that. Using a Coddlet I can relatively easily change what the "input tenticles" tap into. IOW, I see no benefit and some drawbacks (moving around methods that even you agreed a bit with) to putting a strong bond between the operation and an entity.



>> Why do I think there always is a natural coupling? Because of the structure of our language (and, therefore, our thought process). <<

It is a bit premature to assume that language reflects the way our individual heads *actually* work. English is *not* optimized for my head, as you can tell by reading this. You are also implying that Swaheelly speakers think different than English speakers. That may indeed be the case, but this just underlines the relativism nature of my claims.

>> Whenever we use a verb, there is a noun somewhere, the actor, the doer, explicit or implied. <<

Again, my main goal is to maximize change-friendliness, and not necessarily mirror English sentences. I suppose you could claim that something is easier to change if it is easier to grok (by matching verbal languages), but I would probably reply, "then learn to think in Coddlets" and grow beyond human language. (Mirroring the "take your medicine" suggestions of some of youses.)

In some ways I think my approach models business behavior: a bunch of people or resources temporarily come together to work on some designated task or goal. When the task is done, the team splits up to work on other things in other combinations using other roles.

Note that sentences can have multiple nouns: "Bob, Rita, Miki, Arther-Anderson consultants, and Todd all got together to plan the new Spring advertizing compaign." (Hmmmmm, this kinda reflects what NKING said.)

Yet, there is only *one* verb.
________________
oop.ismad.com
New Re: Spoken Language?

>>>Are you suggesting that it is random?

No, randomized :). You intentionally changed rather good piece of code you had before to demonstrate different approach. And that took you to shorter code, but less obvious meaning.

>>>>>>>>>>>>>>>>
Mirroring the *current* problem statement as strong as possible is not at the top of my priority list, for it will *drift* away from that.
<<<<<<<<<<<<<<<<

The thing is, we have nothing else to "mirror". If the code does not reflect our current understanding of what it's supposed to do, then what does it reflect? And if the code is a self-sufficient object not reflecting anything, how is another person to understand what it's doing?


>>>>>>>>>>>>>
It is a bit premature to assume that language reflects the way our individual heads *actually* work. English is *not* optimized for my head, as you can tell by reading this. You are also implying that Swaheelly speakers think different than English speakers. That may indeed be the case, but this just underlines the relativism nature of my claims.
<<<<<<<<<<<<<

I have to agree, it was my basic assumption. _I_ can only think in words, therefore I can't think outside forms provided by natural language. I assumed it's a general human property. Are you saying I was wrong?

As to Swaheely (sp?), I suspect it's structure is similar to English. I am yet to hear about a language that has no nouns or no verbs.

I do indeed claim that before you change you need to understand. How do you know what part to change whe you are tols that each line in invoice is now allowed its own shipping method? You need to realize how the shipping cost calculation was set up before. I am still not sure what "codlets" are. I have a strong suspicion that they are rather closely related to functions. Care to show an example of coddlet?

>>>>>>>>>>>>>
Note that sentences can have multiple nouns: "Bob, Rita, Miki, Arther-Anderson consultants, and Todd all got together to plan the new Spring advertizing compaign." (Hmmmmm, this kinda reflects what NKING said.)

Yet, there is only *one* verb.
<<<<<<<<<<<<

Yes. And that's called aggregation. Those guys and gals formed something known as Working Group. And, by the way, if you continue the story, you'll find out that Rita presided over meeting, new advertizing ideas were generated by Miki, consultants formed a unified front to shoot those ideas down, and Todd was simple there for head count and drunk lots of coffee. See where I am going? The code would be rather like:


WorkingGroup group = new WorkingGroup();
group.setPresident(rita);
group.addConsultanta(consultantA);
group.addConsultanta(consultantB);
group.setBallast(todd);


void WorkingGroup::conductMeeting()
{
while (president.getNewIdea(miki)) {
if (consultants.ideaIsAcceptable(president.getCurrentIdea()))
president.recordActionItems();
else
president.dropCurrentIdea();
ballast.anotherCuppaCoffee();
}
}







New Hmmmm. Verbal thinkers versus visual thinkers
>> And that took you to shorter code, but less obvious meaning. <<

If one gets used to such, then it *is* obvious.

>> If the code does not reflect our current understanding of what it's supposed to do, then what does it reflect? <<

It *does* reflect it, just not the way you prefer.

>> I have to agree, it was my basic assumption. _I_ can only think in words, therefore I can't think outside forms provided by natural language. I assumed it's a general human property. Are you saying I was wrong? <<

I tend to think visually. Images and actions appear in my mind first, and then I translate them into words (if required). I come from a lineage of artists. I wonder if other artists are also table fans?

I have heard others state that OO fans tend to be "verbal thinkers". I don't remember where I heard this.


>> I am still not sure what "codlets" are. I have a strong suspicion that they are rather closely related to functions. Care to show an example of coddlet? <<

In general they are expressions that tell how to structure and relate something. The idea is to have a formula for the relationships and patterns rather than physically structure things in the desired way. I find it easier to change a formula than to change a physical structure of the building blocks. It is also easier for multiple things to participate in different views this way IMO. It is all about creating "virtual views" of structures and relationships. "Coddlets" usually take the form of Boolean and set-based expressions. SQL is probably the most popular example.

>> if (consultants.ideaIsAcceptable(president.getCurrentIdea()))
president.recordActionItems(); <<

Hmmmm. The president only listens to the consultants.

BTW, I forgot to add the copy machine, photo-lab, and corporate library to the mix.

________________
oop.ismad.com
New Seems like end of conversation, then.
OO is for those who think in words. TOP (I still don't quite get it, but so be it - I guess I think differently) is for those that think in images. Next time, before you start talking to somebody about OO, ask which way he/she thinks. If in pictures - you'll find a thankful listener. If in words - you'll find an intersting but purposeless fight.

If you were asking my opinion (which you aren't) I'd say that words are better suited for computers. But it's just me.

To all: next time you are tempted to argue with Bryce - remember this thread. At least for me, the temptation comes from very basic difference in thinking process. Such differences cannot be settled by an argument.
New See also Stephenson, In The Beginning Was The Command Line..
New Actually, I like command lines
....if they are well-designed.

It is generally easier to type in a substring ("contains") and get a short list of numbered matches than to browse thru a huge picklist of titles. My fingers are faster than my eyes, it seems.

However, I have never seen such implemented like I envision it. Some systems "fill in" from the right side, but that is not good enough. It *must* be a "contains" to work effectively (for me).


________________
oop.ismad.com
New Noted.
He often seems to come so close and then something twists and he won't go any further. I recall much the same sort of discussion way back on IWE about lexical analysis.

Wade.

"All around me are nothing but fakes
Come with me on the biggest fake of all!"

New Can our differences really be all that simple?
>> If you were asking my opinion (which you aren't) I'd say that words are better suited for computers. But it's just me. <<

But they seem to do tables pretty well.
________________
oop.ismad.com
Expand Edited by tablizer Feb. 7, 2002, 09:46:35 PM EST
New Simple?
You call fundamental difference in how people think "simple"? I disagree.

My beef is not with tables. OO can meake good use of SQL, lookup tables, even tables containing code, although that's stretching it. My problem is that you don't see the relationship between action and actor. Apparently, for you, actions just happen, without any acting entity, or at least without a single main acting entity. That goes contrary to the way my brain works.
New Compared to others, yes.
>> You call fundamental difference in how people think "simple"? I disagree. <<

It is a much "cleaner" explanation than most others floated, especially those floated at the end of heated debates :-)

>> My problem is that you don't see the relationship between action and actor. Apparently, for you, actions just happen, without any acting entity, or at least without a single main acting entity. <<

I see the relationship as open-ended and dynamic and multiple. I see the relationship to actors like *local* variables: created, used, then tossed away. IOW, the relationships are "encapsulated" within a given operation more or less. If you make it global, then you have more dependencies to change if the relationships change IMO.
________________
oop.ismad.com
New On visual thinking.
If you haven't read it, you might enjoy [link|http://www.amazon.com/exec/obidos/ASIN/0679772898/qid=1013179102/sr=8-1/ref=sr_8_3_1/103-9334142-8588622|Thinking in Pictures] by Temple Grandin. She's an autistic woman who is a professor and [link|http://www.grandin.com/|designer of cattle handling facilities]. She thinks visually.

It's a very interesting book.

Cheers,
Scott.
New mooooo
>> If you haven't read it, you might enjoy Thinking in Pictures by Temple Grandin <<

A visual thinker with less-than-perfect social skills and who likes to hang around cows?

I donno. My wife thinks I need more exposure to *normal* people.

Movies and books that glorify wacked-out geniuses put too many "risky thoughts" into my head, her theory goes.

Thanks for the tip, however.

________________
oop.ismad.com
New I've heard her speak..
And on the level of this discussion - I second Scott's recommendation. And don't at all get why you'd dismiss with such disinterest -?- a title almost the same as your self-description!

Or is that a feigned obtuseness - to keep your rep intact? ;-)

I don't do code, but still found some of the above examples intelligible enough to imagine I see something of.. (??) different kinds of gears whirling in the old neural networks. The comments re the 'view' of an end-user VS the methodology - I deemed a nice vindication of the idea that, even in complex symbolic logic - good (English or other) language usage can produce near-enough comprehension..

I only got this far because - for once - it seemed there was a mutual desire to actually get to the Sticking point(s). And that's as good as the NY Times Crossword :=\ufffd

Think you ought to check out Temple Grandin -- there can't be Too many out there, constructed 'zackly like You, y'know?

[/book review]


Ashton

Who congrats Arkadiy and Bryce for 'keeping it in the pants' and producing an intelligible sequence.. if not quite the definitive Omega (!?) of it all.
New Sp: "Swahili". Kwaheri, Jambo!
(Which means "Hello, Friend!", IIRC. :-)

Oh, and if you see Bryce talking about "speghetti" or "relevent", he probably means "spaghetti" and "relevant"...

HTH!
   Christian R. Conrad
The Man Who Knows Fucking Everything
New I've had enuf of your irrelevent, speghetti insolts :-)
________________
oop.ismad.com
New Hey Bryce, I was just over on /. and revisited an old...
...post of mine that you'd replied to in the meantime: No, I didn't do any "scoretrolling". (And AFAICR I hadn't read the other posts you referred to; that's why I didn't reply to your points about them.)

Speaking for myself, I couldn't have "scoretrolled" (AFAIK), since I'd posted in the thread... But I don't think anyone else from here would have done that either.
   Christian R. Conrad
The Man Who Knows Fucking Everything
New Okay, you are off the hook
>> No, I didn't do any "scoretrolling". <<

Okay, I apologize for jumping to conclusions. The relative sudden drop in ratings and you coming around could have very well been purely cooncidental.

>> I couldn't have "scoretrolled" (AFAIK), since I'd posted in the thread... <<

Some people have multiple logins.

________________
oop.ismad.com
New Re: Spoken Language?
I am still not sure what "codlets" are.
Baby cod, of course.

They grow up into big cod, destined to end up on my plate alongside chips and mushy peas.

Damn. Now I'm hungry.


Peter
Shill For Hire
[link|http://www.kuro5hin.org|There is no K5 Cabal]
New Nothing else is possible with you.
Bryce:
Perhaps you were born with an OO mind. OO fans often say that OO simply formalized the way they always saw programming when it came along.
Naah, he was probably born with a mind that was *ggod for programming*. That's what OOP is; a codification of "best practices" from pre-OO programming.


And I hope to demonstration that artificial, exaggerated, and/or forced coupling (associations) is not good in the long run.
How about you (at least try to) demonstrate [sic] what's *good* about *non*-OO programming, in stead of going off on yet another silly rant on what's "bad" about OOP?

We'll never be able to understand what you claim is so good about your "p/r"[*] style of programming, until *you* give *us* an example of *your* reasoning[+] -- a full-fledged example, from basic requirements to (at least an outline of) working code.

That's what this thread was supposed to be about (or perhaps rather, lead up to), you know... But as usual, you've diverted the conversation from the original tack taken by someone else, by your obstinate refusal to answer the question asked of you.

Why[#] do you persist in doing that?!?
   Christian R. Conrad
The Man Who Knows Fucking Everything


[*]: Still a misnomer -- OOP is not the opposite of "p/r", it's the opposite of "just p". The opposite of "p/r" would be "OOP/R".

[+]: If there actually *is* any, which I kind of doubt...

[#]: Unless you start to play ball, we'll have no other choice than to assume it's because you know you'd disprove yourself by disclosing it.
New Did you notice...
...I am trying to show some respect here? Calling someone's mind "no ggod for programming" is not going to acomplish much, except starting a flame war.
New What're you talking about?!? I called a mind (yours) "good"!
New Thank you.
But you did it through calling my opponent's mind "not good". I will not be the one to flame you, you see? But the flames will fly anyway, and whatever small possibilioty of understanding we currently have would be lost.
New More like the other way around...
I sez:
What're you talking about?!? I called a mind (yours) "good"!


To which Arkadiy replies:
But you did it through calling my opponent's mind "not good".
Naah. It's vicey-versy; Through calling your mind "good for programming", I left a door open for someone to take away the impression that I don't think Bryce's is as good... But one doesn't *have* to. So, if one does, perhaps that tells more about the one who does so than about what I actually said, eh?

That's called the Fine Art of Implication. (Or was it tFAoInnuendo?)


I will not be the one to flame you, you see? But the flames will fly anyway, and whatever small possibilioty of understanding we currently have would be lost.
Lissen, Ark, when you've been around Bryce for as long as I have -- which is five years, now -- maybe you'll realise that there IS NO, however small, possibility of understanding with Bryce.

And by then you'll certainly know in your bones that most people some times, and some people most of the time -- no prizes for guessing which category I think Bryce belongs to -- DESERVE to be flamed.
   Christian R. Conrad
The Man Who Knows Fucking Everything
New Right you are.
You did not say anything about his mind. I was wrong. I guess it does say something about me.

As for Bryce, I've been around him as long as you, if not longer. I've seen hin appear at IWE. I guess his long sabbatical from these fora (yeah, yeah, I remember how it came about) made me hopeful again. And I have to admit it made him more civil.
New Actually, you are right too...
...about that last point:
And I have to admit it made him more civil.
Too bad he hasn't become any less stubborn, or more open-minded!

Hey, no, sorry: You *have* made some progress, Bryce.


As for Bryce, I've been around him as long as you, if not longer. I've seen hin appear at IWE.
As long, then, but not longer. Dang, really? Sorry, I must have plain forgotten you'd been around for that long. (I think I had, somehow, the impression you were too young for that.)
   Christian R. Conrad
The Man Who Knows Fucking Everything
New not think like me == bad mind ?
>> Lissen, Ark, when you've been around Bryce for as long as I have -- which is five years, now -- maybe you'll realise that there IS NO, however small, possibility of understanding with Bryce. <<

Other table fans who send me email seem to "click" with what I have to say. People who tended to hire me for contracts also liked tablizing things in many ways.

It is a common human fault to conclude that:

! think like me == bad mind

I am trying to overcome this built-in human bias by NOT suggesting that my approach is objectively better. It fits my head better, that is all I objectively claim (if that is not a contradiction). The examples on my website are simply bonus information where I *try* to communicate my dissatisfaction with OOP.

I don't seeing you trying to overcome this bias in any way.

(By the way, he may not have directly said it, but the implication is rather strong.)
________________
oop.ismad.com
New Walk Before Run
>> Naah, he was probably born with a mind that was *[good] for programming*. That's what OOP is; a codification of "best practices" from pre-OO programming. <<

Then why do you CRC have a preference for Delphi over Smalltalk? Sure, I could probably buck up and go with the OOP flow to get by (I'll never be a star perhaps), but that still doesn't answer the question of why X is allegedly better than Y.

BTW, if it is truely "best practices" then it should be relatively easy to show how these practices improve maintenance over the other practices by showing the keystrokes/mousestrokes, typing, etc, that programmers go thru. I know this is a rather crude metric, but in the end that is what it always boils down to from an objective standpoint.

Grokability is generally *not* measurable in individuals, only in aggregate. Thus, what we have left is human body movements to perform various software maintanence tasks. Now, you may claim *most* people fit OOP better and the "left handers" just have to go along, but this is probably not true, and another topic.


>> How about you (at least try to) demonstrate [sic] what's *good* about *non*-OO programming, in stead of going off on yet another silly rant on what's "bad" about OOP? <<

I have a whole website with small examples. True, small examples are of limited value, but when we *do* get into the nitty gritty, the differences often appear to *subjective*. Things like, "if you do it that way, then you risk busting this stuff over here." Reply: "Yeah, but that rarely happens to me practice, so why should I worry about preventing that?" IOW, what F's person A up may *not* F person B up.

I have coined the term "mental ergonomics" for this. (Yeah yeah, I know, you don't like my coinages.)


>> a full-fledged example, from basic requirements to (at least an outline of) working code. <<

IMO, we should walk *before* running. The Reports example is a relatively good starting place. After we beat that one to death, then we can work up to something bigger.

Such a system could grow quite large anyhow as one tacks on one-off changes that the main framework cannot handle directly. Such one-off-ism is a primary complicator of biz software IME.

You are also welcome to present a King Delphi example also.
________________
oop.ismad.com
New A classic real world example: Brooklyn Union Gas
The re-work to an OO design was done in PL/I ( a language that is a marriage of FORTRAN and COBOL from the 1960's), so it is no OO language. I remember reading a report on the project some 10 years or more ago. One of their objects, I still remember, was a gas meter. Talk about the problem domain. Everything to do with the gas meter was grouped in the new code.

Perhaps the oldest and best-known case of the large-scale, beneficial application of object technology is the one at Brooklyn Union Gas, where a customer management system consisting of l.5 million lines of PL/l was replaced by a system written using an object-oriented preprocessor. The new system is very large, with 850 on-line users, a 100-gigabyte database and 10000 code modules. The benefits reported include a 40% reduction in code size due mainly to reuse, low maintenance costs (12 people in the team), trouble-free installation and above all great flexibility and extensibility. These benefits were not free. The developers had to invent their own object-oriented development methods and standards as these were not available in the development period from 1987 to 1990; traditional methods were found seriously wanting.
[link|http://osiris.sunderland.ac.uk/rif/com327/handouts/graham/graham.html|Link.] Look in sectios 2.3 Case Studies.

Arkadiy, you are "right on"!
Alex

"Of course, you realize this means war." -B. Bunny
New One case proves nothing
Large OOP systems have also had huge catastrophies. Unfortunately, companies rarely brag and publish failures (and even sue if consultants mention it). In such a lawyer-friendly environment, anecdotal information is not a very representative sampling technique.

Edward Yourden, an IT writer, has surveyed companies to see which technologies IT managers thought were helpful. OO scored no better than average. In fact, it scored better than average *early* in its odoption, but pettered out to the average line. He speculated that "OO enthusiasts" were deluted over time by "regular" programmers coming into the mix who did not have the same zeal as the initial OO fans.

Further, that page borrowed some of the drivel from Bertrand Meyer it appears. (I have a whole webpage critiquing his book.)
________________
oop.ismad.com
Expand Edited by tablizer Feb. 7, 2002, 09:35:34 PM EST
New Re: One case proves nothing
There is an old Hebrew saying that says "A thousand examples doesn't constitute proof". Or, words to that effect. So in that sense you are right. But, on the other hand, I did not claim this was some kind of proof. It only an example where an OO design (actually re-design) approach worked well.

I mentioned the gas meter object. One of the things that happened was the application users, in reporting a problem, would say "The gas meter is broken. It does...". The communication between the users and developers was enhanced. And, the developers could zoom in on the relevant code quickly.

Can you imagine a user saying "You've got this table, and it..."? Not likely.
Alex

"Of course, you realize this means war." -B. Bunny
New ad-hoc
>> There is an old Hebrew saying that says "A thousand examples doesn't constitute proof". <<

You only presented one, not 1000.

I am not saying that all OOP applications are crap. That is not my stance. I am only saying that OOP is overhyped and the hype is ruining progress and tools for the alternatives.

>> Can you imagine a user saying "You've got this table, and it..."? Not likely. <<

Are you saying that tables are less trace-able than objects? Let's see you do an ad-hoc query on a bunch of objects? For example, "Show me all meters west-side that have reported leakage or cracking problems since last month and serviced by Bob".
________________
oop.ismad.com
New Re: ad-hoc
>> There is an old Hebrew saying that says "A thousand examples doesn't constitute proof". <<

You only presented one, not 1000.
I am amused that you don't recognize that I'm agreeing with you on that point. What I am saying here is that even if I did give you a thousand examples, it would still not be a proof.
I am not saying that all OOP applications are crap. That is not my stance. I am only saying that OOP is overhyped and the hype is ruining progress and tools for the alternatives.

>> Can you imagine a user saying "You've got this table, and it..."? Not likely. <<

Are you saying that tables are less trace-able than objects? Let's see you do an ad-hoc query on a bunch of objects? For example, "Show me all meters west-side that have reported leakage or cracking problems since last month and serviced by Bob".
My point here is that users do not think in terms of tables, but developers do. Users think in terms of things in their problem domain, otherwise known as objects. Tables are things in the solution domain. When the objects in the problem domain match the objects in the solution domain, communication between developers and users is easier.

Ad hoc queries are a separate issue. You either design for them or not depending on user requirements. OO does not exclude use of relational databases.
Alex

"Of course, you realize this means war." -B. Bunny
New English Oriented Programming
>> My point here is that users do not think in terms of tables, but developers do. Users think in terms of things in their problem domain, otherwise known as objects. <<

Yeah, like they are really gonna relate to things like class TransitionStateManager.

Programmers rarely man the customer phones anyhow (except in really small shops). Even under the longshot that I agreed with you that OOP was closer to English, it is mostly moot.

I don't really see how OOP is close to English anyhow. Like I said, English sentences are based on *one* verb and potentally *many* nouns. "Bob and Dora rode a snowmobile to Grandma's house." This better maps to functions if you ask me. Verbs are more pivotable to English than nouns.


>> OO does not exclude use of relational databases. <<

Yes, but does not get along with them very well. OOP and relational thinking tend to fight over territory. Either one gives in, or you duplicate (mirror) stuff.

________________
oop.ismad.com
     How non-OO people think. - (Arkadiy) - (90)
         I just don't get OO design decisions - (tablizer) - (88)
             I believe I understand why you have a problem - (ben_tilly) - (21)
                 Re: I believe I understand why you have a problem - (wharris2) - (1)
                     Well, my philosophy says... - (ben_tilly)
                 ADT's and Coddlets - (tablizer) - (18)
                     Coddlets? - (Arkadiy) - (10)
                         From the context: Applets + Codd = "Coddlets". - (CRConrad) - (9)
                             And "little snippets of data structures" make no sence to me -NT - (Arkadiy) - (8)
                                 Me neither - but don't blame me; it's *his* concept! :-) -NT - (CRConrad)
                                 Virtual Structures - (tablizer) - (6)
                                     I understand all words - (Arkadiy) - (5)
                                         how about this then - (tablizer) - (4)
                                             Odd. Not a single mention of "coddlet" anywhere. - (Arkadiy) - (3)
                                                 "A formula for a pattern or structure" -NT - (tablizer) - (2)
                                                     Still odd. - (Arkadiy) - (1)
                                                         Jay, where is your "Roles" link? -NT - (tablizer)
                     I think you would prefer what Code Complete has to say - (ben_tilly) - (6)
                         You must think in *Russian*! Think in *RUSSIAN*! - (admin) - (2)
                             Firefox, Clint Eastwood and the semi-telepathic MiG. - (CRConrad)
                             Second, was FireFox. (book was better than movie) -NT - (Steve Lowe)
                         Abstraction level is relative and graph-like IMO - (tablizer) - (2)
                             Nested abstractions do work in business - (ben_tilly) - (1)
                                 "Layers" is not appropriate for the most part - (tablizer)
             That's not the kind of post I 'd like to get... - (Arkadiy) - (65)
                 Why the Tree focus? - (tablizer) - (64)
                     No tree focus. - (Arkadiy) - (63)
                         Have you thot of tables? - (tablizer) - (62)
                             Not relevant. - (Arkadiy) - (61)
                                 what is wrong with them? - (tablizer) - (60)
                                     Bryce, please pay attention. - (static) - (3)
                                         seperation of concerns - (tablizer) - (2)
                                             Duh! - (Arkadiy) - (1)
                                                 Perhaps p/r is moving above that -NT - (tablizer)
                                     Bryce, Static is right. - (Arkadiy) - (55)
                                         what is the goal? - (tablizer) - (54)
                                             The goal is to further the discussion. - (Arkadiy) - (53)
                                                 that depends - (tablizer) - (52)
                                                     OK, getting somewhere. - (Arkadiy) - (51)
                                                         Now THAT is the crux.... - (folkert) - (1)
                                                             only one fact here - (tablizer)
                                                         I disagree - (tablizer) - (48)
                                                             May be. - (Arkadiy) - (47)
                                                                 the calculation complexity may not even matter here - (tablizer) - (46)
                                                                     It does not matter indeed. - (Arkadiy) - (45)
                                                                         Regional Scope to the Rescue - (tablizer) - (44)
                                                                             Regional Scope - ok. - (Arkadiy) - (43)
                                                                                 I think so - (tablizer) - (42)
                                                                                     It was really C, not C++ - (Arkadiy) - (41)
                                                                                         Welcome to Table Land - (tablizer) - (40)
                                                                                             So, each clone's data is a row? - (Arkadiy) - (39)
                                                                                                 Multiple Entity Association Candidates - (tablizer) - (38)
                                                                                                     Re: Multiple Entity Association Candidates - (Arkadiy) - (37)
                                                                                                         Genericness - (tablizer) - (36)
                                                                                                             Expressing problem domain - (Arkadiy) - (35)
                                                                                                                 Misunderstanding - (tablizer) - (28)
                                                                                                                     Actual numbers don't matter much. - (Arkadiy) - (18)
                                                                                                                         Spoken Language? - (tablizer) - (17)
                                                                                                                             Re: Spoken Language? - (Arkadiy) - (16)
                                                                                                                                 Hmmmm. Verbal thinkers versus visual thinkers - (tablizer) - (10)
                                                                                                                                     Seems like end of conversation, then. - (Arkadiy) - (6)
                                                                                                                                         See also Stephenson, In The Beginning Was The Command Line.. -NT - (CRConrad) - (1)
                                                                                                                                             Actually, I like command lines - (tablizer)
                                                                                                                                         Noted. - (static)
                                                                                                                                         Can our differences really be all that simple? - (tablizer) - (2)
                                                                                                                                             Simple? - (Arkadiy) - (1)
                                                                                                                                                 Compared to others, yes. - (tablizer)
                                                                                                                                     On visual thinking. - (Another Scott) - (2)
                                                                                                                                         mooooo - (tablizer) - (1)
                                                                                                                                             I've heard her speak.. - (Ashton)
                                                                                                                                 Sp: "Swahili". Kwaheri, Jambo! - (CRConrad) - (3)
                                                                                                                                     I've had enuf of your irrelevent, speghetti insolts :-) -NT - (tablizer) - (2)
                                                                                                                                         Hey Bryce, I was just over on /. and revisited an old... - (CRConrad) - (1)
                                                                                                                                             Okay, you are off the hook - (tablizer)
                                                                                                                                 Re: Spoken Language? - (pwhysall)
                                                                                                                     Nothing else is possible with you. - (CRConrad) - (8)
                                                                                                                         Did you notice... - (Arkadiy) - (6)
                                                                                                                             What're you talking about?!? I called a mind (yours) "good"! -NT - (CRConrad) - (5)
                                                                                                                                 Thank you. - (Arkadiy) - (4)
                                                                                                                                     More like the other way around... - (CRConrad) - (3)
                                                                                                                                         Right you are. - (Arkadiy) - (1)
                                                                                                                                             Actually, you are right too... - (CRConrad)
                                                                                                                                         not think like me == bad mind ? - (tablizer)
                                                                                                                         Walk Before Run - (tablizer)
                                                                                                                 A classic real world example: Brooklyn Union Gas - (a6l6e6x) - (5)
                                                                                                                     One case proves nothing - (tablizer) - (4)
                                                                                                                         Re: One case proves nothing - (a6l6e6x) - (3)
                                                                                                                             ad-hoc - (tablizer) - (2)
                                                                                                                                 Re: ad-hoc - (a6l6e6x) - (1)
                                                                                                                                     English Oriented Programming - (tablizer)
         How I think in Non-OO terms - (nking)

Here, have another hor'd'ouevre.
247 ms