Bubble Foundry


Introduction to Programming

by Peter.

For a while now I’ve been thinking about teaching people how to program and believing that the basics aren’t that hard. Of course, I’ve been programming for a while now, so it’s not surprising I’d think so. I put my money where my mouth was, so to speak, and taught an introductory lesson at the Dev Haag January meetup. I prepared the notes you see below though I used them more as a thematic guide than an exact timeline. I’m putting it up here to share with the participants and with anyone else interested in learning to program.

What is programming? Basically it’s telling the computer to do what you want using commands that look like something between natural language and basic algebra. I think it’s fair to say you all can do basic algebra, right? Then you can program and I’m going to teach you the basics.

We’re going to learn using the programming language called Javascript. The great thing about Javascript is that it’s the language of the web – every browser has it built-in – so it’s really useful and all you need is a web browser to get started. Even better, basic programming concepts are universal so once you have a good grasps of the basics in Javascript you easily pick up other languages. Don’t believe people who say it’s hard: they’re just getting caught up in syntaxical differences and ignoring the fundamental commonalities. It’s just like with a spoken language: if you have a good grasp of the basics of grammar you’ll have an easier time picking up a foreign language than someone that doesn’t. But enough digression.

When we write longer programs we use text editors, sometimes specialized ones, to save our code and then we run it later, and many times. However, to learn and to test code a console, or REPL (read-evaluate-print loop), is the way to go. Basically it’s like the computer keeps asking you what it should do next and you keep giving it commands one step at a time.

The Console

There are lots of Javascript consoles and chances are you have several installed on your computer. If you’re using OS X like I am then you already have two, jrunscript and jsc. In Terminal.app you can load the former by typing jrunscript and the latter by entering /System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc.

But like I said, every modern web browser has a Javascript console and so that’s what we’re going to use. However, we’re not going to be doing any web programming today. We’re going to focus on the basics of programming, period, and the web browser is just a useful tool. Too often, in my opinion, people try to jump straight to web programming (and with Javascript, straight to using the jQuery library) without getting the basics right. But again, let’s not digress too much.

In Chrome I can open its Javascript console by going to View > Developer > Javascript Console. Because I do it so often I’ve memorized its keyboard shortcut: ⌥+⌘+J (Option [Alt] + Command [Apple] + J).

Variables

Did you figure out how to open your console? Great. Do you see the > character (or similar) and the cursor after it? Great, that’s our prompt, the point where the console is asking us for information. Enter your first line of code:

var a = 1

This is what I saw:

> var a = 1
undefined
>

What does that all mean? First, we have a new prompt, so the console is ready for our next command. But the var a = 1 bit? Remember when doing algebra when you had equations like 2a = 2? And then you’d solve the equation, finding that a = 1? In both cases a holds a number. We call this a variable. We simply assigned the number (specifically, it’s an integer) 1 to the variable named a.

Let’s prove it by printing out the value of a again with the following code:

console.log(a)

I think you can probably infer how to enter it but, just again, here’s what I saw:

> console.log(a)
1
undefined
>

See, the variable a holds the number 1. Of course, just because a is 1 doesn’t mean that other variables can’t be 1. Likewise, the value of a can be assigned to other variables:

var b = 1
console.log(b)
console.log(a)
 
var c = a
console.log(c)
console.log(a)

Types

Great, we can work with the number 1, but what about other types of data? Well, we talk about just that, types. Depending the programming language you use you’ll be thinking about typics frequently or very rarely, but it’s important to have a good grounding in them. There’s all sorts of crazy, academic type theory but basically all you need to know is that all data has a type. Every language will at least have the following types: numbers, strings, and booleans.

Numbers are like the number 1 we saw earlier. Some languages, especially ones often used for scientific work, have lots of different number type. Javascript, in contrast, basically just has one (it’s more complicated than that, but we don’t need to discuss that here). For example:

> typeof(1)
"number"
> typeof(1.1)
"number"
> typeof(1e1)
"number"

