Programming as an Art

It’s easy when solving a problem to become irritated and just push out a clumsy solution. In doing this we completely forget about the art of programming! While every now and then, there are problems that can just have a solution pushed out, generally its better to spend some time in how you solve the problem as well as how you implement the solution.

This is the first blog post in a series of blog posts that will cover problem solving as an art. This first post is going to cover the basics of problem solving as well as some of the different steps involved. Later on we will cover the individual steps in greater detail.

Step 1 Defining the problem

The first thing that must be done is defining the problem. We’ll start off with a simple problem that I enjoy as an example problem: How do you decide if a number is even or odd? Of course most programmers know how to solve this problem, which makes it a prime first example.

Our original way of stating the problem seems to be fine (that is: How do you decide if a number is even or odd?) Although this seems like a fine way to put the question, it is not specific enough. We don’t mention any constraints, as well as we don’t mention any specifics. So, lets redefine our question mentioning the language we want to solve this problem in, and a engineering constraint.

How do you decide if a number is even or odd efficiently in C? While this looks quite similar, it is much more clear. We state our final goal (finding out if a number is even or odd), our secondary focus (efficiency), and what language we will be solving this problem in (C).

Step 2 Defining possible solutions

Now that we have a problem, we must create a solution to this problem. Depending on the type of problem, there are several ways to solve it. This problem happens to be one that humans can accomplish. We have the ability to tell if a number is even or odd. This gives us a head start. We should ask our selves: How do I tell if a number is even or odd?

There are several ways we determine if a number is even or odd. If the number ends in 0, 2, 4, 6, or 8 the number is even, if not the number is odd. Another way to tell is if the number is divisible by 2.

Step 3 Writing out possible solutions

Now we need to write out possible solutions for our problem. In a simple problem like this, it will usually entail writing out the actual problems in language . In more complex problems, you might need to write out pseudo solutions first.

// Solution number 1

_Bool IsEven (int i) {
int x = i % 10;
if (x == 2 || x == 4 || x == 6 || x == 8 || x == 0)
return 1;
else
return 0;
}

// Solution number 2

_Bool IsEven(int i) {
if (i % 2 == 0)
return 1;
else
return 0;
}

Step 4 Deciding which solution to use

The first thing that we check is which one is cheaper; which one is more efficient? There are many machine specific ways to determine this, however, in this example it is clear that solution two is cheaper. Although we used the same amount of modulo, we used much less logical operators in that solution.

So, we have decided that checking if a number is divisible by 2 is the best method of determining if a number is even or odd. Now we’re going to make it more efficient.

Step 5 Optimizing your solution

Often times programmers who use compilers will make excuses when writing their code that there is no need for them to optimize their code, as the compiler will do this for them. That is true to a degree; which is the danger of that statement. Seeing as you are likely to use more than one compiler/optimizer, and seeing as you probably didn’t write the optimizer yourself, you probably don’t know enough about the particular optimizer to presume what it will and won’t optimize. Because of this, code that will be frequently ran, or expensive code, should be optimized by you, not just the compiler.

So, what are some ways we can optimize our solution? If we look at our code, we have 2 conditional statements (if and else) and 1 conditional operator (==). None of those are actually required.

What is the result of modulo? Given the arguments x % y, the outcome has a range of 0 to y – 1 presuming y < x. What this means is that the result of our use of modulo (the result of i % 2) will be either 0 or 1. If the result is 0, we can return 1 (remember, in C true =1), and if the result is 1, we can return 0 (false =0). Notice, we are just returning the opposite boolean value that we gain from the modulo. Instead of using if and else to return the opposite value, we can just not (!) the value returned by i % 2, which is several cycles cheaper.

// Improved solution

_Bool IsEven (int i) {
return !(i % 2);
}

We have shortened our algorithm by quite a bit! The optimization isn't done though. On a large amount of machine architects, the way modulo is achieved is by completing either division, or a form of division. Division is an extremely slow operation (about 40-90X slower than addition). So, what can we do? It just so happens that we are programming a computer. We're programming a machine that thinks in binary. It just so happens that if the first digit of a binary number is one, the number is odd, and if not, it is even! With this knowledge we can make our program tremendously faster!

// Improved^2 solution

