Programming Ugly

Pages: 12345
Cope refused to provide proof of concept in C++.
But I'm still interested. So if anybody else can, please do.

A wall of moralizing text roughly translating to RTFM won't suffice, Cope.
Because if this new paradigm is too complex to be intuitive when applied, then it fails its original mission.
closed account (1vRz3TCk)
coder777 wrote:
Imagine a sentence like 'he does something'

In C it would be: does(he, something);
In C++: he.does(something);


coder777 wrote:
In the linguistic world
'does he something' is very different from 'he does something'.

It's not 'syntactic sugar'. That fixes the role of each object ('he' turns into a subject -> the active part) and thus opens a new world. That is what I call object oriented


It is an interesting point... but if you are asking an 'object' to do 'something' isn't it it equally valid to say: 'coder777, please do this' and 'please do this, coder777'?

Edit:
another example, you have a list object and you want to print it:
C: Print(list);
C++: list.Print();
Which one makes more sense to the reader?
Last edited on
hey, cope, since you seem to be an authority on the subject of DCI (relative to those in this conversatioN) is there any chance you can link me to some (or just one) paper published on the matter? I'd actually never heard of it before this, and I'd rather not have to dig through google to find a gold nugget when there is a chance you already know where it is at.


Sigh. O.K., I'll enter the Google searches for you. Here are the results:

http://fulloo.info/Documents/
http://leansoftwarearchitecture.com/
http://www.leansoftwarearchitecture.com/home/more-online-resources

As for published material, there are a few articles:

Coplien, James. DCI and Lean Architecture. Lean Magazine. Issue 5, January 2010,
http://softhouseeducation.com/http//softhouseeducation.com/download/Lean-Magazine-5-24print.pdf

but if you insist on a sound published reference, I recommend the book:

Coplien, James and Gertrud Bjørnvig. Lean Architecture for Agile Software Development:
Building Software as if people mattered. July 2010,
http://www.amazon.com/Lean-Architecture-Agile-Software-Development/dp/0470684208/

A wall of moralizing text roughly translating to RTFM won't suffice, Cope.
Because if this new paradigm is too complex to be intuitive when applied, then it fails its original mission.


Oh, yes, this is a moral issue. People who understand the dynamics of paradigm shifts know that a true paradigm is not intuitive until you've assimilated it. Don't let your ignorance win. Do some work.
It's not 'syntactic sugar'. That fixes the role of each object ('he' turns into a subject -> the active part) and thus opens a new world. That is what I call object oriented.


I'd just point out that it's not what Nygaard, Dahl, or Kay called object-oriented. If that kind of superficiality is important to you, I'd just point out that DCI is another niveau above that.
Last edited on
CodeMonkey wrote:

another example, you have a list object and you want to print it:
C: Print(list);
C++: list.Print();
Which one makes more sense to the reader?


Both can make as much sense, but they have different contexts. The first situation implies the existence of some function which can print generally anything, but we just happen to pass a list. The second one implies that a list object has a print function defined. Both work, but they imply different situations.
coder777 wrote:
But programming is a linguistic problem. Another level of abstraction leads to confusion rather than improvement.
This statement just boggles my mind. I didn't know it was possible to be this wrong about programming.

In the linguistic world
'does he something' is very different from 'he does something'.
If you're going to talk about linguistics, there's nothing special about the SVO order, and not every language follows it. Japanese, for example, follows the SOV order by default, although it can also be order-independent through the use of particles. Thus, "he something does", "does v he s something o", and "something o does v he s" all mean the same thing.
As long as it's unambiguous, neither "he.do(something)" nor "do(he,something)" nor "he something do" are better. They all mean the same thing in their own language.

It's not 'syntactic sugar'. That fixes the role of each object ('he' turns into a subject -> the active part) and thus opens a new world. That is what I call object oriented
That's not object orientation. Not even in C++.
Last edited on
closed account (1vRz3TCk)
Kyon,

my post was in response to coder777s 'linguistic world' and was intended to counters the 'does he something' argument, as 'print list' seems more linguistically correct than 'list print' (unless you are Yoda).


For those wanting code, I have hacked together another online example at:

http://fulloo.info/t-files/C++Examples/Account1/Account.html
CodeMonkey:

It is an interesting point... but if you are asking an 'object' to do 'something' isn't it it equally valid to say: 'coder777, please do this' and 'please do this, coder777'?



Exactly. And it gets even more interesting.

