Pessoal, bom dia.
Aqui é o professor Simão falando.
Eu estou em Curitiba.
No dia 2 de Julho de 2020.
Essa nossa aula é sobre o curso, ou a disciplina,
de orientação a objetos,
a qual tem foco em C++.
Antes de mais nada, deixe-me dizer
que eu vou procurar fazer aulas
ou apresentações, bastante pragmáticas
e rápidas sobre os conteúdos,
porque... Pra vocês não perderem a atenção
e ter ali o conteúdo bastante centrado
em uma meia hora, ou algo assim, em relação a cada conjunto de slides.
Aqui nós estamos no primeiro conjunto de slides parte A,
Neste conjunto de slides em questão,
A gente vê uma introdução a paradigmas,
passando a introdução a orientação a objetos que é um paradigma,
salientando aí a linguagem C++
que suporta a orientação a objetos.
Nesse âmbito, a gente viu
uma geral sobre o conteúdo da disciplina
e a importância sistêmica dessa disciplina.
Inclusive, obviamente, eu dou a orientação a objetos,
e também, sublinhando a linguagem de programação C++.
Slides 2.
Se a gente olhar a evolução
no tocante a paradigmas,
você percebe que, na verdade, primeiro surgiu as linguagens de programação,
e depois que surge a noção de paradigma.
Bom, com o advento do computador digital,
foi necessário maneiras de programá-lo,
aí foi sendo criado as linguagens de programação
e com o tempo as linguagens de programação foram
se distinguindo e foram percebendo que elas tinham
classes distintas, ou seja, paradigmas distintos.
Só subsequentemente,
que, aí, os cientistas da computação começam
antes pensar em paradigmas, pra depois
pensar em linguagens que suporte esses paradigmas.
Então, tem um pouco dessa espiral envolvida.
Bom, lá com o advento da computação digital,
aonde você tem essa dupla de memória e processador,
era necessário uma maneira de
de gerar um entendimento entre esses elementos,
enfim, entre todo o sistema.
E, para tal então, foi criado a linguagem de máquina
que, basicamente, é a linguagem binária,
que vocês já conhecem de disciplinas anteriores.
O problema de fazer uma programação em linguagem binária,
como vocês bem sabem, é que não é evidente.
Pra maior parte das pessoas,
pensar em binário não é, necessariamente, fácil.
Fazer programas de soma, de subtração,
já tem uma complexidade,
e quando aumenta a complexidade dos programas,
fica mais difícil ainda.
Por isso que inventaram, daí,
além da linguagem de máquina,
inventaram a linguagem montadora, ou Assembly.
Linguagem montadora Assembly
é uma linguagem que usa mnemônicos, usa comandos
que permite dar alguma facilidade
pra fazer algumas operações.
Por exemplo, você tem o comando da adição, subtração, decisão...
Você vai ter o comando de jump, ou seja, de pulo,
que permite fazer laços de repetição, ou loops.
Permite você sair de um momento do programa
e ir pra outro momento de programa.
Sendo que o jump joga, na prática,
de um endereço de memória pra outro.
E isso já deu algum ganho,
pro desenvolvimento de programas.
Mas, ainda assim, quando você começava a olhar os programas,
tinham situações que eram extremamente repetitivas.
Pra fazer coisas simples, como uma soma e uma subtração,
era bastante perceptivo a repetição de comandos.
E pequenos comandos sempre tinham que estar sendo repetidos
de maneira casadas para fazer uma dada ação.
Bom, aí, os cientistas da computação percebem
que é possível você criar uma linguagem de um pouco mais de alto nível,
com comandos de um pouco mais de alto nível,
que, justamente, geram esses comandos que se repetem
e isso foi pensado, e concretizado, por meio do advento dos compiladores.
Então, na prática, você tem uma linguagem de mais alto nível,
e você tem um compilador que traduz
aquela linguagem de mais alto nível
em linguagem Assembly, linguagem montadora.
Bom, as primeiras linguagens que surgiram, ou a primeira,
que tá aí classificado no nosso slide.
Slide interessante inclusive.
Ali em 1960, você tem o FORTRAN.
Depois do FORTRAN, você vai chegar à linguagem C.
Que são classificadas como procedimentais.
Bom, obviamente, que era um dos primeiros protótipos dessas linguagens.
O que você tinha era um programa
num módulo único, numa função única,
chamado, entre aspas, "um programa linguiça",
aonde você fazia ali a sua lógica, o seu desenvolvimento.
Bom, como a linguagem mais alto nível
permite uma programação um pouquinho mais produtiva
com relação ao Assembly, por ser menos repetitiva inclusive
as pessoas começaram a fazer programas um pouco maiores.
Eles perceberam aquela necessidade, no final das contas,
de compartimentar esses programas,
pra que eles ficassem viáveis.
Naturalmente, se você vai fazer um artefato
quanto maior fica esse artefato,
chega um momento que você precisa ter módulos, ter compartimentos.
Imagina, você fazer uma casa grande
sem quartos, sem divisões, sem módulos.
Bom, e aí surgiu os procedimentos.
Os procedimentos permitem que você
compartimente um pouco essa...
Essa sua lógica.
Vocês já desenvolveram programas em linguagem C no passado,
ou em outra linguagem procedimental,
e você percebe, naturalmente,
que é necessário criar os procedimentos pras diversas funções.
Imagina que você está fazendo um programa de cadastro, por exemplo.
Você vai ter um módulo de inclusão, de exclusão, de atualização, de listagem e afins.
Se fosse num único programa,
tende que o programa fique ilegível
ou, pelo menos, que o programa fique muito mais complexo de gerenciar.
Nesse âmbito dos procedimentos,
que você bem sabe,
que os procedimentos trabalham com
passagem de parâmetro por valor ou por referência.
Isso é conteúdo de disciplina anterior.
Por valor, é quando você passa o valor pro procedimento
o que acontece com aquele valor lá dentro
não afeta quem doou o valor.
E já na passagem de parâmetro por referência,
quando o valor está dentro do procedimento,
afeta sim quem doou o valor.
Dizendo de uma maneira bastante poética.
Inclusive pra explicar esses paradigmas aqui,
de maneira pragmática,
eu, naturalmente, vou ter que usar alguma licença poética.
Nesse sentido, se você olha
a linguagem LISP
que é a primeira linguagem
que pode ser classificada como paradigma funcional
ela, justamente, explora essa questão
dos procedimentos, ou das funções,
mas focando principalmente
na passagem de parâmetro por valor.
Quando você passa parâmetro por valor,
você aumenta o nível de dependência entre as coisas,
porque o valor tá dentro de uma função não afeta quem doou.
E isso foi bastante interessante do ponto de vista conceitual,
porque você aumenta, na verdade, o nível de encapsulamento
O quê, depois, a gente vai acabar trazendo
o conceito de coesão e desacoplamento.
Bem entendido.
Mas dizendo de maneira simplória,
nesse momento preciso aqui,
então a linguagem funcional pôde permitir,
em alguma medida, aumentar o nível de encapsulamento,
dado que a passagem de parâmetro sempre era por valor.
Novamente, isso aqui é uma licença poética, tá?
A coesão é mais complexa que isso.
O problema lá do paradigma funcional,
é que se você vai passar sempre os parâmetros por valor,
você pode ter um estouro de pilha.
O que significa?
Como quando você passa parâmetro pra funções,
Por exemplo, uma função A passa parâmetro pra uma função B.
A função B passa parâmetro pra função C.
A C passa parâmetro pra função D.
A D passa parâmetro pra função E.
E assim subsequentemente.
Esses parâmetros, em cada passagem
de uma função pra outra, eles vão sendo empilhadas
numa pilha de parâmetros.
E a hora que a função final,
a última que foi chamada, termina de executar,
ela volta pra execução das funções anteriores desempilhando
os respectivos parâmetros que estão
naquela pilha de parâmetros das chamadas de funções.
Antigamente, memória era um problema.
Em sendo um problema,
as linguagens funcionais, naquele momento, não vingaram tanto.
Justamente porque você tinha que tá a todo tempo gerenciando
a sua pilha de execução.
Hoje o contexto é outro.
Tanto é que as funções... que as linguagens funcionais começam voltar à tona.
Me veio à memória agora Haskell, se eu não me equivoco.
Bom, então, na verdade você tem essa...
Você tinha até então ali,
no início das linguagens de programação,
vamos dizer, aí, até 1970,
dois grandes paradigmas principais.
Que era o procedimental e o funcional.
Sendo que, por motivos técnicos e outros, inércia cultural.
O procedimental venceu.
Sendo que a linguagem que entrou em voga,
foi a linguagem C.
A linguagem C foi precedida por protótipos,
se eu não me equivoco a B e mesmo outros.
E ela chegou numa versão estável com nome de C.
A linguagem C ela foi... Foi e é, na verdade, muito impactante.
Por quê? Porque ela permitiu alcançar um bom nível
de programação, em termos linguísticos, em alto nível.
E, ao mesmo tempo, através de uma série de artifícios,
não perdeu contato com o hardware.
Através de gerenciamento de memória,
como alocação e desalocação.
Através de ponteiros, através de operadores bit a bit e afins.
E isso já foi um salto.
Entretanto, os cientistas da computação,
que não param de pensar sobre a computação,
porque são filósofos da computação.
Notaram que poderia haver avanços.
E esse avanço foi encontrado numa situação posta.
Se você olha lá a transição dos anos 70 pros 80,
o pessoal criou uma linguagem chamada SIMULA.
O quê que era a SIMULA?
A SIMULA foi criada lá nos países nórdicos,
pra simular situações reais.
Então, por exemplo, imagina
que você queria fazer um simulador pra simular o trânsito
Imagina, que por algum motivo você tenha a percepção
que seria útil pro trânsito curitibano,
alterar, a título de exemplo,
a mão, o sentido, da Silva Jardim.
Só que, você fazer isso na realidade,
testar, na realidade, se de fato
essa... Essa inversão de mão de fato seria útil
traria um transtorno gigantesco pra cidade
se fosse feito na realidade.
Agora, se foi feito em ambiente de simulação,
o impacto que tem, na verdade, é você construir todo o aparato técnico para tal.
Não afeta a cidade em si num primeiro momento.
Bom, as pessoas então queriam criar sistemas de simulação,
Outro exemplo, até interessante, de simulação,
é, justamente, por exemplo, os simuladores de voo.
Natural emente, que é muito melhor você treinar um piloto
em simulação de voo, que em termos reais num primeiro momento.
Obviamente que a simulação de voo envolve muito mais do que software,
ainda sim, é o conceito de simulação.
Tudo isso dito,
os caras criaram então a linguagem SIMULA.
E na linguagem SIMULA eles perceberam que
era importante, do ponto de vista da simulação,
ter um módulo de software
para cada elemento que fosse simulado na realidade.
Imagine que você tá simulando uma situação de trânsito, como dizia eu.
Então você vai ter que ter o módulo do Carro.
Você vai ter que ter o módulo Rua,
compostos por módulos Quadras.
Você vai ter que ter o módulo Pedestre.
Você vai ter que ter o módulo Semáforo.
Então você começa trazer,
para o teu ambiente de programação,
os objetos que existem no mundo real.
E os módulos,
não são mais módulos abstratos,
eles são módulos inspirados
nos objetos que existem no mundo visto
ou, pelo menos, no mundo imaginado,
mas, no caso aqui, é no mundo visto.
E aí eles criaram uma...
espécie de linguagem de programação,
aonde os módulos, eram mais que procedimentos, eram elementos
que representavam os dados e as funções
dos objetos do mundo real.
Não demorou muito tempo, pras pessoas perceberem
que, na verdade, qualquer programa de computação,
ele... pode ser visto
como simulação, em alguma medida,
do que acontece no mundo real.
Pegue, por exemplo, o sistema acadêmico que vocês utilizam
pra fazer matrícula, gerenciar os seus coeficientes de rendimento,
gerenciar quais disciplinas vocês estão cursando, etc.
Se você parar pra pensar, em alguma medida,
Aquele sistema ali, ele simula, o mundo real.
Você tá simulando a existência das disciplinas,
a existência dos alunos, os professores,
as relações dos professores e dos alunos com relação às disciplinas,
a relação das disciplinas com relação às grades curriculares,
as grades curriculares em relação aos cursos,
os cursos em relação ao departamento.
Bom, longa história curta,
percebeu-se que qualquer programa poderia ser orientado a objetos,
e, para tal, começou então o desenvolvimento de linguagens que suportassem
esse paradigma orientado a objetos,
que não é apenas módulos,
são módulos que se inspiram em objetos,
do mundo concreto, ou de objetos que a gente vislumbra
em algum mundo na nossa mente.
Como nosso mundo real, ele é orientado a objetos,
naturalmente, que a nossa imaginação também é orientado a objetos.
Quando você imagina um cenário hipotético,
por exemplo, um cenário mitológico
com unicórnio, com dragão,
boitatá, sei lá eu o quê.
O dragão, o unicórnio e o boitatá, cada qual são objetos.
Então, na verdade, você programar orientado a objetos,
você tá trazendo a maneira de raciocínio
como o mundo é e como a gente imagina o mundo,
seja ele o mundo concreto que a gente vive,
ou os hipotéticos que também se orientam a objetos.
Bom, o pessoal criou uma linguagem muito importante,
com tudo isso considerado, chamado Smalltalk.
Smalltalk é uma linguagem lindíssima,
puramente orientada a objetos
de uma elegância refinada.
O Smalltalk, eu ensinaria ele pra qualquer turma de Ciência da computação,
porque ele, do ponto de vista da Ciência da Computação,
ponto de vista filosófico, ele é muito bonito.
O problema é que ele não tem... Não tem tanto, impacto prático
como tem outras linguagens,
cito eu aqui, hoje em dia, o C++ e o Java.
Aqui eu vou contar uma história bastante resumida sobre...
o processo histórico, mas se você olhar, as pessoas estavam programando em C.
Criando sistema operacional em C,
estavam criando compiladores em C,
estavam criando uma série de sistemas em linguagem C.
E aí vem alguém e fala: "Ah, nós temos uma linguagem muito bonita chamada Smalltalk".
Você acha que a pessoa vai trocar,
a linguagem que ela conhece, que ela tá produzindo
que ela já tem fluência,
por uma linguagem hipotética, que alguém traz assim...
Imagine vocês que cês falam português e eu chego e falo:
"O, pessoal, a partir de hoje nós vamos falar outro idioma".
Sei lá, eu posso citar aqui: esperanto, grego, latim.
Você vê que vai ser, naturalmente, uma resistência
pra mudar a linguagem que a sua cognição
está acostumada a trabalhar.
Bom, aí você tem o Stroustrop.
O Stroustrop percebe que
a ideia da orientação a objetos é muito legal.
Ele percebe que a linguagem C
tem um impacto já considerado
do ponto de vista de inércia produtiva
e de inconsciente coletivo das pessoas que programam.
Aí ele fala: "Hmm, então vamos criar o C++,"
"que comporta o paradigma procedimental"
"e comporta, ademais,"
"o paradigma orientado a objetos".
E aí, ele vai pras pessoas e diz:
"Olhe, eu tenho aqui uma linguagem de programação"
"E você não precisa esquentar a cabeça que é uma linguagem C, só que '++'".
E aí, essa foi a maneira de cativar as pessoas que programavam em C
a também programarem orientado a objetos,
a conhecerem uma linguagem C incrementada.
Imagine o seguinte, ele falou pra vocês:
"Olha, vocês falam bem português, mas eu tenho aqui uma..."
"Uma maneira de vocês falarem português melhor ainda".
Então, essa aqui foi uma jogada interessante,
de permitir que pessoas migrassem
de um paradigma pra outro.
E daí, à medida que o C++ começa a fazer os seus efeitos,
as pessoas criam linguagens
que, em alguma medida,
são derivadas, ou inspiradas,
melhor dizendo
no C++ como o Java ou o C#.
Se você olha a sintaxe do Java e do C#,
hoje linguagens também impactantes, tá,
do ponto de vista da produção de software.
Você percebe que elas
do ponto de vista ali, de comandos, de sintaxes,
elas são muito próximas do C++.
Enquanto o C++ é o nosso latim,
o Java e o C# seriam aí o nosso italiano, nosso francês, português, enfim.
Bom, aí que o C++ também traz um advento interessante
que é as linguagens que são multiparadigmas.
Então, no C++, você consegue programar procedimental,
orientado a objetos,
até se você quiser, em alguma medida, funcional.
Se você preservar ali
um pouco mais alto nível e uma passagem de parâmetros só por valor.
Novamente, usando aqui a licença poética.
Bom, e aqui você tem um belo conjunto,
das linguagens que são principalmente utilizadas nesse processo histórico
e, também, no processo industrial.
Depois, os cientistas da computação continuam pensando,
e eles começam a criar outras linguagens,
outros paradigmas.
Aqui eu posso destacar, por exemplo, o paradigma lógico.
Aqui, novamente, eu vou usar
uma profunda licença poética, pra dizer que...
Dizer algo sobre o paradigma lógico.
Imagine que você tenha os seus módulos.
não raro, você vai ter que ir num programa
tomar decisões
comparando ou correlacionando os módulos.
Então você tem lá, imagine que você tá fazendo um jogo.
Você tem um módulo que é o módulo... Dragão.
E você tem um módulo... Jogador.
E você tem um módulo Meteoro.
Em algum momento, para que a dinâmica do jogo funcione,
você vai ter que tomar comparações. Dizendo o seguinte:
"Se o Jogador"
"está próximo do Dragão"
"e o Jogador está sem flecha"
"e o Dragão está com poder de fogo"
"então o Dragão vai atirar"
"fogo no Jogador".
Aí você tem uma outra decisão:
"Se o Dragão tá voando sem poder de fogo"
"o Jogador está próximo do Dragão"
"não foi atingido por Meteoro"
"e o Jogador tá com poder de lançamento de flecha"
"então o Jogador ataca o Dragão".
Então vocês tão percebendo que tem decisões aqui
e, não raro, como é que você faz?
Você põe essas decisões num loop,
No loop principal, por exemplo,
aonde você fica tomando decisões, com relação...
Com o estado desses módulos.
De maneira bastante simplória,
o que acontece na programação lógica...
Novamente, com toda licença poética, de maneira bastante simplória,
o que acontece no paradigma lógico,
é que essas decisões, que geralmente são animadas num loop,
ou num conjunto de loops por um conjunto de ifs.
Essas decisões são automatizadas no seguinte sentido:
você não programa mais os loops.
Você, simplesmente, coloca a lógica das decisões
em ifs ou regras,
em altíssimo nível,
dizendo que:
"Se o Dragão tá perto do Jogador,"
"Se o Jogador tá sem poder de flecha"
"e o Dragão tá lá com poder de fogo"
"então o Dragão ataca o Jogador".
Você só faz essa lógica em alto nível,
você não coloca o loop em si,
o loop ele é automatizado.
Ele é automatizado por um elemento chamado mecanismo de inferência.
E aqui a gente já tá falando então, de paradigmas que tão tocando a inteligencia artificial.
Ou chamadas de técnicas de inteligência artificial, bem entendido.
Sendo que o nome inteligência artificial,
é um nome exagerado por definição.
Quanto mais alto nível fica a linguagem,
como é o caso aqui de linguagens lógicas,
aonde os loops são automatizados,
no tocante a decisão, através de máquina de inferência,
mais poder de processamento é exigido.
Quanto mais alto nível é a linguagem, mais poder de processamento é exigido.
Bom, depois começam a surgir outros paradigmas ainda mais recentes,
como é o paradigma orientado a aspectos,
que tem um correlação forte com a orientação a objetos.
O paradigma orientado a agentes,
aonde os módulos,
além de interagirem, além de serem correlacionados através de regras ou ifs,
os módulos aprendem com o tempo,
os módulos podem colaborar,
os módulos podem competir,
os módulos podem até criar novos módulos.
Então, são outros paradigmas mais emergentes.
Eu mesmo trabalho, na minha linha de pesquisa,
com um paradigma chamado: paradigma orientado a notificações.
De minha autoria,
aonde a gente traz alguma luz,
algum avanço no tocante
a composição, execução
e mesmo a harmonia
no desenvolvimento de software.
Bom, isso aqui então é um panorama geral
sobre... Sobre paradigmas.