One of the things I've noticed lately is that there is some level of language superiority among programmers. While this is not restricted in the least to members within the calculator community (programmers are actually worse on many forums that I've seen), this post was nonetheless written for that niche group.
Programming is, at it's very core, the art of writing instructions to be carried out by a deterministic machine. This is the underlying concept of programming and all languages necessarily adhere to it. It also easily defines the various levels of programming.
At the most basic level, one can program in the machine's native language of Binary (or Hexadecimal, if you prefer the easy way out). This was an extremely common form of programming in the early days of computers, but was quickly replaced by higher level logical abstractions. The first of these was the family of languages known as Assembly. Assembly essentially takes every binary instruction recognized by the underlying circuitry and replaces it with an easier mnemonic that generally describes what the instruction does that is translated to machine code by an Assembler. This allows programmers to work more quickly and easily with the logical abstractions of the mnemonics rather than the machine code. The advantage in using either of these languages is that no program can ever be performed more efficiently than by a program written in them. For any given processor, an optimal assembly or machine code program is necessarily at least efficient as a functionally identical program in any other language and often more so (in addition to being the fastest programs possible). Furthermore, all instructions on a processor are available for use (and thus all programs are possible in ASM/Hex). In many higher level languages, these instructions are not usable, which can result in much unnecessary work in writing code such as mathematical operations without machine word sizes. Of the two, Assembly language is the easier, but machine code offers some other advantages as well. For one thing, Assemblers may generate errors on otherwise valid code. Machine code will only ever return an error if the hardware (or emulator) can't handle the code. Secondly, the style of programming known as Self-Modifying Code is significantly easier in machine code than in Assembly. This often results in highly efficient programs, even above normal Assembly. Finally, Machine code has almost no "compilation" time. Whenever the code is ready to be tested, it can be copied/pasted into the executable and run.
After Assembly came the first major jump in abstraction: the compiled language. Compiled languages replace the oftentimes obscure syntax of machine code and Assembly with that of a higher level language containing instructions that don't necessarily correspond to hardware level instructions. The program which translates these instructions to machine code (called a compiler) uses routines of lower level code to synthesize these high level instructions. A good example of such a language is C. As a language, C offers a wide variety of commands and instructions in order to do many different tasks, most of which are not available directly in lower languages. This high degree of logical abstraction allows programmers to work more quickly on many common tasks and generally avoid having to program difficult things such graphics. However, contrary to popular belief, it does NOT increase portability. Compiled programs are turned into machine code, so unless they're compiled on-site by the user (often not the case), they are no more portable than an appropriately written ASM/Hex program. Compiled programs are often extremely fast, but still lower and less memory efficient than an equivalent program written by a [skilled] ASM/Hex coder.
Beyond compiled programs (which often have obscure syntax themselves) come interpreted programs. Interpreted programs are parsed at runtime by a program known as an interpreter, which contains all of the valid routines for that language. The advantage of interpreted languages is that they typically offer extremely simple syntax compared to other types of languages and even higher level instructions. However, this comes at a significant price. Since the interpreters must be kept in memory and parse the program at run-time, interpreted languages often have very high memory footprints and are generally much slower than compiled or assembled languages.
Misconceptions:
There are a few common misconceptions about these languages that I'd like to address as well.
Machine code: Hexadecimal (I'm not aware of anyone who programs in Binary) is often regarded as impossibly complex and unwieldy to program in. This is, at least in my experience, no the case. Rather, it demands a different mentality in programming than almost all other languages. Another common misconception about Hexadecimal is that it doesn't allow convenient program formatting. This is in fact not true. I offer up my own code as an example
Code:
It may look complicated and obscure, but to an experienced Hex coder (which I am not), that should be reasonably obvious as B = (A-N)*(A/N). It also demonstrates the use of comments in hex programming, something that many believe to be impossible. Use of the backspace key to remove those is encouraged before pasting into an executable.
Assembly: Assembly is often regarded as obscure and irrelevant as a language. On many programming forums, questions concerning how to do certain things in Assembly are almost inevitably greeted with at most one or two reasonable responses and a minimum of six posts saying "Why r u using that! try using ruby or c." Frankly, this astounds me as there can be very good reasons for using Assembly (good luck fitting the Python interpreter in the 4 KB of RAM on the Apollo 11 computers, buddy). However, as was stated earlier, Assembly is also the fastest possible language on a processor. That means that any other language can at most be as fast as a well written Assembly program. If Windows were written in Assembly, it'd probably run significantly faster in many places. It'd also have twice as many bugs and only come out around once a century, but those are other matters
Another common misconception of Assembly is that it's slow and painful to write. While more time is certainly spent in initial debugging, a skilled Assembly programmer can often rival a good programmer in a higher level language with most of the difference merely due to typing.
Compiled languages: Compared to ASM and Machine code, compiled languages are typically slower and less memory efficient. However, they offer significant advantages to programmers. For one thing, the nature of the hardware is much less important than it is in Assembly or Machine code. The programmer is also not required to have an intimate knowledge of many common algorithms because they are provided through routines in the language itself. Most importantly, however, they allow for relatively fast program design and the management of massive projects without getting bogged down in processor details. To use the earlier example, if Windows was written in a compiled language, it would be slower and kind of memory hungry, but come out on a reasonable release schedule and not have as many bugs. All of these are of course true since Windows is in fact compiled. Compiled languages also make problems that would be a nightmare in lower languages such as the coordination of the 3000 some processors composing IBM's Watson possible at an acceptable speed. No Assembly programmer in their right mind would hesitate to say that such a complex problem is almost always better left to a higher level compiled language.
Probably the most common misconception of compiled languages is that of "the compiler is always right." Some programmers genuinely believe that compilers produce optimal code. Frankly, that couldn't be farther from the truth. Modern compilers are extremely good at producing efficient code, but they are not and nor will they ever be (in the near future) better the task than humans. One particular case of this misconception that I remember is that of a redditor who, when faced with the challenge of designing a circuit with the minimum number of gates necessary to compute Conway's Game of Life, offered up the explanation to "just compile some vhdl with no timing and strict area constraints." The error in this suggestion should be obvious.
Interpreted languages, while conceptually similar to compiled languages, tend to occupy a niche in the programming marketplace that makes them distinct from compiled languages. One of the most prevalent misconceptions surrounded interpreted languages is that they're slow and inefficient. While this can indeed be true, many modern interpreted languages are quite fast and powerful if the considerations are adjusted properly. They typically don't achieve the speeds of compiled languages, but they're also typically higher level and thus must often deal with more computationally intensive operations than compiled languages. The main advantage of interpreted languages, TI-BASIC in particular, is that they are extremely easy to quickly mock up complex programs and algorithms in. Furthermore, the lack of compilation time makes them valuable for testing purposes. It also turns out that the lack of speed may be a good thing for many programmers' education, for there's nothing for forcing you to learn how to optimize like trying to squeeze that last bit of speed out of your quadratic solver.
Anyway, this is probably enough, as I'm pretty sure I have a giant wall of text by now...
Programming is, at it's very core, the art of writing instructions to be carried out by a deterministic machine. This is the underlying concept of programming and all languages necessarily adhere to it. It also easily defines the various levels of programming.
At the most basic level, one can program in the machine's native language of Binary (or Hexadecimal, if you prefer the easy way out). This was an extremely common form of programming in the early days of computers, but was quickly replaced by higher level logical abstractions. The first of these was the family of languages known as Assembly. Assembly essentially takes every binary instruction recognized by the underlying circuitry and replaces it with an easier mnemonic that generally describes what the instruction does that is translated to machine code by an Assembler. This allows programmers to work more quickly and easily with the logical abstractions of the mnemonics rather than the machine code. The advantage in using either of these languages is that no program can ever be performed more efficiently than by a program written in them. For any given processor, an optimal assembly or machine code program is necessarily at least efficient as a functionally identical program in any other language and often more so (in addition to being the fastest programs possible). Furthermore, all instructions on a processor are available for use (and thus all programs are possible in ASM/Hex). In many higher level languages, these instructions are not usable, which can result in much unnecessary work in writing code such as mathematical operations without machine word sizes. Of the two, Assembly language is the easier, but machine code offers some other advantages as well. For one thing, Assemblers may generate errors on otherwise valid code. Machine code will only ever return an error if the hardware (or emulator) can't handle the code. Secondly, the style of programming known as Self-Modifying Code is significantly easier in machine code than in Assembly. This often results in highly efficient programs, even above normal Assembly. Finally, Machine code has almost no "compilation" time. Whenever the code is ready to be tested, it can be copied/pasted into the executable and run.
After Assembly came the first major jump in abstraction: the compiled language. Compiled languages replace the oftentimes obscure syntax of machine code and Assembly with that of a higher level language containing instructions that don't necessarily correspond to hardware level instructions. The program which translates these instructions to machine code (called a compiler) uses routines of lower level code to synthesize these high level instructions. A good example of such a language is C. As a language, C offers a wide variety of commands and instructions in order to do many different tasks, most of which are not available directly in lower languages. This high degree of logical abstraction allows programmers to work more quickly on many common tasks and generally avoid having to program difficult things such graphics. However, contrary to popular belief, it does NOT increase portability. Compiled programs are turned into machine code, so unless they're compiled on-site by the user (often not the case), they are no more portable than an appropriately written ASM/Hex program. Compiled programs are often extremely fast, but still lower and less memory efficient than an equivalent program written by a [skilled] ASM/Hex coder.
Beyond compiled programs (which often have obscure syntax themselves) come interpreted programs. Interpreted programs are parsed at runtime by a program known as an interpreter, which contains all of the valid routines for that language. The advantage of interpreted languages is that they typically offer extremely simple syntax compared to other types of languages and even higher level instructions. However, this comes at a significant price. Since the interpreters must be kept in memory and parse the program at run-time, interpreted languages often have very high memory footprints and are generally much slower than compiled or assembled languages.
Misconceptions:
There are a few common misconceptions about these languages that I'd like to address as well.
Machine code: Hexadecimal (I'm not aware of anyone who programs in Binary) is often regarded as impossibly complex and unwieldy to program in. This is, at least in my experience, no the case. Rather, it demands a different mentality in programming than almost all other languages. Another common misconception about Hexadecimal is that it doesn't allow convenient program formatting. This is in fact not true. I offer up my own code as an example
Code:
6323 //Store A to second variable
3308
E420
001A //Start division
74FF
3104
2448
8FFB //End division
4324
3325
021A //Move answer back to R2
It may look complicated and obscure, but to an experienced Hex coder (which I am not), that should be reasonably obvious as B = (A-N)*(A/N). It also demonstrates the use of comments in hex programming, something that many believe to be impossible. Use of the backspace key to remove those is encouraged before pasting into an executable.
Assembly: Assembly is often regarded as obscure and irrelevant as a language. On many programming forums, questions concerning how to do certain things in Assembly are almost inevitably greeted with at most one or two reasonable responses and a minimum of six posts saying "Why r u using that! try using ruby or c." Frankly, this astounds me as there can be very good reasons for using Assembly (good luck fitting the Python interpreter in the 4 KB of RAM on the Apollo 11 computers, buddy). However, as was stated earlier, Assembly is also the fastest possible language on a processor. That means that any other language can at most be as fast as a well written Assembly program. If Windows were written in Assembly, it'd probably run significantly faster in many places. It'd also have twice as many bugs and only come out around once a century, but those are other matters
Another common misconception of Assembly is that it's slow and painful to write. While more time is certainly spent in initial debugging, a skilled Assembly programmer can often rival a good programmer in a higher level language with most of the difference merely due to typing.
Compiled languages: Compared to ASM and Machine code, compiled languages are typically slower and less memory efficient. However, they offer significant advantages to programmers. For one thing, the nature of the hardware is much less important than it is in Assembly or Machine code. The programmer is also not required to have an intimate knowledge of many common algorithms because they are provided through routines in the language itself. Most importantly, however, they allow for relatively fast program design and the management of massive projects without getting bogged down in processor details. To use the earlier example, if Windows was written in a compiled language, it would be slower and kind of memory hungry, but come out on a reasonable release schedule and not have as many bugs. All of these are of course true since Windows is in fact compiled. Compiled languages also make problems that would be a nightmare in lower languages such as the coordination of the 3000 some processors composing IBM's Watson possible at an acceptable speed. No Assembly programmer in their right mind would hesitate to say that such a complex problem is almost always better left to a higher level compiled language.
Probably the most common misconception of compiled languages is that of "the compiler is always right." Some programmers genuinely believe that compilers produce optimal code. Frankly, that couldn't be farther from the truth. Modern compilers are extremely good at producing efficient code, but they are not and nor will they ever be (in the near future) better the task than humans. One particular case of this misconception that I remember is that of a redditor who, when faced with the challenge of designing a circuit with the minimum number of gates necessary to compute Conway's Game of Life, offered up the explanation to "just compile some vhdl with no timing and strict area constraints." The error in this suggestion should be obvious.
Interpreted languages, while conceptually similar to compiled languages, tend to occupy a niche in the programming marketplace that makes them distinct from compiled languages. One of the most prevalent misconceptions surrounded interpreted languages is that they're slow and inefficient. While this can indeed be true, many modern interpreted languages are quite fast and powerful if the considerations are adjusted properly. They typically don't achieve the speeds of compiled languages, but they're also typically higher level and thus must often deal with more computationally intensive operations than compiled languages. The main advantage of interpreted languages, TI-BASIC in particular, is that they are extremely easy to quickly mock up complex programs and algorithms in. Furthermore, the lack of compilation time makes them valuable for testing purposes. It also turns out that the lack of speed may be a good thing for many programmers' education, for there's nothing for forcing you to learn how to optimize like trying to squeeze that last bit of speed out of your quadratic solver.
Anyway, this is probably enough, as I'm pretty sure I have a giant wall of text by now...