_Bool IsEven (int i) {
return !(i & 1);
}

By replacing modulo with a logical &, we have increased the speed of our algorithm by a landslide! However, there is still another optimization we can complete. Currently, we have two operations to determine if a number is even or odd. A not, and an and. Both of these operations are extremely fast, however, the not operation isn't needed if we change our program slightly.

// Improved^3 solution

#define IsOdd(i) (i & 1)

This algorithm is now in its most optimized form. By changing the function name from IsEven to IsOdd, we no longer need to not the result of the and, this increases speed by a large amount. Also since this is such a small algorithm, we don't need to have it be a function, so we turn it into a macro and remove the expense of a function call.

Step 6 Documenting the solution

So, now we have our solution! It's smaller, more elegant, and beautiful than our original solution, however, it can still be made more elegant and beautiful, simply by the power of comments.

// ******IsOdd******
// The IsOdd macro does exactly what it sounds like it'd do, it tells if is odd.
// We test to see if the first bit is one or zero, if the first bit is one, then is clearly odd,
// if not, it’s even.
#define IsOdd(i) (i & 1)

Any time you’ve optimized a function, or have written a complex function, it’s a good idea to go ahead and write comments explaining what the algorithm does, and how it works.

So, what are the steps to problem solving?

Define the problem
Define potential solutions
Write out potential solutions
Decide on the solution you want to use
Optimize solution
Document solution

It’s easy to spend too little, or even too much time on any one of these tasks, and in doing so, a bit of the art in programming is taken away. Sometimes it’s important to go back to the basics and remember what we love about programming; sometimes it’s important to remember that programming is an art form; a form of expression as much as a science.

Advertisements
Posted in Abstract, Programming | 2 Comments

Operating System Developers: My computer is not a browser

There seems to be a number of operating systems lately that are attempting to test the bounds of internet browsers by having a browser be the OS itself. Many of the companies behind these operating systems claim that the internet is the future, and that personal computers of the future will be merged with the internet. There are many users that believe this is a good thing, and an innovative idea. I’m not one of them.

The internet is a series of houses that aren’t yours. As fun and as informative as visiting these houses are, they aren’t yours. The books contained within these ‘houses’ aren’t yours, the devices contained within these ‘houses’ aren’t yours, and you don’t have absolute control of these ‘houses’.

What these developers believe is that you should exist as a metaphorical hobo, always being in the town, and never having a ‘home’ where everything is yours. What they forget, is that the owning of a home does not imply that you have an inability to visit other houses. It implies that you don’t want to visit other houses all the time. It implies that you want things that are yours; you want information that is yours; you want control of your environment, and you want the freedom to do what you want when you want to do it.

Of course there are other arguments for a browser based OS. Some of which are “but there aren’t as many components needed in a computer that is a giant browser, so the computers of these operating systems are much cheaper in result!”. Batteries, capacitors, LEDs, and wire is cheap also, however, I am not going to replace my computer with a blinking light. At a certain point you must ask yourself, does the cheap price justify the lack of features?

So, abstractions aside, should operating systems become more integrated with the internet? Definitely, there are many ways that most operating systems could benefit from being more heavily integrated with the internet right out of the box. Things like ‘App Stores’, Entertainment Media Centers/Stores, Online Storage, Internet Setup, and even default web browsers could definitely be improved with better integration. There are lots of improvements and innovations to be made in better integrating operating systems with the internet, however, removing the majority of the operating system is not one of them.

Posted in Technology | 1 Comment

Learning Programming Languages Faster

I have known many people that are experts in linguistics that get dumbfounded by programming. Apon first consideration this makes no sense – until you come to the conclusion that its not the language that they’re having trouble with. In reality its the programming that they’re having trouble with and the language is just heavily associated with the act of programming itself. When you look at most people, when they try to learn programming, its all about memorization. They try to memorize the dos and don’ts, the key words, common syntaxes etc. The problem is, during all of this memorization, they forget to learn to program.

I was watching a college lecture that had been put on the internet that was focused on learning your first programming language. The professor appeared to be great, he taught the students how to create variables, about logical statements, functions, mathematical operators and the like, and then came their first problem: “Okay, so how would you tell if a number is even or odd?”. The class went silent as nobody had an answer to this simple problem. The professor then proceeded to explain that by dividing a number by two, if there is a remainder, it is an odd number. The reason they didn’t know how to solve this problem wasn’t because they didn’t know how to memorize a language – that’s simple – the reason why they didn’t know how to solve this problem is because they didn’t know how to program.

