Software Languages

There are several styles of coding software and many software languages available. I am interested in both coding styles and the possible languages available. Some coding styles work best with specific languages. Some languages have much more flexibility with regard to coding environments than others. It depends on what your purpose for developing code on which coding style and language you choose.

Languages

I like to divide languages into three categories:

  1. Boolean Algebra
  2. Binary, Hex, and Assembler Programming
  3. Compiled
    1. General Principals
      1. Subroutines or Functions or Procedures
      2. Pass by Reference
      3. Pass by Value
      4. Scope
    2. Early Languages
    3. Structured Languages
    4. Object-Oriented Languages
  4. Interpreted
  5. Machine Independent
  6. Software Development Environments (SDEs)

Case Definitions for Names

German and naming conventions for software names have a lot in common. Both define concepts by combining several common words into a new word or name. To indicate where a new word begins in computer naming, several conventions have been established. This is just an overview of the main conventions.

      • All Lower Casethisisanexamplename – hard to see where one word ends and the next begins. Not recommended
      • ALL UPPER CASETHISISANEXAMPLENAME – also not usually recommended, but variations of this form are used to define tags (like #define DEBUG1 1).
      • CamelCaseThisIsAnExampleName and thisIsAnExampleName – Makes seeing the words easier. These type of names are often used in Object Oriented Programming. Classes are usually represented by an upper case initial letter, while instances of classes are represented by a lower case initial letter.
      • Hyphen-Separated-Wordsthis-is-an-example-name – Often used for directory names, especially for WordPress plugins. Can contain upper case letters, but that is not recommended.
      • Underscore_Separated_Wordsthis_is_an_example_name – Often used for file and function names, especially for PHP functions. Can contain upper case letters, but PHP does not accept any Camel Casing of any words.

Boolean Algebra

Boolean Algebra is tied to both software and hardware. It can be used either by hand or through software, but it is also the basis for the initial silicon chip designs. For more detail, please go to the page Boolean Algebra.

Binary, Hex, and Assembler Programming

The card to tell a machine what to do was invented before there were electronic computers. Languages for computers started off as just holes in these cards for the early loom (both in China and in Europe), Babbage’s computer, and 1890 United States Census. The Hollerith card was invented for the 1890 census, based on the size of the dollar bill of that time. TechTarget has a good history of the punch card.

Since computers started as a series of switches, the switch could be open or closed. Based on these switches, the first coding was all binary (zeros and ones). Binary coding was difficult and soon hexadecimal (base 16) coding was introduced because number and letter patterns are easier to recognize than patterns in a string of 0’s and 1’s. Computers all started off as binary machines, therefore to use numbers larger that 0 and 1 they combined bits (think of this as single switches) to make bytes. On various systems, the bytes initially were various lengths. IBM started with 8 bit bytes, which is the current standard. Burroughs had 48 bit bytes and Control Data Corporation (CDC) had 60 bit bytes. Hexadecimal is base 16 or 2^4 (24). The numbers are 0-9 and A-F (10 numbers and six letters).  An example of the three numbering systems would be:

Roman Arabic Binary Hexadecimal
0 0 0
I 1 1 1
II 2 10 2
III 3 11 3
IV 4 100 4
V 5 101 5
VI 6 110 6
VII 7 111 7
VIII 8 1000 8
IX 9 1001 9
X 10 1010 A
XI 11 1011 B
XII 12 1100 C
XIII 13 1101 D
XIV 14 1110 E
XV 15 1111 F
XVI 16 10000 10
XVII 17 10001 11

The big breakthrough came when manufacturers started translating commands into simple instructions. This became known as assembler. Assembler coding is much simpler that binary or hexadecimal coding, and is used in firmware and in code that is speed critical or size limited. In the 1980s, there were two major competing assembler languages, one of the Intel x86 series and one for the Motorola 68000. These were 16/32 bit processors that started attaching to a 16-bit (two byte wide) bus and eventually to a 32-bit (four byte wide) bus when demand required more compute power. The two main processor manufacturers are now Intel and AMD. AMD was the first to go to a 64-bit (eight byte wide) bus, and Intel and AMD agreed on the standard x64 Assembly(Assembler) code. As a side note, it depends on where and engineer was trained on whether the code is called Assembler or Assembly. They reference the same type of code, so either can be used. To be consistent, I will be using “Assembler” throughout my documents.

Compiled Code

As computers were used for “real world” applications, even assembler was not good enough for scientists who wanted to enter long formulas to solve problems. This is where higher level languages started to develop. The earliest were FORTRAN, Cobol, and LISP. The

General Principals

All programs have certain basics, but there are distinct programming approaches, like straight line programming (FORTRAN, COBOL), structured programming (Algol, Pascal, C, Ada), object-oriented programming (SmallTalk, C++, JAVA). The examples listed here are all compiled languages. There are also interpreted languages (often in the form of shell scripts like sh, ksh, bash, PHP, Python). Most programs have called procedures, but how these called procedures and their parameters are handled vary widely.

Subroutines or Functions or Procedures

This allows certain parts of the code to be written once and then used by making simple calls from other parts of the code. Procedures are usually defined in header (.h) files and then implemented in modules that are compile separately and then linked into the program when the final package is being created. For shell scripts, subroutines can be written as independent programs and stored in one of the accessible “bin” directories or stored in another directory that is stored in the universal $PATH variable. Procedures can have parameter inputs or access global variables. They can also return a value on exit. Parameters can either be passed by reference or passed by value.

Pass by Reference

A pointer to the value that is to be used by the procedure is passed into the procedure. For long strings and a limited amount of space, this can be very useful. However, there is always an opportunity for the procedure to modify the value of the information to which the pointer references. FORTRAN was designed to pass by reference. One of the early mistakes of first time FORTRAN programmers is to pass an actual number into s subroutine. For example, if I pass in the number “2” to a FORTRAN subroutine, It passes in a pointer to where the number 2 is stored in the program. Let say that the subroutine changes this variable to 3. From then on out, every time the user uses the number “2” it will now be used as it is a “3”. This could give some interesting results.

Pass by Value

Most languages use Pass by Value as the default. Pass by value passes in some value to the procedure and the procedure then creates a new variable based on the procedure definition and then places the passed in value into the created variable that is viable as long as the procedure is “open.”

Scope

Scope describes over what range a definition is valid. For example, in a structured language like C or C#, a variable can usually be used within the curly braces in which it is defined. The one exception is a variable that is defined as a global variable. Functions and Subroutines will be described more within the individual language. In general, to access a subroutine or function that resides in a different compilation module (usually ending in .o for compiled objects or .a for libraries) is through a header (.h) file that is included in the module where the function or subroutine needs to be accessed. Older languages, like FORTRAN have a variable scope of the routine (main or subroutine) in which it is defined.
For example:

int main(void)
{
   char *mainString="Main String: "; //Initialize variable
   const int upperLimit=10;          //set the upper limit as a constant
   int i=0;                          //initialize index variable.
   while(i=0,i>=upperLimit,i++)
   {
      char innerLoop=" ";  //To be completed when I have time to compile code

There are other programs, like LISP, where the scope definition is not quite as easy. LISP is a string manipulation language that is often used in Artificial Intelligence. The easiest way to think of scope is to say it applies to everything within a set of parenthesis, but not within any items within parenthesis subsets.

Early Languages

Soon the desire for a way to write formulas on one line developed, which led to the development of a Formula Translator, or FORTRAN. Even FORTRAN was too archaic for some people, and they desired a “self documenting” language. This led to the development of the Common Business-Oriented Language, or COBOL (I normally would prefer a direct link to the actual development web-page, but this is as close as I could find. If you have a better link, please let me know). At the University level, a desire to have routines that could recursively call themselves developed, the original FORTRAN and COBOL could not do this. In fact calling subroutines in FORTRAN with an actual number can become quite interesting. The recursive language that developed was LISP, a fun language to use and quite powerful. In LISP every item is defined as a string surrounded by parenthesis. Lazy programmers would always end a LISP program with a square bracket instead of the number of ending parenthesis that would be needed to close the program correctly. This can lead to subtle problems. When I was first learning LISP I always said it stood for “Lots of Insipid Stupid Parenthesis.” It was popular because of its flexibility and power to do programming that the other two languages could not do (like recursion). the only problem was that every university wanted to create its own version of LISP. In the 1980s, a group of LISP users gathered and developed a common definition for LISP, known as COMMON-LISP. The last language of this group to be added was BASIC for students. It was based on a simplified FORTRAN. For example, variable names could only be one letter and one digit, instead of the eight characters that FORTRAN allowed. Microsoft did take BASIC and used it for their development environment (Visual Basic). This was a tremendous improvement for the usefulness of the language.

The languages I would like to cover for this section are:

  • Assembler
  • FORTRAN
  • COBOL
  • LISP
  • BASIC (and Visual Basic)

Structured Languages

As a need for more powerful ways of expressing ideas developed, a push for a more structured approach also began. One of the first structured languages to develop was Algol. It did incorporate several ideas from both LISP (recursive calls) and FORTRAN (being able to write formulas on single lines). This language was heavily used by Burroughs. In fact on their early systems, they had no assembler language. All the control of the hardware was done in Algol. From Algol, several languages were developed. Pascal was developed for teaching University students programming. Bell Labs (AT&T) developed C to help them develop a new Operating System (the code that controls the hardware) call UNIX.

The main languages that will be covered here are:

      • Algol
      • Pascal
      • C
      • Ada (named after the first programmer who worked with Babbage)

Object-Oriented Languages

It has been brought to my attention that there are two languages, Simula and SmallTalk that claim to be the originator of Object-Oriented Programming. They were developed for different purposes. Simula is about ten years older than SmallTalk, but they were developed fairly independently from each other. A good article about the comparison is “Simula and Smalltalk: A Social and Political History.”

Engineers at Xerox were interested in finding ways to connect workstations (computers) and printers. There were several ideas that they created, including Ethernet connections between devices. The main purpose for this, at first, was to allow users to access Xerox copiers and printers. As the engineers were working with individual computers in this configuration, they wanted each computer to have its own screen and keyboard, thus creating some of the earliest workstations. The engineers wanted to develop their own operating system and programming language. They did look at Bell Lab’s UNIX, but this did not fit their needs. Looking at the way most people think, they realized that most people think about objects and decided it would be nice to develop an environment (and language) based on objects. Everything is based on the Object “Object()” and all other objects inherit from this initial definition. What they developed was quite elegant, but Xerox never really took advantage of their head-start with respect to workstations, Ethernet, and object-oriented programming.

With regard to objects, everything is an object. For example, if you think of a car, it has a frame, body, seats, engine, axles, transmission, hubs, tires, steering mechanism, etc. Each of these are objects which make up the object car. Each are also created from smaller objects. When you think of cars, there are also several items of transportation that have similar components. A unicycle has a frame, hub, tire, and seat, a bicycle has everything a unicycle has plus one more wheel and a steering mechanism. With a motorcycle, you add an engine. A truck has the same objects as a car, but can have more axles. A semi-truck then has everything a truck has plus additional objects. To handle all these objects and make sure objects only have to be defined once, Xerox engineers developed the concept of inheritance.  Xerox developed a language called SmallTalk (the last sentence of this article has a good question that is now being answered in computer graphics and artificial intelligence). At first, they probably did not fully realize what they had. Until SmallTalk 80, they freely gave away their concepts and design. Steve Jobs was so impressed with this that he took SmallTalk 76 and created the Macintosh operating system (the O/S did go through several name changes before becoming the Macintosh). Xerox then formalized the language and started to license it in 1980 with SmallTalk 80. Tektronix (a company that started as an oscilloscope company and then grew in fields related to their display technology, and has now shrunk back to less than 1,000 employees) was one of the first companies to license SmallTalk 84 and many of the engineers in my group became heavily involved with object oriented programming. In fact, Tektronix hosted the first Object Oriented Conventions in Portland, Oregon. Xerox was impressed enough with what Tektronix was doing, they created a wholly-owned subsidiary named PARC Place Software in Portland, OR and hired several of the Tektronix engineers to help them fully develop SmallTalk for commercial uses. There were some interesting legal battles between the two companies about the rights to many of the features that Tektronix added to the development environment and language, especially very efficient garbage collection (a topic for a different discussion).  Some of the people with whom I worked contributed to Object Oriented Programming (OOP) were Ward Cunningham (who developed the idea of Wiki’s) and Rebecca and Allen Wirfs-Brock. Rebecca and Allen developed the concept of CRC (Class / Responsibilities / Collaborators) Cards, where you write each object on a 3×5 card along with a description of the object and what it can do. After you wrote out all of the objects, you start grouping them with similar objects. This was a great way to start organizing the structure of your OO program and developing the inheritance hierarchy. All good people. I was involved with the internal diagnostics to make sure the systems that ran their products worked well, but enjoyed working with SmallTalk as much as I could. A humorous paper was written at the time by Ed Post, based on the article “Real Men Don’t Eat Quiche,”  titled Real Programmers Don’t Use PASCAL.

Bell Labs in New Jersey was also impressed with Object Oriented Programming and decided to incorporate it into their C language with C++. The nice thing about the C++ compiler is that it has a tighter check on the use of pointers and other structures in the language. Many programmers use the C++ compiler on C code to find problems with using a pointer with a different structure and/or data type than the structure was defined as using. You can override this restriction by doing an explicit “cast” on the new pointer to change how you are accessing the information, but if that is not done then the compiler will catch that type of error. Pointers are very powerful, there were still some concerns about the power of pointers by the engineers at Sun Microsystems (acquired by Oracle in 2010). The engineers then develop JAVA, which banished pointers to prevent accessing areas of the program or computer that could be dangerous to access. In the early days of C programming and the UNIX operating system developed with C, some programmers were noted for using pointers to go in and change the operating system on the fly to do what they wanted done. This practice eventually led to programs only being able to address the section of memory in which they will execute during run-time, There are many good reasons for JAVA not having pointers. There is an on-going debate on the needs for pointers. At this point, I will leave that discussion up to the reader. The other thing JAVA introduced was the concept of a virtual machine. They would create a run-time environment for each different architecture.  The code would then be compiled to run on this virtual machine. That way, JAVA code can run on any architecture and Operating System. Before then, all programs that were compiled had to be compiled for a specific architecture and operating system. The other possibility was running shell scripts, which were interpreted code that could be edited by anyone trying to run them. JAVA is a very innovative development for OOP. It is now one of the most widely used programming languages. Microsoft (USA English version of their website) saw how well JAVA was penetrating the OOP universe. They wanted to incorporate it into their Visual Studios Suite. However, Microsoft wanted to add their own bells and whistles, which Sun Microsystems refused to do unless Microsoft shared back on the innovations and agreed to follow Sun’s decisions on what could and could not be added. Microsoft decided it would develop its own OOP based more on C++ called C# (since # is twice as good as ++). C# is the language that is most often used in the Microsoft universe for OOP.

The main languages that I will eventually cover here are as follows. Many shell script languages are also object oriented. They will be covered in a different section.

Object-Oriented Basics

Object-Orienting Programming has a few basic concepts. The very basis of OOP is an Object. It is a description of something physical or conceptual that can be acted upon and perhaps can act on other objects. The goal of OOP is to thoroughly describe an object in as generic of way as possible so that other objects can use the same description with their own attributes. The generic description is called a class. A Class has a Class Name, Responsibilities (what it does, how it acts, what information it stores), and Collaborators (with whom does in interact and how does it interacts with the other objects). C-R-C cards are an easy way to put down on 3×5 cards these pieces of information and then start arranging the cards in such a way that you can start determining the hierarchy and arrangement of classes to solve the problem. At the end, I will give a brief example of objects needed to display tires at a tire store. The main terms within OOP are:

      • Class – Generic description of an item, including its attributes and methods (procedures/tasks) it can do. The attributes and methods can be private or public (and for some languages protected).
        • Attributes – types of values a Class can hold. Can either have get/set methods to set and fetch values or access them directly like methods.
        • Methods – things the class can do. Interface must be defined so it can be used. Implementation will determine how it is done.
      • Instance – Created object from a Class will have all the attributes set for describing a particular item based on a Class definition.
      • Inheritance – Allows a user to define slight variations to a Class without having to rewrite the entire class.
      • Structures – “Classes for Attributes” Classes and Structures can both have inheritance, but structures are only a collection attributes. Structures have no methods, except perhaps a get/set pair for each variable.

Software Development Environments (SDEs)

In order to develop software quickly, Software Development Environments are very useful Software Development Environments