Consider that you are writing a text editor. You have a TextBuffer object where the text-in-progress lives; a Dictionary; and a UserInterface (to ask the user whether to effect each correction). The use case Spell Check is part of the end-user mental model. Where does it go?

The first mistake is to find the single object where the SpellCheck method belongs. Most people connect it with TextBuffer — which leaves TextBuffer hopelessly coupled to Dictionary and the UserInterface.

The second mistake is to find the single class where the method belongs. That's class-oriented programming, and I find that it's how most C++ programmers still think.

The third mistake is to say that "spell checking is an emergent behavior of smart objects," and to pretend that we focus on the objects alone without needing to worry about the use case. That's just hogwash: it's a rationalization that came out of the early impoverished design methods and programming technology.

The fourth mistake, again, is to take this reasoning to the class level.

No, I'm not trying to bring back procedural programming. And this isn't about AOP or dependency injection or mix-ins or multi-methods. There is something very deep going on here that is difficult for class-oriented people to grasp. That's why it takes time to study and appreciate, followed by some good practice coding. The first step is to let go of simple prejudices at the level of syntax and to start thinking in terms of human cognition and volition as CodeMonkey illustrates above. It's hard to let go of something that you once had to defend, in the face of an established procedural world, with your very reputation. It's time for that again. Hear the voice of change.
Where would you put a SpellCheck method? Personally I would have Dictionary::SpellCheck(std::string& text), and TextBuffer would have a method similar to the ToString() method in C#. That way neither class relies on the existence of the other class.
The use case is as follows:

1. User requests spell checking of the text buffer
1.1 Alternative flow: User requests spell checking of highlighted / selected text
1.2 Alternative flow: User requests spell checking of a file
2. Spell checking advances to next word
3. The dictionary checks the spelling of the word
4. The dictionary generates a possible correct spelling of the word
4.1 Alternative flow: Spelling is correct: go back to step 2
5. The user is asked whether the suggested spelling is correct
6. The user acknowledges the new spelling
6.1 Alternative flow: The user decides to keep the existing spelling: go back to step 2
7. The new spelling replaces the old one

So you really want to put all of that in dictionary?
It should be, I think, a spell_check(Dictionary,String) that references split_into_words(String). It's not an action that's performed by a specific object (can you imagine giving your page of writing to an actual dictionary and having it corrected, or giving a dictionary to a sheet of paper and it correcting itself?), or there's a single-use type SpellChecker that does the spell checking. SpellChecker could be useful to hold intermediate state between calls to spell_check() if incremental checks are wanted, as Cope says.
That doesn't implement the use case. That implements only step 3. I'm asking: Where do you put the SpellCheck use case from above?
I'll admit, I didn't read any of those links. Regardless, there are some big claims here and not an ounce of insight being provided. For example, "Most people use OOP wrong." Is this true or should it actually be written as, "I think many people use OOP wrong." Or possibly many other variations such as, "I think some people wrongly apply a single OOP approach to all problems, which is inherently wrong."

I prefer an honor-published-best-practices approach to modern development in C++. For example, aiming for high cohesion would not place all of that in a dictionary class. That does not make the solution any less object oriented, though. Let's not forget that there are many, many ways to model a complex object...

Also, object oriented approaches don't require language support. Although it can undoubtedly improve it via data protection, better abstraction for the user, etc.. Check out the OpenMotif source if you want to see polymorphic OOP implemented in C. Also, Perl's "OOP" actually is nothing more than the syntactic sugar mentioned above.

So, once again a thread goes off on a tangent when the OP was asking for resources to improve his art. Well, my advice is to read published books on the subject. Design Patterns, Generic Programming and the STL, and the C++ In-Depth Series books is what I would recommend. (Honorable mentions goto C++ Coding Standards and the Exceptional C++ books).

IMO the SpellCheck method should be along the lines of:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Dictionary {
        ...
        void SpellCheck(std::string text)
        {
                std::vector <std::string> words = split(text, ' ');
                std::vector < std::pair<std::string, std::string> > misspelled;
                /*
                 * Generate list of misspelled words if any
                 */
                for (StringVectorIterator it = words.begin(); it < words.end(); ++it) {
                        if (!(SpelledCorrectly(words[i])))
                                misspelled.push_back(std::pair<std::string, std::string>(*it, SuggestCorrection(*it)));
                }
                /*
                 * Throw exception if any words were misspelled
                 */
                if (misspelled.size())
                        throw SpellingErrorException(misspelled);
        }
        ...
}


The user interface would control everything except the actual spell-checking. If the user selects text and wants it checked, then the UI gives Dictonary::SpellCheck only the selected text. Otherwise it gives it the entire contents of the TextBuffer.

