| Bellacosa Mainframe onde esquecer sintaxe nunca foi o problema |
☕ Um Café no Bellacosa Mainframe
Esquecer Sintaxe Nunca Foi o Problema
O Verdadeiro Desafio é Compreender um Sistema que Sobreviveu aos Próprios Criadores
Imagine que você acabou de entrar em uma empresa para trabalhar como programador COBOL.
Você recebeu seu usuário TSO, uma senha temporária, acesso ao ISPF e uma documentação de quarenta páginas que aparentemente foi impressa durante o período em que os dinossauros ainda preenchiam cartões perfurados.
Seu líder aponta para a tela e diz:
“Precisamos fazer uma pequena alteração nesse programa.”
A expressão “pequena alteração”, no universo dos sistemas legados, deve ser tratada com o mesmo cuidado que a frase “parece tranquilo” em um filme de ficção científica.
Normalmente significa que ninguém sabe exatamente o que será alterado, quais outros programas dependem daquilo, quem escreveu a lógica original ou por que existe um campo chamado WS-IND-ESP-07-B.
Você abre o programa COBOL.
São 14 mil linhas.
Existem 27 COPYBOOKS, quatro acessos ao Db2, três arquivos VSAM, duas chamadas para programas que não aparecem em nenhuma documentação e um comentário histórico extremamente esclarecedor:
* ALTERADO CONFORME SOLICITACAO
Solicitação de quem?
Quando?
Por quê?
Qual regra mudou?
O comentário permanece em silêncio.
É nesse momento que o jovem programador percebe uma verdade fundamental:
O maior desafio de um sistema antigo não é lembrar sua sintaxe.
É compreender sua história.
Não entre em pânico.
Pegue sua toalha, abra o ISPF, prepare o café e venha conosco nesta viagem pelo universo dos sistemas legados.
Capítulo 1 — A ilusão do programador enciclopédia
No início da carreira, muitos programadores acreditam que precisam decorar tudo.
Decoram comandos COBOL.
Decoram parâmetros de JCL.
Decoram opções do DFSORT.
Decoram códigos SQL.
Decoram comandos TSO.
Decoram transações CICS.
Decoram até o nome daquele utilitário misterioso que apareceu uma única vez em um job de fechamento mensal.
A lógica parece simples:
Quanto mais coisas eu memorizar, melhor programador serei.
Essa ideia não é completamente absurda. Ter familiaridade com a linguagem ajuda. Conhecer comandos frequentes acelera o trabalho. Entender estruturas básicas é obrigatório.
O problema começa quando confundimos conhecimento com memorização.
Um programador pode decorar:
MOVE WS-NOME TO LK-NOME
Pode lembrar perfeitamente que:
//ARQSAI DD DSN=EMPRESA.CLIENTES.SAIDA,
// DISP=(NEW,CATLG,DELETE),
// UNIT=SYSDA,
// SPACE=(CYL,(10,5),RLSE)
Pode conhecer a sintaxe de:
EXEC SQL
SELECT NOME, SALDO
INTO :WS-NOME, :WS-SALDO
FROM CLIENTE
WHERE COD_CLIENTE = :WS-COD-CLIENTE
END-EXEC.
Mas nada disso garante que ele compreenda:
por que o arquivo é criado;
quem consome esse arquivo;
por que o saldo é calculado daquela maneira;
qual área de negócio depende do programa;
qual legislação motivou determinada condição;
o que acontece se a regra for removida;
por que o sistema não pode simplesmente ser “reescrito”.
Memorizar a sintaxe permite escrever instruções.
Compreender o sistema permite tomar decisões.
E sistemas não costumam quebrar porque alguém esqueceu uma vírgula que poderia ser consultada no manual.
Eles quebram porque alguém alterou uma regra sem compreender suas consequências.
Capítulo 2 — O cérebro não é uma biblioteca de referência
Seu cérebro é uma ferramenta extraordinária.
Mas ele não foi projetado para funcionar como uma central de documentação IBM contendo todas as versões de COBOL, CICS, Db2, DFSORT, IDCAMS, RACF, JCL, IMS, MQ e z/OS.
Mesmo profissionais experientes consultam documentação.
Aliás, profissionais experientes costumam consultar ainda mais, justamente porque sabem que a memória pode falhar.
Um iniciante pode pensar:
“Tenho certeza de que
DISP=(NEW,CATLG,DELETE)faz isso.”
Um veterano pensa:
“Tenho quase certeza. Portanto, vou confirmar antes de mexer em produção.”
Essa diferença parece pequena, mas representa anos de maturidade.
O exemplo do DISP
Observe:
//ARQSAI DD DSN=EMPRESA.RELATORIO.DIARIO,
// DISP=(NEW,CATLG,DELETE)
O parâmetro DISP possui três posições principais:
DISP=(status, normal, abnormal)
Neste exemplo:
NEW → o dataset será criado;
CATLG → se o step terminar normalmente, será catalogado;
DELETE → se o step terminar de forma anormal, será excluído.
Você pode esquecer isso.
Pode consultar rapidamente.
O manual devolve a resposta.
Mas agora surge uma pergunta muito mais importante:
Por que o dataset deve ser excluído em caso de falha?
Talvez porque um arquivo incompleto nunca possa ser processado pelo job seguinte.
Talvez porque uma versão parcial provoque duplicidade.
Talvez porque um sistema externo interprete sua existência como sinal de processamento concluído.
Talvez porque o dataset contenha informações financeiras e não deva permanecer disponível após uma falha.
Talvez porque alguém, em 1998, encontrou um erro catastrófico provocado por um arquivo incompleto e decidiu adicionar aquele DELETE.
A sintaxe explica o que acontece.
A história explica por que precisa acontecer.
O manual resolve a primeira dúvida.
A segunda talvez não esteja escrita em lugar algum.
Capítulo 3 — Todo programa legado é um sítio arqueológico
Quando você entra em um programa antigo, não está apenas lendo código.
Está realizando arqueologia digital.
Cada trecho pode representar uma camada histórica.
Veja:
IF WS-DATA-MOVIMENTO < 20000101
PERFORM 5000-TRATAR-REGRA-ANTIGA
ELSE
PERFORM 5100-TRATAR-REGRA-NOVA
END-IF
A pergunta superficial é:
O que esse
IFfaz?
A resposta é simples: ele escolhe duas rotinas com base em uma data.
A pergunta correta é:
O que aconteceu no ano 2000 para que o sistema precisasse de duas regras?
Pode ter ocorrido uma mudança tributária.
Uma alteração contratual.
Uma migração de moeda.
Uma incorporação empresarial.
Uma nova política de tarifas.
Uma adaptação ao bug do milênio.
O código é um fóssil de decisões anteriores.
Comentários arqueológicos
Sistemas antigos frequentemente possuem comentários como:
* AJUSTE JOAO 03/98
Ou:
* NAO REMOVER - PROBLEMA PRODUCAO
Ou ainda:
* ALTERACAO EMERGENCIAL
Esses comentários são equivalentes a encontrar uma placa em uma nave abandonada dizendo:
“Não pressione o botão vermelho.”
O problema é que ninguém explicou o que o botão faz.
Você pode remover a rotina e o programa continuar compilando.
Pode passar pelos testes unitários.
Pode funcionar durante semanas.
Até chegar o fechamento anual, quando aquela condição esquecida deveria impedir que uma transação extremamente rara fosse processada duas vezes.
Então o universo envia um pequeno lembrete em forma de incidente crítico.
Capítulo 4 — A diferença entre entender código e entender sistema
Um programa COBOL iniciante pode ser relativamente simples:
IF WS-SALDO >= WS-VALOR-COMPRA
SUBTRACT WS-VALOR-COMPRA FROM WS-SALDO
MOVE 'APROVADA' TO WS-STATUS
ELSE
MOVE 'RECUSADA' TO WS-STATUS
END-IF
Um iniciante entende rapidamente a lógica.
Saldo suficiente: aprova.
Saldo insuficiente: recusa.
Mas um sistema real pode conter:
IF WS-SALDO-DISPONIVEL >= WS-VALOR-COMPRA
IF WS-IND-BLOQUEIO NOT = 'S'
IF WS-LIMITE-DIARIO >= WS-VALOR-ACUMULADO
IF WS-COD-PAIS NOT = 999
PERFORM 7000-VALIDAR-RISCO
END-IF
END-IF
END-IF
END-IF
Agora entram regras de negócio.
O que é saldo disponível?
Qual a diferença entre saldo contábil e saldo disponível?
Quem determina o limite diário?
Por que o país
999possui tratamento especial?O bloqueio é financeiro, judicial ou antifraude?
A validação de risco é síncrona?
O que acontece quando o serviço de risco está indisponível?
Uma compra recusada deve gerar registro?
Existe reversão?
O processo precisa ser idempotente?
Compreender as instruções não significa compreender o sistema.
O programa é apenas uma peça.
O sistema inclui:
arquivos;
tabelas;
filas;
jobs;
transações;
operadores;
usuários;
contratos;
integrações;
janelas de processamento;
procedimentos de recuperação;
regras legais;
exceções históricas.
Um MOVE isolado é fácil.
Descobrir o efeito daquele MOVE em uma cadeia de cinquenta programas é outra aventura.
Capítulo 5 — O conhecimento tribal e os guardiões do sistema
Em muitas empresas, parte significativa do conhecimento não está nos manuais.
Está nas pessoas.
Esse conhecimento é frequentemente chamado de conhecimento tribal ou conhecimento tácito.
Ele aparece em frases como:
“Pergunte para o Carlos. Ele conhece esse processamento.”
“A Maria sabe por que o arquivo precisa chegar antes das 22 horas.”
“O operador do turno da noite já viu esse problema.”
“Esse programa foi feito pelo Roberto, que se aposentou.”
“Ninguém mexe nessa rotina sem falar com a área de faturamento.”
Essas pessoas são verdadeiros bancos de dados vivos.
Elas lembram de incidentes que nunca foram documentados.
Sabem quais mensagens podem ser ignoradas.
Conhecem os horários críticos.
Entendem exceções aparentemente absurdas.
Conseguem explicar por que uma solução considerada “feia” ainda é necessária.
A dica secreta da imagem
A imagem que inspira esta reflexão apresenta uma mensagem perfeita:
“Converse com os antigos.”
Essa é uma das melhores recomendações para quem trabalha com sistemas legados.
Não trate o profissional veterano como alguém que “apenas conhece tecnologia antiga”.
Ele pode ser o único elo restante entre o código atual e as decisões que originaram o sistema.
Pergunte:
Qual problema esse programa resolveu originalmente?
Quais são as situações mais perigosas?
Que alteração já provocou incidente?
Existe algum período em que não devemos mexer?
Quais programas dependem da saída?
Qual área de negócio deve validar a mudança?
Que regra parece inútil, mas não pode ser removida?
Quais mensagens indicam falha real?
Como o processo é recuperado?
Quem acompanha o processamento?
E, principalmente:
Registre as respostas.
Conhecimento oral que não é documentado está sempre a uma aposentadoria de distância do desaparecimento.
Capítulo 6 — O nível secreto chamado compreensão do negócio
Em um RPG técnico, o programador pode possuir várias habilidades:
Sintaxe COBOL ........ Nível 72
Comandos TSO ......... Nível 65
JCL .................. Nível 70
DFSORT ............... Nível 61
Db2 SQL .............. Nível 63
CICS .................. Nível 58
Tudo parece excelente.
Então aparece a habilidade mais importante:
Compreensão do negócio ... Nível 34
E ela evolui lentamente.
Muito lentamente.
Isso acontece porque tecnologia pode ser estudada de maneira estruturada.
Você pode fazer um curso de COBOL.
Pode estudar JCL.
Pode executar laboratórios de CICS.
Pode aprender SQL.
Mas compreender profundamente um negócio exige exposição ao sistema real.
Exige acompanhar incidentes.
Conversar com usuários.
Participar de testes.
Ler regras.
Conhecer exceções.
Entender o calendário operacional.
Observar como áreas diferentes interagem.
Descobrir que duas pessoas usam a mesma palavra com significados completamente diferentes.
Exemplo: “cliente ativo”
Parece um conceito simples.
Mas “cliente ativo” pode significar:
possui contrato válido;
movimentou a conta nos últimos 90 dias;
não está bloqueado;
possui saldo;
possui produto ativo;
não foi encerrado;
teve faturamento no mês;
está regular perante determinado cadastro.
O programador precisa descobrir qual definição vale naquele contexto.
O sistema pode utilizar diferentes definições em programas distintos.
Então surge uma rotina:
IF CAD-SITUACAO = 'A'
AND CAD-DATA-ULT-MOV >= WS-DATA-LIMITE
AND CAD-IND-BLOQUEIO = 'N'
MOVE 'S' TO WS-CLIENTE-ATIVO
END-IF
A sintaxe é elementar.
A regra de negócio, não.
Capítulo 7 — Passo a passo para compreender um programa antigo
Agora vamos transformar a reflexão em método.
Você recebeu um programa que nunca viu.
Por onde começar?
Passo 1 — Descubra quem executa o programa
Localize o JCL, PROC, transação CICS, chamada dinâmica ou processo que inicia a execução.
Procure por:
//STEP010 EXEC PGM=PGMCLIENT
Ou no CICS:
EXEC CICS
LINK PROGRAM('PGMCLIENT')
COMMAREA(WS-COMMAREA)
LENGTH(WS-TAMANHO)
END-EXEC
Ou em outro programa:
CALL 'PGMCLIENT' USING LK-DADOS
Pergunte:
O programa é batch ou online?
É executado sob demanda?
Roda diariamente?
Participa de fechamento?
É chamado por outros programas?
Possui dependências externas?
Passo 2 — Mapeie as entradas
Liste tudo que entra no programa:
arquivos sequenciais;
datasets VSAM;
tabelas Db2;
COMMAREA;
canais e containers;
filas MQ;
parâmetros;
SYSIN;
dados recebidos de outros programas.
Exemplo:
//ENTRADA DD DSN=EMPRESA.CLIENTES.DIARIO,DISP=SHR
Descubra quem cria essa entrada.
Um arquivo nunca “simplesmente aparece”.
Existe um produtor.
E todo produtor possui suas próprias regras.
Passo 3 — Mapeie as saídas
Liste:
arquivos gerados;
tabelas alteradas;
mensagens enviadas;
relatórios;
códigos de retorno;
chamadas a outros módulos;
atualizações em VSAM;
registros de auditoria.
Pergunte:
Quem depende dessa saída?
Essa pergunta frequentemente revela o verdadeiro alcance da alteração.
Passo 4 — Leia a estrutura antes dos detalhes
Em COBOL, observe primeiro:
IDENTIFICATION DIVISION;ENVIRONMENT DIVISION;arquivos;
WORKING-STORAGE;LINKAGE SECTION;fluxo da
PROCEDURE DIVISION;principais
PERFORM;tratamento de erros;
encerramento.
Não comece lendo linha por linha.
Crie um mapa mental.
Algo como:
1000-INICIALIZAR
2000-LER-ENTRADA
3000-PROCESSAR
4000-GRAVAR-SAIDA
9000-FINALIZAR
9990-TRATAR-ERRO
Depois aprofunde cada área.
Passo 5 — Identifique regras e exceções
Procure:
IF
EVALUATE
88-LEVEL
SEARCH
COMPUTE
ADD
SUBTRACT
EXEC SQL
CALL
Cada condição pode representar uma regra.
Marque perguntas como:
Por que esse código é tratado separadamente?
Por que essa data é fixa?
Por que esse valor possui teto?
Por que essa condição ignora determinados registros?
Passo 6 — Observe o tratamento de falhas
Procure:
RETURN-CODE;SQLCODE;RESPeRESP2;FILE STATUS;chamadas de erro;
ABEND;mensagens;
rollback;
arquivos de rejeição.
Exemplo:
IF WS-FILE-STATUS NOT = '00'
MOVE 12 TO RETURN-CODE
PERFORM 9990-TRATAR-ERRO
END-IF
Pergunte:
O processamento para?
Continua?
Rejeita o registro?
Pode ser reexecutado?
Existe risco de duplicidade?
Existe checkpoint?
Passo 7 — Converse com pessoas
Fale com:
analistas veteranos;
usuários;
operadores;
DBAs;
equipe de suporte;
segurança;
responsáveis por sistemas consumidores.
O código mostra o comportamento previsto.
As pessoas contam o que realmente acontece.
Passo 8 — Teste suas hipóteses
Não confunda interpretação com certeza.
Escreva hipóteses:
Acredito que o arquivo temporário existe para impedir que o job seguinte leia dados incompletos.
Depois valide.
Pode ser verdade.
Pode ser completamente falso.
O sistema legado aprecia humildade.
Passo 9 — Documente o que descobriu
Crie uma documentação mínima contendo:
finalidade;
entradas;
saídas;
dependências;
regras principais;
tratamento de erros;
recuperação;
contatos;
riscos;
histórico conhecido.
Você não precisa escrever uma enciclopédia.
Uma página clara já pode salvar horas futuras.
Passo 10 — Altere o mínimo necessário
Evite aproveitar a correção para “modernizar tudo”.
Uma alteração pequena deve permanecer pequena.
Separar refatoração de mudança funcional reduz riscos.
O velho conselho continua válido:
Primeiro compreenda. Depois preserve. Só então transforme.
Capítulo 8 — Dicas para o programador COBOL Padawan
Use folhas de referência
Crie ou mantenha referências rápidas para:
DISP;SPACE;DCB;códigos SQL;
FILE STATUS;abends comuns;
comandos TSO;
comandos SDSF;
opções DFSORT;
respostas CICS.
Não há vergonha em consultar.
A vergonha técnica seria adivinhar em produção.
Crie mapas de dependência
Mesmo um diagrama simples ajuda:
ARQCLIENT
|
v
PGM010
|
+--> Db2 CLIENTE
|
+--> PGM020
|
v
ARQSAIDA
|
v
JOBFATUR
Essa visão vale mais que decorar centenas de linhas.
Leia os logs
JES, SYSOUT, mensagens CICS, Db2 e relatórios de execução contam histórias.
Um programa pode parecer simples no código, mas os logs revelam:
volume real;
tempo de execução;
rejeições;
warnings;
dependências;
comportamento em falhas.
Use nomes de negócio em suas anotações
Não registre apenas:
Campo 47 recebe valor 3.
Registre:
O campo 47 indica transação cancelada após autorização, código 3.
Contexto transforma dado em conhecimento.
Desconfie de números mágicos
Exemplo:
IF WS-CODIGO = 17
Pergunte imediatamente:
O que significa 17?
Crie um nome:
88 OPERACAO-REVERSAO VALUE 17.
Agora o código começa a falar.
Capítulo 9 — Curiosidades do universo legado
Curiosidade 1 — Muitos bugs são decisões históricas fossilizadas
Nem todo comportamento estranho é um erro técnico.
Às vezes é uma regra antiga que continua existindo porque algum processo externo ainda depende dela.
Curiosidade 2 — Código feio pode proteger uma operação crítica
Uma rotina duplicada pode ter sido criada para isolar uma regra emergencial.
Antes de “limpar”, descubra por que foi separada.
Curiosidade 3 — O programa mais simples pode ser o mais perigoso
Um programa de 200 linhas que atualiza uma tabela central pode ser mais crítico do que outro de 20 mil linhas que apenas gera relatórios.
Complexidade técnica e criticidade operacional não são a mesma coisa.
Curiosidade 4 — O operador conhece o sistema de uma maneira diferente
Desenvolvedores conhecem o código.
Operadores conhecem o comportamento durante a madrugada, quando arquivos atrasam, jobs falham e sistemas externos ficam indisponíveis.
Escute-os.
Curiosidade 5 — O nome do arquivo pode esconder um contrato
Um dataset pode ser consumido por sistemas que você nem sabe que existem.
Excluir uma coluna “não utilizada” pode quebrar uma integração mantida por outra empresa.
Capítulo 10 — Os easter eggs escondidos na nave COBOL
Todo grande sistema possui mensagens secretas deixadas por seus antigos tripulantes.
Algumas aparecem como comentários.
Outras como nomes curiosos.
Outras como rotinas aparentemente inúteis.
Easter egg 1 — A condição impossível
IF WS-CODIGO = 9999
PERFORM ROTINA-ESPECIAL
END-IF
Ninguém encontra o código 9999 nos arquivos atuais.
Então alguém decide remover.
Meses depois, descobre-se que ele é enviado apenas durante a recuperação de desastre.
Easter egg 2 — O arquivo vazio obrigatório
Um job cria um arquivo mesmo quando não possui registros.
Parece desperdício.
Mas o job seguinte verifica a existência do dataset como sinal de conclusão.
Sem o arquivo vazio, a cadeia para.
Easter egg 3 — O campo não usado
Um campo do copybook nunca é lido pelo programa.
Então parece seguro removê-lo.
Porém um sistema externo lê o registro completo pela posição.
Ao diminuir o layout, todos os campos seguintes se deslocam.
Parabéns: você encontrou o monstro secreto do LRECL.
Easter egg 4 — A rotina do dia 29 de fevereiro
Ela quase nunca executa.
Talvez a equipe nem consiga reproduzi-la facilmente.
Mas a cada quatro anos ela acorda.
Como um chefe final que segue calendário próprio.
Easter egg 5 — O comentário “não alterar”
Comentários assim nem sempre são superstição.
Frequentemente são cicatrizes de incidentes.
Trate-os como pistas, não como explicações definitivas.
Capítulo 11 — O que realmente merece ser lembrado
Você não precisa lembrar todos os parâmetros.
Mas algumas coisas merecem permanecer em sua memória profissional.
Lembre-se de perguntar:
Qual problema estamos resolvendo?
Quem depende desse processamento?
O que acontece em caso de falha?
A operação pode ser repetida?
Existe risco de duplicidade?
Quem valida a regra?
Qual é a fonte oficial da informação?
Existe uma exceção histórica?
Como voltar atrás?
O que precisa ser documentado?
Essas perguntas são mais valiosas do que decorar a sintaxe completa de cinquenta utilitários.
A tecnologia muda.
As boas perguntas continuam úteis.
Capítulo 12 — A evolução real do desenvolvedor
O programador iniciante se orgulha de lembrar comandos.
O intermediário se orgulha de resolver problemas.
O sênior se preocupa em não criar novos problemas.
O especialista compreende que software é um sistema sociotécnico: código, infraestrutura, negócio, pessoas, história e riscos.
A evolução pode ser vista assim:
Nível 1 — Sintaxe
Você aprende a escrever:
PERFORM PROCESSAR-REGISTRO
Nível 2 — Estrutura
Você entende como organizar o programa.
Nível 3 — Dados
Você compreende arquivos, bancos, layouts e interfaces.
Nível 4 — Execução
Você entende JCL, CICS, filas, transações e dependências.
Nível 5 — Arquitetura
Você enxerga o programa dentro do ecossistema.
Nível 6 — Operação
Você compreende disponibilidade, performance, recuperação e suporte.
Nível 7 — Negócio
Você entende por que o sistema existe.
Nível 8 — História
Você compreende como ele chegou ao estado atual.
Nível 9 — Evolução segura
Você consegue transformá-lo sem destruir as razões pelas quais sobreviveu.
Esse é o verdadeiro caminho do Mestre Jedi do Mainframe.
Conclusão — Não entre em pânico, mas também não altere o IF sem perguntar
Esquecer sintaxe nunca foi o grande problema.
A sintaxe pode ser pesquisada.
O manual pode ser aberto.
Uma folha de referência pode ser consultada.
Um exemplo pode ser testado.
A memória técnica é útil, mas não é o recurso mais raro de um desenvolvedor.
O recurso mais raro é a capacidade de dedicar atenção suficiente para compreender um sistema complexo.
Compreender:
sua finalidade;
suas regras;
suas dependências;
suas falhas;
suas cicatrizes;
seus usuários;
sua história.
Um sistema legado não é apenas um conjunto de programas antigos.
É uma cápsula do tempo contendo decisões de negócio acumuladas ao longo de décadas.
Cada IF pode representar uma reunião.
Cada COPYBOOK pode representar um contrato.
Cada arquivo pode representar uma integração.
Cada código fixo pode representar uma exceção.
Cada comentário misterioso pode representar um incidente esquecido.
Por isso, quando receber sua próxima “pequena alteração”, não comece modificando o código.
Comece fazendo perguntas.
Localize o fluxo.
Mapeie entradas e saídas.
Descubra os consumidores.
Converse com os usuários.
Procure os veteranos.
Leia os logs.
Teste as hipóteses.
Registre as respostas.
E só então toque no programa.
No Guia do Viajante das Galáxias, a resposta para a vida, o universo e tudo mais era 42.
No Mainframe, a resposta costuma ser um pouco diferente:
“Depende da regra de negócio.”
E, em algum lugar do data center, existe um antigo analista que sabe exatamente qual regra é essa.
Talvez seja uma boa ideia convidá-lo para um café antes que alguém decida substituir o sistema inteiro por uma aplicação escrita às pressas em uma tecnologia que também será considerada legada daqui a vinte anos.
Porque linguagens envelhecem.
Plataformas evoluem.
Sintaxes mudam.
Mas sistemas continuam existindo enquanto resolverem problemas importantes.
E o melhor desenvolvedor não é aquele que carrega todos os manuais na cabeça.
É aquele que sabe onde encontrar a sintaxe, com quem conversar, quais perguntas fazer e, principalmente, o que jamais deve ser esquecido.