Programming for non-programmers - 1 - Fundamentals

Whether you are planning to learn how to write software, or you just use software in your daily life, you may have noticed there is a huge gap between people who ‘get it’, and people who don’t. Most programming guides you will find are aimed at explaining a single language. Many assume you already know most of the basic ideas, making them unintelligible for those that do not. Others assume you do not know these concepts, but explain them in terms of their specific language. This confuses the reader about which parts of the teaching are specific quirks of the language at hand, and which are part of the core fundamentals of all programming.

For this reason it seems sensible to create a guide to programming which does not relate to any specific language. One that only covers these basic concepts which are common to all, and in such a way that no knowledge of any programming language is required to understand it.

After reading this you will not be able to write any code, nor will you be able to understand code that you read. But if you can understand the concepts laid out here you will be able to learn any programming language relatively simply. In most cases it is merely a case of learning the syntax – i.e. the symbols and keywords used to designate the program.

But a more important goal for most people will be to understand what software can and can’t do. To understand when they have a reason to complain that it is not working as it should, and when it is reasonable to ask for a new feature or program that they need without programmers being rude to them about it. That’s what the first part of this article focuses on.

If you are thinking about learning how to write code yourself, the second part starts here and explains some more in-depth programming concepts and gives you an overview of the different kinds of languages, to help guide your first steps.part can be found here.

If you are already an experienced programmer I advise you not to read any of this, it will probably annoy the hell out of you.

If you are trying to understand a specific language, I have provided search terms for each section which are marked with bold style. If you want to know how this basic feature works in the language you are interested in you can just search the name of the language, and the search term. For example if you are interested in the language ‘Ruby’ and you are interested in how to write ‘and’ ‘or’ and ‘not’ (see below) you might search the internet for the term “Ruby logical operators” and somewhere in the search results should be a nice table for that language showing all the logical operators.

The most important thing to remember when dealing with software is Don’t Panic. It seems nightmarishly complicated because it actually is. Learning everything there is to know about software would take many lifetimes. Just remember that everyone who knows anything started from a place where they knew very little, and step by step they built up the knowledge. The feeling of panic that rises up when you see something complex will make it very hard for you to learn so if this happens, take a few deep breaths and remind yourself that you only need to understand one new thing at a time.

Building blocks

Instructions

At the root of it all, software is just a set of instructions that are written in such a way that a computer can understand them. Computers are very stupid by human standards and you really have to spell everything out. How we go about spelling everything out, what kinds of instructions we use and how we can get a computer to understand what we want is the basic theme of this guide. The main thing to remember is that we are not stupid, the computer is, and dumbing things down to a level that even a computer can grasp is hard. Once we do that the result is so full of trivial minutiae and mindless repetition that it can look complex and intimidating.

All instructions, after being compiled, interpreted, boiled, sifted, grated, fried and baked with cheese on top, end up in your computer as one or a collection of the following operations:

Copy a value from one place to another.

Change a value with reference to another value (usually adding two numbers together or doing a logical operation - see below)

That is all that computers really do. There are a handful of different places values can be copied to and from, and a handful of different ways to combine different numbers, but not that many of either. You can probably count them on your fingers.

And Or Not

When I learned about this topic at university I found it quite dense and really did not like the course. Once I became more experienced at it I realised it is childishly simple and everyone already understands it from a very young age. Why the university course is so obfuscated is still unclear to me. They call it ‘boolean algebra’ and use a whole host of arcane looking symbols to denote things in it. This leads to vast incomprehensible-looking formulas that seem mainly designed to intimidate the layperson and make the practitioners of this dark art seem more clever than they are.

The basic concept is the same as the everyday words ‘and’, ‘or’ and ‘not’. Different programming languages use different symbols for them, but their meaning is the same as these words mean in English. If you have a bunch of toy blocks for children with a range of different shapes and colours, you may describe a certain block or group of blocks with sentences such as this:

1. The block that has 6 sides and is not red or green.

2. All the blocks that have more than 4 sides and less than 7 sides and are red, or have 10 sides and are yellow.

