☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

Mostrar mensagens com a etiqueta Lambda. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Lambda. Mostrar todas as mensagens

sábado, 10 de junho de 2023

⚔️ YUUYA TENJOU E A DUNGEON DAS ARROW FUNCTIONS — QUANDO O COBOL ENCONTROU A SETA =>

 

Bellacosa Mainframe apresenta o Arrow Function e Lambda Functions

☕ Um Café no Bellacosa Mainframe

⚔️ YUUYA TENJOU E A DUNGEON DAS ARROW FUNCTIONS — QUANDO O COBOL ENCONTROU A SETA =>

Lambda, Arrow Functions, programação funcional, callbacks, map, filter, reduce, pipelines, legibilidade, carga cognitiva — e o dia em que um programador COBOL descobriu que x => x * 2 não era uma tentativa de economizar caracteres no teclado.



🎬 PRÓLOGO — YUUYA ENCONTROU UMA PORTA ESTRANHA

Todo programador possui uma porta para outro mundo.

Para Yuuya Tenjou, em Isekai de Cheat Skill, foi literalmente uma passagem para outro mundo.

Para um programador COBOL, às vezes basta abrir um programa JavaScript moderno.

Você entra inocentemente esperando encontrar variáveis, condições, loops e funções.

De repente aparece:

clientes
    .filter(c => c.ativo)
    .map(c => c.nome)
    .sort((a, b) => a.localeCompare(b));

O programador COBOL observa aquilo durante alguns segundos.

Depois mais alguns.

Finalmente pergunta:

— Cadê o IF?

Silêncio.

— Cadê o PERFORM?

Nada.

— Cadê o END-IF?

Apenas uma seta olhando para ele:

=>

Bem-vindo à Dungeon das Arrow Functions.

O objetivo deste artigo não é convencer você de que arrow functions são maravilhosas, nem dizer que programação funcional é superior ao COBOL.

Nosso objetivo é muito mais interessante:

entender por que essa maneira de programar existe, que problema ela resolve e, principalmente, como um programador acostumado ao pensamento COBOL pode aprender a lê-la rapidamente.

Pegue o café.

Yuuya abriu a porta.

Nós vamos entrar.



🏰 CAPÍTULO 1 — COBOL FOI FEITO PARA SER LIDO

Existe uma razão histórica para um programador COBOL estranhar JavaScript moderno.

Veja:

IF WS-IDADE >= 18
    DISPLAY 'ADULTO'
END-IF

Mesmo alguém com pouco conhecimento de COBOL consegue imaginar o que está acontecendo.

Há uma condição.

Há uma ação.

Há um encerramento explícito.

Compare com:

p => p.idade >= 18

A primeira impressão pode ser:

— Isso não foi construído para humanos.

Na realidade, foi construído para humanos que já dominam determinado vocabulário.

Esse detalhe é importante.

Quando você lê:

PERFORM VARYING IDX FROM 1 BY 1
    UNTIL IDX > WS-TOTAL

um iniciante também pode achar estranho.

Mas depois de anos trabalhando com COBOL, seu cérebro não interpreta individualmente:

PERFORM
VARYING
FROM
BY
UNTIL

Você reconhece um padrão inteiro:

LOOP.

É exatamente isso que precisa acontecer com:

x => x * 2

O objetivo não é interpretar cada símbolo.

O objetivo é reconhecer o padrão.



🧙 CAPÍTULO 2 — PRIMEIRA MAGIA DE YUUYA: => SIGNIFICA RECEBE E DEVOLVE

Vamos estabelecer nosso primeiro cheat skill.

Sempre que encontrar:

x => expressão

leia mentalmente:

RECEBE x E DEVOLVE expressão.

Portanto:

x => x * 2

vira:

recebe x e devolve x * 2.

Isso:

idade => idade >= 18

vira:

recebe idade e devolve verdadeiro se idade for maior ou igual a 18.

Isso:

cliente => cliente.ativo

vira:

recebe cliente e devolve o estado de cliente.ativo.

E:

(a, b) => a + b

significa:

recebe a e b e devolve a soma dos dois.

