The act of constructing a convincing argument which will be presented to your peers will necessarily mean you will need to understand the subject. To construct a convincing argument: * You make your assumptions and rules of deduction explicit * Then set up your problem, and argue! * Digging up your assumptions and tracing your reasoning can be subtle, difficult, and enchanting. * Eventually, every link in your argument rings true, and you attain argument nirvana. This is why I like * patterns ** because they are convincing arguments about design decisions. * math ** because mathematicians have refined the activity of argumentation into a fine art. Beautiful patterns, programs and proofs seem inevitable; they are the ''right thing''. Stretching the analogy a little, a working program is a successful argument with a skeptical listener, who is ready to drop everything and run off to la-la land at the first sign of a mistake (except Smalltalk, which politely says, ''does not understand''). -- AamodSane ---- A dangerous thing about Convincing Arguments is that sometimes they end up '''not''' being about the ''right thing''. What is required for a Convincing Argument (especially in design, patterns or proofs) is a central idea that, once accepted as truth, causes all other related or supportive ideas to be accepted. This can be a common problem with Patterns. If you setup a ''popular'' context, discuss recognizable forces, your solution can address each force and still be incorrect. Create a Pattern for a domain that I don't understand well, and if you push ''all the right buttons'' I may buy into your solution. This also happens in software engineering all the time. I can construct convincing arguments about: * Why you shouldn't use GOTOs. * Why GOTOs are useful and shouldn't be banished ... just don't ask me to. -- ToddCoram ---- Coming from a mathematical background, I look at writing a program as essentially writing a mathematical proof. The point Aamod makes is that a good program is exactly a convincing argument, a well-formed proof. The pleasure of Smalltalk is that it makes it easier to compose a clear and convincing proof/program than in other computer languages. Looking at an individual method, the "theorem" that the argument is designed to prove is contained in the name of the method. A financial program may have a method "interestFrom:to:"; this name asserts that, given two dates, the interest between two dates is equal to the quantity found at the end of this method. A reader of the method should be able to be convinced of the truth of the assertion without much difficulty, if the method/proof is constructed in a convincing way. It is fairly easy to write an argument that is "convincing" to the program compiler -- the program either runs or it doesn't. A rarer skill is to write arguments/programs that are convincing to other people. The clearer the construction of a program is, the easier it is to maintain, by other engineers or by your future self. Long after you have forgotten what you were thinking when you were writing it, a good object or method will reveal its intention, construction, and correctness with a minimum of effort. Part of this emerges in coding style. I find I use temporary variables much more than classically-trained programmers. Each step of the "proof" requires its own label. Programmers who worry about optimizing every bit of code see my temporary variables as a waste of time, and imagine they are being clever by nesting together statements into one long statement. This is fine for the compiler, but it muddles the argument. Writing for the human reader, rather than for the machine, may make code that is a tiny bit slower, but in exchange one has a great improvement in correctness and maintainability. The advice on forming good objects one hears -- such as making sure each object has a well-defined and limited responsibility -- ultimately can be seen to spring from the one principle, that objects should join together to provide a manifest proof of their own correctness. -- GaryGoldberg ''You cannot prove that a program does as it was intended without an indication of intent that is either explicit or implicit in the program. Unfortunately, compilers and code-provers cannot take advantage of intent that is implicit in names and comments. I dislike this use of comments and names... or, more accurately, think it should be replaced with a means of formally passing to the compiler and prover the same sort of information on intent that it conveys to us: Hoare Clauses, unit tests, assertions, formalized representations of requirements specifications and RFCs that can be checked against the implementation or meta-implementation, etc. etc. etc.'' ---- See also: SoftwareAnalogies