You’ll notice that in Javascript we can also use scientific notation for numbers. It also has some special numbers:

> typeof(Infinity)
"number"
> typeof(Math.PI)
"number"
> typeof(NaN)
"number"

NaN means ‘Not a Number’. It is returned when you tried to do something mathematically impossible (to Javascript) like Math.sin(Infinity). But we’re getting into things unique to Javascript, so let’s go back to general things about types you need to know.

Strings are what programmers call text. Like with numbers some languages have several string types but most languages, including Javascript, have one simple, standard string type that you’ll use all the time. Even better, you just need to enclose anything in double quotes to make it a string:

> typeof("hello")
"string"
> typeof("1")
"string"
> typeof("")
"string"

Did you notice how "1" is a string while 1 is a number? Javascript understands that they’re two different things. However, it is also smart enough to see what they have in common:

> 1 == "1"
true

This is called type coercion or typecasting. Because in almost every languages anything can be converted to a string, even if the string is just the thing’s original type’s name, we can make comparisions like that. We generally call languages that do this for the programmer ‘dynamically typed’ languages, as the types are dynamic and can change to whatever the language thinks is most appropriate at the time. Javascript and PHP are two examples of dynamically typed languages. Python, in contrast, is somewhere in the middle, with 1 == "1" not being equal.

Finally, you have statically typed languages, where the types are set and cannot change unless you explicitly convert them into other types. This can require more programmer effort, as the language isn’t doing some of the work for you. However, there are also benefits to this approach: the language doesn’t have to do work converting types, nor does it have to guess what a thing’s type is, so it can run quicker and even perform some optimizations. At the same time, it will throw errors if you treat one type of thing like a type it isn’t, revealing errors and assumptions lurking in your code. Just to promote one of my favorite languages, Scala gives you the best of both worlds: it has static typing but it also tries its best to infer the types you mean so you don’t have to always tell them what type you’re using.

And now let’s consider our final common type: booleans. Booleans are very simple: there’s true and false. You’ll often do tests in programming and booleans are the result: the test returns true or it returns false. At its most basic programming is entirely booleans, as processors work on the basis of transistors, which are either set to true or false.

==, as we saw above, tests if the left side is equal to the right side. If they are, it will return true, otherwise it will return false. But why not just =? In most programming languages you use a single equals sign for assignment, to assign the part on the right to the variable on the left. So, we need another sign to ask if the left and the right sides are equal. In Javascript and many other languages the == is it.

Remember 1 == "1", though? Because it does type conversion in a normal equality test, Javascript also provides you another equality test where types are not converted and the left and right sides must be exactly the same: ===. This triple equals test is common in dynamically typed languages like Javascript where types are otherwise not considered much.

Mutability and Immutability

Like typing, another fundamental concept in programming is mutability. In plain English, it’s whether something can change. If a variable can change we call it mutable and if it can’t we call it immutable. Javascript only has mutable variables. That makes sense, right? Variables can vary. So this is perfectly fine:

> var a = 1
> a = "1"

No problem! However, remembering what we’ve discussed about types above, can you think of some problems that could crop up? Now let’s say that we want to add two to it:

> a + 2
"12"

What!?! That’s not at all what we expected! It should be 3! Well, a is the string "1" and when Javascript sees you adding anything to a string it assumes that you must be combining the first string with another string. In our case that means it converted the number 2 to the string "2" and then combined the two strings.

But this seems to be a problem with dynamic typing, not mutability. Well, partially they’re related, as dynamic typing usually means that you won’t be caught by the language on changing a variable to another type. However, let’s consider another example, this time only with numbers:

> var k = 1
> k = 0
> 5 / k
Infinity

Oops, we divided by zero instead of by 1. In Javascript anything divided by 0 is infinity but in most programming languages your program will crash. Either way, this is not what we expected.

Since Javascript doesn’t have immutable variables, I’ll use the Scala language to show you how the system can help catch things for you:

scala> val k = 1
k: Int = 1
 