Pronto.

A seta perdeu boa parte da magia.



⚔️ CAPÍTULO 3 — LAMBDA NÃO É ARROW FUNCTION

Antes de avançarmos, precisamos separar dois conceitos.

Lambda é uma ideia.

Arrow function é uma sintaxe.

O conceito de funções lambda é muito anterior ao JavaScript moderno e está relacionado ao cálculo lambda desenvolvido por Alonzo Church na década de 1930.

O cálculo lambda tornou-se uma das bases teóricas da ciência da computação e influenciou profundamente linguagens funcionais.

JavaScript apenas oferece uma maneira compacta de escrever determinadas funções.

Compare:

function dobrar(numero) {
    return numero * 2;
}

com:

numero => numero * 2

A segunda forma é uma arrow function.

Conceitualmente ambas representam comportamento:

ENTRADA
   |
   V
numero
   |
   V
numero * 2
   |
   V
SAÍDA

A diferença principal aqui é a quantidade de cerimônia sintática.



🧠 CAPÍTULO 4 — POR QUE ALGUÉM QUIS DIMINUIR AS FUNÇÕES?

Imagine que precisamos filtrar clientes adultos.

Poderíamos escrever:

function clienteAdulto(cliente) {
    return cliente.idade >= 18;
}

const adultos = clientes.filter(clienteAdulto);

Isso é perfeitamente válido.

Mas talvez essa função seja usada somente naquele ponto.

Então podemos escrever:

const adultos =
    clientes.filter(cliente => cliente.idade >= 18);

A função foi criada exatamente onde é necessária.

Essa é uma das grandes vantagens das lambdas:

comportamentos pequenos podem ser definidos e passados diretamente para outras operações.

Em outras palavras, funções passam a ser tratadas como valores.

Podemos passar uma função para outra função.

Esse conceito recebe frequentemente o nome de funções de primeira classe.


📦 CAPÍTULO 5 — QUANDO O COMPORTAMENTO VIRA DADO

Aqui começa a parte realmente importante.

Um programador COBOL está acostumado com algo semelhante a:

PERFORM VALIDAR-CLIENTE

Existe uma rotina chamada VALIDAR-CLIENTE.

Agora imagine que pudéssemos entregar essa rotina para outra rotina dizendo:

Tome esta regra e execute-a para cada elemento.

É aproximadamente isso que acontece aqui:

clientes.filter(clienteAdulto);

Estamos entregando clienteAdulto para filter.

Mas também podemos criar a regra diretamente:

clientes.filter(
    cliente => cliente.idade >= 18
);

filter recebe comportamento.

Isso permite construir abstrações extremamente poderosas.


🏭 CAPÍTULO 6 — O COBOLZEIRO PENSA EM PERFORM

Imagine:

MOVE ZERO TO WS-CONTADOR

PERFORM VARYING IDX FROM 1 BY 1
    UNTIL IDX > WS-TOTAL

    IF CLIENTE-ATIVO(IDX) = 'S'
        ADD 1 TO WS-CONTADOR
    END-IF

END-PERFORM

Aqui estamos descrevendo explicitamente o mecanismo:

  1. inicializar;

  2. criar índice;

  3. incrementar índice;

  4. testar limite;

  5. acessar elemento;

  6. testar condição;

  7. executar ação.

Isso é pensamento imperativo.

Estamos dizendo:

computador, faça isso, depois aquilo, depois aquilo.

Agora observe:

clientes.filter(cliente => cliente.ativo);

Aqui estamos mais próximos de:

Dos clientes, quero aqueles que estão ativos.

Não especificamos explicitamente como percorrer a coleção.

filter já sabe fazer isso.

Nós fornecemos apenas a regra.

Essa diferença é fundamental.


🔮 CAPÍTULO 7 — IMPERATIVO VERSUS DECLARATIVO

Simplificando bastante:

Imperativo

Descreve como fazer.

PEGUE REGISTRO
TESTE
SE ACEITO
   MOVA
INCREMENTE
VOLTE

Declarativo

Descreve mais diretamente o que queremos.

