12

I have a coding style related question. In my example it is java, but I think this can be a generic question regarding languages that are changing rapidly.

I'm working on a java code base which was mainly written targeting java 8. The code was migrated to java 12. By migration I mean the code can run on jdk12, so the necessary library changes/additions were done. However the new language features haven't been used yet (e.g. var keyword).

My question is, what should be the approach to introduce new language elements from readability point of view? How important is consistency?

I have a few possible approaches in my mind.

  1. New language features should be used only in new classes
  2. New language features can be used in newly added parts of existing classes (e.g. a new method), even if the rest of the class is not updated.
  3. When a new language features are added to new parts of existing classes, then the rest of the class should be updated too

I know this question is a bit hard to answer (as coding style questions in general), but still I hope there will be some conclusion.

  • 5
  • @DocBrown I wrote an answer (in a text editor) and now I don't know whether to post it here (a question that will be probably deleted) or in the other one (a question that is 'stale' with no activity since 2017, although with no accepted answer). – Tulains Córdova Nov 16 '19 at 4:34
  • @TulainsCórdova: if a question like this one is a duplicate of a second one, and both got upvotes and some good answers, it is likely one gets closes, but unlikely that it also gets deleted. The community cannot delete it before it gets a score of -3 in total, and I guess Thomas Owens (the only active moderator for this site) won't delete it, either. – Doc Brown Nov 16 '19 at 9:03
  • Consistency is as important as readability because the first contributes to the second. It's a good abit which keeps the code healthy and easy to understand. – Laiv Nov 16 '19 at 9:41
  • OK, so you have a ton of code, 95% of which is not likely to be touched (or looked at) any time soon, if ever again. If it weren't for someone who is dying to use the var keyword for the sake of it. Really, is there a problem to be solved here? – Martin Maat Nov 16 '19 at 20:00
23

When in Rome do as the Romans do.

It's nice if an entire code base follows one consistent style. However that will trap it's style in the past.

If you're enchanted by some new fangled style the worst thing you can do is scatter it randomly among code left in the old style.

This is why when you repaint a house a different color you don't just do it where the paint is damaged. You do it room by room.

It's better to make the change within some boundary. Those reading the code should find it easy to predict what style they will find in each place.

Changing the style of working code is a refactoring. Don't refactor without tests. And don't refactor everything at once. Do one room, step back, and ask others what they think.

When you can't do all that, stick with the old style. Only use new language features that blend well with the old style.

18

I am working with C# since version 1.1 (around 2003), and I have first-hand experience how we introduced new language features into our grewing code base over the years. We simply introduced them whenever they were available, and everyone in the team started to use them in the area of the code where they were working on.

These features included

  • generic collections (instead of weakly typed collections)

  • improved property syntax

  • the var keyword

  • extension methods

  • functional tools like lambda expressions, closures etc.

  • Linq

  • async / await

(just to name a few examples).

Note, even in newly written code, each of these features is used in conjunction with older language features. You don't start replacing every possible loop with a Linq construct just because Linq is available. You don't start to use extension methods for every function just because "extension methods are available". And using var today for every variable declaration does not make your code more readable.

Hence actual experience was not so bad as the other answers might pretend - quite the opposite. In a larger code base, in case you do not want stick to old, clumsy constructs forever, you have to start to use the new constructs somewhere, but you cannot introduce them everywhere - and it would not even make sense to use them everywhere. You usually don't update working code sections to new language constructs when there is no other compelling reason. This automatically leads to some sections with more new language constructs, some with less and some without any, all working well and readable enough, side-by-side, often for years.

So my recommendation here is: don't overthink this. Readability of code where these features are mixed is very subjective, and in a team where everyone knows the old and the new language features well, this is less of a problem as one might think.

  • "And using var today for every variable declaration does not make your code more readable." Au contraire: Using var everywhere it can be used forces you to pick good variable names instead of using the left-hand types as a crutch. Thus it improves the readability of your code. – Kyralessa Nov 18 '19 at 14:17
  • 2
    Using the type as a crutch is a bad idea anyway since it's only visible where the variable is declared. My experience is that good variable names seems to depend only on the developer, and they will usually use good names everywhere or bad names everywhere irregardless of coding style or even language. – Turksarama Nov 25 '19 at 3:57
  • 1
    Don't even make new loops with linq just because it's available. – Scott Hannen Nov 27 '19 at 0:39
4

You are asking how to deal with technical debt. Assuming the critical things have been taken care of (updating the code to work with the new version of Java), the types of changes you are wanting to make don't have any direct impact to the user base. As a result, it is difficult to get product owners or management to agree to invest in that migration.

If you are managing an open source project, you don't have that management aspect to worry about. In that case, it's up to your community to determine how quickly you invest in the updates.

There are risks

  • Due to misunderstanding specifics of a new feature, you might introduce subtle bugs that are hard to detect
  • Some features may force you to rethink how your library/app/service is implemented--those targeted rewrites are very high risk as it will probably also change how it is tested
  • The end result may be less understandable than the code was beforehand--providing a negative benefit

Changing your working code without a healthy set of unit tests is like walking a tightrope without a net. If you are super careful it can be done, but when things go wrong they can go epically wrong.

It is always better to do what you can to mitigate risks when you are paying down technical debt.

2

3

If you are doing some other refactoring/modification in a class, bring the whole of the class to correspond to your current coding guidelines. Avoid having inconsistent styles in the same class. Classes should be small enough that you can do that easily and with low risk, and presumably the class will be tested anyway when you are changing it.

You could apply a change on the whole code base in one go if it can be applied mechanically. E.g. if you decide that var foo = Foo() is better than Foo foo = Foo() then you can reasonably safely apply this to the whole code base in one go with a refactoring tool.

-1

There’s a difference between upgrading the code so that it can run on Java 12, and incorporating functionality so that it must run on Java 12. What version(s) are being used the user(s)?

This is especially true in your example - Java 12 is not an LTS (Long Term Support), unlike Java 8 - so 12 will likely stop being supported before 8.

  • There are multiple "paths" that one can choose regarding JDK updates. You are right, that it is not LTS, but upgrade can be done every time when a new JDK version released, but that was not really what the question was about. The point was not even Java, I just wanted to use that as an example of a language, that had new language features, it could be C# too. – melonT Nov 25 '19 at 9:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.