scala> k = 5
<console>:6: error: reassignment to val
       k = 5
         ^
scala> 5 / k
res0: Int = 5

See, Scala has immutable variables (called values, or val, here) and once I set it I can’t change it. Normally Scala would stop the program once I have that error, but here in the REPL it lets us continue and we can see that 5 / k is 5 as we expect.

As you develop more and more complex programs you’ll learn further advantages and disadvantages of both mutability and immutability. If you’re like me you’ll find immutability provides worthwhile restrictions thanks to the additional safety that is then guaranteed. However, if you’re dealing with large enough amounts of data you may find that using immutable variables involves too much copying of data so that the computer can’t keep up. Just food for thought for now.

Testing Conditions

If you want to test if something is not equals to another thing:

> 1 != 2
true
> !true
false

As you can see, the exclamation mark (or bang in programmer speak) negates. Similar to == and != we have other tests which you probably remember from your math classes: >, <, >=, <=.

But why do we care if some relationship between two things is true? Basically, to only do something in that case but not otherwise. At the most basic you can test if something is true and then, if and only if it is so, perform some action:

> var a = 1
> if (a == 1) { console.log("a is 1") }

You'll notice that "a is 1" gets printed out. Simple. But what happens if a is not 1? Well, nothing is printed out. However, we can also provide an alternative if our if statement is not true: the else statment. Consider this:

> if (a == 1) { console.log("a is 1") } else { console.log("a is not 1") }

See how we can cover all possibilities with this construction? If statements are very simple but very important and you'll end up using them a lot. But what if you want to test an additional state? Well, we can nest our statements. Here I've going to copy-and-paste a longer statement into my console:

> if (a == 1) { console.log("a is 1") }
else {
  if (a == 2) { console.log("a is 2") }
  else { console.log("a is some other number") }
}

However, you can better write it like this:

> if (a == 1) { console.log("a is 1") }
else if (a == 2) { console.log("a is 2") }
else { console.log("a is some other number") }

And now you have else if. In Javascript, as you can see, it truely is nothing else than nesting the statements. However, in some other languages you actually have a dedicated thing, often called elseif, elsif, or even elif.

And did you notice how we're testing the value of variable in each condition? Programmers often do that, so many languages have a construct called a switch statement do this:

> switch (a) {
  case 1:
    console.log("a is 1")
    break
  case 2:
    console.log("a is 2")
    break
  case 3:
    console.log("a is 3")
  default:
    console.log("a is some other number")
    break
}

Looks pretty straight forward, right? We give it the thing we're going to be testing at the top and then each case is like an if or else if. The default is like the final else. But what happens when a == 3?

Did you try it? Both "a is 3" and "a is some other number" are printed out! Why? Unlike the if and else statements where only one can be executed for the whole group, you can 'fall down' from one case to the next. As long as the intial value and the case value are equal the case statements will keep getting executed. However, we can stop this with the break command. Because I used the break command for case 1 and case 2, only own statements will get printed out when a is 1 or a is 2. Often this 'falling down' through the cases is annoying and it's hard to find that you forgot a break, but sometimes it's really powerful.

Functions

Shifting gears, what was that console.log() thing we were using earlier? Well, it's a function. Functions are basically a way to keep code together and produce a result based upon some input. Again, referring to some basic math from school, do you remember graphing equations in geometry? You probably had to graph something like 2x. Sure, at point x = 1, y = 2, just like our 2a = 2 equation earlier. However, we'd need to graph it from x = -10 to x = 10. If you're doing this by hand and didn't have a graphing calculator you'd probably just step through the the values, inputting the next value of x. This is a function. Let's express it this way: f(x) = 2x. That means for every value of x, y is twice the value.

Ok, that was a long explanation but I hope you've got the idea now. Let's write our function in the console:

function f(x) { return 2 * x }

And we can use it:

f(1)

Look familiar? We used it just like console.log(). And do you know why? console.log() is also a function.

