quote:
Original post by Kylotan
Well, considering you opened this topic with "does anyone have an idea about how to use exceptions?" and now you are attempting to tell me the 'right' way to use them, I am glad I have spurred you into thinking all this through, if nothing else.
Happens to me quite a bit...can't figure out why, though. I think it is because these debates make me think out the gray areas in my theories, and logically evaluate them. (There, I just did it again! To ask the question is to answer it.
)
Anyway, I've done a lot of thinking about this (meaning about 5-6 hours per day, since the original post), so I wouldn't be so surprised if I had actually come up with something. At least something more than daily headaches... Anyway, I was mainly looking for intelligent conversation and not just "screw you!" or something similarly irrational. Thanks!
(BTW, I did solve several problems that I had with my theories from the original post
)
quote:
Original post by Kylotan
My exceptions only served one purpose: to show a message. No other operation differed based on the 'type' of exception. Therefore, it made sense for there to be only one type with several possible values. Why invent a different class for each message? At no point was I ever doing any conditional branching based on that message. Saying there -needs- to be a separate class for each message is like saying that you shouldn't use integers, and instead derive class One : public digit {}, class Two : public digit {} and so on! It certainly doesn't involve any more work than it would to write all these separate virtual report() functions.
1) Only 1 report() function needs to be written, in the base class for the entire hierarchy.
2) You are assuming that writing the classes takes more work than writing the strings, which is incorrect. See my example in the last reply.
3) How much time does it take to invent an empty class?
4) What if you need to do conditional branching at some point? You must then adopt another method for doing exceptions, as the two methods are not compatible. (also, you did use conditional branching earlier to justify the method you proposed)
5) One, two and so on are not types of integers but particular instantiations of them, with one data member, value. (Note that for your exceptions example you had to use the word "type" to describe the method that you proposed, while here you did not. Check in your posts for the other times you see the word "type," and try re-evaluating those places with that idea in mind, just for a thought question.)
6) In a real-world app (meaning something on the level of a commercial app), I don't think you will run into a situation where all of the exceptions in a program can be handled in the same way.
quote:
Original post by Kylotan
I will concede that it scales much better to a larger project. But I was supplying a use of exceptions in a localised way that (a) doesn't require any kind of hierarchy to produce the logically correct response, and (b) produces that response whether the events it reacts to were 'exceptional' or not. The code I produced was isolated from any outside module, and therefore keeping track of it here is -easier-, as to create specific exception types for this one function would split the routine across more than one file (probably this CPP file and the accompanying H file).
1) There is no need of scaling to a smaller project, as that is where it starts (one class). The number of classes needed is directly proportional to the number of exceptions needed, with the ratio being 1:1.
2) I can't imagine a real-life situation where you would not access exceptions from outside the class in which they were declared
without using return values to mimic this functionality. All you would be doing is dropping the required enforcement of the "error," as return values are hardly mandatory.
3) The header file is for declaring things; the .cpp file is for defining things. The two together form one module; not 2 separate modules. Any time you declare something in one function and use it in another, you declare it in a header file. Exceptions are no different (pun intended).
quote:
Original post by Kylotan
I'm not being wilfully subjective: I apologize for any error in my terminology, however I do not have a 'Book Of C++ Definitions' handy...
Just a dictionary will do fine. C++ keywords were given English names to accurately and fully describe what they do. The only reference work that I used in this post to prove anything was a dictionary.
quote:
Original post by Kylotan
I believe that, for the example given, my solution was more concise and more localised. I do not believe it scales as well as your solution. I liken this to the way a lot of sort algorithms work: if the data set is smaller than a certain size, use Method X, otherwise, use Method Y.
1) Simpler is better, remember?
2) Anyway, you may be making the sort algorithm faster, but it is 2x (or however many method you propose) more complex. Complexity introduces a chance for error. Why use 2 methods for exceptions when 1 method will work equally well in both situations? (The only thing REALLY limiting your use of the method I proposed is that you somehow believe that writing string descriptions is easier than writing class names as string descriptions.)
3) More localized? Sometimes people try to substitute localization for organization. My room is like that sometimes...
quote:
Original post by Kylotan
By your 'objective' definition, all code is perfectly readable. However, the reader of the code is never 100%objective and never can be, therefore the point is irrelevant: code cannot always be made 100% objectively readable.
Aside: so-called 'objective' definitions in a dictionary are chosen by subjective humans, too.
So, everything is both relative and subjective? We should all let each other alone and just do our own coding styles? LOL Where do you get "learning" in that model? Vague goals do nothing...
1) Definitions are objective. You don't understand: logic is an objective method of taking something subjective and reconstructing the objective object that the subjective was viewing. Yes, it can
certainly be made 100% objectively readable. You see? By taking the word "objective" you have immediately removed the "subjective" definition from the situation. They do not coexist in the same term at the same time. One word cannot have two different meanings, in the exact same context. A word, in a given context, has one definition. You are confusing comments with code.
2) Yes, 'objective' definitions in a dictionary are chosen by 'subjective' humans, but it is, nonetheless, objective. It is an agreed-upon standard that expels any doubt as to the way it must be used. If you wish to use a standard, use it correctly or you will only disrupt the communication that standard affords.
Objective - 1. Existing in a concrete or observable form; material: Physics deals with objective material. 2. Real; actual: objective facts. 3. Not influenced by emotion or prejudice; impartial: an objective account of a revolution.
Subjective - Existing within the mind or perception of an individual and not capable of being observed or experienced by someone else.
Code is objective.
3) Not all code is equally objectively readable because not all code uses the terms by their definitions. Your bit-shifting versus multiplication/division is like that. It uses proper syntax, to be sure, but it ignores the purpose of the code.
Definition - A statement of the precise meaning or meanings of a word, phrase, etc.
Meaning - 1. That which something, as a word or sentence, means or signifies: Look up the meaning of the word "beauty" in your dictionary. 2. That which something intends to show, convey, or indicate: What was the meaning of that remark?
Mean - 1. To have the sense of; signify: Do you know what the word "beauty" means? Your dicionary tells you what words mean. 2. To act as a symbol of; represent: In his poems the budding flower means youth. 3. To be likely to result in; be attended by. 4. To bring about or to have as a consequence. 5. To intend to convey or indicate. 6. To have as a purpose or intention. 7. To intend or design for a certain purpose or end. 8. To be of a specified importance.
Tell me again how you can take the meaning of a term in a language as whatever you wish and not lose any of the communication afforded by the intended meaning?
quote:
Original post by Kylotan
There is often more than 1 way to say effectively the same thing, whether in English or in C++.
1) Of course. But the problem is how similar are they? Is one better? I say yes; you say no.
2) Show me a situation where two methods say the EXACT same thing, and I will show you an error in your reasoning. One way will always be more efficient and more readable, because two terms in the C++ language will not have the same definitions (unless they exist for compatibility, in which case the newer term would be more readable).
quote:
Original post by Kylotan
Are there tools missing from x86 assembly? If so, then whatever C++ provides on top by way of re-arranging that assembly, another language could provide more or better tools. Just because I don't know of those tools due to my inexperience, doesn't mean they don't exist. Maybe you can tell me what a closure is, for instance. I know other languages have them and C++ doesn't, natively. Or local functions, which you have to work around with either a private function or a function object. If you would say there are no tools missing from x86 assembly, then all tools are merely rearrangements of other tools: and therefore rearranging C++ to suit my needs would be just as valid as the existence of the language itself...
1) See statement in previous reply:
"In other words, I would estimate that: the case of not using the language correctly exists 99% of the time, and the case of trying to do something not covered in the language exists 1% or less of the time. Although many cases appear to be of the second type, they are really of the first type through the ignorance of the programmer."
2) I do not know what a closure is, so please tell me. However, I have not seen a piece of code where you were actually inventing something new, and you say that you do not know of any tool that is missing. You do believe they exist. And that is fine. However, beliefs cannot disprove anything in and of themselves, so I will continue on in my belief.
3) You are way off with the "rearrangements" theory. C++ code is not simply "rearranged" assembly. In that case, everyone would use MASM.
C++ stands for something that is not dependent upon assembly code for its meaning.
4) How can you think outside the box if you don't even know what the boundaries of the box are?
(I probably have less experience than you do about most topics, except perhaps code design which is more or less a hobby with me. I would also like to withdraw the statement about using RTTI to new() "unknown" classes, as it doesn't make much sense now that I examine it. Again, instead of hitting the "limits of the language" I have hit the limits of my own logic. Only when you realize your limits is it possible to expand them.
)
quote:
Original post by Kylotan
Did you see my plea for help on almost exactly this same subject elsewhere in this forum?
Actually, I replied to it.
Now I'm not sure whether a linked list of Window* is correct. If the windows truly do not need to know the type of their parents or children, then why is the type required at load time? It must be known to create an object of the type. Or, perhaps allocators should be used? I'll figure it out eventually. And objectively. There -is- one best solution to this problem.
quote:
Original post by Kylotan
That's exactly how I do my program. Except I could catch the string in main() and then add catch handlers to trace it back up
That's how I do mine too! What a coincidence! Except that I could catch the description in main() and then add catch handlers to trace it back up... Maybe you ought to try something like that, too?
quote:
Original post by chippydip
First, I would argue that you aren't using the exceptions at all in the way that they are intended to be used. When an exception in thrown it signifies that something about your operating environment is not ideal (ie, out of memory, currupted file, whatever) but you seem to be implementing them to cover situations that should NEVER occur during the program's execution. Your exceptions signal a problem with the programmer's logic in writing the program, not an unexpected operating state. I would suggest that instead of using these exceptions to help teach programmers how to use your library that you enforce a precondition/postcondition/invariant checking system within your library. This can be done with asserts or some other method that you devise to point the programmer in the right direction to fix his errant ways. This assertion checking should be able to be turned off in the final release build since none of these usage errors should be present in the final code.
1) A user's logic flaw means an invalid operating state for my library, which means an invalid operating environment for the user.
2) Ideally, exceptions should not occur. Therefore all exceptions are invalid?
3) How is a precondition/postcondition/invariant checking system different from what I am doing?
4) Assertions are merely a bad form of exceptions.
Check out STL, and Bjarne Stroustrop's (he's the creator of C++) appendix on exceptions (URL: http://www.research.att.com/~bs/). Exceptions are meant to enforce correct handling of exceptional conditions between layers of software. An exceptional condition results when a class is not used properly, for example.
quote:
Original post by chippydip
If you are looking for a programming feature that C++ does not support, then I would present the assertion checking just described.
// one way
if( condition ) throw exception;
// another way
assert()
You cannot stop the debugger at the point of the exception by a C++ keyword; however, I do not consider that good coding (or indeed at all necessary) as it makes the user wade through the source code in another layer of software instead of looking things up in the docs. Assertions are just another type of exception, and they are incorrect in stopping the code execution and throwing the class implementation at the user. They provide no mechanism for safe cleanup, and that is totally unacceptable. They merely freeze the problem in time. Progress is moving in the right direction, even if it involves moving backwards or sideways a little first to go forward in the future. Assertions make no progress towards solving the problem.
quote:
Original post by chippydip
Next, I would just like to comment on the way you defined the different parts of OOP. You said that nouns were represented by classes, verbs were represented by functions, etc... This is an overgeneraliaztion. A verb can very easily be implemented as a class. Its a special type of class, however, called an interface. For example, I could have an Attack class with a method DoDamage(). Now, if I wanted to have a Sword class and a Spell class which can both be used to attack I can simply inherit the interface. Now I can DoDamage() with either a Sword or a Spell.
Look up verbals in any high school level (and probably lower) english grammar book. Words can easily be different parts of speech in different contexts. Attack() is a verb and is one function. It is required to: do damage, inflict status ailments, etc. Swords and spells are used by the character to attack. The sword or spell does not just decide to attack. In other words, that capability to attack is a method of the character. You can use a sword to attack, but (so far as I know) swords have arributes (data members), like sharpness, rigidity, etc. and cannot attack on their own. You are simply incorrectly modeling the character class, and it has carried over into the other classes that must be formed to compensate for the flaws in the model.
If I may, can you send me your source for those classes (stripped down to remove all but the order of the calls and general descriptions of the functions, if you like)?
quote:
Original post by chippydip
I must comment also on your use of logic. I have a friend who argues much like you do and as I read this post I began to think that you just might be a Vulcan Logic is a wonderful tool, but it is just that, a tool. Nothing more, nothing less. It is a very powerful tool in many cases, but it can be abused if one tries to force its application in areas where its uses is not necessarily helpful.
"in areas where its use is not necessarily helpful." I don't know where you get the idea that individuality has something to do with the best code. Why are you introducing subjectivity into an area where it does absolutely nothing, and then making it into some kind of standard of good code and bad code?
The individuality of the programmer does not serve to create better code. It has nothing to do with how fast a particular block of code executes, whether it has memory leaks, etc. If I write the same exact code while having a different attitude, it will not make the code any faster or slower. Moreover, I simply cannot change the meaning of any keyword to suit my particular "style." Individuality is utterly lost on computers, and in a computer language you are talking to (surprise!) computers. Labeling a coding "style" under individuality merely removes it from debate. You do not want other people reviewing or saying how you should code anything; that is understandable at first, but eventually you will realize that you are protecting something that either: 1) is not even yours, or 2) doesn't even exist.
You can, however, add in comments in your own particular style, if you wish, as comments are not code, but instead the interpretation of it by the individual. Comments supply the only useful individuality to the language.
quote:
Original post by chippydip
The other thing that I've come to realize is that there probably isn't much I can do to provide a convicing argument about that fact that some times logic isn't the best tool since doing that would require using logic to show that logic is not useful. (I know, I know... there are circular arguments and illogical statements all over that explaination, but I don't think there is any way of getting aroud them so you will either have to just try and take a step back to understand the point I'm driving at or just leave it alone and continue as if I had never said any of this.)
Actually, there isn't anything logically wrong with what you said: you used two different definitions of the word logic, so it was like two totally different words, which means no circular reasoning. It would be illogical to extend logic past its logical purpose. (pop quiz: write a paragraph explaining that sentence.)
I'm not so "Vulcan-like" normally; just when the situation warrants that approach. I do enjoy poetry, music, games (of course!
) etc. Life would be as meaningless without subjectivity as without objectivity.
quote:
Original post by chippydip
Finally, I would also like to point out that your argument against 2 equally good solutions (instead of a best solution) existing is incorrect. You assume that, when given some set of inputs which completely describe a given solution to a problem, these inputs can be plugged into some function which will generate a "goodness" value for the given implementation. Ignoring subjuctivity, I would agree with this fact, but what you fail to notice is that it is quite possible for this function to take on equal values given completely different sets of inputs. You seem to be arguing, however, that given a large set of variables, it would be unlikely that the values would be the same, but this implies that you are assuming that the inputs must be the same as well (not what you meant). The inputs, however, will likely vary quite greatly and, therefore, the more inputs you have, the more likely the variations will cancel each other out. This implies that as project size grows, so does the number of equaly good solutions. As an example, consider a system where all that matters are speed and space. If one algorithm take a certain amout of time and space and the other takes 1/2 the time, but twice the space (assuming space and time are equally valuable... you may scale acordingly, however) then both solutions will be equally valid for the given problem.
Hmm...you had to oversimplify your example of adding more variables to get it to work.
1) Differences in probability do not cancel each other out but instead increase exponentially the chance of a particular unique solution occuring. Let's examine that a bit closer. If I have 10 functions existing in my program, between 0 and 10 of them are correct. If I add 10 more functions, between 0 and 20 of them are correct. You see, the middle range seems more probable, but only because it is much bigger (5-15). That doesn't decrease the probabability of it being either good code or bad code. Ratio of the range of good code to medium code to bad code is 5:10:5, which is the same as 2.5:5:2.5, which is the same as 1:2:1. Now, how do they cancel each other out? We could add 980 functions to that model, bringing the total to a nice round 1,000 functions, and the ratio is 250:500:250, or 1:2:1 also. You saw the increase in the middle range, but didn't see the relatively equivalent increases in the high and low ranges. That is, you have no more chance at arriving at a middle range program by merely adding more functions.
2) You made some big assumptions in your model. All functions in my program are independent of each other? All functions are relatively equal in terms of their goodness or badness? All functions compose an equal portion of the program? Two resources can be equally valuable in real life? None of the circumstances are probable, let alone occuring in real life. Finally, I am not talking about a whole program, but individually each and every piece of code in it. there is no real scale of bad to worse in the end, as each is either accepted or rejected and re-compared until one piece of code is found to be the best. In other words, the return value is the whole purpose of the function.
3) I would estimate that a typical solution to a given problem (of the complexity of using linked list or array or whatever) has a ratio of < 1:1,000,000 of being programmed in the exact same way. That is, there are many, many variables found in both the problem and the solution. (Note that the less than sign there means that the second number grows bigger while the first number stays the same; i.e., 1/1,000,000 is bigger than 1/2,000,000)
4) The input must be the same? The function will take on equal values? What are you saying? Perhaps you misunderstood me, so I'll expound on it:
The inputs are comprised of: a) the problem and b) the solution. The constant (or another way of putting it would be the function) is good code, and the input variables (parameters) are the relevant variables of the particular problem and solution. The return value is based on equivalence to good code, returning either true or false for each statement. (If it should happen that all solutions fail this function, they are all compared to one another based on the variables relevant to the problem and the variables relevant to each solution.)
3) I'm sorry, but you didn't state the problem. Without the other half of the input, you will get undefined results.
quote:
Original post by Mezz
Reading it, I find myself smiling because I think of two very reasonable and polite men sitting down trying to have an argument without offending or disagreeing with each other.
LOL I nearly fell off my chair when I read this!
quote:
Original post by Mezz
One thing that did bother me was some of null_pointer's comments about logic.
A view of logic is relative - saying there is only one logical solution I find myself disagreeing with.
Logic - 1. The study of the principles of reasoning, especially of the forms and relationships between stateements as distinguished from the content of the statements. 2. Rational thought; clear reasoning. 2. A particular system or method of reasoning. 4. A way of thinking or reasoning: the political logic of frontier people.
1) Where do you get subjective from that? I am talking about #2. If that definition of logic was subjective, it would not exist as it could not possibly fulfill its purpose.
quote:
Original post by Mezz
You don't have a game. You want it.
Solution A: Buy it.
Solution B: Warez it.
You could argue that solution A is correct because it does not break the law. People without the money would argue differently.
what I'm trying to say is that logic can be relative.
1) Logic, as a set of defined laws and principles, is not relative. You must mean definition #4, a way of thinking. I was talking about definition #2. Definition #4 includes all the rationalisms that commonly go with the logic (here meaning #2) applied to a particular situation.
2) How dare you bring the warez people into a rational discussion!?!
Warez is just stealing; stealing includes no definition of purpose intentionally, because it can be done for any purpose. Stealing is punishable by law. Stealing also disrupts the normal economics of a given system by changing the rewards for capitalism. However, I do not wish to get off topic with a discussion on pirated software.
Everyone: Without a standard there is no comparison. Without comparison you cannot say "good" code or "bad" code. That means a standard must exist. What is the standard?
And BTW, does anyone know how to fix the scroll wheel of a Logitech mouse?
-
null_pointerSabre MultimediaEdited by - null_pointer on 5/6/00 3:26:54 PM