Alto nível vs. baixo nível não é uma coisa em preto e branco, mas uma escala contínua. Os termos são usados para descrever o quão perto uma linguagem de programação está do hardware; quanto maior o nível, mais ele abstrai o hardware.
O nível mais baixo, obviamente, é o código binário da máquina - é a representação exata que o sistema operacional carrega e alimenta na CPU. Assembly é o primeiro nível de abstração construído sobre ele: em vez de código binário, escreve-se códigos simbólicos legíveis por humanos e mnemoics que representam instruções de máquina binária. Isto é o que as pessoas usavam para programação de sistemas antes do UNIX.
C é o próximo passo na cadeia de abstração, agrupando padrões comuns em construções de controle de fluxo e abstraindo instruções específicas da máquina em sintaxe independente de plataforma, e essas últimas abstrações foram um dos principais fatores que tornaram o UNIX revolucionário e altamente bem-sucedido, porque significava que o mesmo código poderia ser compilado para qualquer plataforma sem grandes alterações.
O C ++ adiciona outra camada de abstrações: adiciona classes (abstraindo vtables e contexto passando para uma sintaxe OOP) new
e delete
(agrupando alocação de memória e inicialização variável em uma única construção), verificação de tipo em tempo de compilação, modelos (tempo de compilação com segurança de tipo metaprogramação) e várias conveniências de sintaxe em tempo de compilação, como espaços para nome, sobrecarga de funções e operadores, etc.
Python dá outro grande passo para longe do hardware. O C ++ ainda oferece ao programador controle total sobre a alocação de memória e permite a manipulação direta da RAM; O Python cuida do gerenciamento de memória para você. Além disso, em vez de compilar seu código com instruções de máquina totalmente nativas, ele é executado em uma máquina virtual; isso acarreta uma penalidade de desempenho (que às vezes pode ser pesada, mas geralmente não é algo para se preocupar), mas também permite coisas legais que seriam complicadas em C ++ e extremamente difíceis em C, como manipular funções e classes em execução tempo, obtendo os nomes de objetos arbitrários no tempo de execução, instanciando classes pelo nome no tempo de execução, patch de macaco etc. etc.
Portanto, quando as pessoas dividem os idiomas em "alto nível" e "baixo nível", eles desenham uma linha arbitrária em algum lugar, e essa linha nem sempre é a mesma. Em 1970, a linha estava entre montagem e C (abstraindo as instruções específicas da máquina, sendo o fator decisivo); em 1987, pode ter sido algo entre C e C ++; hoje, pode estar entre C ++ e Java (com o gerenciamento automático de memória como fator decisivo).
Para encurtar a história: alto nível é uma escala móvel e, para as três línguas mencionadas, é C <C ++ <Python.