The syntax of declaring and using, or 'calling', functions may vary a bit from language to language but the basics are the same. You take some input and you something. In our case we multiplied it by 2. Because we need to share the result of this operation outside of the function, we return it. And if we don't?

> function f2(x) { 2 * x }
undefined
> f2(1)
undefined
> f(1)
2
>

See the difference? We get undefined for function f2 because we didn't return anything. But wait, the way the console outputs things, it's almost like f2 returned undefined, you say. You're correct, in Javascript a function always returns a value, so if you don't specifically state what should be returned, undefined is returned because, well, we haven't defined the value the function returns. This is true in many programming languages, but not all.

Since a function always returns a value, even if it's undefined, that means (in Javascript) we can always assign it to a variable:

var f_result = f(1)
var f2_result = f2(1)
console.log(f_result)
console.log(f2_result)

Make sense? Of course, because you're able to store wonky things like undefined to a variable, it may not always be apparent that your code has executed correctly. We'll talk later about how to check your results but for now let's just live with that uncertainty by being careful in how we write our code.

Remember when I said that console.log() was a function? I kind of over-simplified: technically console is an object and log is its property, with its value being a function. What does that mean and how can we make that work for you?

Let's talk about people. My name is Peter and my sister's name is Justine. Let's say I want use our names in my code. I could do something simple:

var peters_name = "Peter"
var justines_name = "Justine"
console.log("We are " + peters_name + " and " + justines_name)

This works but it's not exactly efficient, is it? The variable names are longer than the names and if we wanted to have some other siblings introduce themselves, we'd have to write it again:

var peters_name = "Peter"
var justines_name = "Justine"
console.log("Hello, " + peters_name + " and " + justines_name)
var janes_name = "Jane"
var johns_name = "John"
console.log("Hello, " + janes_name + " and " + johns_name)

Let's simplify a bit:

function greet(person1, person2) {
  console.log("Hello, " + person1 + " and " + person2)
}
greet("Peter", "Justine")
greet("Jane", "John")

That's a little bit better. However, what if there is an only child? Or five children? We can simplify further with something called an array:

function greet(people) {
  for (var position = 0; position < people.length; position++) {
    console.log("Hello, " + person[position])
  }
}
greet(["Peter", "Justine"])
greet(["Joe"])
greet(["Huey", "Dewey", "Louie"])

Pretty cool, huh? But what happens if you forget the brackets?

> greet("Peter")
Hello, P
Hello, e
Hello, t
Hello, e
Hello, r
undefined
> greet(26)
undefined

Interesting, no? There are a lot of things we could discuss here, but first let's explain the basics.

Collections

Those brackets are a short-hand to say we're creating an array. Not every language has this short-hand but neither is it unique to Javascript: Python, for instance, also has it. It's so common in Javascript that we'll almost always use it.

Let's use the following array for our discussions:

var siblings = ["Peter", "Justine"]

So, we've got an array, but what is it? On one hand it represents one thing, since we can assign it to the variable siblings, but on the other hand it represents several things, as we have two different names in it. This dual nature is quite handy, and so the structure is VERY common in programming. When speaking generically about arrays and similar structures that can both be one and be many, we often call them collections.

Collections have a few (almost) universal features:

  • They have some sort of 'size' or length.
  • Their components can be read individually.
  • There is a some way to 'traverse' the collection – that is, move from component to component until you've read them all or decided to stop.

So, Javascript's array is a type of collection. It has a length, as you see by our reference to people.length. And you can access individual elements by referring to their positions in the array. But watch out! You're probably used to starting counting at 1 but programmers start counting at 0. Why, I don't know. So, if an array has two items, then it has a length of 2 and their 'positions' are 0 and 1. This is a VERY strong convention, so unless told otherwise always assume that any sort of sequence begins at 0, not 1.

Iteration

But what about traversing our array? Remember the for (...) { ... } code? This is called a for loop. A for loop basically has 2 parts: the 'circumstances' of the loop and the statement to execute each loop. It's called a loop because the statement is (or rather, can be) executed many times: it loops.