As I have stated previously, programming isn’t the simple act of typing. It is engineering. It is problem solving in a way that is (or better put, appears) abstract. When talking to new programmers, they often times make an emphasis on how many languages the learn. “I know 3 languages”, or “I know 11 languages”, they’re missing the point clearly. It’s not the learning languages that is important, its the learning how to program. Its learning how to problem solve. When you watch a new programmer learn to program, they’ll think in terms of “What feature would I use to solve this problem”, if you watch someone who is more experienced they tend to think in terms of “How would I solve this problem” and then “How would I implement that in this language” or “What tool will I use to implement my solution?”.

So, how can you learn programming/programming languages faster? Separate your learning into two categories, programming, and programming language. One thing you’ll notice about programming language books, is they all teach essentially the same thing. “This is how you use arrays. This is what arrays are.” or “These are the basic operators. Here is how you use them”. Once you’ve learned that, you don’t need to learn it again. Once you understand a programming methodology/ideology, you just have to learn syntaxes and key words.

You don’t even have to memorize key words/syntax, you just have to use the language, and stumble through your nonlogical errors until you can use the language comfortably.

One thing to be weary of is learning to program and then only advancing your skill in programming languages. Often times programmers will go on with a basic understanding, solving problems such as “How do you tell if a number is even or odd” with clumsy solutions such as (x % 2). They don’t even bother to learn enough about computers/software to come to the conclusion that (most) computers are digital machines, all you have to do is check the first bit to see if it is one or zero to figure out if its an even or odd number (x & 1).

My point in all of this is, as programmers we constantly have to learn new languages, and this task shouldn’t be a challenge to us. We should not program worse in a new language. Instead we should have a firm understanding of the concepts behind computers, behind programming, behind engineering, and we should be able to transfer these concepts with little effort. The secret to becoming a better programmer isn’t in learning the most languages, its learning to program the best.

Posted in Programming | 69 Comments

Email Without Spam

The largest problem with Email (in my opinion) is the amount of spam you will inevitably receive. Fraud is quite possible with current Email, and it can in general be somewhat dangerous for the novice user. So, how do we fix this?

There are two measures that need to be taken to fix this in my opinion. The first measure is user verification. When two users converse for the first time, the server which the email is being sent to would have the option of sending a Security Form. The Security Form could be of any size/complexity the user wanted, and would contain a small form that could contain images if necessary. This form could ask math questions, request image-text verification, ask the user to identify the point of a small story, basically any form of human verification. The user would then fill out this form on their client and send it to the other user. This form would either be correct or incorrect, if it is incorrect it sends out an error message to the sender, if it is correct though it sends a ‘all signals go’ message to the other client, and then it stores the address (DNS/Account or IP/Account) of the sender in a whitelist. After one of the users has been verified in the conversation, both users may talk to each-other without filling out another form.

The Second measure is email to email verification. When someone sends an email to another email-user, the sender would first send a security header. The header would contain the address (DNS/Account or IP/Account) of the sender, and a 16 byte identifier (that would be random). On the senders email server, it would store the 16 byte identifier being used to send the email, and correlate it with the address of the user who the email is being sent to. Then the server that the email is being sent to would then send a header back to the original email server which would then check its outgoing email lists to see if there is a 16 byte identifier that correlates to the address of which the header was sent, if there is one, then it sends the contents of the respective message. If there isn’t one, then it informs the sender of the form.

This makes it essentially impossible for a spammer to spam you. If a spammer completes your human verification form manually, then only he can spam you, he can’t give the information to other spammers since only his address is in the white-list and email to email verification prevents a spammer pretending to be another spammer. Also, at that point it would be very easy to block the person, you just put their address on a block-list and remove their address from the whitelist. If someone tries to send a fraudulent header, that won’t work either, as the email to email verification checks to make sure the sender is actually the sender, and it won’t receive the message unless it actually is the sender.

I am not an expert in this area, and I am sure there are ways this design could be improved, however, this shows just one of the things that could be done to improve email.

