diff --git a/_images/rust-energy.png b/_images/rust-energy.png
new file mode 100644
index 0000000..437af43
Binary files /dev/null and b/_images/rust-energy.png differ
diff --git a/porque-rust.html b/porque-rust.html
index e2db6b8..f48bd08 100644
--- a/porque-rust.html
+++ b/porque-rust.html
@@ -102,13 +102,69 @@
... pelo 4⁰ ano seguido.
+
+
+ O resultado do StackOverflow é sobre qual
+ linguagem os programadores realmente gostam de
+ programar (e quais eles tem pavor de usar).
+
+ Pessoalmente, depois de 30 anos programando,
+ quando começei a brincar com Rust, eu
+ finalmente me diverti enquanto programava.
+
+
+ "Low Level Language with High Level Abstractions"
+
+
+
+ Resultado final com performance semelhate ao C...
+
+
+
+
+ Num estudo sobre quais linguagens consomem mais
+ energia, Rust chegou bem próximo de C.
+
+ Parte do trabalho de otimização do Rust vem da LLVM
+ (parte do pacote do Clang), mas a árvore de
+ abstração ainda é gerada pela linguagem -- o que
+ significa que o compilador Rust consegue "ajudar" o
+ LLVM a otimizar o código.
+
+
+
+
+ ... mas com abstrações em algo nível
+
+
+ Strings sem tamanho fixo
+ Listas
+ Mapas
+
+
+
+ Ao contrário de C, em que só se mexe com ponteiros
+ pra cima e pra baixo, Rust tem todas as abstrações
+ de alto nível que estamos acostumados com outras
+ linguagens.
+
+
+
+
Imutabilidade por Default
+
+
+ Por que "imutabilidade" seria algo importante?
+ Imutabilidade muda a forma como pensamos nos dados,
+ e evita que o estado fique mudando quando não
+ queremos.
+
@@ -131,6 +187,11 @@ fn main() {
4 | a = 3;
| ^^^^^ cannot assign twice to immutable variable
+
+
+ Se você tentar mudar um dado depois de criado, o
+ compilador Rust não vai deixar.
+
@@ -141,12 +202,25 @@ fn main() {
println!("{}", a);
}
+
+
+ ... a não ser que você transforme sua variável em mutável.
+
Borrow Checker
+
+
+ O "Borrow Checker" é uma das principais novidades
+ do Rust em comparação com outras linguagens.
+
+ Ele basicamente controla como as variáveis vão ser
+ alocadas, quando serão desalocadas, quem pode
+ acessar o conteúdo da mesma e assim por diante.
+
@@ -157,6 +231,12 @@ a = String::from("hello");
"Variável a
tem o valor "hello"
"
+
+
+ Em todas as linguagens que eu usei, sempre que via
+ uma atribuição, eu pensava "a variável X tem o
+ valor Y" -- mesmo em C.
+
@@ -170,7 +250,24 @@ a = String::from("hello");
-
+
+ Nunca uma linguagem me fez "despensar" no nome da
+ variável pra pensar que ela representa, na verdade,
+ uma posição de memória.
+
+
+
+
+
+
+
+ É mais ou menos isso que Rust "pensa" internamente
+ quando vê uma variável: uma posição de memória, de
+ um tamanho já definido, de um tipo definido.
+
+ E essa posição de memória *pertence* apenas à
+ variável indicada.
+
@@ -206,12 +303,24 @@ error[E0382]: borrow of moved value: `a`
|
= note: move occurs because `a` has type `std::string::String`, which does not implement the `Copy` trait
+
+
+ O borrow checked não deixa a variável "a" ser
+ utilizada: quando a atribuímos "_b" o valor de "a",
+ o que estamos fazendo é indicando que aquela
+ posição de memória agora é controlada por "_b" e
+ não mais por "a".
+
E se eu precisar acessar a variável em mais de um lugar?
References
+
+
+ Assim como C++, Rust tem o conceito de "referências".
+
@@ -225,7 +334,12 @@ fn main() {
-
+
+
+
+ Uma referência nada mais é que um ponteiro para um
+ "controlador" de uma região de memória.
+
@@ -238,6 +352,16 @@ fn main() {
A região é desalocada quando o dono sair de escopo.
+
+
+ Uma coisa engraçada sobre "quando sair de escopo" é
+ que existe uma função semelhante ao "free()" do C,
+ chamada "drop". Essa função não tem nada no corpo,
+ e recebe um parâmetro (sem ser por referência), se
+ tornando a dona da memória; assim, como ela termina
+ exatamente naquele ponto, a região de memória é
+ liberada.
+
@@ -250,6 +374,14 @@ fn main() {
... desde que elas não durem mais do que o dono.
+
+
+ Não é possível ter uma função que cria uma variável
+ e retorna apenas uma referência para essa variável:
+ no momento que a função for encerrada, ela irá
+ levar todas as variáveis com ela e as referências
+ se tornaram inválidas.
+
@@ -267,22 +399,54 @@ fn main() {
+
+
+ E o que isso ajuda, no final das contas?
+
presente := Presente { ... }
canal <- presente
+
+
+ Num exemplo em Go, criamos uma estrutura e passamos
+ essa estrutura para outra thread através de um
+ canal.
+
presente := Presente { ... }
canal <- presente
presente.abrir()
+
+
+ ... e depois de passar o presente pra outra pessoa,
+ nós abrimos o presente.
+
+ Mas se estamos entregando um presente pra alguém,
+ como é que estamos abrindo o presente?
+
+ O borrow checker não permite esse tipo de coisa:
+ Ele irá barrar a função atual de continuar
+ utilizando a variável porque, afinal de contas,
+ agora a região de memória pertence à outra função
+ (uma função que está rodando em outra thread).
+
Swift 5 Exclusivity Enforcement
+
+
+ A ideia do borrow checker é tão interessante que
+ até o Swift 5 agora tem o seu próprio borrow
+ checker (com outro nome, mas o princípio da coisa é
+ basicamente o mesmo, apesar de ser um pouco mais
+ leve no Swift).
+
@@ -297,6 +461,32 @@ presente.abrir()
localtime
SimpleDateFormatter
+
+
+ A muito tempo atrás, eu estava ajudando uma colega
+ a resolver um problema com processamento de eventos
+ num projeto em C. Aparentemente, quando um evento
+ era processado, acontecia do tempo de processamento
+ ficar errado (algo como ficar negativo ou levar
+ menos de 10ms pra fazer uma query num banco
+ oracle). Quando perguntei como ela estava
+ calculando o tempo, ela me falou que estava usando
+ o "localtime". Foi quando me lembrei que
+ "localtime" não é thread-safe e, por isso, quando
+ uma thread passava pela chamada da função, o valor
+ era "resetado".
+
+ Outra situação aconteceu recentemente: Num projeto
+ Java, começou a acontecer de, em alguns casos, a
+ função que convertia strings para Date começou a
+ dar resultados completamente errados.
+ Estranhamente, eu lembrei da questão do localtime e
+ perguntei se o projeto usava threads: sim; fui
+ direto no DuckDuckGo e procurei por
+ "simpledateformatter thread safe" e o primeiro
+ resultado foi uma pergunta do StackOverflow: "Why
+ isn't SimpleDateFormatter thread-safe?"
+
@@ -305,6 +495,17 @@ presente.abrir()
Não
... na verdade, nem ia compilar.
+
+
+ Uma questão importante para o Rust são "Zero Cost
+ Abstractions", segundo a definição do Bjarne
+ Stroustrup, criado do C++: para que algo seja
+ aceito no compilador, é preciso que o custo de não
+ usar algo não acarrete nada; ou seja, tornar uma
+ função thread-safe simplesmente inserindo um mutex,
+ não é zero cost porque, se tu não estiver usando
+ threads, não faz sentido o mutex.
+
@@ -324,6 +525,10 @@ struct Present {
content: String
}
+
+
@@ -456,6 +661,12 @@ OK(())
+
+
Crazy stuff
@@ -535,40 +746,6 @@ fn call_isan(num: &str) -> Result<Success, Error> {
-
-
-
-
- Magic Pocket
-
- Dropbox
-
- Petabyte storage
-
-
-
- Servo
-
- Mozilla
-
- Base do Firefox Quantum
-
-
-
- Azure
-
- Microsoft
-
- Usado na parte de IoT do Azure
-
-
-
-
-