4.4 Programmer Productivity

Increase Programmer Productivity by choice of Paradigms 


The overriding motivation for introducing programming languages based on different paradigms is to increase the productivity of programmers. 

Different problems require different sets of tools to enable the production of efficient and reliable solutions. 

The effect of using languages more suited to particular tasks has an effect on productivity. 

Some of these affects will improve productivity and others may reduce productivity. 

Management must weigh up the positive and negative effects when deciding on a choice of language to be used for particular projects. 

Some areas influencing productivity include:
  • speed of code generation 
  • approach to testing 
  • effect on maintenance
  • efficiency of solution once coded 
  • learning curve (training required)

Speed of code generation

The speed at which programmers can write code which performs the required task in an elegant, efficient manner, is a valuable measure of productivity.

Different programming paradigms are suitable for different type of problems and influence how fast a programmer might be able to code a solution.

The speed at which code can be generated is a traditional method of measuring a programmer’s productivity. 
  • Many software companies still pay programmers based on the number of lines of code they write. 
  • Thankfully, this method of payment has been largely phased out; encouraging programmers to write long-winded source code is certainly not the way to develop efficient and elegant programs. 
  • Nevertheless, the speed at which a programmer can create code to solve a problem is a valuable measure of productivity.

Programming languages that increase the speed of code generation must increase the productivity of programmers. 
  • Similarly, using a language based on a more suitable paradigm will also increase the speed of code generation
  • Different problems are suited to solutions using different paradigms. 
  • Choosing the most suitable paradigm can make the process of software design and code generation more efficient and will result in a more elegant and useable final solution. 

Consider the following:

A software development company is working on a new computer game called Teenager’s Revenge. 
  • This game has various characters that interact with each other; 
    • each character is either a teenager or an adult
    • The teenagers possess qualities in common and similarly the adults have qualities in common. 
      • Teenagers are able to argue with adults and adults are able to attempt to reason logically with teenagers. 
    • Adults are split into sub-types; parents, relatives, teachers and friends. 
    • Of course, the teachers are the most understanding and logical, whereas the parents are the least logical but the most responsible from the teenager’s viewpoint.

This product suits development using an object oriented paradigm. 
  • Each character within the game would be an object with data and methods. 
    • For example, a parent would be an adult object containing low levels of logic combined with a high level of responsibility and a medium level of understanding. 
    • Each parent object would have a method attached to explain how they reason with teenagers of different types. 
    • Teachers would be adult objects with high levels of understanding and logic and medium levels of understanding. 

    • They too would have methods attached to describe how they interact with teenagers. 
    • Similar objects could be created for each of the teenage characters.


Approach to testing

Testing individual models of code, known as unit testing, greatly affects the productivity through being able to continuously, and often automatically, test modules of code as they are written or modified.

This is heavily influenced by the choice of programming paradigm chosen - for example, object oriented programming encourages programmers to write self-contained classes which make it easier for testing.

In Stem 3.4, we examined the testing phase of the software development cycle. Much of what we learnt is relevant to testing software produced using languages based on any of the paradigms.

Unit testing, or testing individual modules, is perhaps where the largest productivity gains can be made. This is particularly the case when using object oriented languages. These languages force programmers to write self-contained classes. These classes (or the objects produced) can be thoroughly tested without requiring reference to other components. Imperative languages do not force programmers to develop such self-contained units. Classes that have been thoroughly tested can be treated as black boxes; the internal processing details need not be retested.

Once a class has been created it is possible to create new classes that inherit the attributes and methods from the original. This ability means that much of the code produced within new software projects will be tried and tested code from previous efforts. The previous section on OOP explained these concepts in more detail. As a consequence, testing is simplified resulting in productivity increases.

It is difficult to discuss testing without mentioning test data. As we said in Stem 3.4, the creation of test data sets is a vital stage of the testing process. Languages that can encapsulate their data in such a way that it cannot be altered by other processes will greatly reduce the magnitude and breadth of the final test data sets. OOP languages discussed in the previous section not only encourage data encapsulation, in some cases they enforce it.


Effect on maintenance

