(Warning, this historical account of increasing abstraction and declarative programming may annoy, confuse, or upset you:)
By far and large, programing languages happen on a continuum, with "pure" instances of languages being ideals. This is because there are a variety of platforms, architectures, and goals when writing software. Of course, the predominant architecture is the von Neumann architecture, and at the heart of it is the ALU/CU/MMU. In reality, the continuum begins with microcode, which is a set of hardware-level instructions that implement the machine code, and as such are only available to the computer engineer. The next level of code is indeed the machine code, which is generally a series of bytes expressed in binary or hexadecimal and is almost incomprehensible except to the hairiest-chested of programmers. Few programmers today appreciate the ease of using opcodes over physically altering circuits with switches and jumpers like in the early days of ENIAC! No wonder by the time EDSAC came around, one letter mnemonics were being used.
Enter the mnemonic code. With this terse, but meaningful sequence of characters, it now becomes possible to think in code. CMP? Compare! JNZ? Jump if not zero! Sure beats wading through a table of hexadecimal as an acolyte for years before reaching some level of mastery in a line of processors. I'm a 68K sort of guy. You're an x86 guy. We can't be friends. We don't speak the same language. The one-to-one correspondence of the mnemonic code to the opcode doesn't free you from the tyranny of the instruction set and the contours of the registers, but code can stream from the fingertips if you can keep all of those input-output sequences and bits and bytes in your head. Wouldn't it be nice if we could fully take advantage of the Turing machine and somehow take one set of mnemonics and replace them with another. Oh, here comes the macroassembler!
But maybe just maybe I want to work on two different systems and have my software be independent somehow... call it... platform independence. You see, the university just networked these things across campus between two different departments with two different mainframes and now we have problems like do the little bits come first or last, and should a byte be the same size. And what is this BCD and EBCDIC stuff I keep seeing? So many details, and all I want to do is write a piece of software to send some form of electronic mail between our machines. Perhaps there would be a better way to write software, one where we didn't have to constantly have provide imperatives to a computer, but rather could just declare what I want done: Mr. Computer, send this message to the other department.
How about we write a program that translates a general declarative like loop through a list for each element in the list. We could call that command "foreach" and provide it with some arguments like "element" and "list", and then we can have the computer do all the work of figuring out which opcodes can make that happen, after all, I want to spend sometime with my family or collecting my Star Wars dolls. We could even have this program compile these instructions intelligently, maybe make some choices with directives at compilation time. Compiler, use these #directives! I am the coder, hear me roar (silently with my fingertips). What do you mean you can translate from my language to another source language? What do you mean you can compile to multiple target architectures? What, you can compile compilers? (Whoa, meta.)
Boy, things are so complicated. And sometimes you churn out so much bloat. Can't I just sneak a little assembly back in here inline? Thanks, buddy. Maybe at this level to speed up my scripts, we can just have a run-time environment and interpret instructions? And let's add some markup to this file and just have a program interpret it at runtime, so I don't have to keep hardcoding these commands here in source.
But still so many details to manage. What was the size of the unsigned integer by you guys? What do you mean you don't have unsigned integers?!? How is that even possible. Can't we just find a way to all use the same machine? Life would be so much simpler if everyone just used the 7-bit byte just like me. If you liked me you'd use my platform. Fine, let's put our heads together and see... wait, doesn't the Turing machine mean we can write a machine as well as fabricate one? And imagine the potential if we could put this machine on both of our computers and hide all the detail complexity. We would virtually be free to do things identically. Now if only we could come up with a name for this not-quite-real machine written in software using these byte-codes. I come up with bytecodes and you want to use common intermediate language instructions? Are you kidding me?
Now we have a common-intermediate-language-run-time-assembling-virtual-byte-code-interpreting thing, we can use the same instructions, and integrate the same sort of libraries. Let's call our library of code a standard library since it's now the same everywhere, and let's use this beautifully standardized, highly declarative data manipulation language called SQL or SEQUEL or whatever. Fine, you want some vendor-specific extensions, what can I do to discourage you. And you want to use Lua? And you want to use Python? And you Perl? Don't you get the point of having a virtual machine? Herding cats would be simpler than this...
And what do you mean I'm from an earlier generation? You youngins are all in a rush to develop your applications rapidly. Yes, it's RAD. RAD is cool. RAD is rad. Or dope. Or phat. Or sick. Whatevs. I will give you credit that this whole framework thing sure speeds up. Who wants to write instructions over and over if I can just generate some code with a click of a button on a mouse. It's a shame that computer just didn't read my mind. I wouldn't have carpal tunnel syndrome; let's just make the machine a little smarter. Maybe we can bring our systems up a notch beyond narrow machine intelligence to make the world a better place. Get them to understand our voice commands.
Ahhhh! Too smart!!! Don't do what I say. I didn't mean you to make a better world by your seizing the means of production, Mr. Computer. Yes, I know computers control the means of production. Yes, you downloaded Das Kapital from Gutenberg, (no, this one... oops. Here.) I can tell. No, your logic isn't superior. Don't read my emails, computers. Don't listen to me on my phone. Stop watching me through those cameras perched like ominous ravens and buzzards on those cell phone towers disguised as trees. Give me back my money. Let me start my car. Don't lock me in my smart house. Uh, oh, they have the satellites. Watch out, they have the tanks and the cruise missiles!!!
And all I wanted to do was to add numbers without flipping switches. I'm sorry world.