summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--fr-fr/javascript-fr.html.markdown2
-rw-r--r--fr-fr/set-theory-fr.html.markdown2
-rw-r--r--func.html.markdown338
-rw-r--r--ldpl.html.markdown7
-rw-r--r--markdown.html.markdown13
-rw-r--r--pt-br/dart-pt.html.markdown5
-rw-r--r--pt-br/sql-pt.html.markdown119
-rw-r--r--python.html.markdown95
-rw-r--r--vim.html.markdown225
-rw-r--r--yaml.html.markdown112
-rw-r--r--zig.html.markdown980
11 files changed, 1702 insertions, 196 deletions
diff --git a/fr-fr/javascript-fr.html.markdown b/fr-fr/javascript-fr.html.markdown
index 186859ab..308f1ca8 100644
--- a/fr-fr/javascript-fr.html.markdown
+++ b/fr-fr/javascript-fr.html.markdown
@@ -94,7 +94,7 @@ let banta = "Harry", santa = "Hermione";
// L'égalité est === ou ==
// === compare la valeur exacte 2 === '2' // = false
-// == convertit la valeur pour comparer 2 === '2' // = true
+// == convertit la valeur pour comparer 2 == '2' // = true
// En général, il vaut mieux utiliser === pour ne pas faire d'erreur.
1 === 1; // = true
2 === 1; // = false
diff --git a/fr-fr/set-theory-fr.html.markdown b/fr-fr/set-theory-fr.html.markdown
index 543bd98b..d1ac2711 100644
--- a/fr-fr/set-theory-fr.html.markdown
+++ b/fr-fr/set-theory-fr.html.markdown
@@ -125,7 +125,7 @@ A △ B = (A \ B) ∪ (B \ A)
```
### Produit cartésien
-Le produit cartésien de deux ensembles `A` et `B` est l'ensemble contenant tous les couples dont la première élément appartient à `A` et la deuxième à `B`.
+Le produit cartésien de deux ensembles `A` et `B` est l'ensemble contenant tous les couples dont le premier élément appartient à `A` et le deuxième à `B`.
```
A × B = { (x, y) | x ∈ A, y ∈ B }
diff --git a/func.html.markdown b/func.html.markdown
new file mode 100644
index 00000000..da1b2214
--- /dev/null
+++ b/func.html.markdown
@@ -0,0 +1,338 @@
+---
+language: FunC
+filename: learnFunC.fc
+contributors:
+ - ["Ivan Romanovich", "https://t.me/ton_learn"]
+ - ["Kirill Malev", "https://fslabs.io"]
+---
+
+The FunC language is used to program smart contracts on the [The Open Network](https://ton.org) blockchain. Contract logic is executed in TVM, the stack-based TON Virtual Machine.
+
+FunC is a statically typed, which is similar to C.
+
+# Basic syntax, the first Smart Contract — Data Types, Storage, Functions
+
+```c
+;; Single line comment
+
+ {- This is a multi-line comment
+ {- this is a comment in the comment -}
+ -}
+
+ (int) sum(int a, int b) {
+ ;; This is a function that gets two integer parameters
+ ;; and return integer result
+ return a + b;
+ ;; All integers are signed and are 257 bit long. Overflow throws exception
+ ;; expressions must end with a semicolon
+ }
+
+ () f(int i, cell c, slice s, builder b, cont c, tuple t) {
+ ;; FunC has 7 atomic types:
+ ;; int - 257 bit signed integers,
+ ;; cell - basic for TON opaque data structure,
+ ;; which contains up to 1,023 bits and up to 4 references to other cells,
+ ;; slice and builder - special objects to read from and write to cells,
+ ;; continuation - another flavor of cell that contains
+ ;; ready-to-execute TVM byte-code.
+ ;; tuple is an ordered collection of up to 255 components,
+ ;; having arbitrary value types, possibly distinct.
+ ;; Finally tensor type (A,B, ...) is an ordered collection ready for
+ ;; mass assigning like: (int, int) a = (3, 5);
+ ;; Special case of tensor type is the unit type ().
+ ;; It represents that a function doesn’t return any value,
+ ;; or has no arguments.
+ }
+
+ ;; During execution, the contract has read access to local context:
+ ;; its storage, balance, time, network config, etc.
+ ;; Contract may change its storage and code,
+ ;; and also may send messages to other contracts
+
+ ;; Let’s write a counter smart contract that gets a number
+ ;; from an incoming message,
+ ;; adds to already stored numbers and stores result in “storage”
+
+ ;; For handling special events, smart contracts have reserved methods:
+ ;; recv_internal() handles internal messages from other smart contracts
+ ;; recv_external() handles external messages from the outside world —
+ ;; e.g., from a user.
+
+ () recv_internal(slice in_msg_body) {
+ ;; Cells play the role of memory in the stack-based TVM.
+ ;; A cell can be transformed into a slice,
+ ;; and then the data bits and references to
+ ;; other cells from the cell can be obtained
+ ;; by loading them from the slice.
+ ;; Data bits and references to other cells can be stored
+ ;; into a builder, and then the builder can be finalized into a new cell.
+ ;; recv_internal gets the slice
+ ;; with incoming message data as an argument.
+
+ ;; As everything else on TON, permanent storage data is stored as a cell.
+ ;; It can be retrieved via the get_data() method
+ ;; begin_parse - converts a cell with data into a readable slice
+
+ slice ds = get_data().begin_parse();
+ ;; `.` is a syntax sugar: a.b() is equivalent to b(a)
+
+ ;; load_uint is a function from the FunC standard library;
+ ;; it loads an unsigned n-bit integer from a slice
+ int total = ds~load_uint(64); ;; `~` is a "modifying" method:
+ ;; essentially, it is a syntax sugar: `r = a~b(x)`
+ ;; is equivalent to (a,r) = b(a,x)
+
+ ;; Now let’s read the incoming value from the message body slice
+ int n = in_msg_body~load_uint(32);
+
+ total += n;
+ ;; integers support usual +-*/ operations as well as (+-*/)= syntax sugar
+
+ ;; In order to keep a store integer value, we need to do four things:
+ ;; create a Builder for the future cell - begin_cell()
+ ;; write a value to total - store_uint(value, bit_size)
+ ;; create a Cell from the Builder - end_cell()
+ ;; write the resulting cell into permanent storage - set_data()
+
+ set_data(begin_cell().store_uint(total, 64).end_cell());
+ }
+
+
+
+ ;; The FunC program is essentially a list of
+ function declarations/definitions and global variable declarations.
+
+ ;; Any function in FunC matches the following pattern:
+ ;; [<forall declarator>] <return_type> <function_name>(<comma_separated_function_args>) <specifiers>
+
+
+ ;; Specifiers:
+ ;; The impure specifier indicates that
+ ;; function calls should not be optimized
+ ;; (whether its result is used or not)
+ ;; it is important for methods that change the smart contract data
+ ;; or send messages
+
+ ;; The method_id specifier allows you to call a GET function by name
+
+ ;; For instance, we can create a get method for the contract above
+ ;; to allow outside viewers to read counter
+
+ int get_total() method_id {
+ slice ds = get_data().begin_parse();
+ int total = ds~load_uint(64);
+
+ ;; Note that (int) and int is the same,
+ ;; thus brackets in the function declaration
+ ;; and in the return statement are omitted.
+ return total;
+ }
+ ;; Now any observer can read get_total value via lite-client or explorer
+```
+
+# Messages
+
+The actor model is a model of concurrent computation and is at the heart of TON smart contracts. Each smart contract can process one message at a time, change its own state, or send one or several messages. Processing of the message occurs in one transaction, that is, it cannot be interrupted. Messages to one contract are processed consequently one by one. As a result, the execution of each transaction is local and can be parallelized at the blockchain level, which allows for on-demand throughput horizontal scaling and hosting an unlimited number of users and transactions.
+
+```c
+;; For normal internal message-triggered transactions,
+;; before passing control to recv_internal TVM puts the following
+;; elements on stack.
+;;;; Smart contract balance (in nanoTons)
+;;;; Incoming message balance (in nanoTons)
+;;;; Cell with an incoming message
+;;;; Incoming message body, slice type
+;; In turn, recv_internal may use only
+;; the required number of fields (like 1 in the example above or 4 below)
+
+;; Let’s dive into message sending
+
+() recv_internal (
+ int balance, int msg_value, cell in_msg_full, slice in_msg_body) {
+ ;;
+ ;; Every message has a strict layout, thus by parsing it,
+ ;; we can get the sender’s address
+ ;; first, we need to read some tech flags and
+ ;; then take the address using load_msg_addr
+ ;; function from FunC standard library - ()
+ var cs = in_msg_full.begin_parse();
+ var flags = cs~load_uint(4);
+ slice sender_address = cs~load_msg_addr();
+
+ ;; if we want to send a message, we first need to construct it
+ ;; message serialization in most cases may be reduced to
+ var msg = begin_cell()
+ .store_uint(0x18, 6) ;; tech flags
+ .store_slice(addr) ;; destination address
+ .store_coins(amount) ;; attached value
+ .store_uint(0, 107) ;; more tech flags :)
+ .store_slice(in_msg_body) ;; just put some payload here
+ .end_cell();
+
+ ;; to send messages, use send_raw_message from the standard library.
+ ;; it accepts two arguments message and mode
+ send_raw_message(msg, 64);
+
+ ;; mode parameter specifies how to process the funds passed into
+ ;; the smart contract with the message and the smart contract funds
+ ;; 64 means send everything from the incoming message —
+ ;; what’s left after the commission is deducted
+
+ ;; Exceptions can be thrown by conditional primitives throw_if and
+ ;; throw_unless and by unconditional throw
+ ;; by default, it will automatically cause a bounce message with 64 mode
+
+ var some = 7;
+ throw_if(102, some == 10);
+ ;; Throw exception with code 102 conditionally
+ throw_unless(103, some != 10);
+ ;; Throw exception with code 103 conditionally
+ throw(101); ;; Throw exception with code 101 unconditionally
+}
+```
+
+# Flow control: Conditional Statements and Loops; Dictionaries
+
+```c
+;; FunC, of course, supports if statements
+
+;;;; usual if-else
+if (flag) {
+ ;;do_something();
+}
+else {
+ ;;do_alternative();
+}
+
+;; If statements are often used as an operation identifier
+;; for a smart contract, for example:
+
+() recv_internal (
+ int balance, int msg_value, cell in_msg_full, slice in_msg_body) {
+ int op = in_msg_body~load_int(32);
+ if (op == 1) {
+ ;; smth here
+ } else {
+ if (op == 2) {
+ ;; smth here
+ } else {
+ ;; smth here
+ }
+ }
+}
+
+;; Loops
+;; FunC supports repeat, while and do { ... } until loops.
+;; for loop is not supported.
+
+;; repeat
+int x = 1;
+repeat(10) {
+ x *= 2;
+}
+;; x = 1024
+
+;; while
+int x = 2;
+while (x < 100) {
+ x = x * x;
+}
+;; x = 256
+
+;; until loops
+int x = 0;
+do {
+ x += 3;
+} until (x % 17 == 0);
+;; x = 51
+
+;; In practice, loops in TON smart contracts are often used to work with
+;; dictionaries, or as they are also called in TON hashmaps
+
+;; A hashmap is a data structure represented by a tree.
+;; Hashmap maps keys to values ​​of arbitrary type so that
+;; quick lookup and modification are possible.
+
+;; udict_get_next? from FunC standard library in combination with
+;; the loop will help, go through the dictionary
+
+int key = -1;
+do {
+ (key, slice cs, int f) = dic.udict_get_next?(256, key);
+
+} until (~ f);
+
+;; udict_get_next? - Calculates the minimum key k in the dictionary dict
+;; that is greater than some given value and returns k,
+;; the associated value, and a flag indicating success.
+;; If the dictionary is empty, returns (null, null, 0).
+```
+
+# Functions
+
+```c
+;; Most useful functions are slice reader and builder writer primitives,
+;; storage handlers and sending messages
+
+;; slice begin_parse(cell c) - Converts a cell into a slice
+;; (slice, int) load_int(slice s, int len) -
+;; Loads a signed len-bit integer from a slice.
+;; (slice, int) load_uint(slice s, int len) -
+;; Loads a unsigned len-bit integer from a slice.
+;; (slice, slice) load_bits(slice s, int len) -
+;; Loads the first 0 ≤ len ≤ 1023 bits from slice into a separate slice.
+;; (slice, cell) load_ref(slice s) - Loads the reference cell from the slice.
+
+;; builder begin_cell() - Creates a new empty builder.
+;; cell end_cell(builder b) - Converts a builder into an ordinary cell.
+;; builder store_int(builder b, int x, int len) -
+;; Stores a signed len-bit integer x into b for 0 ≤ len ≤ 257.
+;; builder store_uint(builder b, int x, int len) -
+;; Stores an unsigned len-bit integer x into b for 0 ≤ len ≤ 256.
+;; builder store_slice(builder b, slice s) - Stores slice s into builder b.
+;; builder store_ref(builder b, cell c) -
+;; Stores a reference to cell c into builder b.
+
+;; cell get_data() - Returns the persistent contract storage cell.
+;; () set_data(cell c) - Sets cell c as persistent contract data.
+
+;; () send_raw_message(cell msg, int mode) -
+;; put message msg into sending queue with mode.
+;; Note, that message will be sent after a successful execution
+;; of the whole transaction
+
+;; Detailed descriptions of all standard functions can be found
+;; in docs https://ton.org/docs/#/func/stdlib
+;;
+```
+
+## Additional resources
+- [FunC Lessons](https://github.com/romanovichim/TonFunClessons_Eng)
+- [TON Development Onboarding](https://www.tonspace.co)
+- [TON Documentation](https://ton.org/docs/#/)
+- [FunC Documentation](https://ton.org/docs/#/func/overview)
+- [TON Smart Contracts examples](https://github.com/ton-blockchain/ton/tree/master/crypto/smartcont)
+- [Community portal](https://society.ton.org)
+- [Blockchain portal](https://ton.org)
+- [Stackoverflow](https://stackoverflow.com/questions/tagged/ton)
+
+## Social
+- [Developer community](https://t.me/tondev_eng)
+- [TON Learn](https://t.me/ton_learn)
+- [FunC Lessons Channel](https://github.com/romanovichim/TonFunClessons_Eng)
+- [FunC onboarding](https://t.me/func_guide)
+- [Tondev News](https://t.me/tondevnews)
+
+## Useful blogposts
+- [Setting up a TON Development Environment](https://society.ton.org/setting-up-a-ton-development-environment)
+- [Hello World on TON](https://society.ton.org/ton-hello-world-step-by-step-guide-for-writing-your-first-smart-contract-in-func)
+
+
+## Future To Dos
+- Add smart contracts examples
+- Add more posts
+
+
+This file is mostly copied from [TonFunClessons 15 minutes intro](https://github.com/romanovichim/TonFunClessons_Eng/blob/main/13lesson/15min.md).
+
+P.S. If by any chance you're familiar with [Forth](https://learnxinyminutes.com/docs/forth/), you can also take a look at [Fift](https://ton-blockchain.github.io/docs/fiftbase.pdf). \ No newline at end of file
diff --git a/ldpl.html.markdown b/ldpl.html.markdown
index 86603d94..449c8670 100644
--- a/ldpl.html.markdown
+++ b/ldpl.html.markdown
@@ -3,6 +3,7 @@ language: LDPL
filename: learnLDPL.ldpl
contributors:
- ["Martín del Río", "https://github.com/lartu"]
+ - ["John Paul Wohlscheid", "https://github.com/JohnBlood"]
---
**LDPL** is a powerful, C++ transpiled, open-source programming language designed
@@ -68,7 +69,7 @@ else if myMap:"someIndex" is not equal to 45 then
else
display "Else!" crlf
end if
-# Valid LDPL comparisson operators are
+# Valid LDPL comparison operators are
# - IS EQUAL TO
# - IS NOT EQUAL TO
# - IS LESS THAN
@@ -123,8 +124,8 @@ get random in myNumber # get a random number between 0 and 1
# files, are divided in sections. The sections found in sub-procedures are
# the PARAMETERS section, the LOCAL DATA section and the PROCEDURE section.
# All sections except the PROCEDURE section can be skipped if they aren't
-# used. If no PARAMTERS nor LOCAL DATA sections are used, the PROCEDURE
-# keyword may be omited.
+# used. If no PARAMETERS nor LOCAL DATA sections are used, the PROCEDURE
+# keyword may be omitted.
sub myFunction
parameters:
a is number # LDPL is pass by reference
diff --git a/markdown.html.markdown b/markdown.html.markdown
index a6000910..cfc0ddf3 100644
--- a/markdown.html.markdown
+++ b/markdown.html.markdown
@@ -40,9 +40,9 @@ specific to a certain parser.
Markdown is a superset of HTML, so any HTML file is valid Markdown.
```md
-<!--This means we can use HTML elements in Markdown, such as the comment
-element, and they won't be affected by a markdown parser. However, if you
-create an HTML element in your markdown file, you cannot use markdown syntax
+<!--This means we can use HTML elements in Markdown, such as the comment
+element, and they won't be affected by a markdown parser. However, if you
+create an HTML element in your markdown file, you cannot use markdown syntax
within that element's contents.-->
```
@@ -370,9 +370,10 @@ Ugh this is so ugly | make it | stop
## Markdownlint
In order to simplify work with Markdown and to unify its coding style,
-`Markdownlint` has been created. This tool is available also as a plugin for
-some IDEs and can be used as an utility to ensure validity and readability of
-Markdown.
+`Markdownlint` has been created. Available as a
+[separate tool](https://github.com/markdownlint/markdownlint)
+as well as a plugin for some IDEs, it can be used to ensure validity and
+readability of Markdown.
---
diff --git a/pt-br/dart-pt.html.markdown b/pt-br/dart-pt.html.markdown
index e9d72850..6aff1ac3 100644
--- a/pt-br/dart-pt.html.markdown
+++ b/pt-br/dart-pt.html.markdown
@@ -3,15 +3,16 @@ language: dart
filename: learndart-pt.dart
contributors:
- ["Joao Pedrosa", "https://github.com/jpedrosa/"]
+ - ["Hélio Oliveira", "https://github.com/insign/"]
translators:
- ["Junior Damacena", "https://github.com/jdamacena/"]
lang: pt-br
---
Dart é uma novata no reino das linguagens de programação.
-Ela empresta muito de outras linguagens mais conhecidas, e tem a meta de não se diferenciar muito de seu irmão, JavaScript. Assim como JavaScript, Dart foi pensada para oferecer grande integração com o Browser.
+Ela absorve muitas teorias de outras linguagens mais conhecidas, e tem a meta de não se diferenciar muito de seu irmão, JavaScript. Assim como JavaScript, Dart foi pensada para oferecer grande integração com o navegador.
-A característica mais controversa da Dart é a sua Tipagem Opcional, ou seja, não é obrigatório declarar tipos.
+As variáveis em Dart tem tipos, mas não é obrigatório declarar devido à função de [detecção automática](https://dart.dev/guides/language/type-system#type-inference).
```dart
import "dart:collection";
diff --git a/pt-br/sql-pt.html.markdown b/pt-br/sql-pt.html.markdown
new file mode 100644
index 00000000..0e4631a6
--- /dev/null
+++ b/pt-br/sql-pt.html.markdown
@@ -0,0 +1,119 @@
+---
+language: SQL
+filename: learnsql-pt.sql
+contributors:
+ - ["Bob DuCharme", "http://bobdc.com/"]
+translators:
+ - ["jovinoguerrero", "https://github.com/jovinoguerrero"]
+lang: pt-br
+---
+
+A linguagem de consulta estruturada (SQL em inglês) é uma linguagem padrão ISO para criar e trabalhar com bancos de dados armazenados num conjunto de tabelas. As implementações geralmente adicionam suas próprias extensões à linguagem; [Comparação entre diferentes implementações de SQL](http://troels.arvin.dk/db/rdbms/) é uma boa referência sobre as diferenças entre os diferentes produtos.
+
+As implementações normalmente fornecem uma linha de comando onde se pode digitar os comandos mostrados aqui de forma interativa, e também oferecem uma maneira de executar uma série desses comandos armazenados em um arquivo de script (mostrar que é feito com o prompt interativo é um bom exemplo de algo que não é padronizado - a maioria das implementações SQL suporta as palavras-chave QUIT, EXIT ou ambas).
+
+Vários desses comandos de exemplo assumem que o [banco de dados de funcionários de exemplo MySQL](https://dev.mysql.com/doc/employee/en/) disponível em [github](https://github.com/datacharmer/test_db) já foi carregado. Os arquivos do GitHub são scripts de comandos, semelhantes aos comandos abaixo, que criam e carregam tabelas de dados sobre os funcionários de uma empresa fictícia. A sintaxe para executar esses scripts dependerá da implementação SQL que você está usando. Um aplicativo executado a partir do prompt do sistema operacional geralmente é o normal.
+
+
+```sql
+-- Os comentários começam com dois hífens. Cada comando é encerrado com um
+-- ponto e vírgula.
+
+-- SQL não diferencia maiúsculas de minúsculas em palavras-chave. Os
+-- comandos de exemplo mostrados aqui seguem a convenção de serem escritos
+-- em maiúsculas porque torna mais fácil distingui-los dos nomes dos bancos
+-- de dados, tabelas e colunas.
+
+-- Em seguida, um banco de dados é criado e excluído. Os nomes do banco de
+-- dados e da tabela são sensíveis a maiúsculas de minúsculas.
+CREATE DATABASE someDatabase;
+DROP DATABASE someDatabase;
+
+-- Mostra numa lista todos os bancos de dados disponíveis.
+SHOW DATABASES;
+
+-- Usa um determinado banco de dados existente.
+USE employees;
+
+-- Seleciona todas as filas e colunas da tabela de departamentos no banco
+-- de dados atual. A atividade padrão é o intérprete rolar os resultados
+-- na tela.
+SELECT * FROM departments;
+
+-- Recupera todas as filas da tabela de departamentos, mas apenas as colunas
+-- dept_no e dept_name.
+-- A separação de comandos em várias linhas é permitida.
+SELECT dept_no,
+ dept_name FROM departments;
+
+-- Obtém todas as colunas de departments, mas é limitado a 5 filas.
+SELECT * FROM departments LIMIT 5;
+
+-- Obtém os valores da coluna dept_name da tabela de departments quando
+-- dept_name tem como valor a substring 'en'.
+SELECT dept_name FROM departments WHERE dept_name LIKE '%en%';
+
+-- Recupera todas as colunas da tabela de departments onde a coluna
+-- dept_name começa com um 'S' e tem exatamente 4 caracteres depois dele.
+SELECT * FROM departments WHERE dept_name LIKE 'S____';
+
+-- Seleciona os valores dos títulos da tabela de titles, mas não mostra
+-- duplicatas.
+SELECT DISTINCT title FROM titles;
+
+-- Igual ao anterior, mas ordenado por valores de da coluna title (diferencia
+-- maiúsculas de minúsculas).
+SELECT DISTINCT title FROM titles ORDER BY title;
+
+-- Mostra o número de filas da tabela departments.
+SELECT COUNT(*) FROM departments;
+
+-- Mostra o número de filas da tabela departments que contém 'en' como
+-- substring na coluna dept_name.
+SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%';
+
+-- Uma união (JOIN) de informações de várias tabelas: a tabela titles mostra
+-- quem tem quais cargos laborais, de acordo com seu número de funcionários,
+-- e desde que data até que data. Esta informação é obtida, mas em vez do
+-- número do funcionário é usada como referência cruzada a tabela employee
+-- para obter o nome e sobrenome de cada funcionário (e limita os resultados
+-- a 10 filas).
+SELECT employees.first_name, employees.last_name,
+ titles.title, titles.from_date, titles.to_date
+FROM titles INNER JOIN employees ON
+ employees.emp_no = titles.emp_no LIMIT 10;
+
+-- São listadas todas as tabelas de todas os bancos de dados. As implementações
+-- normalmente fornecem seus próprios comandos para fazer isso com o banco de
+-- dados atualmente em uso.
+SELECT * FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_TYPE='BASE TABLE';
+
+-- Cria uma tabela chamada tablename1, com as duas colunas mostradas, a partir
+-- do banco de dados em uso. Há muitas outras opções dísponiveis para a forma
+-- em que se especificam as colunas, por ex. seus tipos de dados.
+CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20));
+
+-- Insere uma fila de dados na tabela tablename1. É assumido que a tabela foi
+-- definida para aceitar esses valores como adequados.
+INSERT INTO tablename1 VALUES('Richard','Mutt');
+
+-- Em tablename1, se altera o valor de fname para 'John' em todas as filas que
+-- contenham um valor em lname igual a 'Mutt'.
+UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
+
+-- Se excluem as filas da tabela tablename1 em que o valor de lname começa
+-- com 'M'.
+DELETE FROM tablename1 WHERE lname like 'M%';
+
+-- Se excluem as filas da tabela tablename1, deixando a tabla vazia.
+DELETE FROM tablename1;
+
+-- A tabela tablename1, é excluída completamente.
+DROP TABLE tablename1;
+```
+
+# Leitura adicional
+
+* [Codecademy - SQL](https://www.codecademy.com/learn/learn-sql) A good introduction to SQL in a “learn by doing it” format.
+* [Database System Concepts](https://www.db-book.com/) book’s Chapter 3 - Introduction to SQL has an in depth explanation of SQL concepts.
diff --git a/python.html.markdown b/python.html.markdown
index 0b115c4e..2247f263 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -9,14 +9,17 @@ contributors:
- ["Rommel Martinez", "https://ebzzry.io"]
- ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"]
- ["caminsha", "https://github.com/caminsha"]
+ - ["Stanislav Modrak", "https://stanislav.gq"]
filename: learnpython.py
---
-Python was created by Guido van Rossum in the early 90s. It is now one of the most popular
-languages in existence. I fell in love with Python for its syntactic clarity. It's basically
-executable pseudocode.
+Python was created by Guido van Rossum in the early 90s. It is now one of the
+most popular languages in existence. I fell in love with Python for its
+syntactic clarity. It's basically executable pseudocode.
-Note: This article applies to Python 3 specifically. Check out [here](http://learnxinyminutes.com/docs/pythonlegacy/) if you want to learn the old Python 2.7
+Note: This article applies to Python 3 specifically. Check out
+[here](http://learnxinyminutes.com/docs/pythonlegacy/) if you want to learn the
+old Python 2.7
```python
@@ -96,8 +99,9 @@ bool(set()) # => False
bool(4) # => True
bool(-6) # => True
-# Using boolean logical operators on ints casts them to booleans for evaluation, but their non-cast value is returned
-# Don't mix up with bool(ints) and bitwise and/or (&,|)
+# Using boolean logical operators on ints casts them to booleans for evaluation,
+# but their non-cast value is returned. Don't mix up with bool(ints) and bitwise
+# and/or (&,|)
bool(0) # => False
bool(2) # => True
0 and 2 # => 0
@@ -151,10 +155,10 @@ b == a # => True, a's and b's objects are equal
# You can find the length of a string
len("This is a string") # => 16
-# You can also format using f-strings or formatted string literals (in Python 3.6+)
+# Since Python 3.6, you can use f-strings or formatted string literals.
name = "Reiko"
f"She said her name is {name}." # => "She said her name is Reiko"
-# You can basically put any Python expression inside the braces and it will be output in the string.
+# Any valid Python expression inside these braces is returned to the string.
f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long."
# None is an object
@@ -165,15 +169,6 @@ None # => None
"etc" is None # => False
None is None # => True
-# None, 0, and empty strings/lists/dicts/tuples/sets all evaluate to False.
-# All other values are True
-bool(0) # => False
-bool("") # => False
-bool([]) # => False
-bool({}) # => False
-bool(()) # => False
-bool(set()) # => False
-
####################################################
## 2. Variables and Collections
####################################################
@@ -302,7 +297,7 @@ filled_dict = {"one": 1, "two": 2, "three": 3}
# Note keys for dictionaries have to be immutable types. This is to ensure that
# the key can be converted to a constant hash value for quick look-ups.
# Immutable types include ints, floats, strings, tuples.
-invalid_dict = {[1,2,3]: "123"} # => Raises a TypeError: unhashable type: 'list'
+invalid_dict = {[1,2,3]: "123"} # => Yield a TypeError: unhashable type: 'list'
valid_dict = {(1,2,3):[1,2,3]} # Values can be of any type, however.
# Look up values with []
@@ -356,7 +351,7 @@ del filled_dict["one"] # Removes the key "one" from filled dict
# Sets store ... well sets
empty_set = set()
-# Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry.
+# Initialize a set with a bunch of values.
some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
# Similar to keys of a dictionary, elements of a set have to be immutable.
@@ -428,7 +423,7 @@ for animal in ["dog", "cat", "mouse"]:
"""
"range(number)" returns an iterable of numbers
-from zero to the given number
+from zero up to (but excluding) the given number
prints:
0
1
@@ -462,8 +457,7 @@ for i in range(4, 8, 2):
print(i)
"""
-To loop over a list, and retrieve both the index and the value of each item in the list
-prints:
+Loop over a list to retrieve both the index and the value of each list item:
0 dog
1 cat
2 mouse
@@ -490,10 +484,11 @@ try:
# Use "raise" to raise an error
raise IndexError("This is an index error")
except IndexError as e:
- pass # Pass is just a no-op. Usually you would do recovery here.
+ pass # Refrain from this, provide a recovery (next example).
except (TypeError, NameError):
- pass # Multiple exceptions can be handled together, if required.
-else: # Optional clause to the try/except block. Must follow all except blocks
+ pass # Multiple exceptions can be processed jointly.
+else: # Optional clause to the try/except block. Must follow
+ # all except blocks.
print("All good!") # Runs only if the code in try raises no exceptions
finally: # Execute under all circumstances
print("We can clean up resources here")
@@ -529,7 +524,8 @@ print(contents)
filled_dict = {"one": 1, "two": 2, "three": 3}
our_iterable = filled_dict.keys()
-print(our_iterable) # => dict_keys(['one', 'two', 'three']). This is an object that implements our Iterable interface.
+print(our_iterable) # => dict_keys(['one', 'two', 'three']). This is an object
+ # that implements our Iterable interface.
# We can loop over it.
for i in our_iterable:
@@ -541,15 +537,16 @@ our_iterable[1] # Raises a TypeError
# An iterable is an object that knows how to create an iterator.
our_iterator = iter(our_iterable)
-# Our iterator is an object that can remember the state as we traverse through it.
-# We get the next object with "next()".
+# Our iterator is an object that can remember the state as we traverse through
+# it. We get the next object with "next()".
next(our_iterator) # => "one"
# It maintains state as we iterate.
next(our_iterator) # => "two"
next(our_iterator) # => "three"
-# After the iterator has returned all of its data, it raises a StopIteration exception
+# After the iterator has returned all of its data, it raises a
+# StopIteration exception
next(our_iterator) # Raises StopIteration
# We can also loop over it, in fact, "for" does this implicitly!
@@ -557,7 +554,7 @@ our_iterator = iter(our_iterable)
for i in our_iterator:
print(i) # Prints one, two, three
-# You can grab all the elements of an iterable or iterator by calling list() on it.
+# You can grab all the elements of an iterable or iterator by call of list().
list(our_iterable) # => Returns ["one", "two", "three"]
list(our_iterator) # => Returns [] because state is saved
@@ -607,9 +604,9 @@ all_the_args(1, 2, a=3, b=4) prints:
# Use * to expand tuples and use ** to expand kwargs.
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # equivalent to all_the_args(1, 2, 3, 4)
-all_the_args(**kwargs) # equivalent to all_the_args(a=3, b=4)
-all_the_args(*args, **kwargs) # equivalent to all_the_args(1, 2, 3, 4, a=3, b=4)
+all_the_args(*args) # equivalent: all_the_args(1, 2, 3, 4)
+all_the_args(**kwargs) # equivalent: all_the_args(a=3, b=4)
+all_the_args(*args, **kwargs) # equivalent: all_the_args(1, 2, 3, 4, a=3, b=4)
# Returning multiple values (with tuple assignments)
def swap(x, y):
@@ -619,17 +616,19 @@ def swap(x, y):
x = 1
y = 2
x, y = swap(x, y) # => x = 2, y = 1
-# (x, y) = swap(x,y) # Again parenthesis have been excluded but can be included.
+# (x, y) = swap(x,y) # Again the use of parenthesis is optional.
-# Function Scope
+# global scope
x = 5
def set_x(num):
- # Local var x not the same as global variable x
+ # local scope begins here
+ # local var x not the same as global var x
x = num # => 43
print(x) # => 43
def set_global_x(num):
+ # global indicates that particular var lives in the global scope
global x
print(x) # => 5
x = num # global var x is now set to 6
@@ -637,6 +636,12 @@ def set_global_x(num):
set_x(43)
set_global_x(6)
+"""
+prints:
+ 43
+ 5
+ 6
+"""
# Python has first class functions
@@ -659,7 +664,7 @@ list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3]
list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7]
# We can use list comprehensions for nice maps and filters
-# List comprehension stores the output as a list which can itself be a nested list
+# List comprehension stores the output as a list (which itself may be nested).
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
@@ -719,8 +724,8 @@ class Human:
# Note that the double leading and trailing underscores denote objects
# or attributes that are used by Python but that live in user-controlled
# namespaces. Methods(or objects or attributes) like: __init__, __str__,
- # __repr__ etc. are called special methods (or sometimes called dunder methods)
- # You should not invent such names on your own.
+ # __repr__ etc. are called special methods (or sometimes called dunder
+ # methods). You should not invent such names on your own.
def __init__(self, name):
# Assign the argument to the instance's name attribute
self.name = name
@@ -774,7 +779,7 @@ if __name__ == '__main__':
i.say("hi") # "Ian: hi"
j = Human("Joel")
j.say("hello") # "Joel: hello"
- # i and j are instances of type Human, or in other words: they are Human objects
+ # i and j are instances of type Human; i.e., they are Human objects.
# Call our class method
i.say(i.get_species()) # "Ian: H. sapiens"
@@ -811,8 +816,8 @@ if __name__ == '__main__':
# "species", "name", and "age", as well as methods, like "sing" and "grunt"
# from the Human class, but can also have its own unique properties.
-# To take advantage of modularization by file you could place the classes above in their own files,
-# say, human.py
+# To take advantage of modularization by file you could place the classes above
+# in their own files, say, human.py
# To import functions from other files use the following format
# from "filename-without-extension" import "function-or-class"
@@ -936,8 +941,8 @@ class Batman(Superhero, Bat):
# However we are dealing with multiple inheritance here, and super()
# only works with the next base class in the MRO list.
# So instead we explicitly call __init__ for all ancestors.
- # The use of *args and **kwargs allows for a clean way to pass arguments,
- # with each parent "peeling a layer of the onion".
+ # The use of *args and **kwargs allows for a clean way to pass
+ # arguments, with each parent "peeling a layer of the onion".
Superhero.__init__(self, 'anonymous', movie=True,
superpowers=['Wealthy'], *args, **kwargs)
Bat.__init__(self, *args, can_fly=False, **kwargs)
@@ -1036,8 +1041,6 @@ print(say()) # Can you buy me a beer?
print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
```
-## Ready For More?
-
### Free Online
* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
diff --git a/vim.html.markdown b/vim.html.markdown
index a72db158..e0fdf2e0 100644
--- a/vim.html.markdown
+++ b/vim.html.markdown
@@ -3,6 +3,7 @@ category: tool
tool: vim
contributors:
- ["RadhikaG", "https://github.com/RadhikaG"]
+ - ["kaymmm", "https://github.com/kaymmm"]
filename: LearnVim.txt
---
@@ -19,70 +20,71 @@ specific points in the file, and for fast editing.
## Basics of navigating Vim
```
- vim <filename> # Open <filename> in vim
- :help <topic> # Open up built-in help docs about <topic> if any exists
- :q # Quit vim
- :w # Save current file
- :wq # Save file and quit vim
- ZZ # Save file and quit vim
- :q! # Quit vim without saving file
- # ! *forces* :q to execute, hence quiting vim without saving
- ZQ # Quit vim without saving file
- :x # Save file and quit vim, shorter version of :wq
-
- u # Undo
- CTRL+R # Redo
-
- h # Move left one character
- j # Move down one line
- k # Move up one line
- l # Move right one character
-
- Ctrl+B # Move back one full screen
- Ctrl+F # Move forward one full screen
- Ctrl+D # Move forward 1/2 a screen
- Ctrl+U # Move back 1/2 a screen
+ vim <filename> # Open <filename> in vim
+ :help <topic> # Open up built-in help docs about <topic> if any exists
+ :q # Quit vim
+ :w # Save current file
+ :wq # Save file and quit vim
+ ZZ # Save file and quit vim
+ :q! # Quit vim without saving file
+ # ! *forces* :q to execute, hence quiting vim without saving
+ ZQ # Quit vim without saving file
+ :x # Save file(only when the file is modified) and quit vim
+
+ u # Undo
+ CTRL+R # Redo
+
+ h # Move left one character
+ j # Move down one line
+ k # Move up one line
+ l # Move right one character
+
+ Ctrl+B # Move back one full screen
+ Ctrl+F # Move forward one full screen
+ Ctrl+D # Move forward 1/2 a screen
+ Ctrl+U # Move back 1/2 a screen
# Moving within the line
- 0 # Move to beginning of line
- $ # Move to end of line
- ^ # Move to first non-blank character in line
+ 0 # Move to beginning of line
+ $ # Move to end of line
+ ^ # Move to first non-blank character in line
# Searching in the text
- /word # Highlights all occurrences of word after cursor
- ?word # Highlights all occurrences of word before cursor
- n # Moves cursor to next occurrence of word after search
- N # Moves cursor to previous occurrence of word
+ /word # Highlights all occurrences of word after cursor
+ ?word # Highlights all occurrences of word before cursor
+ n # Moves cursor to next occurrence of word after search
+ N # Moves cursor to previous occurrence of word
- :%s/foo/bar/g # Change 'foo' to 'bar' on every line in the file
- :s/foo/bar/g # Change 'foo' to 'bar' on the current line
- :%s/\n/\r/g # Replace new line characters with new line characters
+ :%s/foo/bar/g # Change 'foo' to 'bar' on every line in the file
+ :s/foo/bar/g # Change 'foo' to 'bar' on the current line
+ :%s/\n/\r/g # Replace new line characters with new line characters
+ :'<,'>s/foo/bar/g # Change 'foo' to 'bar on every line in the current visual selection
# Jumping to characters
- f<character> # Jump forward and land on <character>
- t<character> # Jump forward and land right before <character>
+ f<character> # Jump forward and land on <character>
+ t<character> # Jump forward and land right before <character>
# For example,
- f< # Jump forward and land on <
- t< # Jump forward and land right before <
+ f< # Jump forward and land on <
+ t< # Jump forward and land right before <
# Moving by word
- w # Move forward by one word
- b # Move back by one word
- e # Move to end of current word
+ w # Move forward by one word
+ b # Move back by one word
+ e # Move to end of current word
# Other characters for moving around
- gg # Go to the top of the file
- G # Go to the bottom of the file
- :NUM # Go to line number NUM (NUM is any number)
- H # Move to the top of the screen
- M # Move to the middle of the screen
- L # Move to the bottom of the screen
+ gg # Go to the top of the file
+ G # Go to the bottom of the file
+ :NUM # Go to line number NUM (NUM is any number)
+ H # Move to the top of the screen
+ M # Move to the middle of the screen
+ L # Move to the bottom of the screen
```
## Help docs:
@@ -104,28 +106,28 @@ Vim is based on the concept on **modes**.
- Ex Mode - used to drop down to the bottom with the ':' prompt to enter commands
```
- i # Puts vim into insert mode, before the cursor position
- a # Puts vim into insert mode, after the cursor position
- v # Puts vim into visual mode
- : # Puts vim into ex mode
- <esc> # 'Escapes' from whichever mode you're in, into Command mode
+ i # Puts vim into insert mode, before the cursor position
+ a # Puts vim into insert mode, after the cursor position
+ v # Puts vim into visual mode
+ : # Puts vim into ex mode
+ <esc> # 'Escapes' from whichever mode you're in, into Command mode
# Copying and pasting text
- # Operations use the vim register by default
- # Think of it as vim's private clipboard
+ # Operations use the vim register by default
+ # Think of it as vim's private clipboard
- # Yank ~ copy text into vim register
- y # Yank whatever is selected
- yy # Yank the current line
+ # Yank ~ copy text into vim register
+ y # Yank whatever is selected
+ yy # Yank the current line
- # Delete ~ yank text and delete from file
- d # Delete whatever is selected
- dd # Delete the current line
+ # Delete ~ yank text and delete from file
+ d # Delete whatever is selected
+ dd # Delete the current line
- p # Paste text in vim register after the current cursor position
- P # Paste text in vim register before the current cursor position
+ p # Paste text in vim register after the current cursor position
+ P # Paste text in vim register before the current cursor position
- x # Delete character under current cursor position
+ x # Delete character under current cursor position
```
## The 'Grammar' of vim
@@ -142,64 +144,75 @@ A few important examples of 'Verbs', 'Modifiers', and 'Nouns':
```
# 'Verbs'
- d # Delete
- c # Change
- y # Yank (copy)
- v # Visually select
+ d # Delete
+ c # Change
+ y # Yank (copy)
+ v # Visually select
# 'Modifiers'
- i # Inside
- a # Around
- NUM # Number (NUM is any number)
- f # Searches for something and lands on it
- t # Searches for something and stops before it
- / # Finds a string from cursor onwards
- ? # Finds a string before cursor
+ i # Inside
+ a # Around
+ NUM # Number (NUM is any number)
+ f # Searches for something and lands on it
+ t # Searches for something and stops before it
+ / # Finds a string from cursor onwards
+ ? # Finds a string before cursor
# 'Nouns'
- w # Word
- s # Sentence
- p # Paragraph
- b # Block
+ w # Word
+ s # Sentence
+ p # Paragraph
+ b # Block
# Sample 'sentences' or commands
- d2w # Delete 2 words
- cis # Change inside sentence
- yip # Yank inside paragraph (copy the para you're in)
- ct< # Change to open bracket
- # Change the text from where you are to the next open bracket
- d$ # Delete till end of line
+ d2w # Delete 2 words
+ cis # Change inside sentence
+ yip # Yank inside paragraph (copy the para you're in)
+ ct< # Change to open bracket
+ # Change the text from where you are to the next open bracket
+ d$ # Delete till end of line
```
## Some shortcuts and tricks
<!--TODO: Add more!-->
```
- > # Indent selection by one block
- < # Dedent selection by one block
- :earlier 15m # Reverts the document back to how it was 15 minutes ago
- :later 15m # Reverse above command
- ddp # Swap position of consecutive lines, dd then p
- . # Repeat previous action
- :w !sudo tee % # Save the current file as root
- :set syntax=c # Set syntax highlighting to 'c'
- :sort # Sort all lines
- :sort! # Sort all lines in reverse
- :sort u # Sort all lines and remove duplicates
- ~ # Toggle letter case of selected text
- u # Selected text to lower case
- U # Selected text to upper case
- J # Join the current line with the next line
+ > # Indent selection by one block
+ < # Dedent selection by one block
+ :earlier 15m # Reverts the document back to how it was 15 minutes ago
+ :later 15m # Reverse above command
+ ddp # Swap position of consecutive lines, dd then p
+ . # Repeat previous action
+ :w !sudo tee % # Save the current file as root
+ :set syntax=c # Set syntax highlighting to 'c'
+ :sort # Sort all lines
+ :sort! # Sort all lines in reverse
+ :sort u # Sort all lines and remove duplicates
+ ~ # Toggle letter case of selected text
+ u # Selected text to lower case
+ U # Selected text to upper case
+ J # Join the current line with the next line
# Fold text
- zf # Create fold from selected text
- zo # Open current fold
- zc # Close current fold
- zR # Open all folds
- zM # Close all folds
+ zf # Create fold from selected text
+ zd # Delete fold on the current line
+ zD # Recursively delete nested or visually selected folds
+ zE # Eliminate all folds in the window
+ zo # Open current fold
+ zO # Recursively open nested or visually selected folds
+ zc # Close current fold
+ zC # Recursively close nested or visually selected folds
+ zR # Open all folds
+ zM # Close all folds
+ za # Toggle open/close current fold
+ zA # Recursively toggle open/close nested fold
+ [z # Move to the start of the current fold
+ ]z # Move to the end of the current fold
+ zj # Move to the start of the next fold
+ zk # Move to the end of the previous fold
```
## Macros
@@ -210,9 +223,9 @@ you use, until you stop recording. On invoking a macro, it applies the exact
same sequence of actions and commands again on the text selection.
```
- qa # Start recording a macro named 'a'
- q # Stop recording
- @a # Play back the macro
+ qa # Start recording a macro named 'a'
+ q # Stop recording
+ @a # Play back the macro
```
### Configuring ~/.vimrc
diff --git a/yaml.html.markdown b/yaml.html.markdown
index 6dc5905e..5c898148 100644
--- a/yaml.html.markdown
+++ b/yaml.html.markdown
@@ -2,8 +2,10 @@
language: yaml
filename: learnyaml.yaml
contributors:
+
- [Leigh Brenecki, 'https://leigh.net.au']
- [Suhas SG, 'https://github.com/jargnar']
+
---
YAML is a data serialisation language designed to be directly writable and
@@ -17,6 +19,7 @@ YAML doesn't allow literal tab characters for indentation.
--- # document start
# Comments in YAML look like this.
+# YAML support single-line comments.
################
# SCALAR TYPES #
@@ -28,11 +31,23 @@ key: value
another_key: Another value goes here.
a_number_value: 100
scientific_notation: 1e+12
-# The number 1 will be interpreted as a number, not a boolean. if you want
-# it to be interpreted as a boolean, use true
+hex_notation: 0x123 # evaluates to 291
+octal_notation: 0123 # evaluates to 83
+
+# The number 1 will be interpreted as a number, not a boolean.
+# If you want it to be interpreted as a boolean, use true.
boolean: true
null_value: null
key with spaces: value
+
+# Yes and No (doesn't matter the case) will be evaluated to boolean
+# true and false values respectively.
+# To use the actual value use single or double quotes.
+no: no # evaluates to "false": false
+yes: No # evaluates to "true": false
+not_enclosed: yes # evaluates to "not_enclosed": true
+enclosed: "yes" # evaluates to "enclosed": yes
+
# Notice that strings don't need to be quoted. However, they can be.
however: 'A string, enclosed in quotes.'
'Keys can be quoted too.': "Useful if you want to put a ':' in your key."
@@ -41,25 +56,49 @@ double quotes: "have many: \", \0, \t, \u263A, \x0d\x0a == \r\n, and more."
# UTF-8/16/32 characters need to be encoded
Superscript two: \u00B2
-# Multiple-line strings can be written either as a 'literal block' (using |),
+# Special characters must be enclosed in single or double quotes
+special_characters: "[ John ] & { Jane } - <Doe>"
+
+# Multiple-line strings can be written either as a 'literal block' (using |),
# or a 'folded block' (using '>').
+# Literal block turn every newline within the string into a literal newline (\n).
+# Folded block removes newlines within the string.
literal_block: |
- This entire block of text will be the value of the 'literal_block' key,
- with line breaks being preserved.
+ This entire block of text will be the value of the 'literal_block' key,
+ with line breaks being preserved.
- The literal continues until de-dented, and the leading indentation is
- stripped.
+ The literal continues until de-dented, and the leading indentation is
+ stripped.
- Any lines that are 'more-indented' keep the rest of their indentation -
- these lines will be indented by 4 spaces.
+ Any lines that are 'more-indented' keep the rest of their indentation -
+ these lines will be indented by 4 spaces.
folded_style: >
- This entire block of text will be the value of 'folded_style', but this
- time, all newlines will be replaced with a single space.
+ This entire block of text will be the value of 'folded_style', but this
+ time, all newlines will be replaced with a single space.
- Blank lines, like above, are converted to a newline character.
+ Blank lines, like above, are converted to a newline character.
- 'More-indented' lines keep their newlines, too -
- this text will appear over two lines.
+ 'More-indented' lines keep their newlines, too -
+ this text will appear over two lines.
+
+# |- and >- removes the trailing blank lines (also called literal/block "strip")
+literal_strip: |-
+ This entire block of text will be the value of the 'literal_block' key,
+ with trailing blank line being stripped.
+block_strip: >-
+ This entire block of text will be the value of 'folded_style', but this
+ time, all newlines will be replaced with a single space and
+ trailing blank line being stripped.
+
+# |+ and >+ keeps trailing blank lines (also called literal/block "keep")
+literal_keep: |+
+ This entire block of text will be the value of the 'literal_block' key,
+ with trailing blank line being kept.
+
+block_keep: >+
+ This entire block of text will be the value of 'folded_style', but this
+ time, all newlines will be replaced with a single space and
+ trailing blank line being kept.
####################
# COLLECTION TYPES #
@@ -87,7 +126,7 @@ a_nested_map:
# An example
? - Manchester United
- Real Madrid
-: [2001-01-01, 2002-02-02]
+: [ 2001-01-01, 2002-02-02 ]
# Sequences (equivalent to lists or arrays) look like this
# (note that the '-' counts as indentation):
@@ -98,24 +137,26 @@ a_sequence:
- Item 4
- key: value
another_key: another_value
- -
- - This is a sequence
+ - - This is a sequence
- inside another sequence
- - - Nested sequence indicators
- can be collapsed
# Since YAML is a superset of JSON, you can also write JSON-style maps and
# sequences:
-json_map: {"key": "value"}
-json_seq: [3, 2, 1, "takeoff"]
-and quotes are optional: {key: [3, 2, 1, takeoff]}
+json_map: { "key": "value" }
+json_seq: [ 3, 2, 1, "takeoff" ]
+and quotes are optional: { key: [ 3, 2, 1, takeoff ] }
#######################
# EXTRA YAML FEATURES #
#######################
# YAML also has a handy feature called 'anchors', which let you easily duplicate
-# content across your document. Both of these keys will have the same value:
+# content across your document.
+# Anchors identified by & character which define the value.
+# Aliases identified by * character which acts as "see above" command.
+# Both of these keys will have the same value:
anchored_content: &anchor_name This string will appear as the value of two keys.
other_anchor: *anchor_name
@@ -123,28 +164,35 @@ other_anchor: *anchor_name
base: &base
name: Everyone has same name
-# The regexp << is called Merge Key Language-Independent Type. It is used to
+# The regexp << is called 'Merge Key Language-Independent Type'. It is used to
# indicate that all the keys of one or more specified maps should be inserted
# into the current map.
-
+# NOTE: If key already exists alias will not be merged
foo:
- <<: *base
+ <<: *base # doesn't merge the anchor
age: 10
-
+ name: John
bar:
- <<: *base
+ <<: *base # base anchor will be merged
age: 20
# foo and bar would also have name: Everyone has same name
# YAML also has tags, which you can use to explicitly declare types.
+# Syntax: !![typeName] [value]
+explicit_boolean: !!bool true
+explicit_integer: !!int 42
+explicit_float: !!float -42.24
explicit_string: !!str 0.5
+explicit_datetime: !!timestamp 2022-11-17 12:34:56.78 +9
+explicit_null: !!null null
+
# Some parsers implement language specific tags, like this one for Python's
# complex number type.
python_complex_number: !!python/complex 1+2j
# We can also use yaml complex keys with language specific tags
-? !!python/tuple [5, 7]
+? !!python/tuple [ 5, 7 ]
: Fifty Seven
# Would be {(5, 7): 'Fifty Seven'} in Python
@@ -154,9 +202,10 @@ python_complex_number: !!python/complex 1+2j
# Strings and numbers aren't the only scalars that YAML can understand.
# ISO-formatted date and datetime literals are also parsed.
-datetime: 2001-12-15T02:59:43.1Z
-datetime_with_spaces: 2001-12-14 21:59:43.10 -5
-date: 2002-12-14
+datetime_canonical: 2001-12-15T02:59:43.1Z
+datetime_space_seperated_with_time_zone: 2001-12-14 21:59:43.10 -5
+date_implicit: 2002-12-14
+date_explicit: !!timestamp 2002-12-14
# The !!binary tag indicates that a string is actually a base64-encoded
# representation of a binary blob.
@@ -171,7 +220,7 @@ set:
? item1
? item2
? item3
-or: {item1, item2, item3}
+or: { item1, item2, item3 }
# Sets are just maps with null values; the above is equivalent to:
set2:
@@ -186,3 +235,4 @@ set2:
+ [YAML official website](https://yaml.org/)
+ [Online YAML Validator](http://www.yamllint.com/)
++ [JSON ⇆ YAML](https://www.json2yaml.com/)
diff --git a/zig.html.markdown b/zig.html.markdown
new file mode 100644
index 00000000..0efe5f64
--- /dev/null
+++ b/zig.html.markdown
@@ -0,0 +1,980 @@
+---
+language: zig
+filename: learnzig.zig
+contributors:
+ - ["Philippe Pittoli", "https://karchnu.fr/"]
+---
+
+
+[Zig][ziglang] aims to be a replacement for the C programming language.
+
+**WARNING**: this document expects you to understand a few basic concepts in computer science, such as pointers, stack and heap memory, etc.
+
+**WARNING**: Zig isn't considered as ready for production. Bugs are expected.
+DO NOT TRY ZIG AS YOUR FIRST PROGRAMMING EXPERIENCE.
+The compiler, even the language and its libraries aren't ready, yet.
+You've been warned.
+
+Prior knowledge of C is recommended.
+
+
+## Quick overview: Zig compared to C
+
+- Syntax is mostly the same, with some improvements (less ambiguity).
+- Zig introduces namespaces.
+- Try and catch mechanism, which is both convenient, efficient and optional.
+- Most of the C undefined behaviors (UBs) are fixed.
+- Compared to C, raw pointers are safer to use and less likely to be needed.
+ * The type system distinguishes between a pointer to a single value, or multiple values, etc.
+ * Slices are preferred, which is a structure with a pointer and a runtime known size, which characterizes most uses of pointers in the first place.
+- Some arbitrary language limitations are removed. For example, enumerations, structures and unions can have functions.
+- Simple access to SIMD operations (basic maths on vectors).
+- Zig provides both low-level features of C and the one provided through compiler extensions.
+ For example: packed structures.
+- An extensive standard library, including data structures and algorithms.
+- Cross-compilation capability is provided by default, without any dependency.
+ Different libc are provided to ease the process.
+ Cross-compilation works from, and to, any operating system and architecture.
+
+## Zig language
+
+
+```zig
+//! Top-level documentation.
+
+/// Documentation comment.
+
+// Simple comment.
+```
+
+
+### Hello world.
+```zig
+// Import standard library, reachable through the "std" constant.
+const std = @import("std");
+
+// "info" now refers to the "std.log.info" function.
+const info = std.log.info;
+
+// Usual hello world.
+// syntax: [pub] fn <function-name>(<arguments>) <return-type> { <body> }
+pub fn main() void {
+ // Contrary to C functions, Zig functions have a fixed number of arguments.
+ // In C: "printf" takes any number of arguments.
+ // In Zig: std.log.info takes a format and a list of elements to print.
+ info("hello world", .{}); // .{} is an empty anonymous tuple.
+}
+```
+
+### Booleans, integers and float.
+```zig
+// Booleans.
+// Keywords are prefered to operators for boolean operations.
+print("{}\n{}\n{}\n", .{
+ true and false,
+ true or false,
+ !true,
+});
+
+// Integers.
+const one_plus_one: i32 = 1 + 1;
+print("1 + 1 = {}\n", .{one_plus_one}); // 2
+
+// Floats.
+const seven_div_three: f32 = 7.0 / 3.0;
+print("7.0 / 3.0 = {}\n", .{seven_div_three}); // 2.33333325e+00
+
+// Integers have arbitrary value lengths.
+var myvar: u10 = 5; // 10-bit unsigned integer
+// Useful for example to read network packets, or complex binary formats.
+
+// Number representation is greatly improved compared to C.
+const one_billion = 1_000_000_000; // Decimal.
+const binary_mask = 0b1_1111_1111; // Binary. Ex: network mask.
+const permissions = 0o7_5_5; // Octal. Ex: Unix permissions.
+const big_address = 0xFF80_0000_0000_0000; // Hexa. Ex: IPv6 address.
+
+
+// Overflow operators: tell the compiler when it's okay to overflow.
+var i: u8 = 0; // "i" is an unsigned 8-bit integer
+i -= 1; // runtime overflow error (unsigned value always are positive)
+i -%= 1; // okay (wrapping operator), i == 255
+
+// Saturation operators: values will stick to their lower and upper bounds.
+var i: u8 = 200; // "i" is an unsigned 8-bit integer (values: from 0 to 255)
+i +| 100 == 255 // u8: won't go higher than 255
+i -| 300 == 0 // unsigned, won't go lower than 0
+i *| 2 == 255 // u8: won't go higher than 255
+i <<| 8 == 255 // u8: won't go higher than 255
+```
+
+### Arrays.
+```zig
+// An array is a well-defined structure with a length attribute (len).
+
+// 5-byte array with undefined content (stack garbage).
+var array1: [5]u8 = undefined;
+
+// 5-byte array with defined content.
+var array2 = [_]u8{ 1, 2, 3, 4, 5 };
+// [_] means the compiler knows the length at compile-time.
+
+// 1000-byte array with defined content (0).
+var array3 = [_]u8{0} ** 1000;
+
+// Another 1000-byte array with defined content.
+// The content is provided by the "foo" function, called at compile-time and
+// allows complex initializations.
+var array4 = [_]u8{foo()} ** 1000;
+
+// In any case, array.len gives the length of the array,
+// array1.len and array2.len produce 5, array3.len and array4.len produce 1000.
+
+
+// Modifying and accessing arrays content.
+
+// Array of 10 32-bit undefined integers.
+var some_integers: [10]i32 = undefined;
+
+some_integers[0] = 30; // first element of the array is now 30
+
+var x = some_integers[0]; // "x" now equals to 30, its type is infered.
+var y = some_integers[1]; // Second element of the array isn't defined.
+ // "y" got a stack garbage value (no runtime error).
+
+// Array of 10 32-bit undefined integers.
+var some_integers: [10]i32 = undefined;
+
+var z = some_integers[20]; // index > array size, compilation error.
+
+// At runtime, we loop over the elements of "some_integers" with an index.
+// Index i = 20, then we try:
+try some_integers[i]; // Runtime error 'index out of bounds'.
+ // "try" keyword is necessary when accessing an array with
+ // an index, since there is a potential runtime error.
+ // More on that later.
+```
+
+### Multidimensional arrays.
+```zig
+
+const mat4x4 = [4][4]f32{
+ [_]f32{ 1.0, 0.0, 0.0, 0.0 },
+ [_]f32{ 0.0, 1.0, 0.0, 1.0 },
+ [_]f32{ 0.0, 0.0, 1.0, 0.0 },
+ [_]f32{ 0.0, 0.0, 0.0, 1.0 },
+};
+
+// Access the 2D array then the inner array through indexes.
+try expect(mat4x4[1][1] == 1.0);
+
+// Here we iterate with for loops.
+for (mat4x4) |row, row_index| {
+ for (row) |cell, column_index| {
+ // ...
+ }
+}
+```
+
+### Strings.
+```zig
+
+// Simple string constant.
+const greetings = "hello";
+// ... which is equivalent to:
+const greetings: *const [5:0]u8 = "hello";
+// In words: "greetings" is a constant value, a pointer on a constant array of 5
+// elements (8-bit unsigned integers), with an extra '0' at the end.
+// The extra "0" is called a "sentinel value".
+
+print("string: {s}\n", .{greetings});
+
+// This represents rather faithfully C strings. Although, Zig strings are
+// structures, no need for "strlen" to compute their size.
+// greetings.len == 5
+```
+
+### Slices.
+```zig
+
+// A slice is a pointer and a size, an array without compile-time known size.
+// Slices have runtime out-of-band verifications.
+
+const array = [_]u8{1,2,3,4,5}; // [_] = array with compile-time known size.
+const slice = array[0..array.len]; // "slice" represents the whole array.
+ // slice[10] gives a runtime error.
+```
+
+### Pointers.
+```zig
+
+// Pointer on a value can be created with "&".
+const x: i32 = 1;
+const pointer: *i32 = &x; // "pointer" is a pointer on the i32 var "x".
+print("1 = {}, {}\n", .{x, pointer});
+
+// Pointer values are accessed and modified with ".*".
+if (pointer.* == 1) {
+ print("x value == {}\n", .{pointer.*});
+}
+
+// ".?" is a shortcut for "orelse unreachable".
+const foo = pointer.?; // Get the pointed value, otherwise crash.
+```
+
+### Optional values (?<type>).
+```zig
+// An optional is a value than can be of any type or null.
+
+// Example: "optional_value" can either be "null" or an unsigned 32-bit integer.
+var optional_value: ?u32 = null; // optional_value == null
+optional_value = 42; // optional_value != null
+
+// "some_function" returns ?u32
+var x = some_function();
+if (x) |value| {
+ // In case "some_function" returned a value.
+ // Do something with 'value'.
+}
+```
+
+### Errors.
+```zig
+// Zig provides an unified way to express errors.
+
+// Errors are defined in error enumerations, example:
+const Error = error {
+ WatchingAnyNetflixTVShow,
+ BeOnTwitter,
+};
+
+// Normal enumerations are expressed the same way, but with "enum" keyword.
+const SuccessStory = enum {
+ DoingSport,
+ ReadABook,
+};
+
+
+// Error union (!).
+// Either the value "mylife" is an an error or a normal value.
+var mylife: Error!SuccessStory = Error.BeOnTwitter;
+// mylife is an error. Sad.
+
+mylife = SuccessStory.ReadABook;
+// Now mylife is an enum.
+
+
+// Zig ships with many pre-defined errors. Example:
+const value: anyerror!u32 = error.Broken;
+
+
+// Handling errors.
+
+// Some error examples.
+const Error = error {
+ UnExpected,
+ Authentication,
+};
+
+// "some_function" can either return an "Error" or an integer.
+fn some_function() Error!u8 {
+ return Error.UnExpected; // It returns an error.
+}
+
+// Errors can be "catch" without intermediate variable.
+var value = some_function() catch |err| switch(err) {
+ Error.UnExpected => return err, // Returns the error.
+ Error.Authentication => unreachable, // Not expected. Crashes the program.
+ else => unreachable,
+};
+
+// An error can be "catch" without giving it a name.
+const unwrapped = some_function() catch 1234; // "unwrapped" = 1234
+
+// "try" is a very handy shortcut for "catch |err| return err".
+var value = try some_function();
+// If "some_function" fails, the current function stops and returns the error.
+// "value" can only have a valid value, the error already is handled with "try".
+```
+
+### Control flow.
+
+```zig
+// Conditional branching.
+
+if (condition) {
+ ...
+}
+else {
+ ...
+}
+
+// Ternary.
+var value = if (condition) x else y;
+
+// Shortcut for "if (x) x else 0"
+var value = x orelse 0;
+
+// If "a" is an optional, which may contain a value.
+if (a) |value| {
+ print("value: {}\n", .{value});
+}
+else {
+ print("'a' is null\n", .{});
+}
+
+// Get a pointer on the value (if it exists).
+if (a) |*value| { value.* += 1; }
+
+
+// Loops.
+
+// Syntax examples:
+// while (condition) statement
+// while (condition) : (end-of-iteration-statement) statement
+//
+// for (iterable) statement
+// for (iterable) |capture| statement
+// for (iterable) statement else statement
+
+// Note: loops work the same way over arrays or slices.
+
+// Simple "while" loop.
+while (i < 10) { i += 1; }
+
+// While loop with a "continue expression"
+// (expression executed as the last expression of the loop).
+while (i < 10) : (i += 1) { ... }
+// Same, with a more complex continue expression (block of code).
+while (i * j < 2000) : ({ i *= 2; j *= 3; }) { ... }
+
+// To iterate over a portion of a slice, reslice.
+for (items[0..1]) |value| { sum += value; }
+
+// Loop over every item of an array (or slice).
+for (items) |value| { sum += value; }
+
+// Iterate and get pointers on values instead of copies.
+for (items) |*value| { value.* += 1; }
+
+// Iterate with an index.
+for (items) |value, i| { print("val[{}] = {}\n", .{i, value}); }
+
+// Iterate with pointer and index.
+for (items) |*value, i| { print("val[{}] = {}\n", .{i, value}); value.* += 1; }
+
+
+// Break and continue are supported.
+for (items) |value| {
+ if (value == 0) { continue; }
+ if (value >= 10) { break; }
+ // ...
+}
+
+// For loops can also be used as expressions.
+// Similar to while loops, when you break from a for loop,
+// the else branch is not evaluated.
+var sum: i32 = 0;
+// The "for" loop has to provide a value, which will be the "else" value.
+const result = for (items) |value| {
+ if (value != null) {
+ sum += value.?; // "result" will be the last "sum" value.
+ }
+} else 0; // Last value.
+```
+
+### Labels.
+```zig
+
+// Labels are a way to name an instruction, a location in the code.
+// Labels can be used to "continue" or "break" in a nested loop.
+outer: for ([_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }) |_| {
+ for ([_]i32{ 1, 2, 3, 4, 5 }) |_| {
+ count += 1;
+ continue :outer; // "continue" for the first loop.
+ }
+} // count = 8
+outer: for ([_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }) |_| {
+ for ([_]i32{ 1, 2, 3, 4, 5 }) |_| {
+ count += 1;
+ break :outer; // "break" for the first loop.
+ }
+} // count = 1
+
+
+// Labels can also be used to return a value from a block.
+var y: i32 = 5;
+const x = blk: {
+ y += 1;
+ break :blk y; // Now "x" equals 6.
+};
+// Relevant in cases like "for else" expression (explained in the following).
+
+// For loops can be used as expressions.
+// When you break from a for loop, the else branch is not evaluated.
+// WARNING: counter-intuitive.
+// The "for" loop will run, then the "else" block will run.
+// The "else" keyword has to be followed by the value to give to "result".
+// See later for another form.
+var sum: u8 = 0;
+const result = for (items) |value| {
+ sum += value;
+} else 8; // result = 8
+
+// In this case, the "else" keyword is followed by a value, too.
+// However, the syntax is different: it is labeled.
+// Instead of a value, there is a label followed by a block of code, which
+// allows to do stuff before returning the value (see the "break" invocation).
+const result = for (items) |value| { // First: loop.
+ sum += value;
+} else blk: { // Second: "else" block.
+ std.log.info("executed AFTER the loop!", .{});
+ break :blk sum; // The "sum" value will replace the label "blk".
+};
+```
+
+### Switch.
+```zig
+
+// As a switch in C, but slightly more advanced.
+// Syntax:
+// switch (value) {
+// pattern => expression,
+// pattern => expression,
+// else => expression
+// };
+
+// A switch only checking for simple values.
+var x = switch(value) {
+ Error.UnExpected => return err,
+ Error.Authentication => unreachable,
+ else => unreachable,
+};
+
+// A slightly more advanced switch, accepting a range of values:
+const foo: i32 = 0;
+const bar = switch (foo) {
+ 0 => "zero",
+ 1...std.math.maxInt(i32) => "positive",
+ else => "negative",
+};
+```
+
+### Structures.
+```zig
+
+// Structure containing a single value.
+const Full = struct {
+ number: u16,
+};
+
+// Packed structure, with guaranteed in-memory layout.
+const Divided = packed struct {
+ half1: u8,
+ quarter3: u4,
+ quarter4: u4,
+};
+
+// Point is a constant representing a structure containing two u32, "x" and "y".
+// "x" has a default value, which wasn't possible in C.
+const Point = struct {
+ x: u32 = 1, // default value
+ y: u32,
+};
+
+// Variable "p" is a new Point, with x = 1 (default value) and y = 2.
+var p = Point{ .y = 2 };
+
+// Fields are accessed as usual with the dot notation: variable.field.
+print("p.x: {}\n", .{p.x}); // 1
+print("p.y: {}\n", .{p.y}); // 2
+
+
+// A structure can also contain public constants and functions.
+const Point = struct {
+ pub const some_constant = 30;
+
+ x: u32,
+ y: u32,
+
+ // This function "init" creates a Point and returns it.
+ pub fn init() Point {
+ return Point{ .x = 0, .y = 0 };
+ }
+};
+
+
+// How to access a structure public constant.
+// The value isn't accessed from an "instance" of the structure, but from the
+// constant representing the structure definition (Point).
+print("constant: {}\n", .{Point.some_constant});
+
+// Having an "init" function is rather idiomatic in the standard library.
+// More on that later.
+var p = Point.init();
+print("p.x: {}\n", .{p.x}); // p.x = 0
+print("p.y: {}\n", .{p.y}); // p.y = 0
+
+
+// Structures often have functions to modify their state, similar to
+// object-oriented programming.
+const Point = struct {
+ const Self = @This(); // Refers to its own type (later called "Point").
+
+ x: u32,
+ y: u32,
+
+ // Take a look at the signature. First argument is of type *Self: "self" is
+ // a pointer on the instance of the structure.
+ // This allows the same "dot" notation as in OOP, like "instance.set(x,y)".
+ // See the following example.
+ pub fn set(self: *Self, x: u32, y: u32) void {
+ self.x = x;
+ self.y = y;
+ }
+
+ // Again, look at the signature. First argument is of type Self (not *Self),
+ // this isn't a pointer. In this case, "self" refers to the instance of the
+ // structure, but can't be modified.
+ pub fn getx(self: Self) u32 {
+ return self.x;
+ }
+
+ // PS: two previous functions may be somewhat useless.
+ // Attributes can be changed directly, no need for accessor functions.
+ // It was just an example.
+};
+
+// Let's use the previous structure.
+var p = Point{ .x = 0, .y = 0 }; // "p" variable is a Point.
+
+p.set(10, 30); // x and y attributes of "p" are modified via the "set" function.
+print("p.x: {}\n", .{p.x}); // 10
+print("p.y: {}\n", .{p.y}); // 30
+
+// In C:
+// 1. We would have written something like: point_set(p, 10, 30).
+// 2. Since all functions are in the same namespace, it would have been
+// very cumbersome to create functions with different names for different
+// structures. Many long names, painful to read.
+//
+// In Zig, structures provide namespaces for their own functions.
+// Different structures can have the same names for their functions,
+// which brings clarity.
+```
+
+### Tuples.
+```zig
+// A tuple is a list of elements, possibly of different types.
+
+const foo = .{ "hello", true, 42 };
+// foo.len == 3
+```
+
+### Enumerations.
+```zig
+
+const Type = enum { ok, not_ok };
+
+const CardinalDirections = enum { North, South, East, West };
+const direction: CardinalDirections = .North;
+const x = switch (direction) {
+ // shorthand for CardinalDirections.North
+ .North => true,
+ else => false
+};
+
+// Switch statements need exhaustiveness.
+// WARNING: won't compile. East and West are missing.
+const x = switch (direction) {
+ .North => true,
+ .South => true,
+};
+
+
+// Switch statements need exhaustiveness.
+// Won't compile: East and West are missing.
+const x = switch (direction) {
+ .North => true,
+ .South => true,
+ .East, // Its value is the same as the following pattern: false.
+ .West => false,
+};
+
+
+// Enumerations are like structures: they can have functions.
+```
+
+### Unions.
+```zig
+
+const Bar = union {
+ boolean: bool,
+ int: i16,
+ float: f32,
+};
+
+// Both syntaxes are equivalent.
+const foo = Bar{ .int = 42 };
+const foo: Bar = .{ .int = 42 };
+
+// Unions, like enumerations and structures, can have functions.
+```
+
+### Tagged unions.
+```zig
+
+// Unions can be declared with an enum tag type, allowing them to be used in
+// switch expressions.
+
+const MaybeEnum = enum {
+ success,
+ failure,
+};
+
+const Maybe = union(MaybeEnum) {
+ success: u8,
+ failure: []const u8,
+};
+
+// First value: success!
+const yay = Maybe{ .success = 42 };
+switch (yay) {
+ .success => |value| std.log.info("success: {}", .{value}),
+ .failure => |err_msg| std.log.info("failure: {}", .{err_msg}),
+}
+
+// Second value: failure! :(
+const nay = Maybe{ .failure = "I was too lazy" };
+switch (nay) {
+ .success => |value| std.log.info("success: {}", .{value}),
+ .failure => |err_msg| std.log.info("failure: {}", .{err_msg}),
+}
+```
+
+### Defer and errdefer.
+```zig
+
+// Make sure that an action (single instruction or block of code) is executed
+// before the end of the scope (function, block of code).
+// Even on error, that action will be executed.
+// Useful for memory allocations, and resource management in general.
+
+pub fn main() void {
+ // Should be executed at the end of the function.
+ defer print("third!\n", .{});
+
+ {
+ // Last element of its scope: will be executed right away.
+ defer print("first!\n", .{});
+ }
+
+ print("second!\n", .{});
+}
+
+fn hello_world() void {
+ defer print("end of function\n", .{}); // after "hello world!"
+
+ print("hello world!\n", .{});
+}
+
+// errdefer executes the instruction (or block of code) only on error.
+fn second_hello_world() !void {
+ errdefer print("2. something went wrong!\n", .{}); // if "foo" fails.
+ defer print("1. second hello world\n", .{}); // executed after "foo"
+
+ try foo();
+}
+// Defer statements can be seen as stacked: first one is executed last.
+```
+
+### Memory allocators.
+Memory isn't managed directly in the standard library, instead an "allocator" is asked every time an operation on memory is required.
+Thus, the standard library lets developers handle memory as they need, through structures called "allocators", handling all memory operations.
+
+**NOTE**: the choice of the allocator isn't in the scope of this document.
+A whole book could be written about it.
+However, here are some examples, to get an idea of what you can expect:
+- page_allocator.
+ Allocate a whole page of memory each time we ask for some memory.
+ Very simple, very dumb, very wasteful.
+- GeneralPurposeAllocator.
+ Get some memory first and manage some buckets of memory in order to
+ reduce the number of allocations.
+ A bit complex. Can be combined with other allocators.
+ Can detect leaks and provide useful information to find them.
+- FixedBufferAllocator.
+ Use a fixed buffer to get its memory, don't ask memory to the kernel.
+ Very simple, limited and wasteful (can't deallocate), but very fast.
+- ArenaAllocator.
+ Allow to free all allocted memory at once.
+ To use in combinaison with another allocator.
+ Very simple way of avoiding leaks.
+
+A first example.
+```zig
+// "!void" means the function doesn't return any value except for errors.
+// In this case we try to allocate memory, and this may fail.
+fn foo() !void {
+ // In this example we use a page allocator.
+ var allocator = std.heap.page_allocator;
+
+ // "list" is an ArrayList of 8-bit unsigned integers.
+ // An ArrayList is a contiguous, growable list of elements in memory.
+ var list = try ArrayList(u8).initAllocated(allocator);
+ defer list.deinit(); // Free the memory at the end of the scope. Can't leak.
+ // "defer" allows to express memory release right after its allocation,
+ // regardless of the complexity of the function (loops, conditions, etc.).
+
+ list.add(5); // Some memory is allocated here, with the provided allocator.
+
+ for (list.items) |item| {
+ std.debug.print("item: {}\n", .{item});
+ }
+}
+```
+
+### Memory allocation combined with error management and defer.
+```zig
+
+fn some_memory_allocation_example() !void {
+ // Memory allocation may fail, so we "try" to allocate the memory and
+ // in case there is an error, the current function returns it.
+ var buf = try page_allocator.alloc(u8, 10);
+ // Defer memory release right after the allocation.
+ // Will happen even if an error occurs.
+ defer page_allocator.free(buf);
+
+ // Second allocation.
+ // In case of a failure, the first allocation is correctly released.
+ var buf2 = try page_allocator.alloc(u8, 10);
+ defer page_allocator.free(buf2);
+
+ // In case of failure, both previous allocations are correctly deallocated.
+ try foo();
+ try bar();
+
+ // ...
+}
+```
+
+### Memory allocators: a taste of the standard library.
+```zig
+
+// Allocators: 4 main functions to know
+// single_value = create (type)
+// destroy (single_value)
+// slice = alloc (type, size)
+// free (slice)
+
+// Page Allocator
+fn page_allocator_fn() !void {
+ var slice = try std.heap.page_allocator.alloc(u8, 3);
+ defer std.heap.page_allocator.free(slice);
+
+ // playing_with_a_slice(slice);
+}
+
+// GeneralPurposeAllocator
+fn general_purpose_allocator_fn() !void {
+ // GeneralPurposeAllocator has to be configured.
+ // In this case, we want to track down memory leaks.
+ const config = .{.safety = true};
+ var gpa = std.heap.GeneralPurposeAllocator(config){};
+ defer _ = gpa.deinit();
+
+ const allocator = gpa.allocator();
+
+ var slice = try allocator.alloc(u8, 3);
+ defer allocator.free(slice);
+
+ // playing_with_a_slice(slice);
+}
+
+// FixedBufferAllocator
+fn fixed_buffer_allocator_fn() !void {
+ var buffer = [_]u8{0} ** 1000; // array of 1000 u8, all initialized at zero.
+ var fba = std.heap.FixedBufferAllocator.init(buffer[0..]);
+ // Side note: buffer[0..] is a way to create a slice from an array.
+ // Since the function takes a slice and not an array, this makes
+ // the type system happy.
+
+ var allocator = fba.allocator();
+
+ var slice = try allocator.alloc(u8, 3);
+ // No need for "free", memory cannot be freed with a fixed buffer allocator.
+ // defer allocator.free(slice);
+
+ // playing_with_a_slice(slice);
+}
+
+// ArenaAllocator
+fn arena_allocator_fn() !void {
+ // Reminder: arena doesn't allocate memory, it uses an inner allocator.
+ // In this case, we combine the arena allocator with the page allocator.
+ var arena = std.heap.arena_allocator.init(std.heap.page_allocator);
+ defer arena.deinit(); // end of function = all allocations are freed.
+
+ var allocator = arena.allocator();
+
+ const slice = try allocator.alloc(u8, 3);
+ // No need for "free", memory will be freed anyway.
+
+ // playing_with_a_slice(slice);
+}
+
+
+// Combining the general purpose and arena allocators. Both are very useful,
+// and their combinaison should be in everyone's favorite cookbook.
+fn gpa_arena_allocator_fn() !void {
+ const config = .{.safety = true};
+ var gpa = std.heap.GeneralPurposeAllocator(config){};
+ defer _ = gpa.deinit();
+
+ const gpa_allocator = gpa.allocator();
+
+ var arena = arena_allocator.init(gpa_allocator);
+ defer arena.deinit();
+
+ const allocator = arena.allocator();
+
+ var slice = try allocator.alloc(u8, 3);
+ defer allocator.free(slice);
+
+ // playing_with_a_slice(slice);
+}
+```
+
+### Comptime.
+```zig
+
+// Comptime is a way to avoid the pre-processor.
+// The idea is simple: run code at compilation.
+
+inline fn max(comptime T: type, a: T, b: T) T {
+ return if (a > b) a else b;
+}
+
+var res = max(u64, 1, 2);
+var res = max(f32, 10.50, 32.19);
+
+
+// Comptime: creating generic structures.
+
+fn List(comptime T: type) type {
+ return struct {
+ items: []T,
+
+ fn init() ... { ... }
+ fn deinit() ... { ... }
+ fn do() ... { ... }
+ };
+}
+
+const MyList = List(u8);
+
+
+// use
+var list = MyList{
+ .items = ... // memory allocation
+};
+
+list.items[0] = 10;
+```
+
+### Conditional compilation.
+```zig
+const available_os = enum { OpenBSD, Linux };
+const myos = available_os.OpenBSD;
+
+
+// The following switch is based on a constant value.
+// This means that the only possible outcome is known at compile-time.
+// Thus, there is no need to build the rest of the possibilities.
+// Similar to the "#ifdef" in C, but without requiring a pre-processor.
+const string = switch (myos) {
+ .OpenBSD => "OpenBSD is awesome!",
+ .Linux => "Linux rocks!",
+};
+
+// Also works in this case.
+const myprint = switch(myos) {
+ .OpenBSD => std.debug.print,
+ .Linux => std.log.info,
+}
+```
+
+### Testing our functions.
+```zig
+const std = @import("std");
+const expect = std.testing.expect;
+
+// Function to test.
+pub fn some_function() bool {
+ return true;
+}
+
+// This "test" block can be run with "zig test".
+// It will test the function at compile-time.
+test "returns true" {
+ expect(false == some_function());
+}
+```
+
+### Compiler built-ins.
+The compiler has special functions called "built-ins", starting with an "@".
+There are more than a hundred built-ins, allowing very low-level stuff:
+- compile-time errors, logging, verifications
+- type coercion and convertion, even in an unsafe way
+- alignment management
+- memory tricks (such as getting the byte offset of a field in a struct)
+- calling functions at compile-time
+- including C headers to transparently call C functions
+- atomic operations
+- embed files into the executable (@embedFile)
+- frame manipulations (for async functions, for example)
+- etc.
+
+Example: enums aren't integers, they have to be converted with a built-in.
+```zig
+const Value = enum { zero, stuff, blah };
+if (@enumToInt(Value.zero) == 0) { ... }
+if (@enumToInt(Value.stuff) == 1) { ... }
+if (@enumToInt(Value.blah) == 2) { ... }
+```
+
+
+### A few "not yourself in the foot" measures in the Zig language.
+
+- Namespaces: names conflicts are easily avoided.
+ In practice, that means an unified API between different structures (data types).
+- Enumerations aren't integers. Comparing an enumeration to an integer requires a conversion.
+- Explicit casts, coercion exists but is limited.
+ Types are slightly more enforced than in C, just a taste:
+ Pointers aren't integers, explicit conversion is necessary.
+ You won't lose precision by accident, implicit coercions are only authorized in case no precision can be lost.
+ Unions cannot be reinterpreted (in an union with an integer and a float, one cannot take a value for another by accident).
+ Etc.
+- Removing most of the C undefined behaviors (UBs), and when the compiler encounters one, it stops.
+- Slice and Array structures are prefered to pointers.
+ Types enforced by the compiler are less prone to errors than pointer manipulations.
+- Numerical overflows produce an error, unless explicitly accepted using wrapping operators.
+- Try and catch mechanism.
+ It's both handy, trivially implemented (simple error enumeration), and it takes almost no space nor computation time.
+- Unused variables are considered as errors by the compiler.
+- Many pointer types exist in order to represent what is pointed.
+ Example: is this a single value or an array, is the length known, etc.
+- Structures need a value for their attributes, and it still is possible to give an undefined value (stack garbage), but at least it is explicitely undefined.
+
+
+## Further Reading
+
+For a start, some concepts are presented on the [Zig learn website][ziglearn].
+
+The [official website][zigdoc] provides a reference documentation to the language.
+
+For now, documentation for standard library is WIP.
+
+[ziglang]: https://ziglang.org
+[ziglearn]: https://ziglearn.org/
+[zigdoc]: https://ziglang.org/documentation/