Click to See Complete Forum and Search --> : Object Orientation Pt 2
yrwyddfa
Jan 11th, 2006, 04:30 AM
Pt 1 (http://www.vbforums.com/showthread.php?t=380688)
The human race has been fond of abstraction for years. For centuries, in fact. Abstraction is a concept or idea not specifically connected to one instance; a famous example is Newton’s model of gravity. Programmers have been abstracting for years since the birth of that ubiquitous thing called a function.
A very popular abstraction model is set theory; and its implication within the programming world has been immense. Set theory, and its power, is the mathematical idea behind Codd’s relational model, and because its basis is mathematical the ideas and rules are globally consistent.
The success of the relational model means that nearly every data storage technology, where the storage requirements are more than just cursory, uses it. Even for those technologies that don’t use it a driver that supports accessing it in a relational manner exists.
Object orientation is just another theory, and there have been plenty, but none quite like this.
In the real world – and I’m trying to avoid those awful ‘training’ examples which map OO onto the real world about as honestly as the moon is made of cheese – a significant software system is made up of many layers. This used to happen well before someone coined the term n-tier.
The bottom layer is the data storage. The choice is clear – you and I both know you are going to use a RDBMS; sure there are arguments about which implementation of the technology to use, but it’s underlying theory is going to based on DeMorgan’s and Codd’s rules and laws.
The next layer is going to be about how to get the data in and out of the data storage in an efficient manner. The SQL language is normally used, and it’s been highly successful.
Now we get to the interesting part. What comes next? If you are an OO fan then you are going to write a translation layer. You are going to convert one high level model into another. Why? The relational model has proved itself over many decades and is both a mathematical and commercial success. What’s wrong with implementing software against the relational model? Why do you want to convert your data into another high-level model? If you were honest you’d probably admit that you do it because either you were told it was the best way to do it, or simply read it on some website or in a book.
The rest of the layers are pretty much unimportant for this discussion, but the whole list (for an OO system) is something like this: RDBMS, data-access, Relational/Object Mapping, Business Logic, GUI. Of course, different people do things in slightly different ways, but nevertheless this is a realistic example of an n-tier system
Whilst writing this something occurred to me. I’m you’ve all seen the cartoons where the guy has a light bulb appear above his head? Well, that’s just happened to me.
N-tier systems split essential functionality into different logical, and sometimes (quite a lot actually) into different physical tiers. The layers are split by a necessity to divide essential operations, and ensure scalability.
Of all the technologies running around at the minute there is one that doesn’t subscribe to this philosophy: yup – you’ve guessed it, it’s OO. By it’s very definition, by the very mantra of encapsulation, the data and behaviour are mixed together in the same class. Behaviour simply doesn’t act on incoming data as the world of mathematical abstraction suggests it should do. It acts on data held locally. Data, and behaviour are consistently held together and are considered identical (which is what Turin’s big thing was – but at a very low level of abstraction, not at a business level)
Software, unlike the vast majority of scientific disciplines, requires some form of management of change. OO is completely oblivious at the most fundamental level to any concept of change. It should be self evident that mutual storage at high levels of abstraction of both the data, and behaviour is simply not a good idea.
I can hear the religious fervour of those who have already fallen for the seductive delights of the PhD driven software revolution (also known as scientific drivel)
Change, they say, is easy. You inherit from a different class, extend an interface, or hell damn it just override the function.
But can’t you see? This is such a bad idea. Such a terrible disgusting idea that it should never be allowed by law. There should be statutes written and discussed in the political institutions the world over to prevent people from doing this.
Inheritance is evil. There has been a massive increase in the number of technologies sold, and/or implemented that allow the decoupling of systems from each other. I spend a fair degree of time protecting my user’s data from hardware failure, or integration failure. The classic way of doing this is to use a temporary store such as queue, so that if the target hardware fails, when it recovers (or you buy new hardware) the software continues to process the contents of the queue and the data is safe.
When you rely on inheritance all the way down your class hierarchy you have a massively coupled system, which means it’s difficult, and perhaps impossible to design an external fault-tolerant system by default. I hope it’s no surprise to the reader that software does exist in the real world, and not just in the virtual world. I’m sure that die-hard fans will point to design pattern solutions, but they involve clever use of interfaces and avoid inheritance anyway.
Inheritance strongly implies a hierarchical structure to the software (both the data and the behaviour) Is this a good idea? Look at the extremely successful and mathematically robust relational model. The data structures are mostly acyclic graphs (of which a hierarchy is one.) How do you propose to write a data-mapping layer between an acyclic graph and a hierarchy? For those who don’t know a tree is a restricted form of acyclic graph. Once again we see that OO restricts what can naturally be modelled from the real world, and the relational model (I’m going to start using RM, now because I’m sick of typing ‘relational model’) allows you to model whatever it is that you need.
The more experienced OO programmers sometimes tell me that they try to avoid the use of inheritance as a rule, but happily admit, that it’s a feature of the language and in many cases it’s unavoidable, and there’s generally no other way of doing what it is they want to do. I mention ‘object-composition’ and all I get is a blank stare. If you’re into modern OO then I strongly suggest you learn what object-composition is and implement it where you can. Remember that Google is your friend (as long as you don’t allow them to set cookies) Object composition is far more flexible than inheritance, and its perhaps the lesser of the two evils.
yrwyddfa
Jan 11th, 2006, 04:59 AM
Pt 3 coming soon . . .
penagate
Jan 11th, 2006, 05:04 AM
I can't wait
yrwyddfa
Jan 11th, 2006, 05:07 AM
I can't waitSarcasm and all that . . . .
penagate
Jan 11th, 2006, 05:08 AM
Sarcasm? Meeeeeee? Never......
:p
CornedBee
Jan 11th, 2006, 05:33 AM
Now we get to the interesting part. What comes next? If you are an OO fan then you are going to write a translation layer. You are going to convert one high level model into another. Why? The relational model has proved itself over many decades and is both a mathematical and commercial success. What’s wrong with implementing software against the relational model? Why do you want to convert your data into another high-level model? If you were honest you’d probably admit that you do it because either you were told it was the best way to do it, or simply read it on some website or in a book.
Absolutely honest now: no.
Why would I convert one high-level abstraction into another? Because abstractions always come with trade-offs. That's a fact: to combine two concrete cases into one abstraction, you must discard some of the differences between the cases.
Different abstractions have different trade-offs. As such they are useful for different applications. The relational model is wonderful for data storage, but I don't want to even begin thinking about programming a larger application completely against data in third normal. Functional programming languages like Haskell or XSLT are very cool for data transformations of all kinds, but making them interact with a user gives me headaches. Object-oriented imperative languages are not too bad (though rather unstructured) at data storage, but are really bad for data transformation, but they are wonderful for building a GUI out of components. (You'll find that things in OOP languages that deal with data transformation tend to look very functional, or else to be completely unreadable.)
The rest of the layers are pretty much unimportant for this discussion, but the whole list (for an OO system) is something like this: RDBMS, data-access, Relational/Object Mapping, Business Logic, GUI. Of course, different people do things in slightly different ways, but nevertheless this is a realistic example of an n-tier system
A peculiar thing happened with n-tier systems and their domain objects. They have become very close to structs. A domain object usually is responsible only for storing its data, ensuring its own data integrity and possibly load (or rather request loading of) associated data.
What does that mean? I don't know. But it's definitely a move back towards the procedural model.
It should be self evident that mutual storage at high levels of abstraction of both the data, and behaviour is simply not a good idea.
I'm afraid it's not at all self-evident. Why is it a bad idea?
I can hear the religious fervour of those who have already fallen for the seductive delights of the PhD driven software revolution (also known as scientific drivel)
I don't believe in such a thing as a "PhD-drived software revolution". Software development is, despite managerial intervention, still at its roots a Mendelian environment. OO has fared well. For a paradigm to reach a popularity where it can gain managerial support, it must be good, or else it will die before a manager ever hears of it.
But can’t you see? This is such a bad idea. Such a terrible disgusting idea that it should never be allowed by law. There should be statutes written and discussed in the political institutions the world over to prevent people from doing this.
How come? What on earth are you talking about?
Inheritance is evil. There has been a massive increase in the number of technologies sold, and/or implemented that allow the decoupling of systems from each other. I spend a fair degree of time protecting my user’s data from hardware failure, or integration failure. The classic way of doing this is to use a temporary store such as queue, so that if the target hardware fails, when it recovers (or you buy new hardware) the software continues to process the contents of the queue and the data is safe.
This has nothing at all to do with inheritance.
When you rely on inheritance all the way down your class hierarchy you have a massively coupled system, which means it’s difficult, and perhaps impossible to design an external fault-tolerant system by default. I hope it’s no surprise to the reader that software does exist in the real world, and not just in the virtual world. I’m sure that die-hard fans will point to design pattern solutions, but they involve clever use of interfaces and avoid inheritance anyway.
If you rely on inheritance that much, you have misunderstood OOP.
Inheritance strongly implies a hierarchical structure to the software (both the data and the behaviour) Is this a good idea? Look at the extremely successful and mathematically robust relational model. The data structures are mostly acyclic graphs (of which a hierarchy is one.) How do you propose to write a data-mapping layer between an acyclic graph and a hierarchy?
You make it seem as if, say, a File object should derived from the Directory object that contains it, or something like that. I hardly need to point out that OOP doesn't work that way, do I?
For those who don’t know a tree is a restricted form of acyclic graph. Once again we see that OO restricts what can naturally be modelled from the real world, and the relational model (I’m going to start using RM, now because I’m sick of typing ‘relational model’) allows you to model whatever it is that you need.
Absolute nonsense! Object relationships in OOP model a possibly cyclic graph. Object inheritance would be modeled by separating common data of several tuples into a separate tuple referenced by the others. The behaviour doesn't come into play here, because the relational data model has no concept of behaviour.
Don't blame misuse of a paradigm on the paradigm.
yrwyddfa
Jan 11th, 2006, 05:56 AM
Succinctly:
(i) I believe that storing behaviour, and data together is a bad idea, and I base this belief on the mathematical notion of functions, not on the programming idiom. Data in software, in my opinion, should be transient, and state should always be persisted. This is as much a problem with procedural, and functional programming as it is with OO Why do you want to tie data to a particular programming paradigm? The goal of programming is to process data and do something useful with it. Data, in both it's finite, and transitive states should be stored in shared environment (I think so anyway) This is just an opinion . . .
(ii) Inheritance promotes strong coupling of source-code. It has too. If you inherit from another class then surely that class has to exist? And that class will inherit from another. I'm sure you are no stranger to the 'fragile-base-class' syndrome? I'd bet a small fortune that most OO shops have strict procedures in place to avoid the fragile base class syndrome: this means that you are changing your business model to fit software development. This, in my opinion, is the wrong way around. Software is, and always should be, the slave to the business model.
(iii) It's difficult to model the real world into hierarchies and in some cases it's impossible. Your claim that OOP models cyclic graphs is nonsense. A tree is an directed acyclic graph that has no cycles. Unless you know of a technology that can resolve circular references (in both object references, and inheritance) I'm afraid you're going to have to admit that the use of inheritance hierarchies is a further restriction than the RM on real world modelling.(http://en.wikipedia.org/wiki/Glossary_of_graph_theory#Trees) Your point that if you rely on 'inheritance this much' is a very good point.
(iv) Your opinion that 'it must be good otherwise it would've died a death' is anthropological rubbish. Any cursory study of human nature demonstrates this. A simple and obvious example is Hitler's popularity prior to gaining power (democratically) and whilst in power. 20/20 hindsight is a wonderful thing, but I wouldn't agree that because Hitler was popular in his time, then his rise to power must have been a good thing.
yrwyddfa
Jan 11th, 2006, 05:58 AM
Don't blame misuse of a paradigm on the paradigm.Funny you should say that; look out for Pt3 which deals with precisely this point.
As I probably won't finish Pt3 today the point I'll be making is that why would you go to the effort of creating a complex hierarchical language when it's real world use is quite limited? This is, as you've inferred, the most abused area of OO. I believe it should be an option and not inherently built in.
CornedBee
Jan 11th, 2006, 06:52 AM
Succinctly:
(i) I believe that storing behaviour, and data together is a bad idea, and I base this belief on the mathematical notion of functions, not on the programming idiom. Data in software, in my opinion, should be transient, and state should always be persisted. This is as much a problem with procedural, and functional programming as it is with OO Why do you want to tie data to a particular programming paradigm? The goal of programming is to process data and do something useful with it. Data, in both it's finite, and transitive states should be stored in shared environment (I think so anyway) This is just an opinion . . .
I'm not quite sure what you consider "storing" behaviour. I haven't heard of any OOP language that stores its method code next to the data. Not even JS, which probably comes closest.
(ii) Inheritance promotes strong coupling of source-code. It has too. If you inherit from another class then surely that class has to exist? And that class will inherit from another. I'm sure you are no stranger to the 'fragile-base-class' syndrome? I'd bet a small fortune that most OO shops have strict procedures in place to avoid the fragile base class syndrome: this means that you are changing your business model to fit software development. This, in my opinion, is the wrong way around. Software is, and always should be, the slave to the business model.
If you call one function from another, it has to exist, too. Cooperation of related components is not the same as strong coupling. Strong coupling ensues when the derived class assumes implementation details of the parent class. Protected variables can lead to this, for example.
(iii) It's difficult to model the real world into hierarchies and in some cases it's impossible. Your claim that OOP models cyclic graphs is nonsense. A tree is an directed acyclic graph that has no cycles.
I didn't claim that inheritance models cyclic graphs, but object relations do. Just look at any UML class diagram or domain model.
Unless you know of a technology that can resolve circular references (in both object references, and inheritance) I'm afraid you're going to have to admit that the use of inheritance hierarchies is a further restriction than the RM on real world modelling.(http://en.wikipedia.org/wiki/Glossary_of_graph_theory#Trees) Your point that if you rely on 'inheritance this much' is a very good point.
It's not possible to resolve circular references in inheritance - the resulting object would be of infinite size, and there is no theoretical base to it either.
Circular references in object references are very common and well supported by all OO languages.
public class Region
{
private List<File> files;
}
public class File
{
private Region container;
}
(iv) Your opinion that 'it must be good otherwise it would've died a death' is anthropological rubbish. Any cursory study of human nature demonstrates this. A simple and obvious example is Hitler's popularity prior to gaining power (democratically) and whilst in power. 20/20 hindsight is a wonderful thing, but I wouldn't agree that because Hitler was popular in his time, then his rise to power must have been a good thing.
Don't confuse the moral notion of "good" with the evolutional notion of "good" (as in "effective"). And don't invoke Godwin's Law ;)
Your analogy is completely flawed. Hitler's success proved that his methods were effective for the time. Post-WW1 Germany was in deep trouble. The war had crippled its economy, and reparations imposed by the winners made restoring it a very difficult task. Hitler gave the people hope, a vision, and a scapegoat. Hitler's methods were "right" in that they facilitated his goals: power.
Later, Hitler started using methods that were "bad": he started another war, one that he was ultimately doomed to lose. You can't fight the world. The war did not facilitate his goals, and as such it was bad.
The main goal of programmers has traditionally been to make their own job easier. Easier meaning that their tools made programs easier to write and easier to maintain. Object orientation accomplished this by making it easier to understand what's going on. The key to nearly every single successful innovation in the software industry has been that it makes things easier. Assembly? Easier than machine code. Procedural structured programming? Easier than Assembly. Object orientation? Easier than procedural. IDEs? Easier than text editor+command line tools. Windows? Easier than DOS. Linux is one of the few exceptions to this, catering to ideology instead - but Linux's success is thus limited; Windows still has the market. I believe that even XML's success comes mainly from the fact that it's easier to reuse a single metaformat for which parsers and tools exist than writing your own format every time. It also makes it easier to agree on something with other people.
But if you believe that directly using the relational model makes things easier, you're welcome to develop a complete programming paradigm based on that. I'd love to talk about it.
FunkyDexter
Jan 11th, 2006, 08:15 AM
Well, firstly, it has to be understood that OO is an interface to the human programmer, and not to the machine. This has been the most insightful point you've made thus far. Why are expecting it to be more than that? The drive of OO was to promote code reuse by making it easier for the next programmer down then line to use your components because they are understandable in human terms. To my mind it's been pretty successful at that.
yrwyddfa
Jan 11th, 2006, 08:19 AM
Don't confuse the moral notion of "good" with the evolutional notion of "good" (as in "effective"). And don't invoke Godwin's Law ;)
Your analogy is completely flawed. Hitler's success proved that his methods were effective for the time. Post-WW1 Germany was in deep trouble. As most of what I say is opinion, and you provide no strong argument I shall ignore most of it. Rationality is based on mathematics and not on code examples, btw.
Anyway, I don't want to regurgitate what you've said, but:
For a paradigm to reach a popularity where it can gain managerial support, it must be good, or else it will die before a manager ever hears of it.This is so childish, and so lacking in any substance that it deserves to be relegated to the dustbin, recycle bin or whatever else you choose to put it. Don't argue that you didn't say it, though.
The rest of my 'arguments' are opinion and should be treated as such, btw.
yrwyddfa
Jan 11th, 2006, 08:22 AM
This has been the most insightful point you've made thus far. Why are expecting it to be more than that? The drive of OO was to promote code reuse by making it easier for the next programmer down then line to use your components because they are understandable in human terms. To my mind it's been pretty successful at that.Good for you. You are clearly a better architect than me. I still believe, though, that OO is fundamentally flawed. It solves nothing apart from getting geek hackers to actually think about what they're writing. But that can be achieved with any paradigm of programming.
As a challenge: tell me what's wrong with procedural programming, and how OO solves it. If you can't, then it's not worth you posting here.
In my opinion reactionary comment is worthless. Tell me the joys of OO, tell me how it's improved your life, tell me how programmers are being made redundant because of the inherent efficiences of the paradigm. Post something that is a positive OO seller. Give the world a clue as to how the OO paradigm has improved the lot of mere mortals.
Please.
yrwyddfa
Jan 11th, 2006, 08:28 AM
I didn't claim that inheritance models cyclic graphs, but object relations do.Yes you did: reread your first post.
yrwyddfa
Jan 11th, 2006, 08:31 AM
But if you believe that directly using the relational model makes things easier, you're welcome to develop a complete programming paradigm based on that. I'd love to talk about it.Would you? I think you're pretty closed minded on this issue. Your replies are standard marketing stuff (I loved the muddled tuples thing. Cool: I'm sure everyone accepted it)
Belief, is belief: and it's rampant. As a general rule the programming community are significantly more intelligent than the rest of society. It's just such a shame that the belief in OO is without foundation. If there is a foundation then please share it.
yrwyddfa
Jan 11th, 2006, 08:35 AM
Hitler's success proved that his methods were effective for the time. Post-WW1 Germany was in deep trouble. The war had crippled its economy, and reparations imposed by the winners made restoring it a very difficult task. Hitler gave the people hope, a vision, and a scapegoat. Hitler's methods were "right" in that they facilitated his goalsYup that's exactly what I meant; but you expressed it better.
yrwyddfa
Jan 11th, 2006, 08:47 AM
And don't invoke Godwin's Law Yes I am guilty of that: especially on a semiotic level
FunkyDexter
Jan 11th, 2006, 10:33 AM
You are clearly a better architect than me Glad to see you're coming round to my way of thinking :bigyello: Only kidding, and I hope you noticed I said most insightful, not only insightful. I just thought it was a particularly incisive comment that pretty much hit the nail on the head.
tell me what's wrong with procedural programming Nothing at all and I didn't mean to imply there was. Either aproach has it's strengths and weaknesses.
Tell me the joys of OO, tell me how it's improved your life The most obvious examples I can think of are the gui controls that graphical languages offer. Have you ever tried to implement a listbox without some sort of object orientation? It's a nightmare having to maintain separate arrays for the contents, their keys, any extra tags you might want, the display format, the currently selected item number... far better to structure the whole thing as an object and then you can wrap up all those things as properties (ie member variables).
It's worth noting that the main benefit of OO isn't felt by the programmer coding the objects - if anything his job's a little harder. It's felt by the guy who's using those objects. Using the list box example, in a procedural aproach the guys who's using the list is probably going to have to maintain all those arrays and values, in an object aproach it should already have been encapsulated into the objects properties.
CornedBee
Jan 11th, 2006, 10:35 AM
I like your way of arguing. Have you made any actual point aside from baselessly ridiculing my arguments and misinterpreting them?
yrwyddfa
Jan 11th, 2006, 10:35 AM
The most obvious examples I can think of are the gui controls that graphical languages offer. Have you ever tried to implement a listbox without some sort of object orientation? It's a nightmare having to maintain separate arrays for the contents, their keys, any extra tags you might want, the display format, the currently selected item number... far better to structure the whole thing as an object and then you can wrap up all those things as properties (ie member variables).It's funny. In Pt3 I uphold OO for all things GUI-like. I feel pre-empted :( (although I'm pretty sure I've mentioned it in the past in another thread)
yrwyddfa
Jan 11th, 2006, 10:36 AM
I like your way of arguing. Have you made any actual point aside from baselessly ridiculing my arguments and misinterpreting them?Not really. It's only a monologue. I didn't expect anyone to take any notice, or get upset by it . . .
Apologies, if you think they're due.
FunkyDexter
Jan 11th, 2006, 10:54 AM
I feel pre-empted Yes! [pats self on back and looks smug] There are other components that lend themselves to OO other than GUI controls though. Broadly, if you can think of it as a 'thing' it'll probably benefit from being implemented as a class, if it's something you want to do then it's probably better implemented as a procedure. I personally see nothing wrong with mith mixing the two (though my old lecturers - and probably some folks on this board - would nail me to a tree for saying that).
yrwyddfa
Jan 11th, 2006, 11:11 AM
Pt 3 (http://www.vbforums.com/showthread.php?t=380890)
Shaggy Hiker
Jan 11th, 2006, 01:01 PM
As a challenge: tell me what's wrong with procedural programming, and how OO solves it. If you can't, then it's not worth you posting here.
After part 1 of this epic, I mentioned writing in Quattro Pro and how hideous it was. There is nothing essentially wrong with procedural programming, but if you have written something large enough, you have probably created a de facto subset of OO.
For larger VB6 projects, I found that I was lumping conceptual units together in rational ways. The language facilitated this with Modules. I expect that everybody who used VB prior to .NET did something like this. Modules, when arranged in this fashion, can often map quite easily into Classes (in fact, Modules are classes in .NET). There is nothing in .NET OO that I could not accomplish in VB6, but the way I was accomplishing these things in VB6 was fundamentally OO with each module being a class. Nothing wrong with it being procedural, but call a spade a spade.
Of course, this isn't true OO, and there certainly wasn't anything like inheritance, but then again, inheritance can be overused.
In all textbooks that I have seen on OO, there are some trivial examples, such as apples and fruit to show inheritance principles. About a year ago the editor of a programming journal disparaged this teaching example by asking whether anybody ever actually used such a thing. The question was rhetorical, but I almost answered him.
There is one area where OO fits like a glove in a way that procedural systems can't match: Biological systems and related GAs. I have two programs that use this type of thing, and several programs that do not. When writing an evolutionary program, you WILL be thinking OO, whether you like it or not. You could make an evolutionary program that was purely procedural, but you would be doing so for the sake of doing it.
The concept of genes, genomes, and populations, while it doesn't require inheritance, is a set of discrete objects. I defy anybody to write an evolutionary algorithm without OO that is as clear as one that is OO in nature. Since the problem is conceptual object based, writing non-object based code to model the problem will not produce anything as clear as object based code would be.
The other case I have that is similar is modeling a biological community. A crayfish is an organism makes considerable sense for such a model, especially in a community of several different species. Each species will have distinct behaviors, but all species must have some common properties (such as location). While it would be possible to handle such a model using only procedural techniques, why do it? Without runtime polymorphism, the first thing a behavior function would have to ask would be, "What am I?". This is simple and obvious for runtime polymorphism, and inheritance makes creating a new species particularly simple. Perhaps this is why the textbooks use examples like this, they make so much sense.
I realize that these points may have no place in the business world, but that's not the world I live in anyways. None of these things require OO, you could handle them using some other technique, but it would be inferior, and the resulting code would be less clear, and hence it would be less easily maintained. Perhaps you should just say: OO isn't a panacea for all situations. Render in OO that which is OO.
doyer
Jun 6th, 2007, 06:47 PM
all problems can be solved by my ideology/religion/awsomenesss....
- i believe in DOS.
Now all i have left is to force that particular belief/religion/ideology/awsomeness onto every1 else thru some amish terrorist group.
*this is where i get afraid that somebody thinks im serious and gets the FBI to come to my house*
KMDcomp
Jun 7th, 2007, 02:55 PM
It's scary, but this discussion was SO much more interesting they any programming or computer science class I've ever taken. :thumb:
daemonk
Jun 10th, 2007, 05:15 PM
a lot of argument by exaggeration going on here I think. I personally probably am too noobish to understand all the technical terms here but its hard to take an argument seriously when you deem something as evil and go on to spend a paragraph exaggerating how we should deal with it.
A lot of opinions here. Full of sound and fury.
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.