Conceitos de Linguagem de Programação.
Paradigmas da programação
Na ciência e filosofia, um paradigma é um conjunto distinto de conceitos ou padrões de pensamentos, incluindo teorias, métodos de pesquisa, postulados - princípios, premissas ou preposições não demonstradas que são admitidos como verdadeiros sem discussão, servindo como ponto de partida para o início de um raciocínio, dedução ou construção de uma teoria, atuando como hipóteses iniciais aceitas para validar um sistema lógico ou empírico -, e padrões para que constituam legitimamente contribuições para um campo.
Mas, e no contexto de desenvolvimento de software?
Paradigma significa um modelo para estruturar e representar problemas, cuja solução deseja-se obter por meio de um programa, construído a partir de uma linguagem de programação.
Dividindo-se essencialmente em dois grandes grupos.
Imperativo:
Estruturada;
Procedural;
Orientada a Objetos (OOP).
Declarativo:
Funcional;
Lógica.
Claro, há outras e, pode-se usar mais de um paradigma para um software.
Legibilidade do código
"high readability means low cognitive load"
A legibilidade é um critério de avaliação que diz respeito à facilidade com que humanos conseguem entender o fluxo de controle, estrutura de dados e a intenção de um pedaço de código. Antes de 1970 o desenvolvimento de software era baseado na escrita de código, ou seja, o mais importante era, efetivamente, escrever programas.
A legibilidade pode ser avaliada nas seguintes características:
Simplicidade Global
Uma linguagem que contenha poucos recursos básicos (comandos, tipos de dados, formas de controle), pode ser mais complexa e difícil de se aprender. Isso faz com que desenvolvedores tenham um comportamento seletivo, onde raramente eles aprendam tudo. Em vez disso, aprendem um subconjunto (grupo menor de recursos) que achem útil e ignorem o restante. O maior problema disso é que se o programador A aprendeu o subconjunto X e o programador B aprendeu o subconjunto Y, e ambos escrevem código para o mesmo projeto, o código pode ficar confuso. Cada um de nós podemos criar programas diferentes, com recursos diferentes, para resolver um mesmo problema.
Isso deixa claro que programar é um ato de criatividade, ou seja, não é algo que pode ser, a princípio, automatizado. Alguns fatores que reduzem a legibilidade são:
Multiplicidade de recursos: diz respeito à existência de mais de uma maneira de realizar uma mesma operação. Por exemplo, a incrementação, que pode ser feita de várias maneiras e algumas com resultados diferentes.
contador = contador + 1;
contador+= 1;
contador++;
++contador;
Sobrecarga (overloading): de operador, quando um único símbolo tem mais de um significado. Por exemplo: o sinal de adição (+) pode ser usado para adição de números inteiros e para matrizes (arrays), e no paradigma de OOP, quando escrevemos um método com diferentes assinaturas.
Ortogonalidade
Uma linguagem que seus recursos podem ser combinados livremente, sem regras especiais ou restrições, é claro, precisamos ter o equilíbrio nessas permissões.
Uma linguagem que seja altamente ortogonal, pode facilitar a leitura, já que você aprende um conjunto de regras e pode combinar de forma previsível, reduzindo drasticamente o número de "casos especiais" que precisam ser decorados.
Em C
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // 'arr' vira um ponteiro para o primeiro elemento
int a = arr[2]; // 30 - indexando array
int b = ptr[2]; // 30 - indexando ponteiro
int c = *(arr + 2); // 30 - dereferenciando array
int d = *(ptr + 2); // 30 - dereferenciando ponteiro
Após estudarmos, sabemos que podemos usar [] em ponteiros.
Porém, alta ortogonalidade pode dar brechas para combinações perigosas ou sem sentido. Em C++, existe a regra da virgula, que permite ela em condicionais.
int x = (5, 10); // x recebe 10. O 5 é avaliado e descartado.
if (false, true) { // Isso é válido. O 'false' é descartado, condição vira true.
// Este bloco sempre executa.
}
GOTO em C:
um rótulo criado para desvios
goto fim;
printf("Isso não será executado\n");
fim:
printf("O código pula para cá\n");
Um goto pode ser usado com loops tradicionais ou para montar códigos. Mas o problema é que ele depende da estruturação do pensamento humano.
Somos bons em entender estruturas alinhadas mas temos dificuldades em seguir saltos aleatórios.
o goto em ação:
i = 0;
inicio:
if (i >= 10) goto fim;
if (arr[i] == 0) goto proximo;
if (arr[i] < 0) goto negativo;
positivo:
soma_pos += arr[i];
goto proximo;
negativo:
soma_neg += arr[i];
proximo:
i++;
goto inicio;
fim:
printf("Pronto\n");
sem o goto:
for (int i = 0; i < 10; i++) {
if (arr[i] > 0) {
soma_pos += arr[i];
} else if (arr[i] < 0) {
soma_neg += arr[i];
}
// zeros são ignorados
}
printf("Pronto\n");
Tipos de dados
Uma classificação que define (1) quais valores uma variável pode assumir, (2) quais operações podem ser feitas sobre ela. Conceito de linguagem de programação, nível sintático/semântico.
- int, float, double, string, ..
Representa a natureza do dado
Estruturas de dados
Uma classificação que define a organização de dados na memória, definindo como os elementos se relacionam e como podem ser acessados/manipulados. Conceito de ciência da computação, está no nível lógico/algoritmo.
- array, lista, stack, fila, árvore, hash table
int num[5] = {10, 20, 30, 40, 50};
Tipo de dado: inteiros (int)
Estrutura de dado: array, um conjunto de elementos contíguos na memória.
Em python, podemos ver um "embrulho"
lista = [1, 2, 3] # 'list' é um tipo na linguagem
dicionario = {"a": 1} # 'dict' é um tipo na linguagem
os tipos de dados (list / dict) mas implementam estruturas de dados (array dinâmico e hash table), que pode acontecer em outras linguagens.
Confiabilidade
Um programa é considerado confiável se ele se comportar de acordo com as suas especificações sob todas as condições. Isto pode ser verificado por meio de inúmeros testes que devem ser realizados antes do software ser disponibilizado aos usuários. A confiabilidade pode ser medida por meio de 1) verificação de tipos 2) manipulação de exceções; e 3) aliasing
1) A verificação de tipos é realizada por meio de testes, para identificar se existem erros de tipo em um programa. Se declararmos uma variável do tipo inteiro e, o usuário ao entrar com os dados, digita um caracter alfabético. É um erro de semântica.
2) É a capacidade de um programa interceptar erros em tempo de execução, por em prática medidas corretivas e, depois, prosseguir com a execução.
3) O conceito define que existem dois ou mais métodos, ou nomes, distintos para fazer referência à mesma célula da memória, isso se configura como um recurso perigoso em uma linguagem de programação. Por exemplo. se criarmos um método que receberá um parâmetro com passagem por referência (apontando para a mesma área de memória), estamos modificando o valor desta área de memória dentro do método - isso é aliasing.
Custo
A última característica a ser avaliada é o custo de uma linguagem de programação. O custo para treinar desenvolvedores, compreendendo as características ligadas à simplicidade e à ortogonalidade. O custo para executar e manter programas. O custo da má confiabilidade. O custo da manutenção de programas.
Esclarecimentos:
Esse é uma nota básica autodidata que eu fiz, sem intenções de ganhar crédito.
Agradecimentos:
https://en.wikipedia.org/wiki/Paradigm
Comments
Post a Comment