FILTRAR CLIENTES ATIVOS

Programação funcional frequentemente permite aproximar o código dessa segunda maneira de pensar.

Isso não significa que uma seja universalmente melhor.

Significa que estamos trabalhando em níveis diferentes de abstração.


🗺️ CAPÍTULO 8 — O COPYBOOK SECRETO DAS FUNÇÕES FUNCIONAIS

Yuuya encontra agora um pergaminho escondido na dungeon.

Nele estão apenas sete palavras.

Memorize-as:

FILTER = QUEM FICA?

MAP = VIRA O QUÊ?

FIND = QUAL DELES?

SOME = EXISTE ALGUM?

EVERY = TODOS?

REDUCE = ACUMULA COMO?

SORT = COMPARA COMO?

Esse pequeno mapa muda completamente a maneira de ler JavaScript moderno.


🧹 CAPÍTULO 9 — FILTER: QUEM PASSA PELO PORTÃO?

Considere:

clientes.filter(
    cliente => cliente.idade >= 18
);

Não comece pela lambda.

Veja primeiro:

filter

Pergunte:

Quem fica?

Agora leia:

cliente => cliente.idade >= 18

Resposta:

clientes cuja idade seja maior ou igual a 18.

filter funciona como uma peneira.

Entrada:

Ana     15
Maria   27
João    17
Carlos  44

Regra:

IDADE >= 18

Saída:

Maria   27
Carlos  44

A lambda usada por filter normalmente produz:

TRUE

ou:

FALSE

TRUE passa.

FALSE fica para trás.


🪄 CAPÍTULO 10 — MAP: TRANSFORME UMA COISA EM OUTRA

Agora:

clientes.map(cliente => cliente.nome);

Pergunta:

Vira o quê?

Cada cliente vira seu nome.

Entrada:

[
    { nome: "Ana", idade: 30 },
    { nome: "Maria", idade: 41 }
]

Saída:

[
    "Ana",
    "Maria"
]

Pense:

CLIENTE --------> NOME
CLIENTE --------> NOME
CLIENTE --------> NOME

map é uma transformação.


🔎 CAPÍTULO 11 — FIND: ENCONTRE UM REGISTRO

clientes.find(
    cliente => cliente.id === 123
);

Leia:

encontre o cliente cujo ID seja 123.

Mentalmente, isso é muito próximo de procurar um registro por determinada condição.

O interessante é que não precisamos escrever explicitamente toda a lógica de iteração.


🧪 CAPÍTULO 12 — SOME E EVERY

Veja:

clientes.some(cliente => cliente.bloqueado);

Pergunta:

Existe algum cliente bloqueado?

Agora:

clientes.every(cliente => cliente.ativo);

Pergunta:

Todos os clientes estão ativos?

Esse vocabulário começa a tornar o código surpreendentemente expressivo depois que você aprende a lê-lo semanticamente.


👹 CAPÍTULO 13 — YUUYA ENCONTRA O BOSS: REDUCE

E finalmente chegamos ao monstro que assusta muita gente:

pedidos.reduce(
    (acc, pedido) => acc + pedido.valor,
    0
);

O COBOLzeiro olha:

— Agora vocês passaram dos limites.

Calma.

Vamos desmontar.

O 0 é o valor inicial.

Portanto:

ACC = 0

Depois:

(acc, pedido) => acc + pedido.valor

significa:

recebe acumulador e pedido e devolve acumulador + valor do pedido.

Em COBOL conceitualmente teríamos:

MOVE ZERO TO WS-TOTAL

PERFORM VARYING IDX FROM 1 BY 1
    UNTIL IDX > WS-QTD-PEDIDOS

    ADD PEDIDO-VALOR(IDX)
        TO WS-TOTAL

END-PERFORM

Portanto:

pedidos.reduce(
    (total, pedido) => total + pedido.valor,
    0
);

é essencialmente:

TOTAL = TOTAL + PEDIDO-VALOR

repetido para todos os pedidos.

O dragão morreu.


🏗️ CAPÍTULO 14 — O PODER REAL ESTÁ NO PIPELINE