Posted in Uncategorized | 1 Comment

Originality

Original:
1 used or produced at the creation or earliest stage of something : costumes made from the original designs | the plasterwork is probably original.
• [ attrib. ] present or existing at the beginning of a series or process; first : the original owner of the house.
2 created directly and personally by a particular artist; not a copy or imitation : original Rembrandts | playing original material.
3 not dependent on other people’s ideas; inventive and unusual : a subtle and original thinker. See note at creative .

Originality in a mathematical sense is hard to define. It’s not inequality, it’s not incongruence. It is being unique.

Unique:
being the only one of its kind; unlike anything else : the situation was unique in modern politics | original and unique designs.
• particularly remarkable, special, or unusual : a unique opportunity to see the spectacular Bolshoi Ballet.
[ predic. ] ( unique to) belonging or connected to (one particular person, group, or place) : a style of architecture that is unique to Portugal.

In a sense though, uniqueness is being unequal or incongruent, which seems to make my previous statement oxymoronic. However, uniqueness isn’t just being unequal or incongruent, it’s being so in a context dependent manner. Example, if we were judging the uniqueness of colors in birds, a red colored Black Bird may be unique under the context of Black Birds, but it wouldn’t be unique under the context of all birds.

I’m sure we have all heard a statement such as “Nothing is truly original”. I will attempt to disprove this.

The general reason some people arrive at the conclusion that nothing is truly original is not due to a logical fallacy, but an incorrect definition of original. Example:

Proof 1: Carbon is an element, and there are multiple elements, thus Carbon is unoriginal. Carbon is an element, and no other element is like it, thus Carbon is original.

Both of these statements are true, carbon is an element, and no other element is like carbon. However, the conclusion of such statements is contradictory, thus, one of these statements is using the principle of originality incorrectly, or, one of these statements is incorrect. Since both statements are correct, one of them must be using the idea of originality incorrectly.

In the first statement, we define carbon as being unoriginal because it is an element, and not the only element. In the second statement we define it as original because nothing else in it’s category is like it. So, which is correct? I would argue that the first definition is incorrect. There is even a simple proof to prove that it’s incorrect. Before I cover this proof, I would like to explain object oriented logic/objects/statements a little bit for those who are unfamiliar with it. If you are familiar with such principles though, feel free to skip over this part.

Object oriented logic is essentially categorical logic in which we can make a statement such as:

All mortals die eventually. People are mortal, therefor they will die eventually.

Object oriented objects state there are ‘nodes’. Each node contains various variables and operations which can be done to this node. Each node can have child nodes, where the child has all of the attributes (variables and functions/methods [operations which can be done to said node]) of the parent, although it can also have it’s own variables and functions/methods. This is called ‘inheritance’. You can then use object oriented objects as variables. An example:

Lets define an object “plant” with no parent. This object has the variables “size” and “growthRate”, as well as the function “grow”. Grow causes the operation size = size + growthRate. Lets define another object “tree” which is a child of “plant”. This object has the variable “fruitType”. We could then create some sort of variable such as

tree appleTree

appleTree.size = 500
appleTree.growthRate = 3
appleTree.fruitType = apple

Also, from the categorical logic sense of object oriented objects, we know that since tree’s parent is plant, a variable that is a tree is also a plant. Therefor, appleTree is a plant.

Getting back on topic, lets see that proof I was talking about.

Proof 2: there is an object B. B is the parent of object C, C is the parent of object D. Object B has the variable “1”, object C has the variable “2” and by inheritance “1”. Object D has the variable “3” and by inheritance the variables “1” and “2”. There is a fourth object Z which has no parent. It has the variables “1” and “2” and “3”. For this proof we will presume that all variables are actually constants that equal 1337. Now, we have an object Z and we have an object D which have the same variables (1, 2, and 3), of the same type (constant), that are equal to the same value (1337), however, by the definition that originality is based upon the parents of the objects, these two objects are fully original. Clearly they aren’t original though, thus we have proven that the first definition is bogus.

So, lets now assume that the second use of originality is correct, however, lets further define it to make it more clear. First, to find out if something is original there must be a context. This context will act like a searching parameter. The context will represent a parent context, in which we search for matching values/variables/patterns in all child objects. If none match, then the object is original. If a context isn’t defined or implied, then the originality of the unknown context is defined as being the originality of the most significant context for that object.

