From XpFaq:
See OnceAndOnlyOnce, DontRepeatYourself, YouArentGonnaNeedIt, RefactorMercilessly, ContinuousIntegration, FrequentReleases, XpValueFeedback?, TestDrivenDesign.
XP doesn't generally encourage strict typing?
Pavel A. Perikov wrote:
Reading comp.object I gotta impression that XP doesn't generally encourage strict typing. Smalltalk & Python is good, C++ sucks :) Is there any [semi-] official XP statement about strictly typed languages such as C++ (putting away other major drawbacks), Java, Eiffel etc?
I'm about as semi-official as you can get.
XP isn't language specific, although the things you have to do need to be adjusted. Strictness of typing isn't one of the issues, although the language contortions it takes to support strict typing may be.
Strict-typing languages like C++ and Java induce you to declare something in one place, then define it in another, then use it in a third. They generally won't let you use something before you go somewhere else first. It's a bit like having to pitch your tent every night before going to bed. It worked well for the nomads but it's not terribly efficient.
Types are comments and assertions. They stand as compile-time checks because the most native constraint is that a value never change types unless under programmer control. Dynamic languages crack this by always absolving the check on the assumed type.
In addition, most implementations of these languages are compile-link-run in nature, rather than incremental compilers. This isn't necessary, but it is the way things turned out.
The effects of these characteristics are that (a) you have to edit in more places to do any given refactoring, and (b) as your program grows, it takes longer to install a change and test it.
The non-strict languages, such as Smalltalk and LISP and, yes, Python, throw up fewer of these obstacles. If refactorings allow you to change less code, refactorings are easier, quicker, less error-prone. If you can move from change to test in one second instead of 1 minute, you can make smaller changes, again reducing error.
In Smalltalk, there are some additional advantages. The ordinary Smalltalk browsers let you find and access things in ways that Emacs people can't even imagine. (Yes, I know, you can grep your source files. Smalltalk actually knows what it's looking at.) Even better, the Refactoring Browser actually knows how to DO the refactorings for you. It's a power tool for refactoring.
Languages like Smalltalk and LISP have yet another advantage. These languages are written in themselves. They are reflective, which means that there are Smalltalk or LISP statements that can manipulate the running code. This is a good way to kill yourself, but it also means that you can extend the programming environment when you need to. This isn't something for beginners, but it means that you can acquire powerful and valuable tools from experts, and integrate them into the IDE with ease. This, too, used with good judgment, speeds your programming.
The cumulative effect of all this is that a competent programmer in these languages can go faster than an equivalently competent programmer in the strict languages. Part of it is due to the cost of strictness, part to the toolset.
So ... XP is easier to do in Smalltalk or Python than in C++. It's still quite doable in C++, just not as fast and not at such a small increment of change.
Bottom line: There's nothing "wrong" with strict typing languages. It happens that they don't provide the most productive development environment - arguably for many things, and certainly for XP practices like refactoring and test-first design.
Just my opinion, of course ... but I believe a fairly expert one. And semi-official to boot.
Ronald E. Jeffries
"This path has been placed before you, the choice is yours alone."
Static typing, the way C++ and Java/C# enforce it, is negative reinforcement. The compile fails if your types attempt to think outside their box, and you are punished.
TestDrivenDevelopment, by contrast, is positive reinforcement. When your strong but dynamic types work correctly together, the tests pass, and you are rewarded.
This is why TDD with a dynamic language is often preferable to TDD with a static language _and_ static type checking.
Hence, the Agile movement often favors the dynamic languages for the high-level code - the CommandAndControl? code that runs far from the metal. The closer you get to the metal, the more important becomes thinking inside the box!
--PhlIp
Sorry for moving your response down in the page; however, it seemed like a less definitive response than Jeffrie's response.
However, I disagree with your assertion that static typing the way C++ enforces it is negative reinforcement. I've coded with C++ and Java using TDD and the static type system simply never got in my way. Ever. How can you explain this?'
When my program (accidentally) interprets the bit-level representation of a type in an "out of the box" fashion, yes, I absolutely do want the compile to abort. Immediately. With great haste, and for great justice. Particularly since doing so means that it's proven the program will fail otherwise. I've never seen the compiler err in its determination. I have seen the compiler err in the opposite direction though, where it thought similar types would be compatible, but were not (e.g., what is the sum of two file handles, as they're defined by POSIX?).
The real problem with using a statically-typed language is their inherent difficulty in supporting a highly interactive environment. You have to quit your program. You have to edit your tests. Then you have to hand-link those tests into some test suite object. Then, in some cases, you have to hand-link those test suites together into a framework object. Then you run your test framework's runner. Only then do you get the chance to respond to the test's results.
I hate to say this, but KentBeck's influence on the *Test industry is the real problem with trying to use TDD with C++ or other statically typed languages. Say it together now, "SUnit is great for Smalltalk, but positively disasterous for not." What this means is that not all unit test packages need to be like SUnit. This is why I wrote my CUT tool (http://www.falvotech.com/content/cut/2.6). It works by processing C source files to discover things which are tests, setups, etc. so I don't have to. I am now able to unit test software in C or C++ with the a level of ease that would render even PyUnit users jealous, since I don't have to write stupid test suite linkage definitions.
I've been trying to say stuff like this for years, but people keep sloughing me off as some young upstart who hasn't a lick of a clue. Guess what? I do have a clue, and it's obvious that now others are starting to get it too.
SUnit isn't the end-all, be-all of unit testing tools. Its architecture works great for Smalltalk and similar environments. It quickly becomes a burden in other languages, though. What's needed are TDD tools tailored for your language of choice. You'll find TDD goes MUCH more smoothly if you do.
See also:
Universe wrote:
> You have not explained what code has to do with a high level design solution!
High level design solutions have to work. They don't work until they have been coded. Coding them provides insights into design issues and ultimately changes the design.
> If so please show me how? If we are taking an OO approach to development, how does coding affect the desirability or indesirability of one high level, implementation, environment free, design solution versus another?
It lets you test them. It lets users see and touch the growing system. It's the only act that can close the feedback loop.
> How can we start out without a map? How do we analyze key elements of the domain and its use cases first?
It is not now, nor has it ever been, a matter of failing to analyze the domain. Rather it is a matter of how and when that analysis is done. I prefer to do this analysis incrementally and iteratively concurrent with implementation.