Agora podemos juntar tudo:

const total =
    pedidos
        .filter(pedido => pedido.status === "PAGO")
        .map(pedido => pedido.valor)
        .reduce(
            (total, valor) => total + valor,
            0
        );

Não tente ler cada símbolo.

Primeiro veja:

PEDIDOS
   |
FILTER
   |
MAP
   |
REDUCE

Agora pergunte:

FILTER

Quem fica?

PEDIDOS PAGOS

MAP

Vira o quê?

PEDIDO → VALOR

REDUCE

Acumula como?

SOMA

Então o algoritmo inteiro significa:

Pegue os pedidos pagos, transforme-os em valores e some esses valores.


🖥️ CAPÍTULO 15 — ISSO PARECE MAIS MAINFRAME DO QUE VOCÊ IMAGINA

Podemos imaginar:

INPUT DATASET
      |
      V
    FILTER
      |
      V
 TRANSFORMATION
      |
      V
 AGGREGATION
      |
      V
   OUTPUT

Familiar?

Muito.

Um pipeline:

dados
    .filter(...)
    .map(...)
    .reduce(...)

pode ser mentalmente interpretado como uma sequência de etapas de processamento.

É quase como observar um fluxo batch.

Você primeiro identifica:

INPUT
STEP01
STEP02
STEP03
OUTPUT

Depois entra em cada etapa.

Essa é uma excelente estratégia para um programador mainframe.


📞 CAPÍTULO 16 — CALLBACK: TOME ESTA ROTINA E CHAME DEPOIS

Arrow functions aparecem muito em callbacks.

Veja:

setTimeout(() => {
    console.log("Olá");
}, 1000);

Primeiro:

() => {
    console.log("Olá");
}

significa:

função que não recebe parâmetros e imprime "Olá".

Agora:

setTimeout(FUNCAO, 1000);

significa aproximadamente:

execute essa função depois de 1000 milissegundos.

Poderíamos escrever:

function dizerOla() {
    console.log("Olá");
}

setTimeout(dizerOla, 1000);

A arrow function evita criar um nome para uma rotina utilizada apenas naquele ponto.


⚠️ CAPÍTULO 17 — MENOS CARACTERES NÃO SIGNIFICA MELHOR CÓDIGO

Agora Yuuya encontra uma armadilha.

Veja:

x => x.a > 10

Curto?

Sim.

Legível?

Depende.

O que é x?

O que é a?

Por que 10?

Compare:

cliente =>
    cliente.saldo > LIMITE_CREDITO

Muito melhor.

A arrow function não era o problema.

O problema eram os nomes.

Essa é uma lição extremamente importante.

Código compacto não é necessariamente código simples.


🧠 CAPÍTULO 18 — COMPRESSÃO DE CÓDIGO E DESCOMPRESSÃO CEREBRAL

Imagine:

x.filter(a=>a.b).map(c=>c.d).reduce((e,f)=>e+f,0)

Poucos caracteres.

Mas o cérebro precisa descobrir:

x = ?
a = ?
b = ?
c = ?
d = ?
e = ?
f = ?

Economizamos digitação e transferimos o custo para quem lê.

É como compactar o programa.

O desenvolvedor precisa executar mentalmente:

UNZIP ALGORITMO

antes de poder entendê-lo.

Código de produção vive muito mais tempo sendo lido do que sendo digitado.

Isso vale para COBOL.

Vale para JavaScript.

Vale para Java.

Vale para Python.

E valerá para a próxima linguagem da moda.


🧱 CAPÍTULO 19 — QUANDO NÃO USAR UMA LAMBDA GIGANTESCA

Isto é aceitável:

pedidos.filter(pedido => pedido.ativo);

Mas considere:

pedidos.filter(pedido =>
    pedido.ativo &&
    pedido.valor > 1000 &&
    pedido.cliente?.status !== "BLOQUEADO" &&
    pedido.itens.some(item => item.quantidade > 0)
);

Ainda funciona.

Mas talvez seja melhor escrever:

