Click here to Skip to main content
15,390,456 members
Articles / Programming Languages / C#
Article
Posted 1 Aug 2021

Tagged as

Stats

21.2K views
34 bookmarked

Explaining C# Code to Non-Programmers

Rate me:
Please Sign up or sign in to vote.
4.96/5 (32 votes)
1 Aug 2021CPOL38 min read
How I explain code to non-programmers using C# as the programming language
To those who know nothing about computer programming, code looks either like gibberish or, at best, a foreign language. Much of the syntax and keywords have to be explained by metaphor so they can relate to what they are seeing in a context with which they are familiar. In this article, I'll be using C# as the programming language to explain to non-programmers.

Introduction

Sometimes my friends, who know nothing about computer programming, ask me to show them what code looks like and to explain it. To them, it looks either like gibberish or, at best, a foreign language. Much of the syntax and keywords have to be explained by metaphor so that my friends can relate to what they are seeing in a context with which they are familiar. I thought it would be informative and entertaining to the community here to read how I explain code to non-programmers. I'll be using C# as the programming language to explain to non-programmers.

And yes, I ramble on a bit in places, mainly because it's fun to ramble in a more conversational way, but I've tried to indicate where those tangential ramblings occur. Also, this kind of article could be written in many different ways -- the approach I ended up taking seems to me to be excessively long -- yes, I admit that -- none-the-less, it was fun to write.

Programmers be warned - my ramblings tend to be rather critical of the past, present, and future state of software development.

Explaining Hello World

Let's take this simple piece of code that we all pretty much write when we're learning a new programming language.

C#
using System;

namespace Explaining_Code
{
  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Hello World!");
    }
  }
}

Rather than starting with explaining code, I'm going to start by talking about the structure of the code -- for us programmers, the things that don't result in actual machine instructions being generated by the compiler. We will therefore start in the middle, with the keyword namespace.

What is a Namespace?

Explaining code to non-programmers depends primarily on establishing a solid foundation which can be visualized by the non-programmer rather than beginning with keywords that simply result in abstract concepts that the non-programmer cannot visually build upon. A namespace is a good entry point to begin the visual-conceptual process.

The House

A namespace is like a building, typically about the size of a house but sometimes smaller, like a yurt, and sometimes bigger, like a high-rise office building. Like a house, it contains different rooms. The name of the namespace is like an address.