Edit: You could also define misspelled as std::vector < std::pair < std::string, std::vector <std::string> > > so that you could have multiple possible corrections, though that would be somewhat complicated.
Last edited on
¡¿throw an exception?!
I think we agree that the dictionary should say if a word is mispelled or not. Providing a set of alternatives, a likelihood value, etc. (points 3,4 of the UC). The implementation is another issue

But I don't think that that is being discussed here (I'm not sure what is discussed here), but you can't pretend to put a UC in just one method of a class. You need interaction in order to accomplish your task
Well it could be in the "system" class...

The rest of this post is gibberish. Skipped if you want
1. User requests spell checking of text
__ Interaction between the UI and the text_buffer in order to obtain the text to be processed. In doesn't matter the later operation (maybe a little) a
2. Spell checking advances to next word
__ I'm not sure of who should know what a word is, but maybe this will be better to be outside dictionary.
__ So we are traversing the text and we don't care about the UI or the dictionary, but we need to maintain a correspondence with the text_buffer.
3. The dictionary checks the spelling of the word
4. The dictionary generates a possible correct spelling of the word
__ Poor little dictionary, isolated from the world.
4.1 Alternative flow: Spelling is correct: go back to step 2
5. The user is asked to choose one "correction" (also, do nothing)
__ UI, with context provided by the text
6. The new spelling replaces the old one
__ Now the mapping takes place

aThere is the need to adecuate the text to its processing. By instance, remove the format specifiers.
Last edited on
I'd make spellchecking a separate class so that you could just write:

 
SpellCheck sc("some long text to spellcheck", dictionary);


This way, it could provide methods for getting list of incorrect / suspicious words with their respective positions in text, suggest replacements etc. This would allow it both to work interactively, but also to underline incorrect words by the GUI.
rapidcoder wrote:
I'd make spellchecking a separate class

I agree. Each use case should be a separate (context) class. I'd
make a minor modification, though. I would do something like this...

SpellCheck sc(text_source, dictionary);

...where text_source would be a TextSource pointer. TextSource would be a so called
methodless role class from which TextBuffer, TextSelection and TextFile would inherit.
Right! The idea is to make TextSource be a role rather than a class. This starts to sound like DCI.

Saying:

SpellCheck sc("some long text to spellcheck", dictionary);


has two problems. First, it doesn't address the problem of the original use case — how do I alternate between checking the TextBuffer, a file, and some selected text? Second, I presume that dictionary is a pointer to some class. That couples the function to a class — that's static, compile-time coupling. That, again, is thinking in classes instead of in objects.
moorecm whines:

I'll admit, I didn't read any of those links. Regardless, there are some big claims here and not an ounce of insight being provided.


So let me get this straight. 1. You didn't read the links I pointed you to. 2. You are looking for insight. So, tell you what: Open your mind. Just believe in ESP. I'm transmitting to you now.

Or, for your ilk, perhaps you can just buy the book and put it under your pillow. One can always hope for osmosis through your pillow.

For example, "Most people use OOP wrong." Is this true or should it actually be written as, "I think many people use OOP wrong." Or possibly many other variations such as, "I think some people wrongly apply a single OOP approach to all problems, which is inherently wrong."


I've worked with hundreds of projects over the past 30 years and I stand my ground. How many have you looked at?

I prefer an honor-published-best-practices approach to modern development in C++. For example, aiming for high cohesion would not place all of that in a dictionary class. That does not make the solution any less object oriented, though. Let's not forget that there are many, many ways to model a complex object...


As someone who has been one of the primary contributors to that body of literature over history, I'm sorry to report to you that most of what is published describes a style of programming that, at best, we can call "Restricted OO." It doesn't live up to even the original vision of OO from Alan Kay. It's time to move on.

Wow, these comments are so classically Kuhnian that it's almost a caricature.

Also, object oriented approaches don't require language support.


First, show me some OO code in FORTRAN.

Once having convinced me of your claim, we can then move on to what OO is. Let's take the definition of the guy who invented the term — Alan Kay. That's consistent with the broad use we are exploring in DCI.

So, once again a thread goes off on a tangent when the OP was asking for resources to improve his art. Well, my advice is to read published books on the subject. Design Patterns, Generic Programming and the STL, and the C++ In-Depth Series books is what I would recommend. (Honorable mentions goto C++ Coding Standards and the Exceptional C++ books).


We'll leave you in the old paradigm, then.
Pages: 12345