Do we avoid breaking changes too much?

In the software industry do we avoid breaking changes too much? I am talking about the big stuff. I am talking about browsers and programming languages. Breaking changes are difficult in these systems as there are multiple groups that need to coordinate to implement the change.

What is a breaking change? A breaking change is an upgrade that sacrifices compatibility with previous versions. For example, Python 3 was a breaking change, Python 2 code will not run on the Python 3 interpreter. This may be thought of as a branch. Breaking changes are noted by a change in the ‘major’ version number. For example 2.0.0 to 3.0.0 is a breaking change. See: Semantic versioning

Breaking changes are a big deal. I don’t want to under-emphasize this fact. There are people still upset about Python 3. Breaking changes incur costs to the users of the code. And if there are a lot of users then there is a ton of costs. But there are benefits, python 3 has risen to the top of the charts. I think the change to 3.0 allowed Python to expand to the king of the hill status. Without that breaking change, Python fades away.

A technology we have held on too long is a ‘Turtle’ technology (I just made that up, so don’t go Googling it). Developers that use a technology too long are called ‘Turtles’. They lock onto it like a snapping turtle and won’t let go. They growl at you and doubt your sanity if you suggest an alternative or doubt the rightness of it.

For some perspective let’s look at something that the a group of developers held on to for too long. Let’s talk about IBM’s green screen. Known as IBM 3270 and IBM 5250. Subsequently called 3270 in this essay. 3270 was developed in 1971 and was a very good solution for communication to a mainframe on a remote terminal. You could do anything on a 3270 including programming and debugging. But the 3270 was character-based and could not display graphics or bar codes. I worked in the AS/400 and IBM 5250 in 1995 and the developers were in the full turtle mode. Their forceful obstinacy seemed, to me, a bit irrational.

In the end, IBM wrote Java drivers for the database and all the systems for the AS/400, and we wrote a web page interface in short order. IBM even added Java to the AS/400. After which green screen development decline to a natural level for applications in which it makes sense to use, data entry applications, and such.

Another turtle technology is the ‘C’ programming language. C turtles are not the irrational kind. They acknowledge the problems of the language, such as buffer overruns and race conditions. C was created in the 1972-1973 time frame. It remains a very popular language and is the ‘go-to’ language for systems programming, low level, and embedded. C has several descendants such as C++ and C#. C++ adds object-oriented programming but still suffers C’s problems. C# is just Java misspoken and is more of a Java descendant than a C decendant. Both are very good, but neither one was designed to be a ‘systems’ language. I don’t know why it has 48 years to find something better. It may be the C is just that great. The good news it is looks like Rust may be the successor to C. Rust fixes most problems with C and still remains a systems-level language.

Try not to be a turtle. Remember all technologies will lose popularity. If your favorite tech is currently falling and in ridicule then recognize, accept it. Don’t take it personally. Don’t disparage your fellows on the other side. You can take steps to reverse the demise or move to something new or just live with it and ride the bubble down the drain.

General ways to solve a programing problem

Let’s say you have been given a programming task, such as "Given an integer as input, can you round it to the next (meaning, "higher") 5?” How many ‘general’ ways to solve this simple problem? I mean the term ‘general’ in a broad sense, like the barometer story. Here are some general solutions. These are from CodeWars Kata. My goal is to help me internalize these general solutions and to approach new problems with a variety of solution types.

Note: I am not testing values 2,147,483,646 and 2,147,483,647 as they don’t have a valid solution in Java Integer values.

Loops

Loops are used for a ton of solutions. They are the first solutions most programmers attempt to solve the problem. Loops are a good place to start. Here is a loop example:

public Integer roundUp5(Integer number) {
	while (number % 5 != 0) {
		number++;
	}
	return number;
}

This is a good simple solution. It uses a simple while loop to increment to the next multiple of five. This is the simple solution and maybe the quickest to code and debug. Loops are a very powerful tool to solve problems, remember to use them

If Statements

If statements are also used for solutions. Here is my solution using an If statement.

public Integer roundUp5(Integer input) {
	if (0 < input) {
		input = input + 4;
	}
	return (input / 5) * 5;
}

This takes longer to think of and debug because it uses a ‘trick’ of integer division. It is not as ‘direct’ or simple as the loop solution. Most programs use If statements, but it may wise to consider other solutions first. In my opinion, If statements are overused.

This is a good solution using the If statement

function roundToNext5(n){
  if (Math.abs(n) % 5 === 0) 
    return n;
  else {
    let remainder = n % 5;
    if (n < 0) {
      return n - remainder;
    }
    return n + 5 - remainder;
  }
}

This doesn’t use the integer division trick which makes it easier to understand. It could be cleaned up a bit, such as I think the Math.abs(n) on line 2 is not needed and the else on line 4 is not needed. It is not the greatest code but it is simple and easy to maintain.

Switch Statement

Switch statements are very handy for solutions. Here is a simple JavaScript solution.