A basic for loop's 'circumstances' consist of 3 parts: the initialization expression, the condition, and the counting expression. You can probably guess what that means, but let's break it down in plain English: In a for loop you have an initial state, then, every time before you would execute the statement you check if the condition is true. If it is, then the statement is executed, otherwise the loop ends. After the statement is executed the counting expression is executed and we loop back to the condition.

Still with me? The other fundamental loop you'll find in just about every programming language is the while loop. A while loop is even simpler than a for loop, because all its first part has is the condition that must be true for it to keep looping.

We can rewrite our greet function with a while loop:

function greet2(people) {
  var position = 0
  while (position < people.length) {
    console.log("Hello, " + person[position])
    position++
  }
}

See how we still have the initialization expression, the condition that must be try to continue looping, and the counting expression? So, we can essentially consider for loops to be specialized while loops. Programmers often call such things which do something already possible in a language but in a simpler way for the programmer 'syntactic sugar', as they make the language's syntax sweeter! However, because for loops are so fundamental few people go around calling them syntactic sugar for while loops. In fact, Wikipedia suggests that it's the other way around: while loops are syntactic sugar for for loops. But feel free to claim for loops are syntactic sugar if you want to start a fun argument with a programmer!

Because loops, well, loop, they can also be dangerous. What's wrong with the following while loop? And don't execute it unless you don't mind crashing your browser!

var position = 0
while (position < 10) {
  console.log(position)
}

Did you find the problem? Because we never increase position, it will always be 0. And because it's always 0, it's always less than 10. This means the loop will continue forever!

And, don't think for loops are immune from this. The following is perfectly valid but, again, will continue forever:

var position
var c
for (var a = 0; position < 10; var c = 0) {
  console.log(a)
}

Luckily modern web browsers like Chrome try to isolate your code from the rest of the application so that if your code messed up the rest of the app is left standing. However, even there an infinite is a BAD THING(tm). In other, more permissive and/or less forgiving environments you can be in a real world of hurt.

Fheww, that took a while! However, that was necessary because loops are so fundamental to programming. But, you may have noticed that we barely made reference to collections. Mostly this is because loops don't actually need to be used with collections and because, like I said, loops are just something you need to know.

Let's do something rather crazy: let's iterate over an array without actually using any sort of loop. Here we go:

function printElements(theArray) {
  if (theArray.length > 0) {
    console.log(theArray[0])
    return printElements(theArray.slice(1))
  }
}
printElements(siblings)