function pedidoElegivel(pedido) {
    return (
        pedido.ativo &&
        pedido.valor > 1000 &&
        pedido.cliente?.status !== "BLOQUEADO" &&
        pedido.itens.some(
            item => item.quantidade > 0
        )
    );
}

pedidos.filter(pedidoElegivel);

Agora o algoritmo principal diz:

filtre pedidos elegíveis.

A regra de elegibilidade está isolada.

Isso lembra muito:

PERFORM VALIDAR-PEDIDO

em vez de colocar 47 condições no meio do processamento principal.


🧭 CAPÍTULO 20 — O MÉTODO YUUYA PARA LER LAMBDAS

Encontrou:

usuarios
    .filter(u => u.ativo)
    .map(u => ({
        nome: u.nome,
        total: u.pedidos.reduce(
            (a, p) => a + p.valor,
            0
        )
    }))
    .filter(u => u.total > 1000);

Não entre em pânico.

Faça quatro passagens.

PASSO 1 — IDENTIFIQUE A ENTRADA

usuarios

Estamos trabalhando com usuários.

PASSO 2 — IGNORE AS LAMBDAS

Leia somente:

FILTER
MAP
FILTER

Já temos:

USUÁRIOS
   |
 FILTRAR
   |
TRANSFORMAR
   |
 FILTRAR

PASSO 3 — ABRA AS REGRAS EXTERNAS

Primeiro:

u => u.ativo

Somente usuários ativos.

Depois:

u => ({
    nome: u.nome,
    total: ...
})

Transforma usuário em:

NOME + TOTAL

Depois:

u => u.total > 1000

Mantém total superior a 1000.

PASSO 4 — ENTRE NA LAMBDA INTERNA

u.pedidos.reduce(
    (a, p) => a + p.valor,
    0
)

Tradução:

some os valores dos pedidos.

Resultado final:

USUÁRIOS
     |
     V
SOMENTE ATIVOS
     |
     V
CALCULAR NOME + TOTAL DOS PEDIDOS
     |
     V
TOTAL > 1000

Agora o código deixou de ser hieróglifo.


⚡ CAPÍTULO 21 — NÃO EXECUTE O PROGRAMA INTEIRO NA CABEÇA

Essa talvez seja a melhor dica deste artigo.

Programadores experientes não necessariamente entendem código complexo porque conseguem simular cinquenta instruções simultaneamente.

Eles reconhecem padrões.

Um operador de mainframe experiente olha:

IEFBR14

e não precisa analisar cada caractere.

Um programador COBOL olha:

PERFORM VARYING

e reconhece imediatamente um padrão.

Queremos construir o mesmo reflexo:

.filter(...)

→ seleção.

.map(...)

→ transformação.

.reduce(...)

→ agregação.

Depois disso, sua velocidade de leitura aumenta enormemente.


🎒 CAPÍTULO 22 — A DUNGEON TEM NÍVEIS DE ABSTRAÇÃO

Uma das grandes mudanças da programação moderna é o aumento do nível de abstração.

Antigamente poderíamos escrever:

PEGUE ELEMENTO
COMPARE
INCREMENTE
COPIE
VOLTE

Hoje escrevemos:

filter(...)

Isso não significa que o loop desapareceu.

Ele foi encapsulado.

Esse conceito é importantíssimo.

Abstração não elimina trabalho.

Abstração esconde implementação atrás de uma interface.

Quando fazemos:

SELECT *
FROM CLIENTES
WHERE ATIVO = 'S';

também não especificamos como o banco deve percorrer fisicamente cada página.

O SGBD resolve.

Um COBOLzeiro já trabalha com abstrações há décadas.

Talvez apenas não chamasse dessa maneira.


📜 CAPÍTULO 23 — CURIOSIDADE: COBOL TAMBÉM É UMA GRANDE ABSTRAÇÃO

Imagine explicar para um programador Assembly de décadas atrás:

ADD WS-VALOR TO WS-TOTAL

Ele poderia responder:

— Preguiçosos! Cadê os registradores?

😂

Toda geração acha que a próxima está escondendo detalhes demais.

Assembly abstraiu código de máquina.