With this understanding we will use this paper to prove that there are in-fact things that are original.

The most significant context for this paper would be papers (of course I mean paper as in thesis’s or essays, not as in thin sheets of pulp). There is no paper with the exact same characters, format, and patterns as this paper, covering the same theories, proofs, and proving the proofs in the same way as this one. Thus this is an original paper, and thus some things are truly original.

Posted in Arguments | 1 Comment

The problem with learning and college.

Learning is an unavoidable experience that while being perceived as controllable, quite often isn’t. This by itself I don’t consider a problem, the problem emits from the perceived abilities of those who are learning.

There was a study done in the 1980’s by Hubert and Stuart Dreyfus on a Construct Theory called the Dreyfus Model. The Dreyfus Model suggests that there are 5 stages that a person goes through in the process of learning. Novice, Advanced Beginner, Competent, Proficient, and Expert. Most people will agree it takes a minimum of 10,000 hours of work to advance from novice to expert. The problem comes from people that are in-between advanced beginner and competent.

When someone is in-between advanced beginner and competent, they have just enough knowledge to be dangerous, and yet not enough knowledge/experience to really do any complex problem solving. The problem is, a certain percent of these people see their improvements and think they are experts. Of course the problem with thinking your an expert is, you probably aren’t. An expert doesn’t think to them selves how amazing they are, and how they are an expert, they just are an expert. What’s even worse is most of these people also realize that the majority of society aren’t experts, and will behave in accordance to the delusion that they are superior.

In reality, they aren’t an expert, they are just an advanced beginner behaving like everyone other than them are beginners. This just pisses people off.

The most common place to observe people like this is college. In college, students gain a large amount (or at least, reasonable amount) of knowledge in a fairly short amount of time. Often times not having any experience in their field before college. On top of that, they will usually be 17-20 upon entrance, which is when they are naturally arrogant. Even more than that, they are in a class room full of other novices or advanced beginners. This just makes it easier to assume they are the experts, and the people around them are the ‘noobs’, when in reality they are all ‘noobs’.

There’s yet another problem with the advanced beginner/novice though. That is, they can’t know what they don’t know. An obvious statement, however, a statement that they don’t seem to understand. Often times, someone who is fairly new in a field will try to shoot down an idea that they think they understand, but don’t. Why don’t they understand? Because they don’t have the experience/knowledge to understand it. It’d be unreasonable to expect them to understand it, but often times they will expect themselves to understand it.

So, how do you fix this? Easy, force all of the students to work on a *reasonably* complex online open source project (or if it is a field where there aren’t open source projects, make it some sort of community research project). What happens in an environment like this, is there is always a decent number of experts/people who are proficient that the student will be in close contact with and will be forced to work with. Working with an expert is a very humbling task, and it makes it nearly impossible for a student to presume they are experts when they aren’t.

How is this applicable to us developers as a whole? As I said in my blog post The Violin Effect, the software industry is constantly expanding, and as a result, we are forced to learn a vast amount of new technologies, ideologies, and methodologies, as well as a large amount of us developers are in college. It is very easy for us to presume while learning something new that we are experts in an area that we aren’t.

Do your fellow developers a favor, and ask your self before you act, are you really an expert in this area? Are you shooting down an idea you don’t fully grasp? Does the person you’re talking to understand this subject more than you? Do us all a favor and ask yourself these questions before acting as though you are an expert that fully grasps the subject at hand and is better at this subject than anyone else participating in the current project.

(On a side note, I have been busy lately, however, I will write on my language design series when I get a chance.)

Posted in Uncategorized | 3 Comments

The Violin Effect

It seems that often times new programmers and old programmers have a tendency to over-evaluate themselves. They will believe they can do something faster/better than they can, or they might look back at some old code they wrote, and think to themselves “Gee… I used to suck back then, my code is tons better now though”. I call this the violin effect. When someone plays the violin, since they rest their chin on the sound box, often times it effects what they actually hear. Even if they play scratchy and out of key, often times they will presume that they played beautifully, because that’s what they heard. Programmers do the same thing. We have a tendency to normalize our current skill level, to a previous skill level, and then notice how good we are comparatively.