Do you notice something weird? The function is calling itself! Wouldn't that be a recipe for distaster, just like the infinite loops we saw earlier? Yes, if we were missing the if condition. Because we keep calling the function with one fewer element each time (that's what theArray.slice() does, gives us a new array with all the elements starting from position 1, which, remember, is the second element!), eventually we're down to an empty array and the function isn't called again. This technique is called recursion and for some types of collections, such as trees (think family trees, though we won't discuss them), it is pretty much the only way to traverse them.

Finally, now let's briefly consider a similar but different way to loop that is kind of unique to collections:

var statement = function (item) { console.log("Hello, " + item) }
["Peter", "Justine"].forEach(statement)

Pretty cool, huh? It's quite concise and the forEach function takes responsibility for making sure our statement function gets called once for each element in the array. Why is this useful? Well, we can create our functions and pass them around, only excuting the appropriate one later:

var morning = function (item) { console.log("Good morning, " + item) }
var evening = function (item) { console.log("Good evening, " + item) }
if (new Date().getHours() > 11) {
  ["Peter", "Justine"].forEach(morning)
} else {
  ["Peter", "Justine"].forEach(evening)
}

I'm sure you can start to think of cool things you can do with this approach, but we'll leave it at that. This kind of approach, where you pass functions assigned to variables around and also where you iterate, is called functional programming. Functional programming was traditionally an esoteric (i.e. academic) thing but thanks to Javascript and other more recent languages it's becoming more popular. Javascript makes it pretty darn easy and you'll find yourself resorting to functional techniques quite often when writing Javascript for the web, as things like AJAX essentially require it.

Objects

You're now learned about arrays but let's cover another type of collection before we wrap things up: objects. Not every language has objects but they are very common and very important. What are they? Like arrays they're a collection. Unlike arrays you don't refer to their contents by their numeric positions in the collection, but instead by string keys. Remember console.log()? console is an object and log is one of its properties. A property is basically just a variable attached to a parent variable, the object. The value of our log variable is the function that prints out the input we give it.

While console.log() is common in many Javascript environment, it doesn't exist in jrunscript's envrionment (you might remember that jrunscript is a Javascript console included with OS X). However, it does have a print() function. Let's use that to create console.log() so I don't have to change any of my previous examples:

var console = {"log": print}

And there we go, we we have a working console.log() in jrunscript. Like array's square brackets, the curly brackets are a very common shorthand in Javascript for creating objects.

As you can see, the object consists of properties, or keys, and values, in this case only one of each, and written key: value. The syntax may change and the names, and functionality, maybe be slightly different, but the basic key: value logic can be found across many collections in many programming languages. Look for collections called things like hashes or maps or dictionaries (the Python name for something with the exact same curly bracket syntax). Some language make strong distinctions between objects and their properties, and dictionaries and their keys and values. Javascript doesn't.

We created our object all at once, but there are other ways:

var console = {}
console.log = print
 
var console = {}
console['log'] = print

And we have two different ways to call the function too:

console.log("test")
console['log']("test")

And remember how we used the array property length?

people.length

And some languages (PHP) talk about associative arrays... Hmm...

Well I hope you've picked up on it: in Javascript arrays are just a specialized type of objects. Handy! The fact that (just about) everything is an object means that it's easy in Javascript to extend anything with additional properties. Other languages, in contrast, are much stricter about defined properties once and, once created, an object can't add or remove properties (though perhaps they can change their values). There are pluses and minuses to both approaches.

Regardless of what you call it and how you approach it, it's really useful to be able to refer to the elements in your collection by some logical name rather than by its order in the collection. It is for this reason that you'll see people create and use lots of simple objects in Javascript, and you'll probably end up doing so too. For instance, consider this example:

var peter = {'name': "Peter", 'emotion': "happy"}
var justine = {'emotion': "sad", 'name': "Justine"}
function emotional(person) {
  console.log(person.name + ' is ', person.emotion)
}
emotional(peter)
emotional(justine)

See the benefit of using an object here instead of an array? I didn't need to worry about enforcing a common order or remembering it. Now let's add another propety to our objects and use it:

var peter = {'name': "Peter", 'emotion': "happy"}
var justine = {'emotion': "sad", 'name': "Justine"}
var sayHello = function() {
  console.log(this.name + " says hello.")
}
peter.sayHello = sayHello;
justine.sayHello = sayHello;
peter.sayHello()
justine.sayHello()

That's pretty straight forward, right? Except you'll notice that sayHello() doesn't take any input but instead seems to get this.name... magically? In most languages with objects, and Javascript is no exception, when you're 'inside' an object 'at' a property you can access the object, and thus its other properties, via the special this object which is automatically created for you. So, this.name inside the peter object is the same as peter.name but inside the justine object it's equal to justine.name. I'll add that there are was to monkey with what the this object represents but for now we'll leave it at that.

Even with all the things that objects can do, there's still a role for arrays. Consider this simple example:

var people = [{'name': "Peter", 'emotion': "happy"}, {'emotion': "sad", 'name': "Justine"}]
function emotional(person) {
  console.log(person.name + ' is ', person.emotion)
}
people.forEach(emotional)

And there you have it, you know the basics of programming! Through the composition of a few fundamental pieces: variables, conditions, functions, loops, and collections you can assemble code that does just about anything. Even better, as people share code and find good common metaphors, your productivity and knowledge increases more and more, to the point that what took you an hour to get through here will take you just a few minutes in the future.