Framework or language? Get off my lawn!

Written by azw | Published 2018/04/02
Tech Story Tags: programming | history | software-development | history-of-programming | framework-or-language

TLDRvia the TL;DR App

An addendum to my very personal history of programming

Programmers today…

…do not really know where the language stops and the framework begins.

What do I mean by this?

Up until about 1988 most programs that a person (like you) would use had been programmed from the ground up by a handful of programmers (often just one) using a 3GL (3rd generation language). The key words being: from the ground up.

As I explain in the first article of this series, 3GLs abstract assembly or machine language into reserved words.¹ A programming language is a collection of reserved words and some rules about grammar that restrict how one can use those words in a way that will not confuse the compiler (which expands the words into a series of machine language instructions). Together, this is referred to as the language’s syntax.

As you can see most languages have surprisingly few reserved words to remember. SmallTalk has only 6!

So back to pre-1988 software, if you look at the code of a program written before that time, the only words you will see besides the handful of reserved words are the names of variables and functions that the programmers created. This is what most people think of as programming.

The image comparison code (written in C) below uses two reserved words: for and double. The two underlined words ( fabs, and printf) are functions from included libraries (stdio.h and math.h). When a library is included like this it is called a dependency. All of the other words in this program are either variables or comments written by the programmer.

By simple word count, 90% of this code was written by the programmer. Less than 10% of the code is someone else’s, 4% from the language and 6% from the two libraries.

for(x=0; x < im1->width; x++){for(y=0; y < im1->width; y++){totalDiff += fabs( GET_PIXEL**(im1, x, y)[RED_C]** - GET_PIXEL**(im2, x, y)[RED_C]** ) / 255.0;totalDiff += fabs( GET_PIXEL**(im1, x, y)[GREEN_C]** - GET_PIXEL**(im2, x, y)[GREEN_C]** ) / 255.0;totalDiff += fabs( GET_PIXEL**(im1, x, y)[BLUE_C]** - GET_PIXEL**(im2, x, y)[BLUE_C]** ) / 255.0;}}printf("%lf\n", 100.0 * totalDiff / **(double)(**im1->width * im1->height * 3) );

Now lets look at the Java version of the same function:

