Learn Programming

This section is dedicated on helping you take the first baby steps in your journey toward learning to code. You will understand why the programming languages do the things they do the way they do it.

In my opinion those are the two questions you have to be able to answer yourself to say you understand something : HOW ? and WHY ?

That said as I mentioned in the [Understanding programming] section we will firstly explore some basic concepts, before we dig into the details about the specific languages.

The program

The program is a set of data and instructions executed in specific order.

To help you understand the quote above better I will use a method borrowed from Math, namely an abstract representation of The program, so that we can make an informed deductions and conclusions about the nature of the problems programs try to solve.

This abstraction of The program is simply a very very long linearrecipe“, where linear means that there are no jumps. The instructions just follow one after the other. Turtles all the way ;). If we need to solve the same problem again and again we just repeat the instructions. Setting up this idealized system helps us to formalize the problem in such a way that we can answer any question about a program with as much certainty as possible.
The kind of questions we ask are :

When the program will end ? What follows after X ? What happen before X ? if X then What ?

Illustration …

Lets try a silly example. Lets write a recipe that starting from 1 count the next two odd numbers, then sum them, count next two even numbers, sum them … then repeat 1 million times.

The program on the left is the very long one, which is closer to the ideal Model. We can answer the questions above pretty easily, we just look at the line of interest. It has high redundancy and low complexity.

On the other hand it will be harder to prove that the second one is correct or answer the questions looking at the code. But. In practice the program on the right is preferable. It has low redundancy and average complexity.

So the goal of a programmer is to write a program with as low complexity and redundancy as possible balanced by the available resources. That is why we have loops, Functions, classes, rules, relations …. frameworks and libraries.

count 1
count 3
sum 1 + 3
count 2
count 4
sum 2 + 4
count 3
count 5
sum 3 + 5
count 4
count 6
sum 4 + 6
.....
INIT: store 0 => A register

LOOP:
  IF A == 1000000 : jump END
  copy A => N1
  copy A => N2
  N1 = N1 + 1
  N2 = N2 + 3
  count N1
  count N2
  sum N1 + N2
  A = A + 1
  jump loop

END:
  exit

You can clearly see that with this abstraction it is easy to answer those questions. Now that we established that we can reason clearly about The program, next step is to make it practical i.e. lower the redundancy, so that we can use it.
We could try to compress repeatable sequences of instructions from this model with the hope to end up with solution which is a compromise between complexity and redundancy. Which would also answer the “Why” question i.e. Why programs are structured the way they are.

The general problem as we discussed is two fold for now.
First the question is how to separate repeated code from the main recipe ?
The reason for asking this question is because we want to abstain from writing the same thing over and over again. Instead of that we want to just refer to a copy of that repeated piece of code, while storing it aside.
Second we have to decide which language we would use to express the algorithm.

The third option we don’t discus in this recipe abstraction are the program interaction with the outside world. We will leave that for another day.

The removal of redundancy in the program is achieved by using loops, Functions, Procedures, modules, classes and objects, libraries and frameworks.

Now lets talk about the specific concepts.

Values

Values are the atoms of the programming languages and are also known as Literals.
Hers is a basic list :

  • Numbers – 0,1,2 .., 0.45, 4.32, …
  • Characters – a,b,c, … z, A, B, C, … Z
  • Strings – sequence of characters
  • Booleans – true, false

Variables

A scalar variable, is a variable that holds one value at a time. 

Variables stores Values. You can think of them as a Container/Box.
When you assign a Value to a Variable the old Value is lost.
In some languages (Logic and Functional) assigning value more than once is prohibited. The second time you try to assign a value you will get an error. Those variables are called immutable variables.

Types

To illustrate types we will use an example which uses Boxes and Objects.

Let say we have 3 boxes, box A is empty, box B has 5 balls and box C has 7 cubes. In addition we have a no-mix rule i.e. we are not allowed to put different items in the same box.
Now if somebody ask you to move the items from box B and C to A i.e. simulating summation operation, your answer should be that we can’t do that because of the no-mix rule.

Balls + Cubes => A

But what if instead we are allowed to treat the ball and cubes as Objects, instead of as separate entities. Then the no-mix rule does not apply because the items from this point of view are the same.

Now we are ready to say what is what :