COBOL abstraiu muitos detalhes da máquina.

SQL abstraiu mecanismos de acesso aos dados.

Bibliotecas abstraíram algoritmos.

Frameworks abstraíram infraestrutura.

filter, map e reduce abstraem padrões de iteração.

A história da programação é, em boa medida, a história da criação de abstrações.


🥚 EASTER EGG — 03:17 NA DUNGEON

Às 03:17, Yuuya encontra um programa:

const incidente =
    eventos
        .filter(evento => evento.critico)
        .find(evento => evento.hora === "03:17");

O operador pergunta:

— Encontrou a causa?

Yuuya responde:

— Não. Só encontrei correlação.

O veterano do mainframe sorri.

Finalmente alguém aprendeu troubleshooting.

Porque:

CORRELAÇÃO != CAUSALIDADE

Nem mesmo uma arrow function possui Cheat Skill suficiente para mudar isso.


🧰 CAPÍTULO 24 — EXERCÍCIO PARA TREINAR SEU CÉREBRO COBOL

Pegue:

transacoes
    .filter(t => t.aprovada)
    .map(t => t.valor)
    .reduce((total, valor) => total + valor, 0);

Não traduza sintaxe.

Faça:

ENTRADA:
TRANSAÇÕES

FILTER:
QUEM FICA?

APROVADAS

MAP:
VIRA O QUÊ?

VALOR

REDUCE:
ACUMULA COMO?

SOMA

Conclusão:

some o valor de todas as transações aprovadas.

Agora imagine o equivalente COBOL:

MOVE ZERO TO WS-TOTAL

PERFORM VARYING IDX FROM 1 BY 1
    UNTIL IDX > WS-QTD-TRANSACOES

    IF TRANSACAO-APROVADA(IDX) = 'S'
        ADD TRANSACAO-VALOR(IDX)
            TO WS-TOTAL
    END-IF

END-PERFORM

São dois estilos descrevendo essencialmente a mesma intenção.


🏆 CAPÍTULO 25 — QUANDO ARROW FUNCTIONS REALMENTE BRILHAM

Elas são especialmente convenientes quando a função é:

  • pequena;

  • local;

  • usada uma única vez;

  • semanticamente evidente;

  • passada como callback;

  • utilizada em transformação de coleções.

Por exemplo:

precos.map(preco => preco * 1.10);

Perfeitamente razoável.

Mas quando a lógica cresce, nomes podem ser superiores.

Em vez de:

clientes.filter(c =>
    c.a &&
    c.b &&
    !c.x &&
    c.y > 500
);

prefira algo como:

clientes.filter(clienteElegivel);

O nome carrega significado.


🧙 CAPÍTULO 26 — A REGRA DE OURO DE YUUYA

Depois de atravessar a dungeon, Yuuya escreve na parede:

Não tente entender a seta. Entenda o fluxo dos dados.

Essa é a mudança fundamental.

Diante de:

dados
    .filter(...)
    .map(...)
    .reduce(...)

pergunte:

DE ONDE VÊM OS DADOS?

QUEM SOBREVIVE?

NO QUE SE TRANSFORMAM?

COMO SÃO AGREGADOS?

QUAL É A SAÍDA?

Essas perguntas funcionam quase independentemente da linguagem.


☕ EPÍLOGO — O COBOLZEIRO VOLTA DA DUNGEON

Yuuya atravessou a porta para outro mundo e descobriu habilidades que inicialmente pareciam mágicas.

O programador COBOL pode passar por experiência semelhante quando encontra programação funcional moderna.

No começo:

x => x * 2

parece uma linguagem inventada por alguém que cobrava por caractere.

Depois entendemos:

RECEBE X
DEVOLVE X * 2

Então encontramos:

filter

e aprendemos:

QUEM FICA?

Encontramos:

map

e perguntamos:

VIRA O QUÊ?

Encontramos:

reduce

e finalmente percebemos:

ACUMULA COMO?

A dungeon deixa de parecer tão assustadora.

Arrow functions não foram criadas porque funções tradicionais estavam erradas.