function roundToNext5(n){
  switch (n % 5){
    case 0: return n;
     break;
    case 1: return n+4;
     break;
    case 2: return n+3;
     break;
    case 3: return n+2;
     break; 
    case 4: return n+1;
     break; 
    case -1: return n+1;
     break;
    case -2: return n+2;
     break;
    case -3: return n+3;
     break; 
    case -4: return n+4;
     break;    
  }
}

This is a simple and easy to debug solution. One item to point out is that this solution does not have special cases. Most of the solutions add a special case where number % 5 == 0. This is a great first solution because you can see the pattern of what needs to be added to the number. Now that you know the pattern you may be able to move or refactor to a better solution.

Recursion

Recursion has it share of bad press; it is the step-brother of the “goto” statement. It is a general solution type that is not used to often. For this problem it is a good solution.

public Integer roundUp5(Integer number) {
	if (number % 5 == 0) {
		return number;
	} else {
		return roundUp5(number + 1);
	}
}

This is a simple way to solve this problem. Remember to think about recursion on new problems.

Look at the API

If a problem has you stumped then look for a solution in the programming language. This is similar to the If statement solution but uses the Math.ceil() (aka ceiling) function.

//
public int roundUp5(Integer number) {
	return (int) (Math.ceil(number.doubleValue() / 5.0) * 5.0);
}	

The use of the ceiling function does get you a step closer to the solution. This is a good strategy to use. Unfortunately, in this case, the conversion from Integer to Double and back to Integer is a source of bugs. Finding a solution can also include importing third-party modules such as Apache Commons or any of the millions of artifacts in the maven repository.

Functional programming

Functional programming is a good class of solutions to use on arrays and collections.

public int roundUp5_ver4(Integer number) {
		int[] kRounder = IntStream.rangeClosed(-1_000_000, 1_000_000).map(k -> k * 5).toArray();
		return number == 0 ? 0 : IntStream.of(kRounder).filter(
			n -> n - number == 0 || (number - n < 5 && n > number)).findFirst().orElse(0);
	}

Unfortunately, this solution, which I did not write, takes a lot of resources, it creates an array of two millionIntegers. It does not give the correct answer when 5,000,000 < Math.abs(number). This is buggy and difficult to debug. Functional programming can be quite elegant. This solution is a ton of overkill.

Conclusion

There are other ways to solve problems, but these are a quick summary. When facing a new problem try to think what way is the best then try it. If the first way you chose is frustrating, difficult, and bug filled then step back and try a different method. Try to hone your instincts to know when to switch methods.

Favorite Software Part 2

Beyond Compare

Beyond Compare website Beyond Compare Logo

It is natural for a programmer to find a favorite text compare tool. Getting used to a one takes a while as there is a lot of complex information to display. There are plenty of good compare tools to choose from and all of them are good and each has its own standout features. I use Beyond Compare by Scooter Software. It responds well when I push it to the limits or there is some use case that is far past the program specifications. Beyond Compare can integrate with any version control system and the website contains a web page with instructions. The one support issue I submit, it was a feature enhancement, was handled quickly and with a long discussion. It was a very helpful resolution.

Features that I use that may be overlooked by reviewers and sales documentation:

FTP – The feature to compare files using FTP is one feature I used regularly on my job. The use case was the files were stored in source control and needed to be copied to the drive of an embedded device. Beyond Compare made this an easy task.

Save Session – The feature to save a session is most useful. When you need to compare the same set of files every day this saves a bunch of time. It took me a long time to realize the value of this feature and to incorporate it into my daily toolset, don’t make the same mistake take the time to figure it out and use it.

Rules Replacement – If you have two files that should be the same except for one should read “Tank1” and the other should read “Tank2”. This feature is solves this problem. Rules Replacement will ignore these situations. The replacement list may be as long as you like.

There are many other great features of this software. Highly Recommended

7-Zip

7-Zip website Logo that reads "7-Zip"

7-Zip does one thing very well. It is a ‘uni-tasker‘ . It zips and unzip files to the zip format and any other format in the world of computers. 7-Zip is free and does not contain advertising.

Favorite Software

This is a list of software I used every day and is the first to be installed on a new computer. Some are a bit old and haven’t been upgraded in a while but I still use them, which is a good statement on the application. These are applications that I have a full license to use, which further shows my recommendation.

This is in no particular order.

Boxer text editor

Website I have used Boxer since the 1990s. It shows a focus on good user interface that very rare in 2010, the last update, and today is not seen as much as it should be. This is software that has been sanded and polished. The main programmer David has made this a very easy text editor to work with.

I don’t use this much for coding these days but there are a few tricks that this application shines. It handles extremely large files. When Atom or NotePad++ are brought to their knees with a large file Boxer will open it as if it were a 2k file. Boxer has my favorite binary file editor. I use it to open WebAssembly files to view and edit the file in hexadecimal.

ClipMate

Website ClipMate has been my clipboard manager since the Windows 3.1 days. I use it in so many ways to save time and as a note-keeping application. Its snipping tool was way ahead of its time and hasn’t been bested until the Windows 10 snipping tool. This hasn’t been updated in five or so years, I keep looking for a replacement but nothing comes close.

To Be Continued.