Programação
Técnicas Alternativas de
Cléber Zavadniak
2020
Cléber Zavadniak
- ~1999: "Apostila de C"
- 2004: Ciência da Computação, UFPR
- 2004: C[MCUs] / C++
- Linux+Networks
- PHP+MySQL
- 2013: Python[Django]+MySQL+integrações
- Python[Django]+Postgres+EDA+Microsserviços+REST
- Python[Django]+Postgres+RPC+Mezzoserviços+REST
- Python[Flask]+SQLAlchemy+Postgres+QuasiREST
- 2020: Go+Postgres+GraphQL
https://cleber.solutions/
Apoio:CyberLabs
Apoio: Cyberlabs
Commodities
versus
Valor
Commodity
- Produto de baixo valor agregado
- Não sofre processo de alteração
- Pouco diferenciado
Programação de Commodities
- Comunicação via HTTP
- Operações sobre arquivos
- Interface REST/GraphQL
- Comunicação com o banco de dados
- Desktop:
- Visualizador de imagens
- Editor de texto plano
Why not X?
- Why not Rust?
- Why not Julia?
- Why not Lua?
- Você fica meio sem jeito
- e fica pensando em como responder.
- Mas no fundo sabe que não tem resposta.
- Porque não faz diferença, realmente.
"Features" de linguagem
importam muito menos que
outras características de ecossistema.
Programação de Valor
- Sistemas operacionais
- SGBD
- Visão computacional
- Fotogrametria
- Análise de sinais
- Cartografia
- Algoritmos complexos em geral
- Renderizador de HTML
- Encoder/decoder de mídia
Why X?
Agora, sim, a pergunta faz sentido.
Commodity != "ruim"
Docker
Sistema Operacional
Seu software
Docker
- HTTP server/client
- CLI client
- Algumas syscalls
- Manipulação de FS
Commodity.
Hardware
C#
Java
JS
Python
Go
PHP
Técnicas Tradicionais
Fortran
COBOL
C++
C
asm
Nem tudo nesse mundo são pregos.
Técnicas Alternativas
Nos trilhos de algumas linguagens
Menções honrosas
LISP
Haskell
Shell Script
Zig
Esqueça tudo, agora.
Prolog
Programação Lógica
Programação Lógica
- Baseada em... Lógica
- Basicamente, o estudo estruturado da verdade
- Entre outras coisas, "cálculo de predicado"
- Cerne dos programas em Prolog: encontrar a verdade.
Esqueceu tudo?
- Variáveis
- Funções
- Controle de fluxo.
No terminal
swipl -f awesome.pl
swipl -f roads.pl
path(a, e, Path, Distance).
path(a, e, Path, Distance), [H|T] = Path, [H2|T2] = T, H2 = b.
append([a], [b], X).
append(A, B, [a, b, c, d]).
<vírgula> = AND | <ponto-e-vírgula> = OR/ELSE | <ponto> = END
Vide:
https://medium.com/clebertech-en/prolog-is-not-that-hard-f8cb2b8b3e43
https://medium.com/clebertech-en/prolog-is-not-that-hard-part-2-3a88ac8f02e0
Casos de uso
- Lógica
- Análise combinatória
- Inteligência Artificial
- Compiladores (semantic checks)
- Geradores automáticos de testes
Exemplo interessante: "julian"
Datas, baseado somente em constraints.
julian
:- use_module(library(julian)). :- use_module(library(clpfd)). solution(Year) :- % Eisenhower presidency had % Fourth of July on Sunday in ... form_time([dow(sunday), Year-07-04]), Year in 1953..1961. ?- solution(Y). Y = 1954.
Em outras linguagens
- Python
- kanren ("logpy")
- Go
- golog
- Javascript
- tau-prolog
Erlang
Actor Model
Erlang
Código feito para rodar eternamente.
- Pattern matching
- Tail recursion
- Actor Model
Pattern Matching
Casamento de padrões: herdado do Prolog
(Ver no terminal)
{Status, Fd} = file:open(Filename, [read]).
{ok, Fd} = file:open(Filename, [read]).
- Não existe "atribuição", só casamento de padrão!
- O binding de valores acontece sempre à esquerda.
- Também há matching de parâmetros de funções.
X = 10. 10 = X. → Erro!
Tail Recursion
(Recursão no rabo)
Ver no terminal
(arquivos.erl+29)
read_line consegue "printar" um arquivo
de qualquer tamanho
sem variação no uso de memória.
IMPLEMENTAR: "count.erl"
count(N): printa os números de 0 até N.
Registro de ativação atual
Registro de ativação atual
C
Erlang
Processos
-
Extremamente leves.
- Cerca de 1,2KB de memória.
- Per-process Garbage Collection.
- Todos tem uma "mailbox".
- Podem ser dependentes entre si.
- Tail recursion é fundamental.
- Uma thread da Beam por core.
- Um scheduler por thread
- Cada um com sua fila de processamento
Ver: processos.erl
Processos != Coroutines
(Ou green threads)
- Os processos são conhecidos e acessíveis.
- Pid = spawn(fun).
- Pid ! message
-
Programação defensiva é desencorajada.
- Co-rotina falha:
- Grande problema
- Difícil de depurar
- Processo falha:
- É melhor que morra, mesmo.
- Dano é contido via "behaviors".
- Co-rotina falha:
Erlang não é "ultra-rápido"
- É rápido o bastante.
- Ser rápido não é o objetivo.
- O objetivo é rodar eterna e ininterruptamente.
Let it crash!
- Um componente com problemas não deve afetar os demais.
- Certos processos são responsáveis por supervisionar outros.
- Várias "fórmulas" são comuns e são chamadas "behaviors".
Supervisor
(one_to_one)
Supervisor
(one_to_all)
Dict
Dict client
Dict client
Conceitos comuns
-
Let it crash
- Não trate exceções prematuramente
- É melhor pedir perdão que permissão
-
Mailboxes
- EDAs com filas
- message→SNS→SQS→Worker
- Kafka/NATS/Rabbit
- EDAs com filas
-
Behaviors
- Orquestração de serviços
Erlang
Nim
Metaprogramação
Nim
"Tão rápida quanto C,
tão expressiva quanto Python,
tão extensível quanto LISP."
- UFCS
- Operator overloading
- Generics
- Templates
- Macros
UFCS
- Unified Function Call Syntax
- (Presente também na linguagem D)
Valores do tipo do primeiro parâmetro de uma função
podem chamá-la com notação similar a
chamada de métodos
(dot notation)
Ver no terminal: ufcs.nim
Operator and method overloading
Ver no terminal
Generics
(Ver no terminal)
the_minimum(2, 3)
the_minimum[float](2, 3)
Templates
(Ver no terminal: templates.nim)
Templates são macros limitadas
- Fazem substituições sempre iguais na AST do programa.
- Ajudam demais em casos extremos de DRY.
- Como tratadores de erro com `return`.
Ver no terminal: templates.nim
Macros
Vide:
https://hookrace.net/blog/introduction-to-metaprogramming-in-nim/
Entendendo a diferença
Se você escrever um `if`...
- Num template:
- Nim insere isso onde o template foi chamado
- Numa macro:
- Nim interpreta isso em tempo de compilação
Templates versus Macros
Nim
Transpilação
Hardware
CPython
C compiler
Nim Transpiler
Nim
Generated C
Rust
Rust Compiler
Binário
Binário
C
Python
1
2
3
4
Transpilação de Nim
- Alvos: C, C++, Objective-C e Javascript
- Permite aproveitar o ecossistema de cada alvo
- Tudo bem "battle tested"
- Muita otimização
- Acompanha novos avanços
E o desempenho?
https://github.com/kostya/benchmarks
https://github.com/drujensen/fib
BF = Máquina de Turing.
base64 = encoding.
Havlak = Sei lá. Mas usa várias estruturas de dados.
Absolutamente recomendado:
https://benchmarksgame-team.pages.debian.net/benchmarksgame/sometimes-people-just-make-up-stuff.html
BF 1
C++ (1s)
Nim GCC (1.75)
Nim Clang (1.78)
C GCC (1.81)
Kotlin (1.87)
Resto:
Rust (2.02)
C Clang (2.16)
Go (2.42)
BF 2
C GCC (12s)
Crystal (16s)
C Clang (17s)
C++ (17s)
C# (17s)
Rust (18s)
Nim GCC (18s)
Nim Clang (20s)
Kotlin (21s)
Java (21s)
Resto:
Go (40.15)
base64
Rust (1.33s)
C (1.47)
Nim Clang (1.65)
Nim GCC (1.66)
V (~2)
Crystal (2.13)
Ruby (2.17)
Java (2.49)
Resto:
Kotlin (2.62)
Node (2.91)
Go (2.93)
Havlak
Crystal (6.90s)
Nim GCC (11.72)
Nim Clang (12.21)
Resto:
C++ (14.20)
Go (18.72)
Min
Programação concatenativa
(M-i-n, não "Nim".)
Também Forth, Joy e Cat
Stack based
- Operações sempre na pilha
- Pode não haver variáveis
"Concatenativa" não significa necessariamente
"stack based". Mas a maioria é.
Concatenativa:
Prog_A <concat> ProgB =
Prog_B(Prog_A)
Stack
- [] # Pilha vazia
- 100 → [100]
- 200 → [100, 200]
- 300 → [100, 200, 300]
- + → [100, 500]
- * → [50000]
Fatorial
- Colocar um valor X na pilha
- Chama "factorial"
- Atribui o nome "n" ao topo (X)
- Põe 1 na pilha
- Atribui o nome "i" ao topo (1)
- Põe 1 na pilha
- Atribui o nome "f" ao topo (1)
- Empilha a expressão (i <= n)
- Empilha:
- f = f * i
- i ++
- while (i <= n) {código acima}
- Coloca "f" na pilha
(
:n
1 :i
1 :f
(i n <=)
(
f i * @f
i succ @i
) while
f
) :factorial
But... WHY?
Imagine que
você tem apenas
32 bytes de memória
disponíveis
e precisa executar algoritmos razoavelmente complexos.
Exemplo muito distante?
Argo Submersible Vehicle
Space Shuttle (now retired)
Fim
- Commodity versus Valor
- Programação Lógica / Prolog
- Actor Model / Erlang
- Metaprogramação / Nim
- Programação Concatenativa / Min
Dedique algum tempo para estudar uma parada ridícula.
http://cleber.solutions
Técnicas Alternativas de Programação
By Cléber Zavadniak
Técnicas Alternativas de Programação
- 225