You should be able to pick out the blocks described without any issue. The second one might need to be re-read a couple of times to get clear, but there are no new concepts here. So congratulations, if you read and understood those two sentences you understand boolean algebra.

Of course you are a genius compared to a computer, so in programming this would be represented much differently. Many words in English are somewhat redundant and can be removed, like ‘the’ and ‘is’, and other parts require some assumptions which your computer is far too stupid to understand without help. In addition, in programming we try to replace a lot of commonly used concepts with symbols to make them faster to type. So it is worth looking at a more machine-like version of these sentences:

1. block sides = 6 AND (block NOT red AND block NOT green)

In this example we have to say ‘the block is not red’ and ‘the block is not green’, because our dullard computer will have already forgotten what we are talking about by the time we get past counting the sides. The brackets around the colour part are implied in the original sentence, but the computer will just read right to left and think we mean ‘The block that has 6 sides and is not red, and the block that is not green’.

2. (block sides > 4 AND block sides < 7 AND block red) OR block sides = 10 AND block )

The > and < symbols mean ‘greater than’ and ‘less than’, as you would expect. This is true in most programming languages as far as I am aware. Again brackets are implied in the original that need to be put in for the computer.

There really is not a lot more to boolean algebra than understanding the words ‘and’, ‘or’ and ‘not’ in English. One important difference is worth noting however. Take the following two sentences:

“are you coming or staying here”

“do you want something to eat or drink”

In normal language the word ‘or’ means two subtly different things. In some cases it can mean ‘either a or b but not both’, and in some cases it can mean ‘a or b or both’. Yes you guessed it, computers are too thick to understand the context, so we have to specify. The first case, where both is not an option is called ‘exclusive or’ which is shortened to xor. If you tell a computer ‘a or b’ it means ‘a or b or both’.

Many programming languages do not use the words ‘and’, ‘or’ and ‘not’ for these concepts and instead use symbols. ‘And’, ‘or’ and ‘not’ are what are called ‘logical operators’. This is the term to search for in the documentation of a language if you want to know what symbols that language uses for them.

Functions

When telling a computer how to do something, sometimes you need to repeat yourself over and over. Sometimes this happens thousands of times. We save time by wrapping a bunch of instructions up in a package so we can name them. Again this happens in normal language too. You might have to explain to someone how to change a tyre on a car by running them through it step by step.

But the next time we want that person to change a tyre we just say ‘Hey, change the tyre’. This is the basic principle of functions.

Each language writes (defines) functions differently but there will usually be some kind of name, followed by a set of instructions, and then some marker to show where it ends. Something like this:

function change a tyre {

Jack up the car

Undo the lug nuts

Pull off the old tyre

Put on the new tyre

Do up all the nuts again

Let down the jack

}

In this case I have used curly brackets to show the start and end of the instructions, this is common in several major languages. Later if we want to tell the computer how to do it again we just say:

change a tyre

There are a few things in the example above that are actually wrong, in pretty much every language.

The first is that you can never put spaces in any of the names you choose or the computer will think that each word refers to a different thing, so actually the function should be called

changeatyre

To make that easier to read, different languages have different conventions, e.g. change-a-tyre and changeATyre are both common and in most languages you can do it how you want.

The second thing to note is that in virtually all languages functions have inputs and outputs. For example you might want to say which car or which tyre to change. Of course the computer is never going to figure that out for itself and you don’t want it to change the wrong tyre. It is common to use another kind of brackets to show where the inputs (also known as ‘arguments’ or ‘parameters’) are defined. So the usage of the function above might be something like:

changeATyre(blueHonda, leftFront)

and the definition might be more like:

function ChangeATyre(whichCar, whichTyre) {

JackUpTheCar(whichCar)

UndoTheLugNuts(whichTyre)

(whichTyre)

(whichTyre)

DoUpAllTheLugNuts(whichTyre)

LetDownTheJack(whichCar)

}