Rather than complicate the matter too much (what's the difference between a house and yurt?) I'll stick with just one visual metaphor for now, that of the house.

In the line: namespace Explaining_Code, I'm simply saying that I'm building a house that lives at an address called Explaining_Code.

Rooms in the House

Very importantly, namespaces can have rooms, so for example when we see a namespace that looks like this:

C#
namespace Explaining_Code.Helpers;

it means we are in the house "Explaining_Code" and in the room "Helpers."

Why Make the Distinction Between Houses and Rooms?

While the visualization of a house with rooms is rather obvious and simple to achieve, this is an important question. Another metaphor helps to answer this question.

Some things in a house are common to all rooms. Perhaps you house has central air or a heating system that heats all rooms at the same time. A house typically has electrical outlets protected by a master circuit breaker. The address of the house (its namespace) contains all the things common to the house.

Rooms in a house contain specific things -- it's a way to organize your house functionally -- there's a kitchen, a bathroom, a living room, a dining room, a bedroom, an attic, a basement, and so forth. While programming doesn't mean you actually create "things that go in the basement," where "basement" is an actual physical representation, the programmer will create logical rooms where certain things are expected to be found. And in those rooms, we have "things."

What is a Class?

Classes are things in the house or a room in the house. For example, a living room might have furniture like a couch and a coffee table. A kitchen will contain appliances, a sink, some cabinets, and so forth. Importantly, the things in each room have their particular purpose. In the kitchen, you don't wash dishes in the refrigerator, you wash dishes in the sink. You don't keep your cups on the floor of the living room, you probably keep your cups in a cupboard of the kitchen. You don't sleep on the couch unless you're in trouble with the wife.

Furthermore, a "class" tells you not only what the thing is but sets some reasonable expectations about what it does. A refrigerator keeps food cold or frozen. Maybe it makes ice as well. A blender blends food. Between what the thing is and what it does the programmer can usually infer when to use it. We do this pretty much automatically -- if I have a dirty dish, I use the sink to clean it. If it's a hot day, I fill the ice cube tray with water and put it into the freezer. This is an important concept -- depending on what I want done (we often call this the "context"), an experienced programmer will know what to look for:

  • What house (namespace)
  • What room (namespace-dot-namespace2)
  • What appliance (class)
  • How to use that appliance (class)

Ramble: And if the programmer doesn't know, they can "google" for the answer and usually find it. Alas, the days of actual documentation with real indexes to look up how to do something is long gone, but on a positive note, the programmer will usually find several different solutions and may learn a few things along the way. The Internet is a great tool that is continually evolving with new information (and lots of useless old information) that is a significant improvement over a physical book that provides, at best, only a couple fixed answers.

Going back to what is a class, when we see something like this:

C#
namespace Explaining_Code
{
  class Program
  {

It means we have a house called "Explaining_Code" and in that house, a thing called "Program," and as described above, a "class" tells you not only what it is but sets some reasonable expectations about what it does. In this case, "Program" is a way of telling the programmer, hmm, this is probably where the program starts.

Ramble: One of the things that makes programming difficult is not the question "what does this class do?" but rather the question "what does this class not do?" This is very much the bane of computer programming -- much of the time, the house that a programmer has built has rooms and furniture or appliances in the rooms that have various purpose and functions. However, the programmer didn't consider that another person might want to use the furniture or appliance in a different way and so didn't write the class to handle the behavior another programmer needs. Furthermore, programmers often write code so that the room only contains specific furniture or appliances. Another programmer might want to add an appliance -- for example, I've noticed some people have a washer and dryer in their kitchen rather than the basement.

Ramble: For example, think of the lights in your house. They are controlled by a light switch. But perhaps you're the romantic sort and would like to dim the lights for romantic dinners. You can't do that unless you replace the light switches with dimmers, or you happen to have candles and a nice candelabra in your house. If you're really into the holistic thing, you might want to change the level of blue light depending on the time of day, which would mean getting those fancy multi-color LED bulbs and a controller so you can reduce the amount of blue light at night. By analogy, if the programmer didn't write the "classes" in the room (light switch, bulb, color, etc.) in a way that makes it possible for you to customize the room the way you want to, well, it's sort of like saying, hmmm, I'm going to need to get a different house. This is one of the reasons that programs are constantly rewritten and programmers are always in demand -- their programs were not designed to be extensible to accommodate the needs of different users -- residents. Or quite frankly, you're living in a hut without electricity or running water and it's time to move into a new house. This last example is analogous to how the web has taken over the world of applications you used to have to install on your computer, and how those applications took over the even more obsolete "terminal" screens where all you had were letters, numbers, and symbols -- no fancy graphics, art, etc.

Code is ultimately a "best guess" as to what another programmer will want to do with the code. The corollary to this is really critical: Code is ultimately a "best guess" as to what user of the code wants to do. And it creates the conundrum that code serves several purposes:

  1. The "user" is actually another programmer.
  2. The "user" is a person using the program to do something productive (or not.)
  3. The "user" is actually another program that communicates with the first program to do things that the first program doesn't do itself.

Ramble: A lot of conflicts and teeth gnashing occurs when the code doesn't do what "we" want it to do. On the other hand, this constant "it doesn't do what I want it to do" syndrome keeps programmers employed and drives the innovations and bankruptcies in the tech industry.

Why Namespaces are Important?

I have a dining room table in the dining room of my house, and my house is very small:

C#
namespace MyHouse.DiningRoom
{
  class DiningRoomTable
  {
  }
}

However, if I'm Mr. Vanderbilt living in The Breakers in Newport RI:

my idea of a dining room table is very different:

C#
namespace Mansion.DiningRoom
{
  class DiningRoomTable
  {
  }
}

While the "thing in the room" is named the same as "DiningRoomTable", the namespace lets the programmer differentiate between the table in my little house and the huge dining room table in Mr. Vanderbilt's house.

Things with the Same Name can Behave Differently

As I stated above: just like any appliance, a class does specific things. So my dining room table seats up to four people. Mr. Vanderbilt's dining room table can seat many more people and probably has leaves to expand or contract it depending on how many guests he is having over for dinner! (And no, that is not a picture of the main dining room at The Breakers! It's actually a picture of The Breakers on the Ocean Restaurant, Spring Lake, New Jersey, but it gets the point across.) The point is, depending on the house and room (the namespace) the functionality of the thing in the room (the class) can be quite different. This is another reason why programming can be difficult - is the programmer using the correct class in the correct namespace?

What is "Using"?

Now we can explain the line:

C#
using System;

Here, we are telling the program that we want to use some stuff in another person's house! And we can even tell the program, we want to use stuff in a particular room!

C#
using System.Drawing;

Here, we are telling the program that we want to use stuff in the "Drawing" room of the "System" house! We know that the other house and its rooms will also have classes -- things in that house or room -- just like our house has things in it.

What are Those Squiggly Lines?

In this code:

C#
namespace Mansion.DiningRoom
{
  class DiningRoomTable
  {
  }
}

we see squiggly lines { } called curly braces.

In English, most sentences (unless your a poet like E.E. Cummings) begin with a capital letter, end with a period, question mark, or exclamation mark, and most importantly, are organized into paragraphs. Code represents the start of a "paragraph" with an open curly brace { and the end of a paragraph with a close curly brace }. The curly braces are also used to indicate the start / end of a chapter and the start / end of a book. And yes, this can be confusing which is why the tools that programmers use will vertically align the open/close curly braces for you so you know where in the "book" you are. (Unless you're programming in C or Javascript.)

Some programming languages don't use curly braces - instead, they rely on the indentation of the code. Other programming languages use words like "begin" and "end" to indicate the start and end of a book, chapter, paragraph, or sentence. Regardless of the programming language, this concept of denoting when something begins and when it ends is common to almost all languages.

Multiple Metaphors

We've actually now created two metaphors. It's an important realization that there are several visual-metaphor concepts occurring simultaneously in code and therefore in the programmer's head, whether they realize it or not. For example, given this fragment:

C#
namespace Explaining_Code
{
  class Program
  {

We can say:

Here we have a house at the address "Explaining_Code" that has a thing called "Program" in that house.

but we can also say:

Here have a book called "Explaining_Code" and a chapter called "Program."

A programmer will use both contexts simultaneously and quite unconsciously. Programmers code within the house/room/appliance context and they write the code within the book/chapter/paragraph (as well as words in the sentence and letters in the word) context.

What is that Semicolon?

A semicolon, at least in C#, means that "this is the end of the sentence (also known in programming parlance as a "statement") in the paragraph. Usually. Not all sentences need to end with a semicolon and not all programming languages use a semicolons. So to correct myself from what I said earlier, while in the English language sentences start with a capital letter and end in one of three punctuation marks (".", "?", "!") in the C# language, a sentence ends in a semicolon. The programmer knows where the next sentence begins only by the fact that the previous sentence ended in a semicolon. Usually.

What is Main?

Now we see the most strange thing:

C#
static void Main(string[] args)

First, appliances have "functions." Here we are saying that the appliance "Program" has a function, or purpose, called "Main." In code, a class (what I'm calling the "appliance") often has many functions (purposes.) For example, an oven typically has bake, broil, and clean "functions."

It's also important to realize that, as with any language, there are words that mean specific things. "House" does not mean "cat." In the world of programming, we have many words that mean specific things, called "keywords." The word "Main" is a keyword that tells the program "start here" when the program is run. There are three other keywords in that line: "static", "void" and "string".

Ramble: Incidentally, the word "run" predates computer programming -- for example, "run the engine." In the BASIC programming language, the word "run" meant "start the program", so we use the word "run" or "start" or the probably less politically correct term "execute" which all mean (yet another term for the same thing) "fire up the program!" which is a fun metaphor harking back to the days of steam engines or even further back in time.

Every programming language has a certain syntax as well, similar to the use of punctuation in a sentence. For example we use ? to indicate the sentence is a question. In the line above, the "punctuation" consists of the parenthesis and the open-close square brackets []. And yes, angle brackets <> have a special meaning as well.

In layman's terms (hopefully):

The keyword "static" is a way of telling the computer that the "appliance" Program has a purpose that always exists in the house "Explaining_Code" and that purpose is called "Main." The appliance ("Program") does not have to be first bought for the room "Explaining_Code" to use it, it's always there. You can use the appliance "Program" to do something called "Main" because the appliance is built into the room of the house. And no, I'm not going to explain yet why appliances do or do not need to be bought first, but I imagine programmers know what I'm avoiding talking about and are chuckling.

The keyword "void" tells the program that the "appliance" Program has a purpose called "Main" but that purpose doesn't actually produce anything. Think of a fork. It has a purpose but it doesn't make anything, assuming you use it as intended. Contrast that with a blender -- you put in some ingredients in it, push a button, and it produces a mush that we might call "a smoothie." Contrast that with a knife - it makes big things smaller; it cuts something into smaller pieces.

Ramble: Another reason programming is complicated is that some "appliances", like a spoon, may make something or not. You can use a spoon to stir things, but you can also use a spoon to separate a big bunch of stuff into a smaller parts of that stuff, which is what you're doing when you use a spoon to measure things. You can "spoon" (cuddling), you can "spoon into" something (soil into a pot), you can separate one part from the whole by "eating with a spoon." There are many times when a programmer uses a word for a class or a function and its not clear from the word what the intention of that function is without looking at the code. And since programmers rarely document their code, the only way to figure it out is to actually look at the code. If have access to the code (another topic.)

The keyword "string" is one of the concepts (known as the "type") that most programming languages know about. In this case, the type "string" simply means, well, any letter, word, sentence, phrase, number or other concept, which is a pretty big and complicated thing for a program to work with. So instead of everything being "strings", programming languages have ways of defining a "types" more precisely. Some types are just numbers, no letters allowed. Some types are just "state", like "on", "off", or "true", "false." Some types are actually groups of types. The programmer can even create new "types!"

Ramble: To make life more confusing, some "number things" are just integers, some are rational numbers having something to the right of the decimal point, and numbers can have different ranges depending on how they are stored -- for example, a number might be between 0 and 255, or 0 and 65535, or -128 to +127. Even worse, the computer has no good way of representing fractions like 1/3, so it will approximate the number, and there is also something called "precision", and programmers have to use the right "type" to deal with possible rounding errors, and, and, and!

And more confusingly, some programming languages infer the type from how you use it. In the programming language Javascript, if I write:

JavaScript
"5" + 6

I get "56". Here, "5" is a string containing the character 5 (strings are usually denoted with quote marks, but this is language dependent), and I'm concatenating the number 6 to the string "5", so JavaScript says the answer is "56".

But if I write in JavaScript:

JavaScript
5 + 6

I get 11! Here, I have two numbers, 5 and 6, and I'm simply adding them.

Ramble: In programming parlance, this is the difference between "un-typed" programming language like JavaScript, and "typed" programming languages like C#, and there is a constant argument between programmers as to which is better and which they prefer to use, all of which is opinion rather than solid reasoning. Also, this is called "operator overloading" - the concept of addition (the "plus" symbol) means different things depending on what the "inputs" are.

The [] is one way of telling the program that "string" is not just a single "string" but a group of 0 or more strings, which in programming parlance is often called "a collection", an "array", or a "list," all of which seem analogous in the English language but actually have specific nuanced meaning to programmers and how the "group of things" is used, because we usually don't want to have a run-on sentence like this one but instead we want to tell the program that something is actually a collection of that thing.

So what is (string[] args) actually saying here? Most appliances perform functions (like "Main") only if you put something in them. Yes, a refrigerator will keep the air cold in the refrigerator but unless you put food into the refrigerator, you're wasting electricity. A blender just makes noise if you start it up without putting something in it to blend. So the parenthesis () is the syntax we programmers use to say "here is the stuff we're putting into the appliance for the purpose of performing the function "Main." Now, most programmers will cringe at how I worded that but I contend that it is a completely valid way of describing "declaratively" what is going on. Given:

C#
namespace Explaining_Code
{
  class Program
  {
    static void Main(string[] args)

we are saying the house "Explaining_Code" has a built-in appliance "Program" that performs the function "Main" when you put in 0 or more strings, but it doesn't actually produce anything. Funny to say it that way!

If we have a function like:

C#
WaitABit();

We are telling the program that there is nothing that this function requires (the empty parenthesis) to do what it's supposed to do. So if the function of an appliance just does something on its own without putting something into the function, we would write the function with empty parenthesis, like Stop(). It is actually the parenthesis that tells the program, this is a function of the appliance. Usually. Functions are almost always named to read as action verbs. Except for "Main"!

How can a function do something without putting something into it? In this scenario, the function figures out what to do often by "calling" other functions that give it the information it needs to do what it is supposed to do.

Ramble: It's a little bit like calling someone on the phone. "Hey, what do you want for dinner?" And yes, just as in real life where sometimes the connection doesn't go through, or you get a busy signal, or you get the wrong number, or you get answers like "clean the litter box" because the person on the other end misheard, there are analogous responses in the world of programming, which is why programmers write code to check that the "answer" makes sense. Well, programmers ought to do this, but they usually don't, which is one of the reasons programs have bugs or worse, crash.

The word "args" is just shorthand for "arguments" and is called the parameter of the function. The word "argument" is another word co-opted by programmers from the definition of "argument" in the context of linguistics. It doesn't mean the program is going to quarrel with itself, but rather "any of the noun phrases in a clause that are related directly to the verb, typically the subject, direct object, and indirect object." You see now that the code:

C#
static void Main(string[] args)

has a "verb(nouns)" structure. It means: do this action -- the verb -- with these things -- the nouns.

To make life more complicated for programmers:

  1. A function can have more than one parameter (argument).
  2. A function can have optional parameters.
  3. The same verb used to name the function can be used repeatedly as long as the parameters (the nouns) are different.
  4. Most modern programming languages let the programmer specify a verb as the parameter instead of a noun which is a very special kind of programming called functional programming that I won't get into.

What Does Main Do?

Now we can finally figure out what Main does:

C#
static void Main(string[] args)
{
  Console.WriteLine("Hello World!");
}

First, the squiggly braces {} says "here is the start of a book, chapter, or paragraph." Yes, it can pretty much mean any of those things. The sentence is Console.WriteLine("Hello World!"); because it ends in a semicolon.

When you see something with a dot, like Console.WriteLine, it means we are doing something, in this case WriteLine, on the variable or class to the left of the dot, in this case Console. This is a standard notation in C# and many other programming languages and can almost always be read as withThisThing.DoSomething.

Ramble: This book/chapter/paragraph/sentence structure is one of the ways anyone can tell if a program is written well even if they have no programming experience. If there is a novel between a paragraph's {}, or there are a thousand sentences in a paragraph, it's a very poorly written program. If instead, what's between the {} are concise sentences and not too many sentences, and the chapter doesn't have too many paragraphs, and the book doesn't have too many chapters, then it's a very well written program. Or it just doesn't do very much.

So the sentence Console.WriteLine("Hello World!"); is saying: using the appliance "Console" which is part of the house "System", use the appliance's function "WriteLine" to print the string "Hello World" on the computer screen.

The Importance of Naming

Rambling stuff:

Name confusion is in part why programming is actually difficult. When one programmer writes some code, we have to learn not only what is in his house and his rooms, we also have to learn what the intention of the house, room, and things in the room are, and the name of the thing in the room is often not sufficient to really grok this. Words are used to describe concepts and what a programmer is doing is constantly changing the definition of words. For example, before the rise of the Internet, everyone new that this:

is a cloud. But at some point, some programmer (or manager or marketing person) decided that the word "cloud" should also mean:

Which means what exactly? We have this obtuse definition: " 'The cloud' refers to servers that are accessed over the Internet, and the software and databases that run on those servers." (from cloudflare.com) but when you think about it, it is a really stupid new definition of the word "cloud." Clouds live in the sky, and nothing "lives" in a cloud except water vapor and ice and angels. So we shouldn't say "does this data live in the cloud?" but rather "does this data live in the sky?" as the sky has clouds and birds and 5G. But "sky" was probably rejected because it was too scary a term for people's wild imaginations.

Ironically, "skynet" is a great term to use for the Internet, but like I said...

What Actually Then is a Program?

Now that we hopefully have a visual way of approaching code, what actually is a program? The answer to this is astonishing in its simplicity. A computer program does three things and three things only:

  1. MRF operations
  2. CRUD operations
  3. The rest of programming: higher order MRF and CRUD operations

What?

MRF is my acronym for three concepts: map, reduce, and filter. CRUD is a common acronym for Create, Read, Update, and Delete. Let's looks at each of these.

Map, Reduce, and Filter

We do these processes in real life even though we don't realize it. We are constantly converting (mapping), summing or averaging (reducing), and filtering (filter) information. Filling out a tax form is a great example:

  • Converting your net income to your taxable income is the process of mapping -- you are multiplying your net income by a percent based on the tax rate for that net income.
  • Summing up all your income and expenses and subtracting the two is the process of reducing. First, you reduce your income to a single number, your total income. Then, you sum your expenses by reducing them to a single number. Finally, you reduce your income and expenses to a "net income" by subtracting the two -- your profit or loss.
  • Filtering is another process we perform when filing our taxes. In order to claim a deduction such as a medical expense, we have to exceed a certain dollar amount for that expense. If we don't exceed that amount, we can't use the expense on our taxes. This is filtering -- something is either eliminated or it isn't.

The elegance of this is that every single thing we do, every single thing our body does, every single thing the universe does, is a mapping, reducing, and/or filtering process. The sun is constantly mapping hydrogen into helium and other elements. Your body reduces complex carbohydrates into simple sugars. Your kidneys filter out chemicals that need to be disposed of. Some mapping processes are not so direct. For example, your lungs absorb oxygen and release carbon dioxide, but to understand the mapping, reducing, and filtering process, one pretty much has to look at the cellular level and circulatory system. This is a perfect example of the third item in previous list "higher order MRF and CRUD operations." Making a cake from raw ingredients, mixing them, applying heat from the oven, is another example of "higher order MRF operations."

Ramble: The skill of the programmer then becomes one of clearly understanding the requirements of the process in terms of map/reduce/filter operations (even though they don't consciously realize that's what they are doing) and expressing the MRF processes in a hierarchy of simple MRF processes which are then called by "higher order" MRF processes, and so forth, until the end result is a moist cake. Unfortunately, computer programs are ripe with examples of "spaghetti code" where there is no clean hierarchy and instead all the ingredients are thrown into the oven and the programmer hopes for the best.

Some re-iteration of this and examples follow.

Map

Mapping is simply the conversion of one thing or several things to another thing.

For example, in the US, we measure fuel efficiency as miles per gallon. In Canada, fuel efficiency is measured by liters per 100 kilometers. Not only is this a conversion of units but it also is an inversion of those units! So in the US, we think "the more miles we get out of a gallon of gas, the better our fuel economy" but Canadians think "the more liters I need to travel 100 kilometers, the worse my fuel economy." This requires a calculator, though A simpler example might be converting miles per hour to kilometers per hour. That one we can usually do in our heads.

An even simpler example of mapping is working with recipes -- we need to double or triple a recipe, or halve the recipe, depending on how much we are making. A simple code example of doubling a recipe:

C#
var measurements = new int[] { 1, 2, 3 };
var doubled = measurements.Select(m => m * 2);

Here the syntax:

C#
var measurements = 

We are putting some stuff into the variable "measurements."

C#
new int[]

We are creating an array of integers. The keyword "new" means to create something out of thin air.

C#
{ 1, 2, 3 };

and we are putting the numbers 1, 2, and 3 into the array. End of sentence.

C#
var doubled = measurements.Select(m => m * 2);

Here, we are defining another variable, called "doubled", in which we are selecting each of the numbers in "measurements" and multiplying the number by 2.

Reducing

As described earlier, reducing is converting several things into one thing of that same type. When you go to the store and buy stuff, the total amount you need to pay is the process of reducing, by summing the cost of all the items to a single item. Here's a code example:

C#
var itemCosts = new int[] { 1, 2, 3 };
var totalCost = itemCosts.Sum();

Filtering

Perhaps instead of paying for everything, you want to shoplift some items that can fit in your pocket. You "filter" what you place in the basket vs. what you conceal in your pocket by its size:

C#
var itemSize = new int[] { 1, 3, 5, 7, 8, 10 };
var basketItems = itemSize.Where(size => size > 7);
var shopliftedItems = itemSize.Where(size => size <= 7);

Here the syntax => is simply saying: for the item in the array itemSize, followed by see if it's bigger or smaller than 7.

But Code of Course is not That Simple

Ramble: Unfortunately, implementing actual MRF code is not quite as elegantly clean as what you see above, although in some programming languages, like C#, you could write all your MRF operations with "select", "where", and "coalescing" (aka reduce) operations. Sometimes it's simpler (as to whether that is simpler or not, well, I'll let you decide) to write something like this:

C#
var itemSizes = new int[] { 1, 3, 5, 7, 8, 10 };
var basketItems = new List<int>();
var shopliftedItems = new List<int>();

for (var i = 0; i < itemSizes.Length; i++)
{
  var itemSize = itemSizes[i];

  if (itemSize > 7)
  {
    basketItems.Add(itemSize);
  }
  else
  {
    shopliftedItems.Add(itemSize);
  }
}

Here, you see several things:

  1. We are making a list of basketItems and shopliftedItems that are integers and begin with being empty with the sentence new List<int>();.
  2. We are "looping" through each item in the itemSizes array with the start of the paragraph for (var i = 0; i < itemSizes.Length; i++)
  3. We are extracting the specific item size from the array with the sentence var itemSize = itemSizes[i];
  4. We are testing the size with the start of a sub-paragraph if (itemSize > 7)
  5. Based on whether the test is true or false, we are putting the item into the basket or our pocket with the sentences basketItems.Add(itemSize); and shopliftedItems.Add(itemSize);

And you can also see how the curly braces are used to denote sub-paragraphs within the paragraph that further splits up the sentences.

Create, Read, Update, and Delete

Memory

Non-programmers often don't understand the difference between a computer's memory and a computer's storage system. A computer's memory is reincarnation -- you (usually) can't remember your past life. Similarly, when you shut off a computer (like death) and then you turn it on again later (like rebirth), it cannot recall anything about its prior "life."

Physical Storage

Conversely, a storage system is like the Akashic record (see https://en.wikipedia.org/wiki/Akashic_records). The program can record things onto a physical medium that is non-volatile, meaning it retains what you put into it even when you turn off the power. Unlike the Akashic record though, your hard drive will not have the next 10 years of future tax returns stored in it. Historically, we preserved data on devices called hard drives.

Persistent Memory Storage

To make life more confusing, we now have something called a Solid State Drive (SSD) which is actually a kind of memory that behaves like a hard drive -- it retains information even after it loses power. It looks a lot like computer memory -- the item in the lower left of the screenshot above but is smaller and faster than a mechanical hard drive -- the other two items in the center and top right of the picture.

Using the Computer's Memory

Create, read, update and delete are also essential operations that a computer program almost always performs. Programs can create things in memory using a special keyword called new:

C#
var itemSizes = new int[] { 1, 3, 5, 7, 8, 10 };

This literally allocates some space in the computer's memory for the numbers 1, 3, 5, 7, 8, 10. Since it's an array, the numbers are placed physically next to each other in memory. The program even knows how many items there are in the array!

Programs typically have to update values, and this can be done in memory as well. For example, this changes the first element in the array from 1 to 1000:

C#
itemSizes[0] = 1000;

Reading from memory is one of those unconscious things programmers don't really realize is happening. If I write:

C#
var a = itemSizes[1];

What the program is really doing is:

  1. Create a space in memory for the variable a.
  2. Read the value in the memory cell at index 1 for the array itemSizes also in memory.
  3. Put the value into the memory location we created in step 1.

Ramble: An "update" operation is almost always a combination of create, read and write, but we programmers don't realize that, but it's one of the reasons that some things we ask a program to do take a long time and requires the programmer to optimize the entire algorithm because there are efficient was of updating data and there are some really inefficient ways of updating data.

Deleting stuff is an odd duck. In older programming languages like C and C++, the programmer had to be very careful to delete anything created with the new keyword, using, you guessed it, the delete keyword. More recent languages, like C#, will have a janitorial service that cleans up after the programmer, figuring out if anything is still referencing the memory and if not, will delete if for you automatically, a process called garbage collection.

Ramble: In the old days with languages like C and C++, if the programmer wasn't careful about deleting all the things the program created, this would result in a memory leak. The memory would never be freed up and the program would use more and more of the computer's available physical memory. At some point, the computer would become unusable and the user would have to close (or kill) the program or reboot the computer. Now, with languages that clean up after the programmer automatically, the programmer still has to be careful -- sometimes the "garbage collection" process can take a while, making the program slow to respond to the user.

Using the Computer's Storage Abilities

Any time you create or edit an existing document on your computer, you are using the computer's storage system and create, read, update, and delete operations, except in this case, the operating system is retrieving the data from the physical storage device and putting it into memory so that you can edit the data, and when you're done and "save" the file, it updates the physical storage with the new version. But there are other kinds of ways to use a physical storage device, the most common is know as a database. A database is actually where the acronym CRUD originates as the programmer very specifically creates, reads, updates, and deletes physical records in the database. A record is basically anything -- an ingredient in a recipe, the name of the recipe, the ingredients that make up a recipe, and so forth. A database can even be used to store a computer program! More generally, you can think of a computer's storage system or database as a card filing system -- the card file organizes information, indexing cards so they are easy to find (read), let's you add new cards (create), remove old cards (delete), and update existing cards (update.)

Ramble: Another thing that makes computers slow is that physical storage systems tend to be slow, and not just because older physical devices, like hard drives, were mechanical with a spinning platter and a magnetic needle -- thing of a phonograph but the record spins much faster and you can record new tunes. Even with SSDs, the programmer particularly has to pay attention to the way a database indexes the information. If the database is not properly indexed, it will be very slow in retrieving data. Conversely, and ironically, when you index something, the database can retrieve the data faster but it takes longer to add new data because the new data has to be added to the index! Other programmers (and academicians) spend a lot of time figuring out how to optimize the algorithms that a database uses so it's as fast as possible.

The Cloud

Ramble:

Back to SkyNet, um, I mean "the cloud", aka the Internet. The latest trends are to store data not on your physical machine but "in the cloud." Ultimately, this still requires a computer (or several) connected to physical storage devices like hard drives or SSDs, but there are several advantages:

  1. The information is accessible by more than just your computer sitting in your office -- your phone, your computer at home, your friend's computer, the government, the advertising companies, the hackers...oops, that's too much information.
  2. You can put a lot more information into "the cloud" than your own physical storage device has space for. Examples censored.
  3. Often, the computer that is managing the data is much faster at accessing the data than your own computer!

Regarding point #1, once the Internet was "born" a whole new line of work for programmers was created - data security!

All of this is great as long as:

  1. You live in a first world country with a decent paying job so you can afford have high speed Internet.
  2. You actually have an Internet connection where you are.
  3. You have electricity and can pay your electric bill.
  4. An X-level solar flare doesn't wipe out the electrical grid and anything magnetic or that acts like an antenna.
  5. The zombie-apocalypse hasn't happened yet.

The Rest of Programming: Higher Order MRFs and CRUDs

The rest of programming is the process of creating more complicated things from smaller, simpler things. Let's say you have functions that do the math for each line item on your tax forms. You then combine them into a bigger function, say, one for each kind of tax form. Then you combine those functions into another function, say "Federal Taxes." So at the end of the day, that's really all that programming is -- using small pieces of code that do very limited things into bigger pieces of code that do more complicated things, rinse and repeat.

Ramble: Most programmers get this process completely wrong, resulting in one huge function, like a run-on sentence, that does everything which then becomes a nightmare to find and fix bugs or change the code as requirements change. We've even had programming languages change, creating structures called object oriented programming, to try and get programmers to write code in smaller pieces. This has failed. We even have guidelines, like DRY (Don't Repeat Yourself) and SOLID (don't ask) that are commonly ignored.

Conclusion

Programming is like any language: you first have to learn how to read, write and speak it and then you can progress to "thinking in it." But like a professional Shakespearean actor, a truly professional programmer, by analogy, understands more than just the syntax of the language and definition of the words -- they also understand the underlying meter, syllable stresses, and so forth of the "verse" of the program. And as there are different ways to speak Shakespeare, there are different ways to write programs, but both have to have an underlying foundational structure and "sensibility" that needs to be adhered to if the audience (aka another programmer) is to truly apprehend (meaning "to grasp with the understanding") the program and therefore comprehend its implementation. If the programmer does not adhere to a sensible structure, then another programmer only experiences apprehension (meaning "to anticipate especially with anxiety, dread, or fear") when working with someone else's code.

There is also a debate as to whether programming is an art or a science. As one blogger eloquently wrote:

"Ask anyone who has coded their own program, or chipped away at a software product to make it run smoother and quicker with cleaner code. Firstly and most obviously, programming is art in a skilled craft sense. Programming can also be used to create art; with code as a resource to create a beautiful end product. But beyond that, on a deeper level, programming is often art as a form. Programming can be aesthetically beautiful. It is imagination and ingenuity manifest; pure creation branded with each developer’s own individual style. If that’s not art, then what is?" (my emphasis)
- https://www.parkersoftware.com/blog/is-programming-art//

Given that, I will leave the non-programmer and programmer alike with these two concluding thoughts.

"All serious art, music, literature is a critical act. It is so, firstly, in the sense of Matthew Arnold's phrase: 'a criticism of life.' Be it realistic, fantastic, Utopian or satiric, the construct of the artist is a counter-statement to the world."
- George Steiner - American writer, 1929-20200

And a thought regarding programming as a "naive art" vs. a "critical art":

"In all our activities, two things must be taken into account: the activity itself, and our knowledge of its laws. We may be completely absorbed in the activity without worrying about its laws. The artist is in this position when he does not reflect about the laws according to which he creates, but applies them, using feeling and sensitivity. We may call him 'naive.' It is possible, however, to observe oneself, and enquire into the laws inherent in one's own activity, thus abandoning the naive consciousness just described through knowing exactly the scope of and justification for what one does. This I shall call critical. I believe this definition comes nearest to the meaning of this concept as it has been used in philosophy, with greater or lesser clarity, ever since Kant. Critical reflection then is the opposite of the naive approach. A critical attitude is one that comes to grips with the laws of its own activity in order to discover their reliability and limits. Epistemology can only be a critical science. For its object is an essentially subjective activity of man: cognition, and it wishes to demonstrate the laws inherent in cognition. Thus everything 'naive' must be excluded from this science. Its strength must lie in doing precisely what many thinkers, inclined more toward the practical doing of things, pride themselves that they have never done, namely, 'think about thinking.'"
- Rudolf Steiner, Truth and Knowledge, Chapter 3, 'Epistomology Since Kant.' (Epistomology means "the theory of knowledge, especially with regard to its methods, validity, and scope. Epistemology is the investigation of what distinguishes justified belief from opinion."-- Oxford Languages)

History

  • 1st August, 2021: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Marc Clifton
Architect Interacx
United States United States
Blog: https://marcclifton.wordpress.com/
Home Page: http://www.marcclifton.com
Research: http://www.higherorderprogramming.com/
GitHub: https://github.com/cliftonm

All my life I have been passionate about architecture / software design, as this is the cornerstone to a maintainable and extensible application. As such, I have enjoyed exploring some crazy ideas and discovering that they are not so crazy after all. I also love writing about my ideas and seeing the community response. As a consultant, I've enjoyed working in a wide range of industries such as aerospace, boatyard management, remote sensing, emergency services / data management, and casino operations. I've done a variety of pro-bono work non-profit organizations related to nature conservancy, drug recovery and women's health.

Comments and Discussions

 
GeneralMy vote of 4 Pin
tbayart3-Aug-21 23:04
professionaltbayart3-Aug-21 23:04 
GeneralRe: My vote of 4 Pin
Marc Clifton5-Aug-21 2:13
mvaMarc Clifton5-Aug-21 2:13 
QuestionGreat read. Pin
jpaxtons3-Aug-21 14:36
Memberjpaxtons3-Aug-21 14:36 
GeneralMy vote of 5 Pin
Ștefan-Mihai MOGA3-Aug-21 10:18
professionalȘtefan-Mihai MOGA3-Aug-21 10:18 
GeneralA Great Read Pin
Choroid3-Aug-21 9:35
MemberChoroid3-Aug-21 9:35 
GeneralRe: A Great Read Pin
Marc Clifton5-Aug-21 2:08
mvaMarc Clifton5-Aug-21 2:08 
Question"What is a program?" Pin
Dan Sutton3-Aug-21 5:42
MemberDan Sutton3-Aug-21 5:42 
AnswerRe: "What is a program?" Pin
dbrenth3-Aug-21 10:47
Memberdbrenth3-Aug-21 10:47 
GeneralRe: "What is a program?" Pin
Dan Sutton3-Aug-21 11:41
MemberDan Sutton3-Aug-21 11:41 
AnswerRe: "What is a program?" Pin
AchLog12-Aug-21 23:46
MemberAchLog12-Aug-21 23:46 
GeneralRe: "What is a program?" Pin
Dan Sutton13-Aug-21 6:54
MemberDan Sutton13-Aug-21 6:54 
GeneralMy vote of 5 Pin
BBar23-Aug-21 1:46
MemberBBar23-Aug-21 1:46 
QuestionMinor quibble Pin
Val Cohen2-Aug-21 11:23
MemberVal Cohen2-Aug-21 11:23 
QuestionMy vote is 5 Pin
AchLog2-Aug-21 9:56
MemberAchLog2-Aug-21 9:56 
QuestionThis has never happened PinPopular
louisj2-Aug-21 3:56
Memberlouisj2-Aug-21 3:56 
AnswerRe: This has never happened Pin
Marc Clifton2-Aug-21 4:27
mvaMarc Clifton2-Aug-21 4:27 
AnswerRe: This has never happened Pin
Pleby2-Aug-21 7:50
MemberPleby2-Aug-21 7:50 
GeneralRe: This has never happened Pin
Marc Clifton2-Aug-21 11:21
mvaMarc Clifton2-Aug-21 11:21 
GeneralRe: This has never happened Pin
11917640 Member 1-Sep-21 3:59
Member11917640 Member 1-Sep-21 3:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.