public enum ImgDiffPercent {;

**public** **static** **void** main**(**[**String**](http://www.google.com/search?hl=en&q=allinurl%3Astring+java.sun.com&btnI=I%27m%20Feeling%20Lucky)**\[\]** args**)** **throws** [**IOException**](http://www.google.com/search?hl=en&q=allinurl%3Aioexception+java.sun.com&btnI=I%27m%20Feeling%20Lucky) **{**  
    _// https://rosettacode.org/mw/images/3/3c/Lenna50.jpg_  
    _// https://rosettacode.org/mw/images/b/b6/Lenna100.jpg_  
    [**BufferedImage**](http://www.google.com/search?hl=en&q=allinurl%3Abufferedimage+java.sun.com&btnI=I%27m%20Feeling%20Lucky) img1 = ImageIO.**read(new** [**File**](http://www.google.com/search?hl=en&q=allinurl%3Afile+java.sun.com&btnI=I%27m%20Feeling%20Lucky)**(**"Lenna50.jpg"**))**;  
    [**BufferedImage**](http://www.google.com/search?hl=en&q=allinurl%3Abufferedimage+java.sun.com&btnI=I%27m%20Feeling%20Lucky) img2 = ImageIO.**read(new** [**File**](http://www.google.com/search?hl=en&q=allinurl%3Afile+java.sun.com&btnI=I%27m%20Feeling%20Lucky)**(**"Lenna100.jpg"**))**;  

    **double** p = getDifferencePercent**(**img1, img2**)**;  
    [**System**](http://www.google.com/search?hl=en&q=allinurl%3Asystem+java.sun.com&btnI=I%27m%20Feeling%20Lucky).**out**.**println(**"diff percent: " + p**)**;  
**}**  

**private** **static** **double** getDifferencePercent**(**[**BufferedImage**](http://www.google.com/search?hl=en&q=allinurl%3Abufferedimage+java.sun.com&btnI=I%27m%20Feeling%20Lucky) img1, [**BufferedImage**](http://www.google.com/search?hl=en&q=allinurl%3Abufferedimage+java.sun.com&btnI=I%27m%20Feeling%20Lucky) img2**)** **{**  
    **int** width = img1.**getWidth()**;  
    **int** height = img1.**getHeight()**;  
    **int** width2 = img2.**getWidth()**;  
    **int** height2 = img2.**getHeight()**;  
    **if** **(**width != width2 || height != height2**)** **{**  
        **throw** **new** [**IllegalArgumentException**](http://www.google.com/search?hl=en&q=allinurl%3Aillegalargumentexception+java.sun.com&btnI=I%27m%20Feeling%20Lucky)**(**[**String**](http://www.google.com/search?hl=en&q=allinurl%3Astring+java.sun.com&btnI=I%27m%20Feeling%20Lucky).**format(**"Images must have the same dimensions: (%d,%d) vs. (%d,%d)", width, height, width2, height2**))**;  
    **}**  

    **long** diff = **0**;  
    **for** **(int** y = **0**; y < height; y++**)** **{**  
        **for** **(int** x = **0**; x < width; x++**)** **{**  
            diff += pixelDiff**(**img1.**getRGB(**x, y**)**, img2.**getRGB(**x, y**))**;  
        **}**  
    **}**  
    **long** maxDiff = 3L \* **255** \* width \* height;  

    **return** **100.0** \* diff / maxDiff;  
**}**  

**private** **static** **int** pixelDiff**(int** rgb1, **int** rgb2**)** **{**  
    **int** r1 = **(**rgb1 >> **16)** & 0xff;  
    **int** g1 = **(**rgb1 >>  **8)** & 0xff;  
    **int** b1 =  rgb1        & 0xff;  
    **int** r2 = **(**rgb2 >> **16)** & 0xff;  
    **int** g2 = **(**rgb2 >>  **8)** & 0xff;  
    **int** b2 =  rgb2        & 0xff;  
    **return** [**Math**](http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky).**abs(**r1 - r2**)** + [**Math**](http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky).**abs(**g1 - g2**)** + [**Math**](http://www.google.com/search?hl=en&q=allinurl%3Amath+java.sun.com&btnI=I%27m%20Feeling%20Lucky).**abs(**b1 - b2**)**;  
**}**  

}

Everything in bold is a key word, everything underlined is a function from an imported library. This listing is about 65% code written by the programmer, and 20% code from the language syntax and 15% depedencies upon external libraries.

I am not saying that this is a bad thing. I am merely making a statement of fact. As it happens, including code from libraries is an important productivity enhancer. There is no justifiable reason for the average programmer to re-invent the wheels of language; reserved words, library classes and functions. So in most modern code, this trend towards less code written by the programmer, and relying more and more upon code written by someone else in the form of a library has increased exponentially. And although not inherently a bad thing, many agree that things have gone too far.

And magic happens…

In early 2016, what felt like half of the Internet broke because a programmer removed an 11 line program called left-pad from a public repository called npm. It turned out that some of the biggest, most used JavaScript frameworks in the world included a dependency on left-pad rather than type out the ten lines of code below:

function leftpad (str, len, ch) {str = String(str);var i = -1;if (!ch && ch !== 0) ch = ' ';len = len - str.length;while (++i < len) {str = ch + str;}return str;}

Another npm package called isArray had 18 million downloads in February of 2016, and is a dependency for 72 other NPM packages. 18 Million everyday programmers, and 72 package authors used an include rather than type this 1 line of code:

**return** toString.call(arr) == '[object Array]';

Now I’m just a country boy, but to me this pretty clearly indicates that the programmers that created these 72 npm packages either had the most twisted sense of humor I have ever seen, or really had no idea of what was in isArray and how JavaScript actually works. I take it to be an example of cargo cult programming at its most extreme.

To further drive home the point that most modern programmers blindly use class libraries without understanding what is in them I refer you to Jordan Scales sobering (and depressing) account of his personal reaction to the left-pad fiasco.

Get off my lawn

So where am I going with all of this?

My point is that “programming” as the average person imagines it hardly exists today. The only programmers “writing code” in the form of new algorithms are either working at very big Internet companies, or are writing specialized image, video, or sound processing sofwtare for a startup.

The armies of “kids today” working in the salt mines of corporate and government IT are doing something else entirely. The coding they do is the software equivalent to meme creation and social media posts, complete with post-modern pop culture references. Only instead of recycling pictures of Clint Eastwood, Good Guy Greg, or Scumbag Steve, they are cutting and pasting code and indiscriminately using libraries such as left-pad or isArray. They do not really know where the language ends and the framework begins. It is all just one big soup to them.

And although I am not a “kid”, I am scarcely better myself. I describe myself as a cargo cult programmer (reluctantly but honestly). Some of you may be familiar with the epic Story of Mel. Next week I will tell you…

The Story of Me

[1] In ALGOL, FORTRAN, and PL/1 there are no reserved words, only keywords. The difference is not really that important in the context of this article. In this article I will use reserved words to refer to both.

This article is an excerpt from my upcoming book The Chaos Factory which explains why most companies and government can’t write software that “just works”, and how it can be fixed.


Written by azw | IT strategist, Startup positioner, Cargo cult programmer. chaosfactorythebook.com
Published by HackerNoon on 2018/04/02