As you may have noticed, all the instructions themselves are also functions, and we basically just pass the parameters on to the ones that need them. This is normal, so many functions have been written already and programmers usually share them around so you never really have to write actual basic machine instructions. If you did they would basically just be: copy this value to memory address a, add the values in a and b and write the result in c, copy the value in c to d. Generally you will not have to work on this level. Either way you can use a function to bundle up a bunch of other functions and this is the main activity of a programmer. Generally even functions with no parameters are still written with empty brackets after them to show they are functions. e.g.

()

Looping and Branching

Computers, dull, uninventive creatures that they are, will basically plod through your instructions one at a time in order. Sometimes this can make things difficult, so most languages have ways of directing and redirecting them. The most basic and common of these is the ‘if’ statement. This works the same way as in normal language:

if amountOfBait > 0

goFishing()

This can be paired with an else like:

else

cutBait()

But the else is usually optional. These allow us to tell the computer to only do the instruction under specific circumstances.

In some cases we want the computer to do the same set of instructions over and over. These are called loops. Again it is pretty intuitive, you have to tell the computer how many times to loop and/or when to stop.

loop 100000

print(“all work and no play make jack a dull boy”)

Should be pretty clear, as should:

while (thirsty and water > 0)

drink()

This simply says keep drinking until you run out of water or you don’t feel thirsty any more. Some languages have ‘for’ and sometimes ‘foreach’ which just say ‘take this list of things, then do these instructions for each one’.

foreach car in allMyCars

changeATyre(car, leftFront)

This pretty much covers it. There are a few other specialised ones but you can do most things with just these examples.

Variables and Assignment

Information used by the program has to be stored in memory somewhere. When you want to store something there are a few steps.

Declaration is when you say ‘here is this thing I want you to remember’. It reserves some memory to store the value, and declares a label for it to refer to it later. The label can be anything you want. Some languages have conventions for naming them but these are optional.

Variable assignment is when you set a value for that variable. There are a couple of things that can trip new people up here. The first is that many languages use the equals (=) sign for variable assignment. (also called the assignment operator) This can be confusing as

seven = 7

might look like a comparison, but in most major languages it is not, and

seven = 42

is just as valid (although seven is a terrible name for a variable that doesn’t equal 7. In fact, lets just all promise to never name a variable with a written-out number, it will never be a good idea). This is why, as mentioned above, usually == is used for comparing if things are equal. The second pitfall is that many languages allow declaration and assignment in the same statement, but also allow them to be separate. So in one place you might see

var myAge = 86

and in another you might see the declaration first

var myHeight //Declaration

and then later the assignment

myHeight = 86 //Assignment

Also worth noting, variables can be set and reset as often as you like, hence the name. They are basically just labels that refer to places in memory where some value is stored.

Types

In programming, data or information always has a type. Some programmers talk about ‘typed’ and ‘untyped’ languages, this does not mean some languages don’t have types. It means some languages don’t have a formal system for keeping track of them.

All the information a program uses has to be stored in memory as binary code somewhere. As a programmer in most high level languages you do not have to understand how each type of information is stored, just that they are different and not interchangeable. If I save the number 7 to a variable it will get saved as 111. Well more likely it will get saved as 00000000000000000000000000000111, but as I said, we don’t really need to worry about that. The point is that if I save the value “seven” to one variable and then try to use that in a place that is expecting a number, the computer will panic and crash your program. So something like:

7 + “Seven”

is probably going to end in tears.

Interestingly in many languages

“Seven” + 7

will not crash and the computer will end up with the value “Seven7”.

The type of “7” is integer, and the type of “seven” is string (because it is a ‘string’ of characters, programmers aren’t renowned for their talent at naming things). Generally values of two different types won’t play nicely together. One thing that trips up newcomers, and is common in the majority of languages, is that 1 and 1.0 are different types. Numbers with and without decimal points are stored in memory in an entirely different way. In fact some languages even have signed and unsigned number types so that 1 and -1 are different types.

This is why type systems are useful. A type system is just a way for the compiler to keep track of what the type of each variable is so that the programmer doesn’t have to. So when you try to do a calculation that violates type rules it will tell you like a spellchecker in a word-processor before you embarrass yourself.

