jack: (Default)
[personal profile] jack
Most people would understand code like:
int main() {
  int square_size = 12;

  int square_area = square_size * square_size;
  cout << "The area of the square is: " << square_area;
}

Even if you've not done any programming in your life, you should get the general idea.

Q. Help! I don't understand even that much?

A. That is, we calculate the area by multiplying together the square's width and height (both 12), and then display the result to the screen, looking something like:

The area of the rectangle is: 144


What is immediately obvious to a programmer, SO obvious that it's often left out of even the most basic tutorials, is that if you ACTUALLY want to calculate the area of a square, a calculator is just as good as this program, but why this program is valuable, is if you later want to calculate, say, the area of lots of squares, or the area of a square where the size is typed in by a user later, or use the area of the square in a longer calculation, it's very easy to alter this function to do so.

A professional programmer looking at this toy example can see at a glance that the original size could just as easily be a parameter of the function as a constant without changing the following code, and sees them as almost synonymous, even though there's nothing on the screen to say so explicitly.

It sounds obvious in this example, but the point is that a professional programmer might understand very much more complicated likely future changes to the code, and subconsciously write code in such a manner that those will be as facilitated as possible. He/she's seeing an invisible pile of "possible code" hanging behind the actual code.

OK, now what if we have several squares? Even a non-programmer could probably produce the following:
int main() {
  int square1_size = 12;
  int square2_size = 7;
  int square3_size = 11;

  int square1_area = square1_size * square1_size;
  int square2_area = square2_size * square2_size;
  int square3_area = square3_size * square3_size;

  cout << "The area of the square #1 is: " << square_area;
  cout << "The area of the square #2 is: " << square_area;
  cout << "The area of the square #3 is: " << square_area;
}

But it would be better to produce something like:
int main() {
  int square_sizes[4] = {12, 7, 11, 9}

  int squares_area[4] = {
    squares_size[0] * squares_size[0],
    squares_size[1] * squares_size[1],
    squares_size[2] * squares_size[2]
    squares_size[3] * squares_size[3]
  }

  cout << "The area of the square #1 is: " << squares_size[0];
  cout << "The area of the square #2 is: " << squares_size[1];
  cout << "The area of the square #3 is: " << squares_size[2];
  cout << "The area of the square #4 is: " << squares_size[3];
}

And at that point you realise that you're able to write:
int main() {
  int square_sizes[4] = {12, 7, 11, 9}

  int squares_area[4];
  for (int i=0;i<4;++i) {
    squares_area[i] = squares_size[i] * squares_size[i],
  }

  for (i=0;i<4;++i) {
    cout << "The area of the square #" << (i+1) << " is: " << squares_area[0];
  }
}

Now, hypothetical beginner, what's going on? I'm sure you can see what the code does, but why, in this simple example, is it better?

Most programmers use arrays (or equivalent data structures) so instinctively it's literally hard to remember what the pros and cons are (I'm going to leave out half of them). But the advantages of the change are things like:

* If you later add a fifth square, you only have to change the number 4 to 5 (or to 319) you don't have to add one more (or 315 more) lines of code.
* The text "The area of..." is only written in one place, so if you have to change it, you don't have to make the change multiple times, and MUCH MORE IMPORTANT, you won't FORGET half way through changing it and leave half of them changed and half of them unchanged. (This is ugly when you're changing text, but if you're changing code will probably make it "not work")
* It would be easy to change the code to accept an array from some other part of the program, even if you don't know when you write the code how many squares you may need to calculate.
In fact even in this simple example, you should make a couple more changes. For instance, the number "4" appears in four places (and also implicitly that you put four sizes into the initialization), and to follow the advice I just gave, you should make sure that they all take their value from just one place.

If you're an arrogant proto-programmer, you may think "it's ok, I'll remember what I need to change." But believe me, you won't. There's plenty of more complicated stuff you need to remember, don't make yourself remember anything you don't have to. (It may be true in a throw-away program. What's not obvious to people who have just learned to write code is that the bigger the code base, the greater the proportion of the time is spent reading the code, so making it clear to read without working it out from scratch all over again is incredibly necessary.)

In fact, if you ever find yourself writing some code and think "hang on a minute, I'm writing this line of code almost identically twice or more", ask yourself "if I change one of these, will the other likely have to change as well?" and if so, "is there any way I can reuse the first instance (for instance, by putting a calculation into a function, or putting a value into a variable, or doing something more complicated)"

(If you CAN'T you'll just have to live with it, unless you start using a more advanced programming language. But if may be useful to (a) put all the similar lines next to each other so you can see at a glance if one of them gets out of sync or (b) put a comment to the effect that "if this needs to change, remember to change the other value". Or even "this is a copy of the function in blah file or blah textbook, so if you're trying to understand this, you may want to read that first.")

(If you're Liv, you can IM me ask me instead if you like :))

Now, the array wasn't very interesting. But tomorrow I will teach you about rectangles, and about "struct", which is where my philosophical comments will have some bite.