I often see a programmer commenting “I used to write code like that, now I’m better though.” then a two years later they will make a comment “I looked at some code two years back that I wrote… I really sucked back then… It’s a good thing I’m writing good code now” and they will continue making comments about how their old code wasn’t that good, and their new code is much better. In reality, their new code isn’t any better. Its just that they are currently working on it, and they understand it. Later on when they don’t share the mindset of their old code, they realize how much their code sucks.

A lot of this is caused by programmers not planning their code in advance. Instead they write it as they go. As they’re writing out their ideas, they understand what they are trying to do. Once they stop, they don’t see any internal structure, and suddenly their code looks terrible. Planning is an important part of any project, and it is also often overlooked.

Another reason for this is, technology and methodology in the computer industry are advancing faster than virtually any other industry. This is a good thing in my opinion, however, often times programmers assume they are getting better, when in reality, the technology/methodology around them is getting better, and their actual skill level is still about the same.

A recent poll showed 90% of of people working in an intellectual field believe they are above average in their field. Surely, some of them are above average, however, a large amount of them aren’t. We have a natural tendency to assume that we are better than most people, and in some cases we are. The danger occurs when we become biased, basing our assumed skill level not on evidence, but on our own opinion.

I’d argue, you should always try to realize what sucks in your code and try to get better in that area. The moment you’ve stopped realizing what sucks in your code, you’ve stopped improving. However, don’t try to compliment your code by concentrating on the bad things in your old code, and the good things in your current code. In both new and old code, try to notice the bad things and fix them, and also try to notice the good things and reinforce them. If you are unable to balance both tasks, you will just be another one of the 90% who believe they are above average.

Posted in Abstract | 2 Comments

Programming will never be “easy”

There seems to be this idea going around the internet that the reason someone isn’t able to program, is because languages aren’t good enough yet. A couple of people I have seen with have gone so far as to insinuate that the reason programming is to hard for most people, is because we design our languages to be too hard, just to keep people away from programming, and to secure our jobs. In reality, programmers are not trying to make their jobs harder, they are constantly trying to make their jobs easier. The truth of the matter is, programming is just hard.

Some people argue our current languages are too cryptic, other people argue that we need to abandon text-based languages all together, and just use GUI languages. What people don’t realize, is if GUI languages were actually easier, everyone would understand electrical engineering. Most people don’t understand electrical engineering, not because they don’t understand how to connect wires, but because they don’t understand the logic, math, and general engineering behind it.

As for the argument that programming languages are too cryptic, this is just a misunderstanding of what people really want. What people really want, is magic. So is an easy programming language impossible? No. Programming languages have plenty of room to get easier, and to evolve, however the act of programming itself, will never truly be easy, unless you are doing the most basic of tasks.

So just for amusement, what would the easiest programming language look like? Lets say we want to create a window with a table view that adds entries when someone clicks a button. What people would like, is to have a language that would understand some message such as

“Create a window with a table view, and then when someone clicks a button, add an entry to the table view”

While in theory its fully possible to parse a fully human-language, and then generate intermediate code based off of that, in reality, we don’t have that type of technology quite yet, as well as there isn’t near enough information given. What style of window? Initial position? Color? What about the table view? What type of data are the entries storing? How does the user interact directly with the table-view? What about menu items?

Also, what happens if we create two windows? How do we address first one, then address the second one? Well, we have to have some sort of variable naming convention, such as “Create a window named window1” wait, that’s going to be a challenge for the parser to interpret, are we naming the window window1, or are we setting a variable called window1? Lets redefine our variable definition syntax. “Create a window with title ‘Window 1’ and variable name wnd1”. Rather wordy, and already this language is getting complex.

What if we need to do something complex on an engineering level, such as create a scheduler? We can’t just go “Create a scheduler”, we have to figure out how its going to tie in the system, and fully understand the outcome of the code we write, as well as the internal code. So we’d have to describe every variable creation, and every action, to extreme details. It’d be easier to do it in a standard programming language, quite arguably.

All of this is not to say trying to advance programming languages is a bad idea, I’m just trying to explain, no matter how easy the programming language is, if you don’t understand the logic behind the code, you won’t be able to write it in any language.

Posted in Arguments | 117 Comments