I will not be telling you what all the data types are, the list is unlimited. Most languages also let you make up new types at will as you work. If you want a list of the basic types a language uses, the search term is primitive types.

Languages with a proper type system are called statically typed, whereas languages without one are called dynamically typed. Some people talk about dynamic types as though they are an advantage. Don’t listen to them.

Things That Look Like Programming But Aren’t

Markup Languages

Some people say that markup languages are not real programming languages. Just ignore those people, they have personality problems. There is actually a definition for what constitutes a ‘real’ programming language but it is complex and mathematical and only people with personality problems care about it. If you happen to suffer from these types of problems, you can scratch that itch with the search term Turing completeness. Either way, you can’t program for long without needing to use markup at some point. It is also useful to know as a user of software.

Markup is a way to add information to normal text for the computer to read. The main reason this is done is to make it display differently when shown on a screen, but markup languages are also used to describe user interfaces, or to store data (see below). As a programmer you might sometimes find yourself having to write markup in addition to your regular coding language. Generally it involves words and numbers in brackets. You might have something like:

[cursive]This is some [bold]marked up[/bold]text[/cursive].

Which would be used to describe: This is some marked up text.

Note that each tag has an opening and a closing (marked with a ‘/’ at the start) part to show where it starts and ends. The tags themselves are not shown when the text is rendered. This is the general pattern that most markup languages use (a notable exception is the language MarkDown which uses symbols like: *This is some **marked up** text*).

I know I said I was not going to go into specific languages but I need to explain XML . The reason for this is that ev ery website on the internet uses HTML and XML is the general case that html is (kind of, mostly) based on. XML stands for eXtensible Markup Language (programmers naming things again). Basically XML uses tags surrounded by arrow brackets <tag>, and a closing tag marked by a ‘/’.

<cursive>This is some <bold>marked up</bold> text</cursive>.

Please note: Although the example above is valid XML, there is no text renderer I am aware of that will actually render that example as text. It is merely to show how the syntax works. Which tag names are valid and what each one means depends on the software reading it. XML also allows attributes which can add further information to a tag.

<tagName colorAttribute=”green”>Some text</tagName>

Tags and attributes are the main building blocks of XML and also HTML and as long as you understand the basic example above, most real world examples should be massively overcomplicated variations on that. HTML defines specific tags that mean things to web-browsers.

Storing Data as Text

