Let's start by defining a programming language: a programming language is a set of rules (called grammar) which are used to translate instructions into an understandable form for the computer. In order to learn how to program, you need at least some understanding of math and logic because computers execute mathematical formulas in binary code.
Programming languages are essentially how we talk to machines - they're another language and like human languages, some are easier to learn than others. This is where high-level and low-level come in.
High-level and low-level
While high-level languages are easier to read by humans and simpler, low level languages are machine-friendly, harder for us but much more efficient in terms of memory. High level coding has better human interface because it is closer to the language we speak (English).
Low level code can make your computer run a lot faster but is much more difficult to read because it's closer to how computers process information.
If you need speed, go low level but if you want a language that is easier for humans, high-level languages are your best bet.
How they're different
So what does a high-level programming language look like? Java is a great example of this: it's statically typed and uses automated garbage collection - on the whole it uses fewer lines of code and is easier to read.
At the other end of the spectrum, C++ is considered a low-level language because it's statically typed but can be more efficient when running as an interpreter (not compiling into machine instructions). Luckily, it also has automatic memory management built-in which means that you won't have to think about releasing objects from memory.
C however, is very low-level. The code is dense and you're responsible for allocating and releasing memory. But C can be more efficient than high-level languages, if only because there are fewer lines of code to worry about.
But the reason we think that a low level language might be better when dealing with hardware is in their word lengths. Bill Gates had a fantastic quote here:
Measuring programming progress by lines of code is like measuring aircraft building progress by weight.
Which is to say that high-level languages are more verbose than their low level counterparts due to our need for abstraction. A program written in pure assembly will often be much shorter because there's no extra baggage and it has fewer instructions to worry about.
Examples in the real world
But while all of this sounds compelling, the reality is that most programmers work in high-level languages for two reasons:
It's simply easier to build - the abstractions that come into play mean we're able to build, scale and ideate much faster than if we were using a low-level language It's all compiled anyway - while there are performance differences between things like manual and automatic garbage collection, at the end of the day, all our code is compressed and mangled into an unreadable machine code format anyway.
When languages are compiled, they're transformed from human-readable code to binary code that looks like nonsense. This is called machine code or assembly language because it's understandable by computers, not humans.
At this level, you're controlling individual bits and bytes, which is a really low level of programming. It's like building with LEGO blocks instead of creating something from scratch on TinkerCAD - it can be fun but there are lower limits to what you're able to do because the only tools available are very primitive.
Scripting vs Programming
Now that we've talked about programming languages, let's explore how scripting languages work. Scripting languages are easier to learn and use for many tasks, but they're not as powerful or efficient. Some scripting languages such as Perl have been around since the 1970s while other ones like Ruby date back to the 1990s.
The key difference in how a scripting language works vs a programming language is that it's usually interpreted, not compiled. This means that the code is run as you type it in and doesn't need to be saved first before running like a programming language does.
The downside of this is that the program can only do what the script allows for - there are no built-in commands or libraries available by default with scripting languages.
Which language should I pick?