Locating sections of code to be modified, and then having the required skills to modify that code (depending on the language and paradigm used), can be a time consuming task and influences productivity. 

The paradigm chosen has a great impact on this, e.g. object-oriented programming languages encourages programmers to modularise their code.

Maintenance is primarily about the ability of the code to be modified to meet changed requirements. 
  • To modify code requires locating the section of code that requires modification and then actually implementing the changes within the code. 
  • This requires thorough documentation throughout the software development cycle but particularly at the design and implementation stages.

Isolating the precise location of the code to be altered can be a time consuming and difficult task, particularly for large applications. 
  • Languages that force programmers to modularise their work greatly assist maintenance programmers to locate particular procedures and functions within the source code. 
  • Object oriented languages do this well, imperative and logical languages certainly provide the facility but it is not enforced. 
  • Ultimately no matter what language is used, programmers can write well-structured, elegant and readable code and they can also write rubbish.

Large software companies are reluctant to develop products using languages that are not widely understood. This is a reasonable and responsible reaction given the limited number of programmers available to maintain the code. If a large bank decided to convert all its applications to a new language then they must ensure maintenance personnel are available to maintain the product.

Robust, bug -free code is the desire of all software companies for it minimises maintenance issues. Many of the concepts we have covered in this chapter encourage or enforce the development of such code. Logical languages such as Prolog operate at a higher conceptual level thus removing the programmer from the technical details at the CPU level. The responsibility for managing memory and CPU operations is removed from the programmer and handed to the language and it’s developers.



Efficiency of solution once coded

Different programming languages have different levels of efficiency once coded. 

For example, imperative languages such as C are aligned closely to the CPU and usually run very efficiently, compared with object-orient languages which are more abstracted - but often easier and more efficient for the programmer.

Efficiency of software once it is coded is often measured in terms of speed. 
  • How fast can an application retrieve a record, process it and store the result? 
  • How many CPU cycles does it take for a word processor to prepare a ten -page document for printing? 
  • These types of tests are designed to test the efficiency of the final solution.

Imperative languages are based on the von Neumann architecture. They have evolved in line with the developments in hardware technologies. Many of these languages e.g. C enable the programmer to work closely with the CPU’s operations. Well written C programs will out-perform most similar programs written using OOP or logical programming languages. Unfortunately, this is a consequence of the development and evolution of hardware technologies rather than software technologies. Essentially, languages using other non-imperative paradigms are, in a sense, crippled by the hardware. They are not able to compete on an even playing field.

The good news is that these languages can considerably reduce development times. In addition, hardware, although not designed for these paradigms, is now capable of executing applications at such a speed that efficiency concerns are often of reduced importance. This is particularly true of many popular OOP languages such as Java and C++.



Learning curve (training required)

Programming languages based on the logical programming paradigm (and other paradigms such as the functional paradigm no longer studied in SDD) have not gained wide acceptance amongst the general software development community. They are often viewed as obtuse and specialised. Many programmers view them as interesting oddities and hence they are only used in specialised areas. It can be argued that intensive and ongoing training and marketing is required to lift the status of these languages. It is a difficult task to thoroughly learn languages based on new paradigms and often the learning curve is steep. The benefits however are often greater than first envisaged.

Object oriented languages, on the other hand, are accepted and used by a large proportion of software development companies. Most universities now teach object oriented languages as part of their computing and engineering degrees. It is true that the languages we first learn are the ones with which we feel most comfortable. Because many programmers are experiencing and learning OOP techniques early in their careers these languages have gained wide acceptance.

Try searching the internet for tutorials on particular imperative, logical, object oriented and functional languages. You’ll most likely find hundreds on C, Basic, Pascal, Fortran and various other imperative languages. You’ll find an almost equal quantity on C++, Java and other OOP languages. What about Prolog, or functional languages such as APL, Haskell or Lisp? Your search will of course reveal them, but specialist interest groups will have written most with not many available as commercial material.

It is not an easy task to learn any new programming language, but when the paradigm on which it is based is also new the problem is compounded. There is no doubt that software developers and the greater community will benefit if they can find the time to examine and learn new ways of doing things.
    




Comments