The boxes A,B and C are variables
Ball, Cube and Object are the Types
no-mix rule is a consequence of the the type difference i.e. operations are allowed only for equivalent types.
The same way we do not mix : Apples and Oranges, Chairs and Tuesday, green and kilogram … because they are categorically different.

A Type only tells us what are the differences between Values or Variables not how they are implemented, that is what Classes are used for.

Operations

Those are what you may expect i.e. things like summation, subtraction … etc. i.e. +,-,*,/, ^,… =, |, &, %

Expressions

In general those are the expressions you know from Math.

What we learned so far :

  • Values are the atoms of a language
  • Variables are either empty or hold Values, and have a Type
  • Type describe what you can do with Values and Variables, but not how to do it
  • Expressions allow us to transform Values and Variables according to the Type rules.

Control flow

As the name implies we will start making The program non-linear by changing the flow of execution. We need that to make writing programs writable and practical.

Conditionals

Those are the statements that fork execution based on conditions.
Normally they have a conditional block and one or more options to choose from.
Example form include :

  1. IF condition THEN action
  2. IF condition THEN action ELSE different-action
  3. IF condition1 THEN action1
    ELSE IF condition2 THEN action2
    ELSE IF condition3 THEN action3
    …..
    DEFAULT action0
  4. GIVEN condition
    CHOOSE (option1, option2, option3, ….)
    DEFAULT option0

The exact syntax differ in different languages but it is normally self evident.
The First two cases are obvious, after that the Third case allows us to have different outcomes for different conditions.
Also in the first three cases the condition has to return True or False value (boolean).
Then in the forth case there is just one condition which uses Categorical value instead of Boolean to select the wining option.
And finally Third and the Forth case in addition have a DEFAULT option to be used in case all conditions fail.

Some languages such as Prolog and the so called Production Systems are like a chain or a list of “if-then”.

Loops

Loops : repetition with condition.

me

Loops are another non-linear construct. The goal with them is to encapsulate repeatable code.
So in general we distinguish between several variants of loops :

  • Counting loops : there is an index variable that changes in every cycle
  • Condition at the beginning
  • Condition at the end

The Loops have a head or tail condition and a body. The condition is checked at every cycle and if the result is False we exit the loop.

DO
…..
loop condition
loop condition DO
…..
END
loop index FROM a TO b DO
…..
END


In contrast languages such as Prolog, Elixir/Erlang do not have loops, because their variables are immutable and we need mutable variables to track changes, on the other hand we can imitate loops by using recursion.

Functions and Procedures

Functions and Procedures are also a tool to encapsulate repeatable code, but the goal here is separation rather than repetition. Once we separate a piece of code from the imaginary-linear program then there arise a need to pass information ( via variables and values) back and forth.

We call those variables arguments or parameters.

Those parameters in most cases are localized (a copy of the variable is made) inside the function so that the original variable value stays the same i.e. we are manipulating a copy and there is no side effects. Values are always copied.

It looks so far that everything is good and dandy, but there is a complication of this arrangement. If a parameter-variable takes too much memory we do not want to pass it around because it will kill the performance and increase memory usage. So in those cases we opt to instead of copying the variable to pass a reference. This means that any change indirectly updates the original variable. But I just said we don’t want side effects !!!

The caveat is that what we are doing is necessary, we can not escape it.

So we can pass parameter by-value or by-reference (that is what they are called). In OOP languages object are passed by-reference by default. With objects updating can be controlled, so changing something unexpectedly is less of a problem.

Beside references some languages also use pointers.

A reference is a Variable that stores the name of another Variable

A pointer is a Variable that stores the memory address of another Variable

On a final note the difference between Functions and Procedures is that the former return values, the latter do not.

Recursion

Definition :
Recursion, see Recursion.

As I mentioned already loops in some programming languages are implemented by using Recursion. But what is recursion exactly ?

It is a programming technique where a function calls itself one or more times until a specified condition is met.

I will give examples when we talk about  specific language.

Data Structures

We saw already that in a variable we can store scalar value.
But solving complex tasks require complex structures.

If we use again for a moment the abstraction of the Container for Variable, we can imagine putting a simple ball inside, but we can imagine also putting a Russian doll. The ball is a simple object like a Number, but the doll is made of parts.
So a variable as we see is much more powerful concept than what we expected.

FYI, the Russian doll structure is called List-of-Lists, abbreviated LoL.

sets

