Tag Archives: .NET

When Does Counting Lines of Code Make Sense?

ALERT: I’m not pulling any punches with this one. If you are looking for a balanced argument including thoughts on some potentially good reasons to measure LoC, you won’t find it here. The best reasoning I can give for the existence this article: it gives me something to point people to when they ask for my opinion on the topic.

Counting Added Lines of Code as a Measure of Productivity

“Any process or procedure that incentivises based on creation or destruction of lines of code is missing the point entirely.”

David Adsit
Software Craftsman – Pluralsight

Counting LoC drives bad behavior and is easily manipulated. It leads to developers being less concise and writing code that is difficult to maintain. There are so many ways to write code less efficiently and these are exploited in a scenario where LoC are measured for productivity.

Here is one extremely simple example of code inflation:

Arrays.fill(array, -1);

and

for(int i = 0; i < array.length; i++)
{
  array[i] = -1;
}

The above examples logically equivalent in Java. They both work. They both do the exact same thing. In C# the first could look like the following:

array = Enumerable.Repeat<int>(-1, array.Length).ToArray();

We could also write our own C# extension method to match the simpler Java method and use it throughout the code in future improving readability and maintainability.

public static void Fill(this int[] array, int fillValue)
{
  for(int i = 0; i < array.length; i++)
  {
    array[i] = fillValue;
  }
}

Once complete, it would be executed as follows:

array.Fill(-1);

This approach would lead to a couple of additional lines when it is first written ONCE and then only one line to do the same work forever after. Assuming of course that people know the extension method exists and they use it… another discussion perhaps.

One of the reasons we use modern programming languages is because they are expressive and easy to read. Even in a current modern language, older and more verbose approaches are still valid in code (to enable us to customize better approaches on our own that are not supported by the framework) and can easily be exploited by developers looking to boost their LoC written.

Counting Added LoC as a Measure of Productivity Must be Based on False Assumptions

“[Counting lines of code as a measure of productivity] presumes that each day or week or month is the same as the last day, week, or month, and that the thought stuff we actually get paid to do doesn’t matter.”

Dwayne Pryce,
Senior Software Engineer Microsoft Research

Measuring added LoC also assumes the work completed before, after, and during the coding process to determine best/cleanest/most maintainable/efficient approaches are meaningless and that testing to verify that the code does what is was intended to do is a waste of time.

