The thing I get asked the most by parents and people trying to figure out how to get into the tech world is where to start. While a knowledge of at least some hardware is important, this post will be more focused on the structure of programming languages and why it is better to know one over another. This really boils down to the common modern day argument over C++ vs JavaScript vs Python.
Before we really get into this, let us first have a look at some things that people tend to forget about coding. Some of this may sound silly, but people do over look this stuff all the time and it is a big deal.
Software, Programs, and Apps run on hardware.
Yes, the cloud is just another computer networked to your computer, smart watch, and smartphone. Surprisingly I have talked to many seasoned programmers that forget this point and it is only a matter of time before hardware smacks them in the face as a reminder. This is one of the primary reasons that I push hardware education so much and tend to leave software dev to the many, oh so many, people already doing it. Your killer App is nothing without the powerful piece of tech that it actually runs on and we need a new generation of people who know how to make it better.
Code languages are built on layers.
When all is said and done, all computers and programmable tech are binary and that is, more or less, the base or lowest level of code that runs on everything. All of the other languages that exist run on top of binary and that is why it is considered a low level language. Now seasoned hardware devs will argue how many levels there are and technically binary is not the lowest level, but I am going to just stick with the major language jumps for this post.
After binary we get to a language that most low level hardware developers should know witch is Assembly Language. This is much more readable for humans, but still a very complex language to learn. It sits deep down in all of the CPUs and microcontrollers that lay the foundation for the stuff that we want to do on our devices. While I do encourage people to learn Assembly, that comes much later in life and we don’t need everyone to know it. I don’t know Assembly, it is kinda where I draw the line of how low I am willing to go. Awareness of the existence and importance of Assembly is something I think is important however. You will see a pattern in this logic soon.
C and C++
This is one of the most common languages for programmers. It has proven so useful that most languages, on a similar level, are largely modeled on it’s syntax. Most use C++ and as a result many libraries exist to make easy work of most complex tasks. This is considered a hardware programming language and while powerful, there is a lot of stuff to learn and typically many ways to do the same thing. When loaded onto hardware, C++ is typically compiled to Assembly so this puts it, more or less, one step away from the lowest level of code. Being so close to binary can make C++ difficult for us to understand, but it also means that you can wright very streamlined and solid code if you know what you are doing. People who want to squeeze the most out of small and inexpensive tech use C++ to do it.
C++ is the language that I recommend most people start with. It can be difficult at first, but once you get familiar with it, just about any other language will share the same structure and syntax. It just makes it easier to learn other things like Java, JavaScript, or whatever. Also, C++ is typically the first to get a stable library for new peripherals and protocols. It is my primary go to for code, but I am also focused on micro computing and hardware code.
JAVA and JavaScript
These languages share a lot in common with C++ in that they are low level code. JAVA took most of its structure and syntax from C++ but it compiles to Bytecode rather than to Assembly. JAVA and C++ are more or less on the same level as far as architecture is concerned. The big difference between the two is that JAVA was created to allow easier creation of software for computers and not originally intended for use on stand alone hardware. In other words, you would use JAVA to create an operating system for a cell phone, but not to make code for a TV remote.
JAVA is another very good base language to learn, but most people go for JavaScript. It is important to know that JavaScript runs on top of JAVA so it is one more layer of code to be compiled. Both JAVA and JavaScript run on a driver that needs to be installed and updated on your computer. Unlike C++, which has become the standard base computer language, JAVA only needs to be installed to support JAVA and JavaScript applications. It is now installed by default onto computers, but you still need special support to run it on microcontrollers. For this reason most hardware developers just stick to C++ to compile down to Assembly.
What is all this about Compilers?
This is a good time to talk a little about what a compiler is and why they are important. Now compilers are a very complex thing and one that is critical to how all of our tech is created and works. I will be using very simplistic term to give an overview of why this stuff is important to at least know about.
The easiest way to think of a compiler is like a translator. We take one programming language and translate it into another, but in the case of a compiler, you are typically moving from an easy to understand language down to one that is more complex and harder to understand. The biggest difference between our languages and the levels of code languages is that higher level code is made up of a few, or many, assembled bits of the lower code. Because of this you will never really run into the types of translation errors that you do with human made languages, like that there is no word for what you are saying in the other language. However, it dose mean that people have to anticipate what combinations of the lower code need to be assembled to create useful structure to the higher code. This can be a difficult balancing act of providing usable access to critical functions while automating routine tasks. Something as simple as switching an IO pin to positive voltage actually requires many steps that hide behind digitalWrite(13, HIGH);
So compilers make it so that we can do our code in a more simplistic language and still have it translate all the way down to binary. It all sounds fabulous, but you have to remember that someone had to create that compiler using a lower language. As new tech is created and our computing needs change, compilers need to have new functionality added before higher level code take advantage to those changes. As a result, we get updated compilers that can handle now protocols or even just because someone figured out a much better way to translate code. Understanding this is fundamental because without those people who still know the lower levels of code we stop getting updates and things get harder to do in the higher levels.
Think about it like this; what if a new kind of supper fast graphics processor came out for your computer. It uses this supper efficient method of sending data, but it is not like how things are already built to work in your computer now. How could you get it to work with your computer? The answer is to go down to a level where the two devices speak a common language and create support for the higher languages to use. That common language would likely be Assembly.
Now on to the problem with compilers. Often, the price for making code easy for us to understand and ensure that we do not make mistakes, compilers tend to produce some rather bloated code. The farther up the chain you get, the more of a problem this becomes. This is due to the compiler needing to find a generic and universal way to translate when lower level code gives you many options to do a thing based on what your end goal is. This ability to do anything more than one way is what allows a good programmer to be efficient and not waist resources on superfluous tasks. It is typical with higher level languages for someone to hit a wall with code. This wall represents the limitations of that higher level and often leads to the creation of complex, round about, or even wasteful ways of writing code. This could all be avoided by simply going down a layer in programming languages to create your code, or expand on the compiler for a higher level code.
So that is the double edged sword of compiling. You have to weight the benefits of easy to understand vs efficient and versatile code.
So you want to learn Python?
Everyone is going crazy over Python and I do understand why. It is a rather easy and human readable language. I mean that is what it was made to be so good job on that guys. However, I know how to code in C++ so why don’t I just stick with that? You see Python is just another major level of code that sits on top of C or JAVA. This means that there is one more compiler away from my lowest level and that much more room for inefficient and bloated code. In addition to the compiler issue, Python is usually the last to get libraries to support new devices and protocols.
All this being said, Python is incredibly useful under the right circumstances. For example, it is very useful for people who need to assemble highly complex logic for things like robotics and data science. Basically, things like machine learning and AI are very complex and do not inherently require mathematical logic to understand. In this way Python can help to translate our complex logic into a math based language that a machine can understand. It may be large and not the best way to do it, but it would take much longer to figure out how to build that level of complexity using C++.
Recently there is a trend of using Python to program microcontrollers and while I understand the motivation to do this, it comes with a price. The idea, it seems, with MicroPython is to remove the need to have a compiler installed onto a computer for programming a microcontroller. This has largely been driven by the use of cloud computers in many schools that will not allow for the install of local software like the Arduino IDE. The goal has been to make a microcontroller that can be plugged into any computer, pop up like a thumb drive and let you copy your code to it via text file. The price in that the compiler has just been moved from the computer and onto the microcontroller it’s self. This means that devices like the MicroBit and Circuit Playground Express require high powered chips to handle compiling the code that is dropped into them. It works, but most of the chips resources are tied up in making it easier to program rather than being free to process more complex data from the intended program. There is actually a growing community that just wipes out the compiler and uses the Arduino IDE to program the chips in C++ and take full advantage of all the processing power ARM chips have to offer. In addition, when you look at MicroPython code, it is not that far off from C++ any way.
What about other languages?
There are so many languages out there and many reasons to choose one over the other. I started in the early days of the internet when advertisers and publishing were just starting to look at it as a viable platform. As a result, I learned a few markup languages like HTML, CSS, and XML. Later when dynamic content became a thing I got into JavaScrypt, PHP, and SQL. Now I do a lot of work with IOT hardware and that has lead me to a bigger focus on C++, TCP/IP, SSH, and MQTT. What these all have in common is that they are the right tool for those specific things at the time that I was doing them. There will always be a new coding language out there and it may be good at doing one thing, but the higher you go up the coding stack, the more specialized a language will be. I have often been caught reminding people that Excel is nice for spread sheets, but SQL is a database.
In conclusion
In the end a lot of this is just my opinion and largely based on conversations with others, my experiences, and a bit of research. I think that Python is a good place to start things out for children and people who have interests in coding that will not require them to get low down in the stack of languages. I do recommend that we push people interested in coding to learn C++ as it is the language that most others take so much from. The most important thing that people need to understand though is the structure of all of these languages and how they all relate to each other. Lack of understanding has lead to some alarming tends, in my opinion, like professionals saying that it is more important to learn Python and C++ dosen’t matter. That is like building a house without pouring a foundation. Except it’s a skyscraper and nobody knows how concrete works.
It is my hope that understanding why there is no one ideal programming language should help people to understand the complexity of it all. You don’t need to know everything about the full stack of languages, you just need to know that one is dependent on the others and the loss of one effects others higher up in the stack. This is at the hart of why so many of us are working to educate the next generation in tech. If this generation grows up only learning about top level programming, who will be left to drive the next big advancement in tech. Eventually we will create an AI that can maintain the lower levels of code better that we can, but it is still a ways off and it means handing control over the tech that runs our lives over to that AI. It will begin creating more and more complex code than we can even begin to understand, but that dose not mean that we shouldn’t try to keep up as long as we can and ensure that it is on the path that we want it to be on. We don’t need everyone to dive in deep, but we do need some truly ambitious people to continue taking on the complexity of low level programming.