Jan 22nd, 2008 | Skills
Thomas J. Bing and Edward F. Redish of University of Maryland analyzed how physics students work on assignments using computer programs:
Symbolic calculators like Mathematica are becoming more commonplace among upper level physics students. The presence of such a powerful calculator can couple strongly to the type of mathematical reasoning students employ… Mathematica plays an active role in focusing and sustaining their thought around calculation. These students still engage in powerful mathematical reasoning while they calculate but struggle because of the narrowed breadth of their thinking. Their reasoning is drawn into local attractors where they look to calculation schemes to resolve questions instead of, for example, mapping the mathematics to the physical system at hand.
These computer tools affect thinking and how students frame and focus their work.
Can we find similarity with the way tools affect programmer’s mindset ? In essence, software programming is operation on ideas and knowledge. We translate people ideas into the source code. But we cannot do it effectively without programming platform and tools – editors, compilers, debuggers and may others. And they have profound effect how we approach and solve customer needs. Our platforms and tools could frame and alter our thinking. PHP, Visual Basic, Java, .NET, Ruby On Rails programmers with the same level of experience will build not only technologically different solutions, but in the most cases solve problems different ways.
Programmer’s platforms and tools affect our mindset in three ways:
- Tools could prevent normal flow of idea implementation. Inconvenient tools, cumbersome environments and long feedback cycles stagnate productivity and lead us to the path of the least resistance, often far from optimal.
- Tools could make ineffective implementation strategies more attractive, affecting how we frame customer ideas. For example, UI-oriented programming environments could shift programmer’s mind to think about the problem in terms of screen elements and UI events (Smart UI) instead of reflecting in the code domain concepts, relations and ideas (Domain Driven Design).
- Tools could shift focus to the implementation perspective from the big picture and broader context of the problem at hand. Narrow focus on implementation and technology has negative impact. Often redefinition of the problem, analysis of alternatives or refining of concepts could bring much better results. Inexperienced programmers (and even experienced) often get into this trap, concentrating on tools the same way as novice drivers are more concentrated on the handling a car instead of observing the road and finding the better way.
What qualities should effective programmer tools have?
- Usability – enhance flow of programmer’s ideas or at least don’t impede and interrupt this flow. Tools should be convenient, easy-to-use and aligned with the way programmers work. Programmers should put most of their mental energy to think about customer ideas and much less how to deal with these tools.
- Representation – enable easy for understanding and modification representation of the structure, ideas and domain concepts in the code. Tools should provide a convenient solution view, organization and navigation for understanding, parsing and manipulation with components, classes, relations and concepts. Modern source-based project organization could benefit from tools like Resharper. Martin Fowler blogged about more radical approaches as repository-based code and Language Workbenches. UML, MDA and code auto-generation tools didn’t prove to be useful for effective code representation.
- Agile development friendly – support evolutionary design, short delivery cycles, refactoring, unit testing and other agile practices.
What do you think? What are the best tools for the programmer to enhance concentration on the problem, unobtrusive flow of thoughts and effective implementation of ideas?
Link: Symbolic Manipulators Affect Mathematical Mindsets, Thomas J. Bing, Edward F. Redish
Jan 9th, 2008 | Skills
Cross Talk complains that the selection of Java as the first programming language in Computer Science education weakens programmers skills and lead to decline in qualification.
The irresistible beauty of programming consists in the reduction of complex formal processes to a very small set of primitive operations. Java, instead of exposing this beauty, encourages the programmer to approach problem-solving like a plumber in a hardware store: by rummaging through a multitude of drawers (i.e. packages) we will end up finding some gadget (i.e. class) that does roughly what we want. How it does it is not interesting! The result is a student who knows how to put a simple program together, but does not know how to program. A further pitfall of the early use of Java libraries and frameworks is that it is impossible for the student to develop a sense of the run-time cost of what is written because it is extremely hard to know what any method call will eventually execute.
Authors noticed other worrisome trends in teaching software professionals:
- Mathematics requirements in CS programs are shrinking.
- The development of programming skills in several languages is giving way to cookbook approaches using large libraries and special-purpose packages.
- The resulting set of skills is insufficient for today’s software industry (in particular for safety and security purposes) and, unfortunately, matches well what the outsourcing industry can offer. We are training easily replaceable professionals.
I want to look into this problem from the broader perspective: what is the best way to become a good programmer for a beginner? There are two fundamental ways:
- Strong theoretical foundation: learn applied math, theories of algorithms and computational complexity, read Knuth’s The Art of Computer Programming, solve problems with Turing machine, etc.
- Shu Ha Ri – learning by experience: learn programming by solving practical problems with modern languages and platforms (Java, .Net, Ruby On Rails, PHP). Fundamental knowledge emerges from experience in solving real problems.
Definitely, there are some domains that require and intensively use CS theoretical knowledge: science, engineering, hardware and system programming. However, majority of software professionals build software for solving business, personal and other non-rocket science problems. I know a PHP programmer, who doesn’t know how to write a sort algorithm (without looking somewhere), but still have built several successful web applications. And I’m confident that there are strong computer science theorists who cannot write easy-to-use programs and make their customers happy.
So, what is the best approach? I believe any beginner should excel in following three areas:
- Train clear logical thinking. The ultimate end result of any programming is a program (I hope it is not a surprise), which is a set of instructions for a computer. You cannot write instructions if you don’t know how to achieve end result. Any language which allows clear procedural expression of logic is fine for start (e.g. Pascal). I would add object-oriented and functional languages on later stages (e.g. Ruby and Lisp).
- Understand modern software concepts and environments: computer architecture, networking, web, mobile, concurrent programming, cloud computing, etc. High level knowledge will give better orientation, starting points and overall understanding of software systems mechanics.
- Learn to effectively implement customer needs. Happy customers and useful software is the end result of any healthy software project. Learning evolutionary, agile development and user experience (including communication and psychology) practices is essential for the effective software developer.
I believe that software development is empirical in nature. Math and computer science theories are great, but in many case they will be only brain exercises without practical results, especially for beginners. On the contrary, beginners will become excellent master programmers by succeeding in discussed above three fundamental areas and relentlessly learning from experience in applying them.
What do you think?
Computer Science Education: Where Are the Software Engineers of Tomorrow?, Dr. Robert B.K. Dewar and Dr. Edmond Schonberg
Is Software Development Empirical or Rational?
Jan 4th, 2008 | Design, Practices
Can we say that clearing house from rubble and debris after home repair is a necessary waste for construction workers? Can we say that making design of the car that could be easily supported and repaired by mechanics is a necessary waste for engineers? Can we say that making ideas clear, easy to follow and understand is a necessary waste for the influential writer?
Amr Elssamadisy posted an interesting opinion on InfoQ about refactoring:
… there are two types of waste in Lean: pure waste, and necessary waste. Pure waste is one that has no value to either the team building the software or the customer using the software. Necessary waste, on the other hand, is the best way we currently know how to do a job even if it does not have customer value. Refactoring is clearly an instance of the latter.
Amr tries to make an important point – minimize refactoring that doesn’t contribute directly to customer requirements under development. It is a reasonable point, but I don’t like word the ‘waste’ and belittling of one of the most important practice of the modern developer. This post sparked a very interesting discussion around value of refactoring with many insightful comments (including Kent Beck and Tom Poppendieck).
We, software professionals, sometimes forget that source code is the most important representation of our ideas about how software should work and what it actually does. In the essence, software development is communication, processing and coding of people ideas. We substantially reduce value of our software if we leave messy, convoluted and difficult to understand software ideas, though correctly implemented. This code will waste time and effort of people who evolves and supports our software (including ourselves). And therefore, it will reduce value of the software for the customers who expects that it will be well supported, easy to change and become better over time. Refactoring is the practice that forces us to improve code and represent software ideas better.
Certainly, as with any complex human activity, we should learn when, how and why we should do refactoring. We should learn how to balance refactoring and development of the new features – software consolidation and expansion phases (read an excellent article from Brian Foote and William F. Opdyke). Refactoring should be not only targeted to reduce technical debt, but also to reduce comprehension debt – understanding, refinement and enhancement of implemented ideas. Finally, refactoring is the essential part of our professional mastery, which distinguish ace programmers from amateurs or indifferent hirelings.