Elas surgiram porque determinadas situações envolvem pequenos comportamentos usados localmente, especialmente callbacks e transformações de coleções, e escrever toda a cerimônia de uma função nomeada repetidamente pode tornar o código desnecessariamente verboso.

Mas existe uma lição ainda mais importante.

Concisão não é sinônimo de legibilidade.

Isto:

x.filter(a=>a.b).map(c=>c.d).reduce((e,f)=>e+f,0)

pode impressionar alguém pela quantidade de lógica comprimida em uma linha.

Mas software corporativo não é campeonato de quem digita menos.

O programa que você escreve hoje poderá ser investigado durante um incidente às 03:17 daqui a quinze anos.

Talvez por alguém que ainda nem entrou na empresa.

Talvez por um jovem programador.

Talvez por uma IA.

Talvez por você mesmo, tentando lembrar:

"Quem foi o animal que escreveu isso?"

E então o Git responde:

AUTHOR: VOCÊ
DATE: 2026

Nesse momento você compreenderá definitivamente por que nomes importam.

COBOL possui algo valioso para ensinar às linguagens modernas: software também é comunicação entre seres humanos.

Programação funcional possui algo igualmente valioso para ensinar ao COBOLzeiro: nem sempre precisamos descrever cada passo mecânico de uma transformação quando podemos expressar diretamente sua intenção.

O verdadeiro Cheat Skill não é decorar:

=>

É aprender a reconhecer:

ENTRADA
   |
   V
SELEÇÃO
   |
   V
TRANSFORMAÇÃO
   |
   V
AGREGAÇÃO
   |
   V
SAÍDA

Quando você começa a enxergar isso, deixa de tentar executar cada instrução mentalmente.

Você passa a enxergar a arquitetura do algoritmo.

E então aquela linha:

pedidos
    .filter(pedido => pedido.pago)
    .map(pedido => pedido.valor)
    .reduce((total, valor) => total + valor, 0);

deixa de parecer uma magia de outro mundo.

Você olha para ela e pensa:

PEDIDOS
  ↓
PAGOS
  ↓
VALORES
  ↓
SOMA

Yuuya guarda a espada.

O COBOLzeiro termina o café.

E a misteriosa porta => permanece aberta.

Desta vez, porém, não existe mais monstro do outro lado.

Existe apenas outra maneira de escrever algoritmos.


☕ COPYBOOK FINAL DO BELLACOSA MAINFRAME

Se quiser guardar apenas uma página deste artigo, guarde esta:

=>      RECEBE → DEVOLVE

FILTER  QUEM FICA?

MAP     VIRA O QUÊ?

FIND    QUAL DELES?

SOME    EXISTE ALGUM?

EVERY   TODOS?

REDUCE  ACUMULA COMO?

SORT    COMPARA COMO?

E diante de qualquer pipeline funcional:

1. DESCUBRA A ENTRADA.

2. LEIA SOMENTE OS NOMES DAS OPERAÇÕES.

3. IDENTIFIQUE O FLUXO DOS DADOS.

4. ABRA UMA LAMBDA DE CADA VEZ.

5. TROQUE => POR "RECEBE E DEVOLVE".

6. DÊ NOMES HUMANOS ÀS VARIÁVEIS.

7. SE A LAMBDA FICOU GRANDE DEMAIS,
   EXTRAIA UMA FUNÇÃO COM NOME.

8. NÃO EXECUTE O PROGRAMA INTEIRO
   NA CABEÇA.

9. RECONHEÇA PADRÕES.

10. LEMBRE-SE:
    MENOS CARACTERES != MENOS COMPLEXIDADE.

No fim das contas, seja em COBOL, JavaScript, Java, Python ou no próximo isekai tecnológico, continuamos fazendo a mesma coisa:

recebendo dados, tomando decisões, transformando informações e produzindo resultados.

A sintaxe muda.

A dungeon muda.

Os monstros ganham nomes novos.

Mas o algoritmo continua lá.

E um programador que aprende a enxergá-lo por trás da sintaxe já desbloqueou seu verdadeiro Cheat Skill.

Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...