A Set is a collection of well defined and distinct objects.

– math

As you expect a sets are used to store multiple unique objects. sets are useful because we can do with them the operations we know from Math, like union, intersection, difference.

Lists

Lists in comparison with sets can hold repeatable items of different types, and have an order (some languages provide Ordered sets ).
Because they keep order you can insert and delete elements. Other operations are access by the index, prepend and append element. You can imagine Lists like a chain of nodes.
Lists also can be thought as mutable Tuples.

1=>2=>3=>4=>5

Tuples

In mathematics, a tuple is a finite ordered list of elements.

In programming Tuples are immutable Lists that means all modification operations are impossible. Because of this they are faster.

Arrays

The problem with Lists is that because they are dynamic, can hold elements of different types and most importantly because the access to any element is sequential Lists are slow and take too much memory.

On the other hand Arrays have homogeneous elements, which means that the app can pre-allocate the required memory because the size of every element and the number of elements is known in advance. The consequence of that is that the address of every element can be calculated easily, so we can have direct access which is fast. Using Arrays is perfect for representing Matrices.

Array fast, Lists dynamic. Arrays good for matrices, Lists good for sequences.

156
492
703
matrix

Dictionaries/Hashes

So far we figured out how to store, retrieve and manipulate multiple Singular values stored in a single variable, but if we want to represent associations we would have to use hashes. f.e.

examplekeyvalue | lvl2-keyvalue | lvl3-keyvalue | lvl4-key
phone bookPeter Pan555-555-5555
——————–——————–——————–——————–——————–
titleJohn JohnsonCEO
Peter PetersonCFO
——————–——————–——————–——————–——————–
medical infoJohn DoeWeight180 lbs
Height178 cm
Blood pressure low90
high130

All three data examples can be represented by a hash.

  • First case is example of a single pair of key => value.
  • Second case is a bunch of key => value pairs.
  • Third case is a 3 level hash of Hashes (HoH).

You can clearly see the difference with all previous data types.

Structs

struct is a composite data type (or record) that defines a physically grouped list of variables under one name in a block of memory.
You can represent Struct by using Hashes, but there are not the same. Struct is more like a multi-varied record and is more memory efficient.

Usage

  • sets : list of unique items
  • Lists : sequences, lists, queues
  • Arrays : matrices, tensors, images
  • Hashes : kv-pairs, graphs, trees
  • Structs : records

Objects, Classes and Methods

The things we discussed so far are about data : scalar, Set, List … and behaviors : Conditionals, Loops, Functions

What would happen if we bundle them together as a single unit ? if we do that we will create an object. An object has attributes (the data), which are the object own variables and methods (the behavior) which are his own personal Functions. The difference is that methods have access internally to the object attributes and Functions are standalone and every piece of information has to be passed as parameters.

What about Class ? Class is simply the definition of what are the Object attributes and methods.

If we return back to the Box abstraction we can make the following mapping :

  • the Box is the Variable
  • the Tag on a box is the Class name
  • the Labels on a box are the Attributes
  • the Instructions manual of how to use the item in the Box are the Methods
  • the Item in the Box is the Object
  • the Tag, Labels and Instructions are the Class

We stretched this analogy alot, but here is one more. If this was a magic box, by reading the magic words i.e. Tag, Labels and Instructions a new Object will be created out of nowhere, that is the power of words 😉

  • Class is the description and implementation
  • Objects are the physical instantiation of the Class definition
  • Method is a function aware of Object variables/attributes
  • Attributes are variables belonging to a Class or an Object
    • Class variables are accessible by all the Objects instantiated from the Class
    • Object variables are accessible only to the object

inheritance

You may not believe me but there is even more ways to reduce repetition and redundancy in our programs. The way to do it is to use inheritance. A typical example to illustrate the idea is to use Animal taxonomy. F.e. let say we want to represent Terrier, Dog, Cat, Mammal and Animal. One way to do this is to create Class for every one of them.

That will of course work, but you can clearly see there are things that can be reused. A Terrier and a Dog both bark (a method), All except Animal have hair (an attribute). So it make sense to remove this redundancy and the tool to do that is to use inheritance.

Conclusions

Knowing the meaning of the Concepts we discussed so far and the Goal they try to achieve will help you decide when and where to use them.

The next step from here is to check the the [Learning] sub-menus. Good luck !