The main reason for covering markup languages (apart from everyone inevitably having to deal with HTML at some point) is because they are often used to store program data on your hard drive while the program is not running. This is actually a terrible idea as there are real object notation languages which are simply better for this. For example JSON and YAML (despite the acronym YAML is, confusingly, not a markup language. In fact YAML stands for “YAML Ain't Markup Language”. This is why programmers should have their naming privileges taken away).

Knowing about text data storage is probably the one most useful thing you can take away from this whole article if you never plan to actually program anything. This is because it allows you to fix problems in the programs you use, make them do what you want, and in many cases literally cheat them. When software runs it has a whole bunch of variables telling it how to behave, and some of these it needs to remember next time you turn it on. So they have to be saved somewhere. For example if you set your browser to always open on duckduckgo.com instead of the usual start page, then close the browser, it has to write that in a file or next time you open it you will have to set it again. Usually this information is stored in plain text somewhere on your computer. If you can find this file and open it in a text editor, you can change things however you want even if the software would not normally let you do those things.

Be careful to always make a backup copy before you edit anything. This way if you break it you can just reset it back to how it was.

Some programs use their own custom system for storing text. It is common to just have a list of variable names each followed by a value, often separated by ‘=’ or ‘:’.

Other programs use markup languages like XML for storing their data, and the ones that aren’t stupid use dedicated data notation languages as mentioned. When you open such a file you need to try to recognise the format that is being used. Then you can do what you want. Some computer games even store their save files in this way so you can simply find the line that says playerCash = 37 and change it to playerCash = 99999999999.

Please note that often these files are not marked as text files. You can still open them in a text editor. Don’t use the W indows notepad though, it is the worst software ever. For W indows users I recommend getting Notepad++. Either way, you can get any random file and open it with a text editor. If it shows a random mess of unintelligible symbols it is not a text file and you can’t do anything with it. But you might be surprised by how many strange looking file types turn out to actually be text files in disguise.

So if you are having problems with some software, you can search the internet to find out where the program’s config file or settings file is stored, and then just change it to suit your needs. Don’t let programmers dictate how you use your software on your device.

Things That Don’t Look Like Programming But Are

Query Languages

Query languages are languages that are used to retrieve data from databases. Actual ly, these do look like programming but I had to mention them and this was the easiest place to put them. Query languages are not very versatile, they are a specialised tool for a single job. But this is a job that every programmer is likely to need to do at some point in their lives. If you are looking for a quick way to get a (well paid but extremely boring) job you should learn SQL, which is the most prevalent family of query languages.

Spreadsheets

Some people say that spreadsheet formulas is not a real programming language. They are wrong. Remember that mathematical definition I mentioned earlier? Well a spreadsheet from a modern spreadsheet editor with the full compliment of formulas fits it. This means if you have ever built a complex spreadsheet with a lot of formulas then congratulations, you were a programmer this whole time.

Some Games

The card game Magic the Gathering and the redstone system in Minecraft are both Turing complete. Playing these games in certain ways could be called programming and certainly many of the same skills are involved. There are many other examples but many of them involve strange hacking that the average player probably wouldn’t normally engage in. There is a game called Pokemon Yellow where you can write arbitrary programs by walking around and purchasing items in just the right way. This is accidental (a bug in the game code ) and you have to be pretty nerdy to be able to do it.

Bureaucracies and Other Human Organisations

Any sufficiently large and complex organisation is technically indistinguishable from a large piece of software. The hardware it runs on is human brains and office buildings and pieces of paper but mathematically it is the same. This means if you have experience organising large groups of people you might have some skills that are useful in programming. This one is a bit more niche however as the programming paradigm (more on them later) that this corresponds to is the concurrent actor model which is not so commonly used or taught to beginners. This model is used in the software that runs telephone systems and other special cases and does not really fit with modern computer hardware that well.

Terminals and Logs

When computers were first invented, the main way for programmers to see what was happening inside was to attach them to a printer and have the computer send text about what it was doing to be printed out. When monitors were invented the same text was simply printed to a screen instead. In addition to this keyboards enabled programmers to type in text based commands to the running software. This method of interacting with software sort of got built in on the most basic level of all software. In fact Linux specifically bases almost all software interaction on this principle under the hood, and encourages users to use text based interfaces.

These text based interfaces are called terminals, also sometimes command prompt or command line. Most languages have functions, usually called something like ‘print’, that take a string of text and send it to the terminal. There are also usually functions that read what the user types into the terminal and makes it available to the code.

Most modern software does not show the terminal to the user, but sometimes if something goes wrong sometimes it will pop up. It is usually a screen of white text on a black background (but in some cases it can be any colour), and it will be filled with random text that means nothing to you. This is a point where most users panic, thinking there is an important message in the hundreds or even thousands of lines of unintelligible nonsense that the program spits out. Sometimes there is an important message there if you know how to read it but remember, no one understands all of this. I have been programming for many years and if I see a terminal pop up from a piece of software I am using I usually understand less than 1% of what is written there. If I wrote the software in question that increases to maybe 50%.

The trick is to skim for keywords and start at the bottom working up. The only keyword you will be likely to recognise at the start is the word ERROR. If you see that, and something is clearly wrong in the software, you should be able to copy the line of text with the word error in it into your browser search bar and if you are lucky some nice person on the internet will have written about exactly what is wrong and how you can fix it. The word warning is not usually important even though it might be highlighted.

Most software saves all the text it writes to the terminal if it is not show to the user. The files that this is saved to are called log files. If you search through the files in a program you might find a file with that in the name. If you do you can use this to find out what went wrong with a piece of software that crashed or failed in some way. Maybe. The answers you need are not always going to be there and even if they are, you often have to be an expert in that exact program to recognise them. If you can find the log files though and you ask someone else for help, those are a good thing to send them.


Go to next part