Additionally, less-experienced junior developers are always going to write more lines of code than senior people for a variety of reasons.

  1. Junior people often take the easiest, most brute force approach because they haven’t learned to do it better. Yet.
  2. Junior people are given less complex tasks to solve that can be done more quickly.
  3. Progressively more experienced people have additional increasing responsibilities (for example mentoring and training less experienced people, doing more code reviews, being involved in architecture/design discussions, taking on difficult roles like security guild, creating documentation, etc.

1 and 2 are arguably best solved by pair programming. Another discussion. Another time.

Counting Removed LoC as a Measure of Paying Technical Debt

“Simplicity is the ultimate sophistication.”

Leonardo da Vinci

Same as measuring added LoC, counting removed LoC drives bad behavior and can lead to developers writing code that is intentionally overcompact and difficult to read. However, in a large and unwieldy application, we want to remove lines that serve no purpose at every opportunity while maintaining the same functionality. If this were trivial, we could simply automate programming and developers would no longer be needed. Making things simpler is, simply put, not easy.

Counting LoC as a Measure of Quality

In the history of computer science, there has never been a valid correlation between LoC and quality in any programming language in existence. Check the textbooks, the internet, or anywhere else you can think of. This correlation does not exist.

The Burden of Unnecessary LoC is Non-trivial

“Measuring programming progress by lines of code is like measuring aircraft building progress by weight.”

Bill Gates

I’ll use a slightly exaggerated example here, but it isn’t too far off, so please bear with me. Let’s assume we have two people attempting to solve a difficult problem.

Persona A

  1. may be less experienced or expert beginner
  2. just get’s it “done”
  3. tends to solving problems hastily without concern for introducing bugs
  4. often works quickly and on their own without taking time for design discussion, planning, and refactoring
Persona B

  1. may be more experienced
  2. cares about quality and hates bugs
  3. aims to understand the scope of the problem before starting to solve it
  4. involves others (seeking real input) to suss out design flaws and make take more complex problems to a mentor

I’ve seen real life scenarios where Persona A will solve a similar problem in 2000-3000 LoC where Persona B would solve it with 200-300 LoC. That may not seem so bad. Maybe Persona A finished their effort in less time than Persona B. Now consider, from the time this code goes into production until it is replaced/removed/refactored/decommissioned, we have to pay to maintain the code that was written. When we want to make a change in the behavior of the

Maybe Persona A finished their effort in less time than Persona B. Now consider, from the time this code goes into production until it is replaced/removed/refactored, we have to pay to maintain the code that is written. When we want to make a change in the behavior of the code or add a new feature, Persona A’s code may require days of review to understand and will also require many changes to achieve. To make a similar change to Persona B’s code, it could be understood in an hour, perhaps. The changes should take considerably less time depending on their complexity.

When we want to make a change in the behavior of the code or add a new feature, Persona A’s code may require days of review to understand and will also require many changes to achieve. To make a similar change to Persona B’s code, it could be understood in an hour, perhaps. The changes should take considerably less time depending on their complexity. Of course, this scenario is hypothetical. This is my one apology for rhetoric.

Coda

For clarity’s sake, I’m in no way arguing against hiring junior people. Fresh blood is vital for tons of reasons I won’t go into here. However, the effective incorporation of junior people must be accompanied by the correct structure and support from more experienced people in order for them to succeed. I AM against hiring expert beginners who’ve been doing this work for many years and thinks the “just get it done” approach is the best/only way.

 

SassAndCoffee Is Not A Smutty Romance Novel

SassAndCoffee !=

 Not SassAndCoffee

So what IS SassAndCoffee? From the author’s (Paul Betts) blog post:

SassAndCoffee is a library for ASP.NET (both MVC and old-school WebForms) that adds drop-in support for two new languages: Sass and SCSS, a language that allows you to write reusable, more structured CSS, as well as CoffeeScript, which is a JavaScript dialect that is much more syntactically elegant, but still preserving 100% compatibility with regular JavaScript.

I’ll go into more detail about the features of SassAndCoffee momentarily, but lets start with getting it into your project in Visual Studio.

You could grab the project form GitHub and compile it yourself but the simplest way to include the assemblies needed is through NuGet

SassAndCoffee’s NuGet project also adds some entries in your web.config:

 <system.web>  
     <httpModules>
       <add name="CompilableFileModule" type="SassAndCoffee.AspNet.CompilableFileModule" />
     </httpModules>
 </system.web>

 

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="CompilableFileModule" />
      <add name="CompilableFileModule" type="SassAndCoffee.AspNet.CompilableFileModule" />
    </modules>
</system.webServer>

 

Once this is complete, just create a .scss or .coffee extension file in your project and reference it from your HTML as if it were already interpreted as .css or .js respectively. We’ll go into more detail on this.

The main features you get from SassAndCoffee are as follows:

  • Easy setup: No need to install Ruby or node.js or anything else. Everything that is required is included in the NuGet project.
  • Automated compilation: simply add .scss or .coffee files to your project and reference them in HTML as you normally would (as .css or .js files) and SassAndCoffee handles the compilation and output linking at runtime.
  • Automated minification: minify your output files as well as other .js and .css files in your application with a simple naming convention.

Now let’s check out an example with Sass using the file SassAndCoffeeDemo.scss:

@mixin customDivText($size){
    font{
        weight: bold;
        size$size;
    }
    text-align: right;
}
 
div.big{
    @include customDivText(70px);
}

div.bigger{
    @include customDivText(150px);
}

Index.cshtml:

<div class="big">Big</div>
<div class="bigger">BIGGER</div>

_Layout.cshtml:

<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" 
type="text/css" />

Now our output looks this in the browser:

And SassAndCoffeeDemo.css contains:

 

div.big {
  font-weight: bold;
  font-size: 70px;
  text-align: right; }

div.bigger {
  font-weight: bold;
  font-size: 150px;
  text-align: right; }

Let’s try a “Hello World” in Coffeescipt. I’ll add the following code to a file named SassAndCoffeeDemo.coffee.

helloCoffeeScripters = (name) -> 
alert("Welcome to Coffeescript, "+ name)
 
$ ->
	helloCoffeeScripters ("World")

And refrence it in my _Layout.cshtml master page:

<script src="@Url.Content("~/Scripts/SassAndCoffeeDemo.js")" 
                        type="text/javascript"></script>

When we run our app we should see the following:

When we view the source of our .js file we see that the Coffeescript compiler has emitter the following javascript:

var helloCoffeeScripters;
helloCoffeeScripters = function(name) {
  return alert("Welcome to Coffeescript, " + name);
};
$(function() {
  return helloCoffeeScripters("World");
});

Now lets consider the other SassAndCoffee feature that tends to get overlooked, Minification. If we change the Coffeescript file name in our _Layout.cshtml file to include “.min” like so:

<script src="@Url.Content("~/Scripts/SassAndCoffeeDemo.min.js")" 
type="text/javascript"></script>

Then when we compile and view the source of our file we will see:

var helloCoffeeScripters;helloCoffeeScripters=function(a){return alert("Welcome to Coffeescript, "+a)},$(function(){return helloCoffeeScripters("World")})

The beauty of SassAndCoffee is in the amount of attention that you DON’T have to pay to it. It just works! Import the NuGet project and you can get to the business of learning how to use Sass and Coffeescript right away.

Refrences:
https://github.com/xpaulbettsx/SassAndCoffee
http://nuget.org/List/Packages/SassAndCoffee
http://sass-lang.com/
http://jashkenas.github.com/coffee-script/

Thanks to @alamocoders for letting me present this topic at their last .NET meeting. I had a blast. Here are the materials from the presentation if anyone is interested. It includes the source code and my slide deck.
http://dubmun.com/projects/SassAndCoffeeDemo.zip