Quartz sync: Oct 30, 2024, 6:27 PM

This commit is contained in:
Ryan Kes 2024-10-30 18:27:56 +01:00
parent 5139864e15
commit 1ff8ec2771
633 changed files with 23051 additions and 0 deletions

View file

@ -0,0 +1,161 @@
---
date: 2020-06-13
id: 8af0e4ee-b090-4903-9ab7-020a4b7328ef
title: JavaScript Variables
---
# Types
## Numbers
JavaScript uses 64 bits to store number values
### Fractional numbers
``` javascript
console.log(9.81)
```
### Scientific notation
``` javascript
console.log(2.998e8)
```
### Special Numbers
1. Infinity
Infinity and -Infinity represent positive and negative infinities
``` javascript
console.log(Infinity - 1)
console.log(Infinity + 1)
console.log(-Infinity - 1)
console.log(-Infinity + 1)
```
2. NaN
Not a number. The returned result if you try to do mathematical
nonsense
``` javascript
console.log(0/0)
console.log(Infinity - Infinity)
```
## Strings
Following are acceptable strings
``` javascript
console.log(`Down on the sea`)
console.log("Lie on the ocean")
console.log('Float on the ocean')
```
Backslash escapes characters
``` javascript
console.log("This is the first line\nAnd this is the second")
console.log("A newline character is written like \"\\n\".")
```
Backtick quoted strings ([template
literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals))
can span lines and also embed other values. \${} in a template literal
will be computed and converted to a string
``` javascript
console.log(`This is a
backtick quotes string`)
console.log(`half of 100 is ${100 / 2}`)
```
## Boolean
``` javascript
console.log(3 > 2)
console.log(3 < 2)
```
Strings can also be compared
``` javascript
console.log("Aardvark" < "Zoroaster")
```
Uppercase characters are always less than lower case characters, so "Z"
\< "a". Non alphabetic characters are less than alphabetic characters
``` javascript
console.log("Zebra" < "aardvark")
console.log("!" < "aardvark")
console.log("!" < "Zebra")
console.log("3" < "Zebra")
console.log("!" < "3")
```
## Empty values
There are two special empty values, null & undefined that denote the
absence of any meaningful value. They can be used interchangeably and
are an [accident of JavaScripts
design](https://medium.com/@stephenthecurt/a-brief-history-of-null-and-undefined-in-javascript-c283caab662e).
``` javascript
console.log(null == undefined);
```
# ES6
## Symbols
They are tokens that serve as unique IDs. You create symbols via the
factory function Symbol() (which is loosely similar to String returning
strings if called as a function):
``` javascript
const symbol1 = Symbol();
```
### Add a description
``` javascript
const tralala = Symbol('tralala')
console.log(tralala) // Symbol(tralala)
```
### Convert to string
``` javascript
const tralala = Symbol('tralala')
console.log(String(tralala)) // `Symbol(tralala)`
```
### Every Symbol is unique
``` javascript
console.log(Symbol() === Symbol()) // false
```
### Property keys
``` javascript
const KEY = Symbol();
const obj = {};
obj[KEY] = 123;
console.log(obj[KEY]); // 123
```
``` javascript
const FOO = Symbol();
const obj = {
[FOO]() {
return 'bar';
}
};
console.log(obj[FOO]()); // bar
```

View file

@ -0,0 +1,27 @@
---
date: 2020-06-13
id: a8f1290e-b4ef-4f80-bc21-69ddb4c22aca
title: JavaScript Operators
---
# Operators
- [Arithmetic
Operators](20201112103849-javascript_arithmetic_operators)
- [Comparison
Operators](20201112105310-javascript_comparison_operators)
- [Conditional (Ternary)
Operator](20201112110025-javascript_conditional_ternary_operator)
- [Nullish coalescing operator
(??)](20201116162237-nullish_coalescing_operator)
- [Optional Chaining Operator
(?.)](20201116162628-optional_chaining_operator)
- [Object Operators](20201113090050-javascript_object_operators)
- [String Operators](20201112104819-javascript_string_operators)
- [Unary Operators](20201112105050-javascript_unary_operators)
# Logical operators
- [Logical Operators](20201112105647-javascript_logical_operators)
- [Short Circuiting of Logical
Operators](20201112105833-javascript_short_circuiting_of_logical_operators)

View file

@ -0,0 +1,17 @@
---
date: 2020-06-13
id: 9e542d77-7a1f-4f6b-a48d-ce12afc68101
title: JavaScript Type Conversion
---
# Syntax
``` javascript
console.log(8 * null)
console.log("5" - 1)
console.log("5" + 1)
console.log("five" * 2)
console.log(false == 0)
console.log(false == "")
console.log(null == 0)
```

View file

@ -0,0 +1,17 @@
---
date: 2020-06-13
id: cc70a2c4-2d57-4a17-8c52-ba5f143d830c
title: Type conversion in JavaScript
---
# Type conversion
``` javascript
console.log(8 * null)
console.log("5" - 1)
console.log("5" + 1)
console.log("five" * 2)
console.log(false == 0)
console.log(false == "")
console.log(null == 0)
```

View file

@ -0,0 +1,135 @@
---
date: 2020-06-13
id: 6adaacc0-8c1e-4fb3-99c2-50db5bcbfa6b
title: JavaScript
---
# Language
## Objects
- [Arrays](20200826201029-arrays)
- [Objects](20200826201605-objects)
## Types
- [Numbers](20200922164416-numbers)
- [Strings](20200922164551-strings)
- [Booleans](20200922164727-booleans)
- [Empty values](20200922164830-empty_values)
- [Numbers](20200922164416-numbers)
- [BigInt](20201116165819-javascript_bigint)
## Values Operators
- [Operators](20200613170705-operators_in_javascript)
- [Type Conversion](20200613170756-javascript_type_conversion)
- [Destructuring](20200922160850-destructuring)
- [Spread (…)](20201014094144-spread)
## Program Structure
- [Binding /
Variables](20200613172137-binding_variables_in_javascript)
- [Control flows](20200613172534-javascript_control_flows)
## Functions
- [Bindings and scopes](20200702203250-bindings_and_scopes)
- [Closure](20200702204351-closure)
- [Recursion](20200702204437-recursion)
- [Higher-order functions](20200827142818-higher_order_functions)
- [Generators](20200911155947-generators)
### Definitions
- [Function
Declarations](20201006111125-javascript_function_declerations)
- [Declaration notation](20201006111244-declaration_notation)
- [Arrow Functions](20201006111349-arrow_functions)
### Parameters
- [Optional arguments](20200702204226-optional_arguments)
- [Parameter default values](20200922162003-parameter_default_values)
- [Named parameters](20200922162127-named_parameters)
- [Rest parameters](20200922162500-rest_parameters)
## Classes
- [Class Notation](20201008090316-class_notation)
- [Method Definition](20201008090449-method_definition)
- [Inheritance](20201008090613-inheritance)
- [Getters &
setters](20201007093418-javascript_object_getters_setters)
## Structures
- [Maps](20201012093745-javascript_maps)
- [WeakMaps](20201012094749-javascript_weakmaps)
- [Sets](20201012094248-javascript_sets)
## Standard Libraries
- [Error handling](20200901105237-error_handling)
- [Regular expressions](20200902162305-regular_expressions)
- [Number](20200923153425-number)
- [Math](20200923153614-math)
## Modules
- [CommonJS](20200916172802-commonjs)
- [ECMAScript](20200916172914-ecmascript)
## Asynchronous Programming
- [Callbacks](20200911150451-callbacks)
- [Promises](20200911154351-promises)
- [Async functions](20201026103714-javascript_async_functions)
## Iterables & Iterators
- [Iterables](20201014092625-javascript_iterables)
- [Iterator](20201014092846-javascript_iterator)
- [Async Iterator](20201030092200-javascript_async_iterator)
## Metaprogramming
- [Proxies](20201022094207-javascript_proxies)
- [Metaprogramming](20201022095438-javascript_metaprogramming)
## Comments
- [Comments](20201030094749-javascript_comments)
## Rest / Spread Properties
- [Rest Operator (…) in Object
Destructuring](20201103111357-rest_operator_in_object_destructuring)
## Imports
- [Dynamic Import](20201116170151-dynamic_import)
- [Module Namespace Exports](20201116170347-module_namespace_exports)
## Misc
- [globalThis](20201116170538-globalthis)
# Frameworks
- [Vue.js](20201021141613-vue_js)
- [React](20201130084544-react)
# Changelog
- [ES6](20201030093404-es6)
- [ES2016](20201023130243-es2016)
- [ES2017](20201026104538-es2017)
- [ES2018](20201030095105-es2018)
- [ES2019](20201113111815-es2019)
- [ES2020](20201116162058-es2020)
# Sources
- [Books](20200613170934-javascript_books)

View file

@ -0,0 +1,14 @@
---
date: 2020-06-13
id: 116e53fb-3830-473d-9474-57c8b45aa996
title: JavaScript Books
---
# Some handy JavaScript books
- [Eloquent JavaScript](https://eloquentjavascript.net/)
- [Exploring ES6](https://exploringjs.com/es6.html)
- [Exploring ES2016 and
ES2017](https://exploringjs.com/es2016-es2017.html)
- [Exploring ES2018 and
ES2019](https://exploringjs.com/es2018-es2019/index.html)

View file

@ -0,0 +1,84 @@
---
date: 2020-06-13
id: cb93f6ba-527b-4602-b5f4-de0281897800
title: JavaScript Types
---
# Numbers
JavaScript uses 64 bits to store number values
## Fractional numbers
``` javascript
console.log(9.81)
```
## Scientific notation
``` javascript
console.log(2.998e8)
```
## Special Numbers
### Infinity
Infinity and -Infinity represent positive and negative infinities
``` javascript
console.log(Infinity - 1)
console.log(Infinity + 1)
console.log(-Infinity - 1)
console.log(-Infinity + 1)
```
### NaN
Not a number. The returned result if you try to do mathematical nonsense
``` javascript
console.log(0/0)
console.log(Infinity - Infinity)
```
# Boolean
``` javascript
console.log(3 > 2)
console.log(3 < 2)
```
Strings can also be compared
``` javascript
console.log("Aardvark" < "Zoroaster")
```
Uppercase characters are always less than lower case characters, so "Z"
\< "a". Non alphabetic characters are less than alphabetic characters
``` javascript
console.log("Zebra" < "aardvark")
console.log("!" < "aardvark")
console.log("!" < "Zebra")
console.log("3" < "Zebra")
console.log("!" < "3")
```
# Empty values
There are two special empty values, null & undefined that denote the
absence of any meaningful value. They can be used interchangeably and
are an [accident of JavaScripts
design](https://medium.com/@stephenthecurt/a-brief-history-of-null-and-undefined-in-javascript-c283caab662e).
``` javascript
console.log(null == undefined);
```
# Related
- [JavaScript](20200613170905-javascript)
- [Arrays](20200826201029-arrays)
- [Strings](20200922164551-strings)

View file

@ -0,0 +1,46 @@
---
date: 2020-06-13
id: 6efc70be-8154-420f-a92e-622ef1ad960c
title: Binding / Variables in JavaScript
---
# ES6
## Let
``` javascript
let caught = 5 * 5
console.log(caught)
let mood = "light"
console.log(mood)
mood = "dark"
console.log(mood)
let luigisDebt = 140;
luigisDebt = luigisDebt - 35;
console.log(luigisDebt);
```
A single let statement my define multiple bindings
``` javascript
let one = 1, two = 2
console.log(one + two)
```
## Const
This is a constant binding. It points to the same value for as long as
it lives
``` javascript
const blaat = "abcd"
console.log(blaat)
/**
* Following will both cause errors:
*
* blaat = "efgh"
* let blaat = "efgh"
*/
```

View file

@ -0,0 +1,132 @@
---
date: 2020-06-13
id: adffc782-d978-49f3-9367-33e77b05af8a
title: Control flows in JavaScript
---
# ES6
## for-of
``` javascript
const arr = ['a', 'b', 'c'];
for (const elem of arr) {
console.log(elem);
}
```
``` javascript
const arr = ['a', 'b', 'c'];
for (const [index, elem] of arr.entries()) {
console.log(index+'. '+elem);
}
```
# if statement
``` javascript
if(true === true) {
console.log("True is true")
}
if (true === false) {
console.log("True is false")
}
else {
console.log("True is not false")
}
```
# while statement
``` javascript
let i = 0
while (i <= 5) {
console.log("Loop " + i)
i++
}
let j = 0
do {
j++
} while (j <= 5)
console.log("Do while j value is " + j)
```
# for statement
``` javascript
for(let k = 0; k <= 5; k++) {
console.log("For loop k " + k)
}
```
# switch statement
``` javascript
switch ("rainy") {
case "rainy":
console.log("Remember to bring an umbrella.");
break;
case "sunny":
console.log("Dress lightly.");
case "cloudy":
console.log("Go outside.");
break;
default:
console.log("Unknown weather type!");
break;
}
switch ("sunny") {
case "rainy":
console.log("Remember to bring an umbrella.");
break;
case "sunny":
console.log("Dress lightly.");
case "cloudy":
console.log("Go outside.");
break;
default:
console.log("Unknown weather type!");
break;
}
switch ("wild card") {
case "rainy":
console.log("Remember to bring an umbrella.");
break;
case "sunny":
console.log("Dress lightly.");
case "cloudy":
console.log("Go outside.");
break;
default:
console.log("Unknown weather type!");
break;
}
```
# Breaking out of a loop
``` javascript
for (let current = 20; ; current = current + 1) {
if (current % 7 == 0) {
console.log(current);
break;
}
}
```
# Comments
``` javascript
// This is a one line comment
let i = 0
/**
This is a multi line comment
Here is the second line
*/
let j = 0
```

View file

@ -0,0 +1,26 @@
---
date: 2020-06-13
id: 65258dfb-bf3f-454a-8219-a22a29cb1683
title: JavaScript Control Flows
---
# Statements
- [if statement](20201030093832-javascript_if_statement)
- [while statement](20201030093956-javascript_while_statement)
- [for statement](20201030094040-javascript_for_statement)
- [for await of](20201030095741-javascript_for_await_of)
- [for of statement](20201030093304-javascript_for_of)
- [switch statement](20201030094138-javascript_switch_statement)
- [try catch](20201116154444-javascript_catch_binding)
# Catch binding
- [Catch Binding](20201116154444-javascript_catch_binding)
- [Optional Catch
Binding](20201116154824-javascript_optional_catch_binding)
# Misc
- [Breaking out of a
loop](20201030094343-javascript_breaking_out_of_a_loop)

View file

@ -0,0 +1,65 @@
---
date: 2020-07-02
id: 40bc3b60-ab05-4ff6-a258-f5cb38322c77
title: Bindings and scopes in JavaScript
---
# Bindings
- For bindings defined outside of any function or block, the scope is
the whole program. We call these `global` bindings
- Bindings created for function parameters or declared inside a
function can only be referenced in that function. These are known as
`local` bindings. New instances of these `local` bindings are
created every time the function is called
- Bindings declared with `let` and `const` are local to the block that
they are declared in
- In pre-2015 JavaScript, only functions created new scopes. So
old-style bindings created with `var` are visible throughout the
whole function that they appear in. If not declared in a function
then scope is `global`
``` javascript
let x = 10
if (true) {
let y = 20
var z = 30
console.log(x + y + z)
}
// y is not accessable here
console.log(x + z)
```
``` javascript
const halve = function(n) {
return n / 2
}
let n = 10
console.log(halve(100))
console.log(n)
```
# Nested scope
``` javascript
const hummus = function(factor) {
const ingredient = function(amount, unit, name) {
let ingredientAmount = amount * factor;
if (ingredientAmount > 1) {
unit += "s";
}
console.log(`${ingredientAmount} ${unit} ${name}`);
};
ingredient(1, "can", "chickpeas");
ingredient(0.25, "cup", "tahini");
ingredient(0.25, "cup", "lemon juice");
ingredient(1, "clove", "garlic");
ingredient(2, "tablespoon", "olive oil");
ingredient(0.5, "teaspoon", "cumin");
};
hummus(1)
```

View file

@ -0,0 +1,40 @@
---
date: 2020-07-02
id: 6e1019ae-983e-42c6-90cf-daa6aebb86ea
title: Optional arguments in JavaScript functions
---
JavaScript is extremely broad-minded about the number of arguments you
pass to a function. If you pass too many, the extra ones are ignored. If
you pass too few, the missing parameters get assigned the value
`undefined`.
``` javascript
function square(x) { return x * x; }
console.log(square(4, true, "hedgehog"));
```
``` javascript
function minus(a, b) {
if (b === undefined) return -a;
else return a - b;
}
console.log(minus(10));
console.log(minus(10, 5));
```
Function parameters can also be given default values
``` javascript
function power(base, exponent = 2) {
let result = 1;
for (let count = 0; count < exponent; count++) {
result *= base;
}
return result;
}
console.log(power(4));
console.log(power(2, 6));
```

View file

@ -0,0 +1,35 @@
---
date: 2020-07-02
id: 8659a753-2c0d-46cb-afdc-095e318aabff
title: Closure in JavaScript
---
Local bindings are created anew for every call, and different calls
can't affect on another calls local bindings.
``` javascript
function wrapValue(n) {
let local = n;
return () => local;
}
let wrap1 = wrapValue(1);
let wrap2 = wrapValue(2);
console.log(wrap1());
console.log(wrap2());
```
A function that references bindings from local scopes around it is
called a closure. This behavior not only frees you from having to worry
about lifetimes of bindings but also makes it possible to use function
values in some creative ways.
``` javascript
function multiplier(factor) {
return number => number * factor;
}
let twice = multiplier(2);
console.log(twice(5));
```

View file

@ -0,0 +1,17 @@
---
date: 2020-07-02
id: f77e6e36-1674-46b6-a8c9-d5a77d40f19e
title: Recursion in JavaScript
---
``` javascript
function power(base, exponent) {
if (exponent == 0) {
return 1;
} else {
return base * power(base, exponent - 1);
}
}
console.log(power(2, 3));
```

View file

@ -0,0 +1,25 @@
---
date: 2020-07-04
id: ed692a43-3267-4b5d-a0a7-cef4a25b4fda
title: History
---
# USSR
- [Economic state of USSR
1942-1943](20200704151508-economic_state_of_ussr_1942_1943)
# Islamic History
- [Stages of Islamic
History](20200706161134-stages_of_islamic_history)
- [The Chaldeans](20200706165803-the_chaldeans)
# Western History
- [Stages of Christian
history](20200706164411-stages_of_christian_history)
# Misc
- [Historical Terms](20201029195742-historical_terms)

View file

@ -0,0 +1,77 @@
---
date: 2020-07-04
id: de009f15-07b5-4e76-8976-349c949bc148
title: Economic state of USSR 1942-1943
---
# Outline
- Impossible to calculate as Soviet figures are unreliable at best.
Relying on convergence of anecdotal evidence
- Source - Economics of ww2 by Harrison
- Cats & dogs going missing in Moscow
- People going to the front because food is so bad at home
- 62nd/63rd/64th army running out of food
- Roosevelt tells Molatov in 42 that he'll send less food to start the
second front in 43 instead of 44. Molatov doesn't want this, he
prefers food
- Census is done in 37. Stalin didn't like the results and had the
people who did the census shot. Next census showed the correct
numbers
- In controlled communist economies prices of goods are made up by
government and are therefore meaningless
- Soviet Union were in dire economic straits. If Stalingrad was won by
the Germans they would probably have collapsed
# Pre war economy
## Agriculture
| Country | Working population in agriculture | Output of non agricultural worker |
|----|----|----|
| USSR | 57% | 33% |
| Germany | 26% | 50% |
| USA | 17% | 40% |
| UK | 6% | 59% |
- Agricultural workers in USSR were female because men were drafted
for the war or in gulags
- Amount of rubels spent on the economy dropped from 58.3bn in 1940 to
31.6bn in 1942
- Inflation was also rampant which amplified the problems
- Ukraine & caucuses were taken by Germany. the wheat basket
- Collectivised farms were terrible for productivity
- Soviet citizens average daily intake of calories from 1942-1943 is
estimated to have been 2555 calories. In 1944 this was increased to
2810 calories. 500 calories less than average german/british
civilian. Americans ate 1000 more.
- Dispossed/hungry licked plates of others meals
- Communist leadership ate well
- 200-300 grams of sub standard bread
- Soviets ate half as much food as US citizens on average
- Zhukov boasted his men lived on 1000 calories / day during the
battle of Stalingrad
- between 1940-1942 real output of civilian branches feel from 1/2 to
2/3
- By 1942 agricultural output fell to 44% of pre war (1937) level
according to official Soviet numbers
- 50m people in USSR employed in agriculture in 1940. By 1942 figure
dropped to 25m according to official USSR numbers
- Half the population were covered by official rationing system
- 80% of the rations were bread
- After 1942 mortality rates in Siberia decreased because the weakest
already died off
# Gulags
- In gulags rations were decreased dramatically. from 1942-1943 people
were starving in gulags
- During war years 5m people were in gulag system. 1m were released to
the front. Majority left in gulags were ill and infirm. They were
given light work. Even before the war food wasn't provided in enough
quantities in 1939
- camp mortality reached it peak in 1942 when 50k prisoners died every
month.
- Over 2m people died in gulags and camps during war years
- Household consumption by workers decreased by 2 fifths from
1940-1942

View file

@ -0,0 +1,8 @@
---
date: 2020-07-04
id: 2e431131-c786-4718-964c-b0ff972de8da
title: Economics
---
- [Economic state of USSR
1942-1943](20200704151508-economic_state_of_ussr_1942_1943)

View file

@ -0,0 +1,120 @@
---
date: 2020-07-04
id: 38f9bc4b-06de-4f23-9626-3e4dad348dd3
title: Ledger
---
# Common [Ledger](https://www.ledger-cli.org/) CLI Commands ([Source](https://gist.githubusercontent.com/agarrharr/03450c1be7f6b3d2b883c6b5e317d2aa/raw/4c5bfa57be1cd98a232e3f4bda0fcc2a51ba0862/index.md))
## Income vs expenses this month?
``` bash
ledger balance income expenses --period "this month"
```
## What did my budget look like at a certain date?
``` bash
ledger balance budget --end 2018-01-02
```
This is how it looked at the end of the day on Jan 1, 2018.
## How much is in the checking account right now?
``` bash
ledger balance checking
```
## What is our net worth?
``` bash
ledger balance ^assets ^liabilities --real
```
## How much money have we made?
``` bash
ledger balance income
```
## How much money have we made from our salaries?
``` bash
ledger balance income:salary
```
## How much do we spend each month on x?
``` bash
ledger register -M expenses:groceries:food
```
## Group transactions by payee
``` bash
ledger register --by-payee
```
## Only show uncleared transactions
``` bash
ledger register --uncleared
```
## Do I have enough budgeted to pay off my credit cards?
``` bash
ledger balance creditcard
```
It should be \$0.00. If it's not \$0.00, run this with different dates
to find the problem:
``` bash
ledger balance creditcard --end 2018-02-01
```
## Import
Change Chase checking from:
``` example
Details,Posting Date,Description,Amount,Type,Balance,Check or Slip #
```
to:
``` example
,Date,Payee,Amount,,,Code
```
Change Chase Credit Card from:
``` example
Type,Trans Date,Post Date,Description,Amount
```
to:
``` example
,Date,Posted,Payee,Amount
```
``` bash
ledger convert ~/Downloads/checking.CSV --input-date-format "%m/%d/%Y" --invert --account Assets:Checking --rich-data -f budget.ledger --auto-match --pager less
```
## Expenses each month (sorted)
``` bash
ledger -M --period-sort "(amount)" reg ^expenses
```
This will show all expenses, grouped by month and sorted by the amount.
## How much do we spend on credit cards each month?
``` bash
ledger -M -r --display 'account=~/creditcard/' reg ^expenses
```

View file

@ -0,0 +1,62 @@
---
date: 2020-07-04
id: 726cec04-6f79-42e8-8677-63d8980f5ca4
title: Vocabulary
---
# Categories
- [Architecture](20201109123541-architecture)
- [Chess Terms](20201109120843-chess_terms)
- [Clothing](20201109123123-clothing)
- [Furniture](20201104090504-furniture)
- [Geographic Terms](20201029195945-geographic_terms)
- [Glassware](20201109123853-glassware)
- [Historical Terms](20201029195742-historical_terms)
- [Political science terms](20201029200040-political_science_terms)
- [Programming Terms](20201126095254-programming_terms)
- [Sexual terms](20201029200327-sexual_terms)
- [Tongue Twisters](20201109122104-tongue_twisters)
# Adjectives, nouns & verbs
- [Adjectives](20201029204304-adjectives)
- [Nouns](20201030183237-nouns)
- [Verbs](20201030182939-verbs)
# Complete list
- [anathema](20201109122445-anathema)
- [antecedent](20201030195742-antecedent)
- [antimacassar](20201109122731-antimacassar)
- [anteroom](20201109123452-anteroom)
- [bluestocking](20201029201415-bluestocking)
- [Carthaginian peace](20201029194838-carthaginian_peace)
- [chenille](20201109121858-chenille)
- [chiffonier](20201104090229-chiffonier)
- [decanter](20201109123736-decanter)
- [detritus](20201029195142-detritus)
- [eidetic](20201109124059-eidetic)
- [epaulet](20201109121407-epaulet)
- [fianchetto](20201109120912-fianchetto)
- [gaberdine](20201109123003-gaberdine)
- [geld](20201030183019-geld)
- [gregarious](20201029204128-gregarious)
- [imperturbable](20201109121645-imperturbable)
- [inchmeal](20201109124204-inchmeal)
- [indolent](20201116182958-indolent)
- [Intercommunicating zones](20201029195404-intercommunicating_zones)
- [insouciance](20201109121245-insouciance)
- [mirth](20201109121522-mirth)
- [percolate](20201109121108-percolate)
- [perfunctory](20201109122833-perfunctory)
- [podophilia](20201029200235-podophilia)
- [précis](20201109122314-precis)
- [prig](20201109122557-prig)
- [rancor](20201109123923-rancor)
- [sanguine](20201109123624-sanguine)
- [tawdry](20220917160601-tawdry)
- [Useful idiot](20201029195302-useful_idiot)
- [viscosity](20210405123214-viscosity)
- [wily](20201109121740-wily)
- [worsted](20201109123326-worsted)

View file

@ -0,0 +1,66 @@
---
date: 2020-07-04
id: 882564c6-4258-40f4-87ec-fb5b267b7ac2
title: Rust
---
- [Rust Tooling](20201119165530-rust_tooling)
# API
- [Functions](20201120110719-rust_functions)
- [Primitive Types](20201120095639-rust_primitive_types)
- [Structs](20201120105306-rust_structs)
- [Traits](20201120103547-rust_traits)
# Language
- [Comments](20200827190035-rust_comments)
- [Control flow](20200827190443-rust_control_flow)
- [Enums](20200902150714-enums)
- [Iterators](20200923150006-iterators)
- [Ownership](20200828170945-ownership)
- [Pointers](20201120102004-rust_pointers)
- [Structs](20200831193417-structs)
- [Tests](20200918183524-tests)
- [Variables](20200827171554-variables_in_rust)
## Common Collections
- [Vectors](20200915140449-vectors)
- [Strings](20200915151358-strings)
- [Hash Maps](20200915153033-hash_maps)
## Concurrency
- [Threads](20200930121904-rust_threads)
- [Message passing](20200930123003-message_passing)
- [Shared-State
Concurrency](20200930123749-rust_shared_state_concurrency)
## Error handling
- [Unrecoverable Errors](20200916162727-unrecoverable_errors)
- [Recoverable Errors](20200916163737-recoverable_errors)
## Functions
- [Functions & macros](20200827170931-functions_macros)
- [Closures](20200923144022-closures)
## Generic Types and Traits
- [Generics](20200917161757-generics)
- [Traits](20200917163203-traits)
## Patterns and Matching
- [Pattern Syntax](20201006102934-pattern_syntax)
# Misc
- [Books & exercises](20200827171318-rust_books)
# Changelog
- [1.48](20201119165257-rust_1_48)

View file

@ -0,0 +1,20 @@
---
date: 2020-07-06
id: 61037644-f96f-4ab2-8ea5-4f8829b4de9c
title: The 10 stages of Islamic History
---
Islamic history can roughly be divided into 10 stages (as opposed to
[the 10 stages of Christian
history](20200706164411-stages_of_christian_history)):
1. Ancient Times: Mesopotamia and Persia
2. Birth of Islam
3. The Caliphate: Quest for Universal Unity
4. Fragmentation: Age of the Sultanates
5. Catastrophe: Crusaders and Mongols
6. Rebirth: The Three-Empires Era
7. Permeation of East by West
8. The Reform Movements
9. Triumph of the Secular Modernists
10. The Islamist Reaction

View file

@ -0,0 +1,22 @@
---
date: 2020-07-06
id: baac5bf7-b54a-4fed-927b-e8a4f220e81c
title: The 10 stages of Christian history
---
When the ideal future envisioned by post industrialized, Western
democratic society is taken as the endpoint of history, the shape of the
narrative leading to here-and-now features something like the following
stages (as opposed to [the 10 stages of Islamic
history](20200706161134-stages_of_islamic_history)):
1. Birth of civilization (Egypt and Mesopotamia)
2. Classical age (Greece and Rome)
3. The Dark Ages (rise of Christianity)
4. The Rebirth: Renaissance and Reformation
5. The Enlightenment (exploration and science)
6. The Revolutions (democratic, industrial, technological)
7. Rise of Nation-States: The Struggle for Empire
8. World Wars I and II.
9. The Cold War
10. The Triumph of Democratic Capitalism

View file

@ -0,0 +1,15 @@
---
date: 2020-07-06
id: fcbdb286-af0e-484f-8a2d-dd5b2e18ff5b
title: The Chaldeans
---
The Assyrians fell at last to one of their subject peoples, the
Chaldeans, who rebuilt Babylon and won a lustrous place in history for
their intellectual achievements in astronomy, medicine, and mathematics.
They used a base-12 system (as opposed to our base-10 system) and were
pioneers in the measurement and division of time, which is why the year
has twelve months, the hour has sixty minutes (five times twelve), and
the minute has sixty seconds. They were terrific urban planners and
architects—it was a Chaldean king who built those Hanging Gardens of
Babylon, which the ancients ranked among the seven wonders of the world.

View file

@ -0,0 +1,59 @@
---
date: 2020-08-26
id: 3e8fc539-e90c-4278-a233-6158dbca89e4
title: Golang
---
# Language
## Basics
- [Packages](20200826142755-packages)
- [Functions](20200826151337-functions)
- [Variables](20200826151514-variables)
- [Flow control statements](20200826151846-flow_control_statements)
- [Tests](20200826191127-tests)
- [Tooling](20200826191508-tooling)
- [Pointers](20200828180957-pointers)
- [Structs](20200828181259-structs)
- [Arrays](20200828182327-arrays)
- [Slices](20200828182546-slices)
- [Maps](20200828192034-maps)
- [Methods](20200831155304-methods)
- [Interfaces](20200831171822-interfaces)
- [Errors](20200909202454-errors)
- [Reflection](20200917155644-reflection)
- [Context](20200921154246-context)
- [Embedding](20200928193245-embedding)
## Concurrency
- [Goroutines](20200901141141-goroutines)
### Sync
- [Mutex](20200918173820-mutex)
- [WaitGroup](20200918174548-waitgroup)
### Misc
- When to use sync.Mutex or a channel[^1]
## Libraries you should probably know about
- http[^2]
## Books & tutorials
- Go by Example[^3]
- Learn Go with tests[^4]
# Footnotes
[^1]: <https://faiface.github.io/post/context-should-go-away-go2/>
[^2]: <https://golang.org/pkg/net/http/>
[^3]: <https://gobyexample.com/>
[^4]: <https://quii.gitbook.io/learn-go-with-tests/>

View file

@ -0,0 +1,66 @@
---
date: 2020-08-26
id: 3123184d-c919-4cf6-8339-3f9b8ca5a1db
title: Golang Packages
---
# Basics
Every Go program is made up of packages. Programs start running in
package \`main\`.
By convention the pacckage name is the same as the last element of the
import path. For instance, the \`math/rand\` package comprises files
that begin with the statement \`package rand\`.
``` go
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println("My favorite number is", rand.Intn(10))
}
```
# Imports
It's best practice to convert multiple import statements to a "factored"
import statement:
``` go
package main
import "fmt"
import "math"
func main() {
fmt.Printf("This uses multiple import statements\n")
fmt.Printf("Now you have %g problems.\n", math.Sqrt(7))
}
```
should be
``` go
package main
import (
"fmt"
"math"
)
func main() {
fmt.Printf("This uses a parenthesized \"factored\" import statement\n")
fmt.Printf("Now you have %g problems.\n", math.Sqrt(7))
}
```
# Exported names
In Go, a name is exported if it begins with a capital letter. When
importing a package, you can refer only to its exported names. Any
"unexported" names are not accessible from outside the package.

View file

@ -0,0 +1,195 @@
---
date: 2020-08-26
id: 009236f9-033d-44ef-8fa4-73cb05c3b390
title: Golang Functions
---
# Arguments
## Basics
A function can take zero or more arguments. [Argument type comes after
the variable name](https://blog.golang.org/declaration-syntax).
``` go
package main
import "fmt"
func add(x int, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
```
When two or more consecutive named function parameters share a type, you
can omit the type from all but the last
``` go
package main
import "fmt"
func add(x, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
```
## Variadic
Go also supports [variadic
functions](https://gobyexample.com/variadic-functions), ie functions
with any number of trailing arguments:
``` go
package main
import "fmt"
func sum(nums ...int) {
fmt.Print(nums, " ")
total := 0
for _, num := range nums {
total += num
}
fmt.Println(total)
}
func main() {
sum(1, 2)
sum(1, 2, 3)
nums := []int{1, 2, 3, 4}
sum(nums...)
}
```
# Returns
## Multiple results
A function can return any number of results
``` go
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
fmt.Println(a, b)
}
```
## Named return values
Go's return values may be named. If so, they are treated as variables
defined at the top of the function. These names shoudl be used to
document the meaning of the return values. A \`return\` statement
without arguments returns the named return values. This is known as a
"naked" return. Naked return statements should be used only short
functions as they can harm readability in longer functions.
``` go
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
func main() {
fmt.Println(split(17))
}
```
## Function values
Like in [JavaScript](20200613170905-javascript) functions can be passed
around
``` go
package main
import (
"fmt"
"math"
)
func compute(fn func(float64, float64) float64) float64 {
return fn(3, 4)
}
func main() {
hypot := func(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}
fmt.Println(hypot(5, 12))
fmt.Println(compute(hypot))
fmt.Println(compute(math.Pow))
}
```
## Function closures
Like [JavaScript](20200613170905-javascript) function closures are
supported in Go as well
``` go
package main
import "fmt"
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
pos, neg := adder(), adder()
for i := 0; i < 10; i++ {
fmt.Println(
pos(i),
neg(-2*i),
)
}
}
```
# Implementing an Interface
Here is an example of a function implementing an
[interface](20200831171822-interfaces):
``` go
type BlindAlerter interface {
ScheduleAlertAt(duration time.Duration, amount int)
}
// BlindAlerterFunc allows you to implement BlindAlerter with a function
type BlindAlerterFunc func(duration time.Duration, amount int)
// ScheduleAlertAt is BlindAlerterFunc implementation of BlindAlerter
func (a BlindAlerterFunc) ScheduleAlertAt(duration time.Duration, amount int) {
a(duration, amount)
}
```

View file

@ -0,0 +1,232 @@
---
date: 2020-08-26
id: ef9ed7f2-0bee-4405-a6d2-993cdea80029
title: Golang variables
---
# Basics
The \`var\` statement declares a list of variables. Type is last. A
\`var\` statement can be at package or function level. Use var when you
to set a variable type but don't want to set the variable value yet.
``` go
package main
import "fmt"
var c, python, java bool
func main() {
var i int
fmt.Println(i, c, python, java)
}
```
This also works with [interfaces](20200831171822-interfaces).
``` go
package main
import "fmt"
type printSomething interface {
print()
}
type agent struct {
}
func (d *agent) print() {
fmt.Println("tralala")
}
var (
a = &agent{}
)
func main() {
a.print()
}
```
# Initializers
A var declaration can include initializers, one per variable. If an
initializer is present, the type can be omitted; the variable will take
the type of the initializer.
``` go
package main
import "fmt"
var i, j int = 1, 2
func main() {
var c, python, java = true, false, "no!"
fmt.Println(i, j, c, python, java)
}
```
# Short variable declarations
Inside a function, the := short assignment statement can be used in
place of a var declaration with implicit type. Outside a function, every
statement begins with a keyword (var, func, and so on) and so the :=
construct is not available.
``` go
package main
import "fmt"
func main() {
var i, j int = 1, 2
k := 3
c, python, java := true, false, "no!"
fmt.Println(i, j, k, c, python, java)
}
```
# Basic types
Go's basic types are
bool
string
int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr
byte // alias for uint8
rune // alias for int32 // represents a Unicode code point
float32 float64
complex64 complex128
The example shows variables of several types, and also that variable
declarations may be "factored" into blocks, as with import statements.
The int, uint, and uintptr types are usually 32 bits wide on 32-bit
systems and 64 bits wide on 64-bit systems. When you need an integer
value you should use int unless you have a specific reason to use a
sized or unsigned integer type.
``` go
package main
import (
"fmt"
"math/cmplx"
)
var (
ToBe bool = false
MaxInt uint64 = 1<<64 - 1
z complex128 = cmplx.Sqrt(-5 + 12i)
)
func main() {
fmt.Printf("Type: %T Value: %v\n", ToBe, ToBe)
fmt.Printf("Type: %T Value: %v\n", MaxInt, MaxInt)
fmt.Printf("Type: %T Value: %v\n", z, z)
}
```
# Zero values
Variables declared without an explicit initial value are given their
zero value.
The zero value is:
- 0 for numeric types
- false for the boolean type
- "" for strings
``` go
package main
import "fmt"
func main() {
var i int
var f float64
var b bool
var s string
fmt.Printf("%v %v %v %q\n", i, f, b, s)
}
```
# Type conversions
The expression \`T(v)\` converts the value v to the type T.
``` go
package main
import (
"fmt"
"math"
)
func main() {
var x, y int = 3, 4
var f float64 = math.Sqrt(float64(x*x + y*y))
var z uint = uint(f)
fmt.Println(x, y, z)
}
```
# Type inference
When declaring a variable without specifying an explicit type (either by
using the := syntax or var = expression syntax), the variable's type is
inferred from the value on the right hand side.
When the right hand side of the declaration is typed, the new variable
is of that same type:
``` go
var i int
j := i // j is an int
```
But when the right hand side contains an untyped numeric constant, the
new variable may be an int, float64, or complex128 depending on the
precision of the constant:
``` go
i := 42 // int
f := 3.142 // float64
g := 0.867 + 0.5i // complex128
```
# Constants
Constants are declared like variables, but with the const keyword.
Constants can be character, string, boolean, or numeric values.
Constants cannot be declared using the := syntax.
``` go
package main
import "fmt"
const Pi = 3.14
func main() {
const World = "世界"
fmt.Println("Hello", World)
fmt.Println("Happy", Pi, "Day")
const Truth = true
fmt.Println("Go rules?", Truth)
}
```

View file

@ -0,0 +1,268 @@
---
date: 2020-08-26
id: db553cc1-625c-4ddf-8d3c-cc0bba7b4345
title: Golang flow control statements
---
# For
Go has no \`while\`, \`do\` or \`until\` keywords for iteration, only
\`for\`
``` go
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
```
Init and post statements are optional:
``` go
package main
import "fmt"
func main() {
sum := 1
for ; sum < 1000; {
sum += sum
}
fmt.Println(sum)
}
```
For is Go's "while":
``` go
package main
import "fmt"
func main() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
```
Infinite loops are possible as well:
``` go
package main
func main() {
for {
}
}
```
Iterate over [Golang Arrays](20200828182327-arrays) & [Golang
slices](20200828182546-slices) with \`range\`:
``` go
package main
import (
"fmt"
)
func main() {
var numbers = []int{1,2,3,4,5}
var sum = 0
for _, number := range numbers {
sum += number
}
fmt.Println("%s", sum)
}
```
# If
Like for, the if statement can start with a short statement to execute
before the condition.
Variables declared by the statement are only in scope until the end of
the if.
``` go
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
```
Variables declared inside an if short statement are also available
inside any of the else blocks.
``` go
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
// can't use v here, though
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
```
# Switch
Go's switch is like the one in C, C++, Java, JavaScript, and PHP, except
that Go only runs the selected case, not all the cases that follow. In
effect, the break statement that is needed at the end of each case in
those languages is provided automatically in Go. Another important
difference is that Go's switch cases need not be constants, and the
values involved need not be integers.
``` go
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.\n", os)
}
}
```
Switch without a condition is the same as switch true. This construct
can be a clean way to write long if-then-else chains.
``` go
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
}
```
Type switches are also a thing:
``` go
package main
import "fmt"
func do(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("Twice %v is %v\n", v, v*2)
case string:
fmt.Printf("%q is %v bytes long\n", v, len(v))
default:
fmt.Printf("I don't know about type %T!\n", v)
}
}
func main() {
do(21)
do("hello")
do(true)
}
```
# Defer
A defer statement defers the execution of a function until the
surrounding function returns. The deferred call's arguments are
evaluated immediately, but the function call is not executed until the
surrounding function returns.
``` go
package main
import "fmt"
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
```
Deferred function calls are pushed onto a stack. When a function
returns, its deferred calls are executed in last-in-first-out order.
``` go
package main
import "fmt"
func main() {
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
```

View file

@ -0,0 +1,205 @@
---
date: 2020-08-26
id: d8edb970-fe2c-4774-b325-2f932b262ef5
title: Tests in Golang
---
# Rules
Test writing rules:
- It needs to be in a file with a name like \`xxx~test~.go\`
- The test funciton must start with the word \`Test\`
- The test function takes one argument only \`t \*testing.T\`
``` go
package main
import "testing"
func TestHello(t *testing.T) {
assertCorrectMessage := func(t *testing.T, got, want string) {
t.Helper()
if got != want {
t.Errorf("got %q want %q", got, want)
}
}
t.Run("saying hello to people", func(t *testing.T) {
got := Hello("Chris", "")
want := "Hello, Chris"
assertCorrectMessage(t, got, want)
})
t.Run("empty string defaults to 'World'", func(t *testing.T) {
got := Hello("", "")
want := "Hello, World"
assertCorrectMessage(t, got, want)
})
t.Run("in Spanish", func(t *testing.T) {
got := Hello("Elodie", "Spanish")
want := "Hola, Elodie"
assertCorrectMessage(t, got, want)
})
t.Run("in French", func(t *testing.T) {
got := Hello("Jean Pierre", "French")
want := "Bonjour, Jean Pierre"
assertCorrectMessage(t, got, want)
})
t.Run("in Dutch", func(t *testing.T) {
got := Hello("Frans", "Dutch")
want := "Hoi, Frans"
assertCorrectMessage(t, got, want)
})
}
```
# Examples
Examples can also be added to ~test~.go files.
``` go
func ExampleAdd() {
sum := Add(1, 5)
fmt.Println(sum)
// Output: 6
}
```
Example function will not be execute if the comment is removed
# Benchmarking
[Benchmarks](https://golang.org/pkg/testing/#hdr-Benchmarks) are a
first-class feature of Go, fantastic stuff!
``` go
func BenchmarkRepeat(b *testing.B) {
for i := 0; i < b.N; i++ {
Repeat("a")
}
}
```
Following command runs benchmarks:
``` shell
go test -bench=.
```
# Tools
## Coverage
[Coverage](https://blog.golang.org/cover) is built in as well:
``` shell
go test -cover
```
## Race conditions
In Go you can detect race conditions by adding the `-race` argument:
``` shell
go test -race
```
# DeepEqual
For \`slices\` & friends you can use \`reflect.DeepEqual\` to compare
variables in tests
``` go
func TestSumAll(t *testing.T) {
got := SumAll([]int{1, 2}, []int{0, 9})
want := []int{3, 9}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v want %v", got, want)
}
}
```
# TableDrivenTests
Writing good tests is not trivial, but in many situations a lot of
ground can be covered with [table-driven
tests](https://github.com/golang/go/wiki/TableDrivenTests): Each table
entry is a complete test case with inputs and expected results, and
sometimes with additional information such as a test name to make the
test output easily readable. If you ever find yourself using copy and
paste when writing a test, think about whether refactoring into a
table-driven test or pulling the copied code out into a helper function
might be a better option.
Given a table of test cases, the actual test simply iterates through all
table entries and for each entry performs the necessary tests. The test
code is written once and amortized over all table entries, so it makes
sense to write a careful test with good error messages.
``` go
var flagtests = []struct {
in string
out string
}{
{"%a", "[%a]"},
{"%-a", "[%-a]"},
{"%+a", "[%+a]"},
{"%#a", "[%#a]"},
{"% a", "[% a]"},
{"%0a", "[%0a]"},
{"%1.2a", "[%1.2a]"},
{"%-1.2a", "[%-1.2a]"},
{"%+1.2a", "[%+1.2a]"},
{"%-+1.2a", "[%+-1.2a]"},
{"%-+1.2abc", "[%+-1.2a]bc"},
{"%-1.2abc", "[%-1.2a]bc"},
}
func TestFlagParser(t *testing.T) {
var flagprinter flagPrinter
for _, tt := range flagtests {
t.Run(tt.in, func(t *testing.T) {
s := Sprintf(tt.in, &flagprinter)
if s != tt.out {
t.Errorf("got %q, want %q", s, tt.out)
}
})
}
}
```
# Fatals
Sometimes you want to throw fatal errors in tests to prevent problems,
for example in case \`nil\` is returned and you need to do stuff with
the return value in later tests:
``` go
func assertError(t *testing.T, got error, want error) {
t.Helper()
if got == nil {
t.Fatal("didn't get an error but wanted one")
}
if got != want {
t.Errorf("got %q, want %q", got, want)
}
}
```
# Handy packages
- httptest[^1]
- quick[^2]
# Footnotes
[^1]: <https://golang.org/pkg/net/http/httptest/>
[^2]: <https://golang.org/pkg/testing/quick/>

View file

@ -0,0 +1,44 @@
---
date: 2020-08-26
id: a8b17c59-bf17-4dc8-a0cd-5bf68b2e15c1
title: Golang tooling
---
# Documentation
Install godoc with `go get golang.org/x/tools/cmd/godoc`
Documentation can be generated with
``` shell
godoc --http :8000
```
# Linters
- [errcheck](https://github.com/kisielk/errcheck)
# Testing
## Code coverage
``` shell
go test -cover
```
## Race conditions
``` shell
go test -race
```
## Vetting
Vet examines Go source code and reports suspicious constructs, such as
Printf calls whose arguments do not align with the format string. Vet
uses heuristics that do not guarantee all reports are genuine problems,
but it can find errors not caught by the compilers.
``` shell
go vet
```

View file

@ -0,0 +1,29 @@
---
date: 2020-08-26
id: e7ed8c3a-ee07-4d46-ace9-f354ee4a47b2
title: JavaScript Arrays
---
- [Array Prototype
Methods](20201009090331-javascript_array_prototype_methods)
- [Array Functions](20201113103917-javascript_array_functions)
- [Destructuring Arrays](20201103111509-destructuring_arrays)
# Syntax
``` javascript
let listOfNumbers = [2, 3, 5, 7, 11];
console.log(listOfNumbers[2]); // 5
console.log(listOfNumbers[0]); // 2
```
# Type
In JavaScript arrays are a type of [object](20200826201605-objects) that
store sequences of things. `typeof` wil therefore return "object"
``` javascript
let listOfThings = ["Car", "Mr Magoo", 42];
console.log(typeof listOfThings); // object
```

View file

@ -0,0 +1,16 @@
---
date: 2020-08-26
id: 18736297-fc4f-450c-be78-a13770d2c1c1
title: JavaScript Objects
---
- [Object Properties](20201113091110-javascript_object_properties)
- [Prototypes](20201113091424-javascript_prototypes)
- [Object Prototype
Methods](20201113093204-javascript_object_prototype_methods)
- [Object Keywords](20201113093613-javascript_object_keywords)
- [Object Operators](20201113090050-javascript_object_operators)
- [Object Functions](20200826201959-object_functions)
- [Object Mutability](20200826201737-mutability)
- [Object Operators](20201113090050-javascript_object_operators)
- [Destructuring Objects](20201103111746-destructuring_objects)

View file

@ -0,0 +1,35 @@
---
date: 2020-08-26
id: fd131977-33f2-42cd-9a3b-46ffd58b9e43
title: JavaScript Object Mutability
---
# Description
With objects, there is a difference between having two references to the
same object and having two different objects that contain the same
properties.
# Examples
``` javascript
let object1 = {value: 10};
let object2 = object1;
let object3 = {value: 10};
console.log(object1 == object2); // true
console.log(object1 == object3); // false
object1.value = 15;
console.log(object2.value); // 15
console.log(object3.value); // 10
```
\`const\` objects can have their values changed
``` javascript
const score = { visitors: 0, home: 1 };
score.visitors = 23;
console.log(score); // { visitors: 23, home: 1 }
```

View file

@ -0,0 +1,32 @@
---
date: 2020-08-26
id: 7b46ba87-7328-479c-8d79-badb24ed7b19
title: JavaScript object operators
---
# Delete operator
The `delete` operator deletes a binding (duh)
``` javascript
let anObject = {left: 1, right: 2};
console.log(anObject.left);
delete anObject.left;
console.log(anObject.left);
console.log("left" in anObject);
console.log("right" in anObject);
```
# In operator
The `in` operator tells you whether and object has a property with that
name
``` javascript
let Object = {
thisPropertyExists: true
}
console.log("thisPropertyExists" in Object)
console.log("thisPropertyDoesNotExist" in Object)
```

View file

@ -0,0 +1,19 @@
---
date: 2020-08-26
id: 1d12fe9c-f655-49d2-8745-3148ec03cef9
title: JavaScript Object Functions
---
- [Object.keys](20201113095226-object_keys)
- [Object.assign](20201113095244-object_assign)
- [Object.is](20201113095300-object_is)
- [Object.entries](20201113102048-object_entries)
- [Object.values](20201113102106-object_values)
- [Object.getOwnPropertyDescriptors](20201113102125-object_getownpropertydescriptors)
- [Object.fromEntries](20201116095124-object_fromentries)

View file

@ -0,0 +1,85 @@
---
date: 2020-08-27
id: 513ff88e-d0c9-41d1-8416-57a4aff100c7
title: JavaScript higher-order functions
---
# Examples
Functions that operate on other functions, either by taking them as
arguments or by returning them, are called higher-order functions. They
allow us to abstract over actions as well as values. There are several
types, here are some examples.
## Functions that create new functions
``` javascript
function greaterThan(n) {
return m => m > n;
}
let greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
```
## Functions that change other functions
``` javascript
function noisy(f) {
return (...args) => {
console.log("calling with", args);
let result = f(...args);
console.log("called with", args, ", returned", result);
return result;
};
}
noisy(Math.min)(3, 2, 1);
```
## Functions that provide new types of flow control
``` javascript
function unless(test, then) {
if (!test) then();
}
repeat(3, n => {
unless(n % 2 == 1, () => {
console.log(n, "is even");
});
});
```
## ES6
### Funciton properties
1. name
The `name` property contains the function's name:
``` javascript
function foo() {};
console.log(foo.name); // foo
let func1 = function () {};
console.log(func1.name); // func1
let func4;
func4 = function () {};
console.log(func4.name); // func4
```
1. Default values
``` javascript
let [func1 = function () {}] = [];
console.log(func1.name); // func1
let { f2: func2 = function () {} } = {};
console.log(func2.name); // func2
function g(func3 = function () {}) {
return func3.name;
}
console.log(g()); // func3
```

View file

@ -0,0 +1,72 @@
---
date: 2020-08-27
id: 1324afaa-085a-401c-9757-df93b6c51423
title: Rust functions
---
# Functions
## Case
Rust uses [snake case](https://en.wikipedia.org/wiki/Snake_case) for
function and variable names. Functions always start with fn
``` rust
fn main() {
println!("Hello, world!");
another_function();
}
fn another_function() {
println!("Another function.");
}
```
## Parameters
In rust you **must** declare parameter types
``` rust
fn main() {
another_function(5);
}
fn another_function(x: i32) {
println!("The value of x is: {}", x);
}
```
## Rust is expressive
Rust is an expressive language, so you have to do stuff like this:
``` rust
fn main() {
let _x = 5;
let y = {
let x = 3;
x + 1
};
println!("The value of y is: {}", y);
}
```
## Return values
Unless you add a return statement, most functions return the last
expression implicitly:
``` rust
fn five() -> i32 {
5
}
fn main() {
let x = five();
println!("The value of x is: {}", x);
}
```

View file

@ -0,0 +1,66 @@
---
date: 2020-08-27
id: 33187ecc-81fd-4136-ad10-b69e8463bd6d
title: Rust tooling
---
# Rustc
Rustc handles Rust compilation `rustc main.rs`
# Cargo
Cargo is Rust's build system and package manager
## Cargo commands
### Create project
``` shell
cargo new hello_cargo
```
### Build project
``` shell
cargo build
```
### Build & run project
``` shell
cargo run
```
1. Backtrace
When you want to see an error backtrace set the `RUST_BACKTRACE`
environment variable:
``` shell
RUST_BACKTRACE=1 cargo run
```
### Check code
``` shell
cargo check
```
### Build for release
``` shell
cargo build --release
```
## Cargo.toml
``` toml
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2018"
[dependencies]
```

View file

@ -0,0 +1,28 @@
---
date: 2020-08-27
id: d1b696d7-2dfa-4b0c-b312-f3762b9ae020
title: Rust books & exercises
---
# Books
- The Rust Programming Language[^1]
- The Rust Performance Book[^2]
- Rust by example[^3]
- Rustonomicon[^4]
# Exercises
- Rustlings[^5]
# Footnotes
[^1]: <https://doc.rust-lang.org/stable/book/title-page.html>
[^2]: <https://nnethercote.github.io/perf-book/>
[^3]: <https://doc.rust-lang.org/stable/rust-by-example/>
[^4]: <https://doc.rust-lang.org/nomicon/>
[^5]: <https://github.com/rust-lang/rustlings>

View file

@ -0,0 +1,152 @@
---
date: 2020-08-27
id: 9a604084-80a1-4868-be7b-950e7f43b65d
title: Rust variables
---
# Mutability
By default variables in Rust are immutable. To make a variable mutable
one must explicity add \`mut\` in front of it
``` rust
fn main() {
let mut x = 5;
println!("The value of x is: {}", x);
x = 6;
println!("The value of x is: {}", x);
}
```
# Constants
Constatns are values that are bound to a name and are not allowed to
change. Some differences with variables:
- You can't use \`mut\` with constants
- Constants are delared with \`const\` keyword instead of \`let\`
- Type value must be annotated
- Constants can be declared in any scope
- Constants may only be set to a constant expression, not the result
of a function call of any other value that could only be computed at
runtime
``` rust
#![allow(unused_variables)]
fn main() {
const MAX_POINTS: u32 = 100_000;
}
```
# Shadowing
You can declare a new variable with the same value as a previous
variable. The new variable "shadows" the previous variable
``` rust
fn main() {
let x = 5;
let x = x + 1;
let x = x * 2;
println!("The value of x is: {}", x);
}
```
Shadowing is different from marking a variable as mut, because well get
a compile-time error if we accidentally try to reassign to this variable
without using the let keyword. By using let, we can perform a few
transformations on a value but have the variable be immutable after
those transformations have been completed.
The other difference between mut and shadowing is that because were
effectively creating a new variable when we use the let keyword again,
we can change the type of the value but reuse the same name. For
example, say our program asks a user to show how many spaces they want
between some text by inputting space characters, but we really want to
store that input as a number:
``` rust
fn main() {
let spaces = " ";
let spaces = spaces.len();
println!("There are {} spaces in the string", spaces)
}
```
# Data types
## Tuple
Tuple elements can be accessed directly by using a period.
``` rust
fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
println!("These are the tuple values {} {} {}", tup.0, tup.1, tup.2)
}
```
## Array
In Rust every element of an array must have the same type. They also
have a fixed length, like tuples.
``` rust
fn main() {
let _a = [1, 2, 3, 4, 5];
}
```
You would write an arrays type by using square brackets, and within the
brackets include the type of each element, a semicolon, and then the
number of elements in the array, like so:
``` rust
#![allow(unused_variables)]
fn main() {
let a: [i32; 5] = [1, 2, 3, 4, 5];
}
```
You can also easily initialize an array that contains the same value for
each element:
``` rust
#![allow(unused_variables)]
fn main() {
let a = [3; 5];
}
```
Accessing array elements is also straightforward:
``` rust
#![allow(unused_variables)]
fn main() {
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
}
```
## Destructuring
Rust also supports destructuring
``` rust
fn main() {
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of x is: {}", x);
println!("The value of y is: {}", y);
println!("The value of z is: {}", z);
}
```

View file

@ -0,0 +1,114 @@
---
date: 2020-08-27
id: f4c04f44-c7c3-4fa0-a4d6-e78995257b9c
title: Rust Comments
---
# Basics
In Rust, the idiomatic comment style starts a comment with two slashes,
and the comment continues until the end of the line. For comments that
extend beyond a single line, youll need to include // on each line,
like this:
``` rust
// So were doing something complicated here, long enough that we need
// multiple lines of comments to do it! Whew! Hopefully, this comment will
// explain whats going on.
```
Comments can also be placed at the end of lines containing code:
``` rust
fn main() {
println!("tralala") // This prints something
}
```
But if you're a sane person you'll comment above the code you're
annotating
``` rust
// This prints something
fn main() {
println!("tralala")
}
```
# Documentation comments
## */*
This is like phpdoc, but for Rust. Documentation comments use three
slashes `///` and support Markdown notation:
``` rust
/// Adds one to the number given.
///
/// # Examples
///
/// ```
/// let arg = 5;
/// let answer = my_crate::add_one(arg);
///
/// assert_eq!(6, answer);
/// ```
pub fn add_one(x: i32) -> i32 {
x + 1
}
```
Run `cargo doc` to generate HTML documentation from the comments.
`cargo doc --open` will open documentation in the browser.
### Commonly used sections
1. Panics
The scenarios in which the function being documented could panic.
Callers of the function who dont want their programs to panic
should make sure they dont call the function in these situations.
2. Errors
If the function returns a `Result`, describing the kinds of errors
that might occur and what conditions might cause those errors to be
returned can be helpful to callers so they can write code to handle
the different kinds of errors in different ways.
3. Safety
If the function is `unsafe` to call, there should be a section
explaining why the function is unsafe and covering the invariants
that the function expects callers to uphold.
## //!
This is used for general comments:
``` rust
//! # My Crate
//!
//! `my_crate` is a collection of utilities to make performing certain
//! calculations more convenient.
/// Adds one to the number given.
// --snip--
///
/// # Examples
///
/// ```
/// let arg = 5;
/// let answer = my_crate::add_one(arg);
///
/// assert_eq!(6, answer);
/// ```
pub fn add_one(x: i32) -> i32 {
x + 1
}
```
# Changes
- [Linking To Items By Name](20201119170237-linking_to_items_by_name)
- [Search Aliases](20201119170710-search_aliases)

View file

@ -0,0 +1,97 @@
---
date: 2020-08-27
id: 0ae97b2d-5a3c-40b5-9ce1-37aacb647c5d
title: Rust control flow
---
# Branching
## If
``` rust
fn main() {
let number = 3;
if number < 5 {
println!("condition was true");
} else {
println!("condition was false");
}
}
```
Because Rust is expressive we can use an \`if\` expression on the right
side of a \`let\` statement:
``` rust
fn main() {
let condition = true;
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
}
```
# Loops
## Loop
This will loop forever
``` rust
fn main() {
loop {
println!("again!");
}
}
```
Loops can also return values:
``` rust
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result is {}", result);
}
```
## While
Rust also supports while loops:
``` rust
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("LIFTOFF!!!");
}
```
## For
For loops are supported as well
``` rust
fn main() {
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
println!("the value is: {}", element);
}
}
```

View file

@ -0,0 +1,7 @@
---
date: 2020-08-28
id: e51ace6b-e3ca-4e83-aa11-80848204bd68
title: Ownership in Rust
---
TODO. Can't be bothered to write this now

View file

@ -0,0 +1,53 @@
---
date: 2020-08-28
id: f2e19e3e-e28a-4998-8b0c-38ebfdb559e5
title: Golang Pointers
---
# Basics
Go also supports pointers. Default value is always NULL and you can't do
pointer arithmetic. Other than that, nothing that will blow your mind
here.
``` go
package main
import "fmt"
func main() {
i, j := 42, 2701
p := &i // point to i
fmt.Println(*p) // read i through the pointer
*p = 21 // set i through the pointer
fmt.Println(i) // see the new value of i
p = &j // point to j
*p = *p / 37 // divide j through the pointer
fmt.Println(j) // see the new value of j
}
```
# Pointers to [Golang Structs](20200828181259-structs)
To facilitate lazy people like me Go allows you to lose the \`\*\` when
using a pointer to a struct
``` go
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
p := &v
p.X = 123
fmt.Println(v)
}
```

View file

@ -0,0 +1,186 @@
---
date: 2020-08-28
id: 463ce364-f426-4089-a0ca-ffe45f0461f2
title: Golang Structs
---
# Basics
Golang structs are what you expect
``` go
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
fmt.Println(Vertex{1, 2})
}
```
# Struct fields
Struct fields are accessed using a dot
``` go
package main
import "fmt"
type Coorindate struct {
X int
Y int
}
func main() {
coordinate := Coorindate{1, 67}
coordinate.X = 26
fmt.Println(coordinate.X)
}
```
# Struct literals
You can also newly allocate a struct by listing the values of its
fields. This is known as a "struct literal" (duh)
``` go
package main
import "fmt"
type Vertex struct {
X, Y int
}
var (
v1 = Vertex{1, 2} // has type Vertex
v2 = Vertex{X: 1} // Y:0 is implicit
v3 = Vertex{} // X:0 and Y:0
p = &Vertex{1, 2} // has type *Vertex
)
func main() {
fmt.Println(v1, p, v2, v3)
}
```
# Struct tags
[Struct tags](https://go.dev/wiki/Well-known-struct-tags) allow other
modules accessing struct members to format member values.
## Control encoding
``` go
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"time"
)
type User struct {
Name string `json:"name"`
Password string `json:"password"`
PreferredFish []string `json:"preferredFish"`
CreatedAt time.Time `json:"createdAt"`
}
func main() {
u := &User{
Name: "Sammy the Shark",
Password: "fisharegreat",
CreatedAt: time.Now(),
}
out, err := json.MarshalIndent(u, "", " ")
if err != nil {
log.Println(err)
os.Exit(1)
}
fmt.Println(string(out))
}
```
## Remove empty fields
``` go
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"time"
)
type User struct {
Name string `json:"name"`
Password string `json:"password"`
PreferredFish []string `json:"preferredFish,omitempty"`
CreatedAt time.Time `json:"createdAt"`
}
func main() {
u := &User{
Name: "Sammy the Shark",
Password: "fisharegreat",
CreatedAt: time.Now(),
}
out, err := json.MarshalIndent(u, "", " ")
if err != nil {
log.Println(err)
os.Exit(1)
}
fmt.Println(string(out))
}
```
## Ignore private fields
``` go
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"time"
)
type User struct {
Name string `json:"name"`
Password string `json:"-"`
CreatedAt time.Time `json:"createdAt"`
}
func main() {
u := &User{
Name: "Sammy the Shark",
Password: "fisharegreat",
CreatedAt: time.Now(),
}
out, err := json.MarshalIndent(u, "", " ")
if err != nil {
log.Println(err)
os.Exit(1)
}
fmt.Println(string(out))
}
```

View file

@ -0,0 +1,26 @@
---
date: 2020-08-28
id: 24d46884-652c-4b64-b8e1-1baf81bea0f4
title: Golang Arrays
---
Arrays are a thing in Go as well. Once initialized arrays cannot be
resized, if you're into **that** type of thing (no judgement) see
[slices](20200828182546-slices)
``` go
package main
import "fmt"
func main() {
var a [2]string
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1])
fmt.Println(a)
primes := [6]int{2, 3, 5, 7, 11, 13}
fmt.Println(primes)
}
```

View file

@ -0,0 +1,290 @@
---
date: 2020-08-28
id: 8b5fb822-d1ad-46de-9299-37e3d3f5108c
title: Golang slices
---
# Basics
A slice is a dynamically sized, flexible view into the elements of an
array. Apparently they are much more common than arrays. Initialization
is pretty straight forward:
``` go
package main
import "fmt"
func main() {
primes := [6]int{2, 3, 5, 7, 11, 13}
var s []int = primes[1:4]
fmt.Println(s)
}
```
Slices are like references. Change something in the slice and the
[array](20200828182327-arrays) it references also changes
``` go
package main
import "fmt"
func main() {
names := [4]string{
"John",
"Paul",
"George",
"Ringo",
}
fmt.Println(names)
a := names[0:2]
b := names[1:3]
fmt.Println(a, b)
b[0] = "XXX"
fmt.Println(a, b)
fmt.Println(names)
}
```
Slices can contain any type, including other slices:
``` go
package main
import (
"fmt"
"strings"
)
func main() {
// Create a tic-tac-toe board.
board := [][]string{
[]string{"_", "_", "_"},
[]string{"_", "_", "_"},
[]string{"_", "_", "_"},
}
// The players take turns.
board[0][0] = "X"
board[2][2] = "O"
board[1][2] = "X"
board[1][0] = "O"
board[0][2] = "X"
for i := 0; i < len(board); i++ {
fmt.Printf("%s\n", strings.Join(board[i], " "))
}
}
```
# Slice literals
A slice literal is like an array, but without the length, so we add more
stuff to it later
``` go
package main
import "fmt"
func main() {
q := []int{2, 3, 5, 7, 11, 13}
fmt.Println(q)
r := []bool{true, false, true, true, false, true}
fmt.Println(r)
s := []struct {
i int
b bool
}{
{2, true},
{3, false},
{5, true},
{7, true},
{11, false},
{13, true},
}
fmt.Println(s)
}
```
# Slice defaults
You can omit high and low bounds. As one would expect these default to 0
and slice length respectively
``` go
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
s = s[1:4]
fmt.Println(s)
s = s[:2]
fmt.Println(s)
s = s[1:]
fmt.Println(s)
}
```
# Slice length and capacity
One can lookup slice length (length of the slice) and capacity (length
of the array the slice references)
``` go
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
printSlice(s)
// Slice the slice to give it zero length.
s = s[:0]
printSlice(s)
// Extend its length.
s = s[:4]
printSlice(s)
// Drop its first two values.
s = s[2:]
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
```
# Nil slices
Empty slices are equal to `nil`. Maybe that's a good idea, maybe it
isn't. Typing this i'm too tired to give rational input to this
philosophical quagmire.
``` go
package main
import "fmt"
func main() {
var s []int
fmt.Println(s, len(s), cap(s))
if s == nil {
fmt.Println("nil!")
}
}
```
# Make
Slices can be created with the `make` function, this way you can treat
them like arrays that we know and love.
``` go
package main
import "fmt"
func main() {
a := make([]int, 5)
printSlice("a", a)
b := make([]int, 0, 5)
printSlice("b", b)
c := b[:2]
printSlice("c", c)
d := c[2:5]
printSlice("d", d)
}
func printSlice(s string, x []int) {
fmt.Printf("%s len=%d cap=%d %v\n",
s, len(x), cap(x), x)
}
```
# Append
New elements can be added to a slice with the
[append](https://golang.org/pkg/builtin/#append) function
``` go
package main
import "fmt"
func main() {
var s []int
printSlice(s)
// append works on nil slices.
s = append(s, 0)
printSlice(s)
// The slice grows as needed.
s = append(s, 1)
printSlice(s)
// We can add more than one element at a time.
s = append(s, 2, 3, 4)
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
```
# Range
You can iterate over slices with `range`
``` go
package main
import "fmt"
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
}
```
Index or value can be skipped by using `_`. In case you only want the
index, just omit the second variable entirely:
``` go
package main
import "fmt"
func main() {
pow := make([]int, 10)
for i := range pow {
pow[i] = 1 << uint(i) // == 2**i
}
for _, value := range pow {
fmt.Printf("%d\n", value)
}
}
```

View file

@ -0,0 +1,126 @@
---
date: 2020-08-28
id: 85fe90d9-f7d2-47fb-9471-f2557b1fa95d
title: Golang maps
---
# Basics
A map maps keys to values, ie: associative arrays. Zero value of a map
is `nil`. `make` function returns a new `map`.
``` go
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex
func main() {
m = make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68433, -74.39967,
}
fmt.Println(m["Bell Labs"])
}
```
# Map literals
These are essentially the same as [struct
literals](20200828181259-structs), keys are required.
``` go
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m = map[string]Vertex{
"Bell Labs": Vertex{
40.68433, -74.39967,
},
"Google": Vertex{
37.42202, -122.08408,
},
}
func main() {
fmt.Println(m)
}
```
If top-level type is just a type name, it can be omitted from literal
elements. Saves some typing.
``` go
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m = map[string]Vertex{
"Bell Labs": {40.68433, -74.39967},
"Google": {37.42202, -122.08408},
}
func main() {
fmt.Println(m)
}
```
# Mutating maps
Nothing shocking here either. Map elements can be
added/deleted/modified/etc.
``` go
package main
import "fmt"
func main() {
m := make(map[string]int)
m["Answer"] = 42
fmt.Println("The value:", m["Answer"])
m["Answer"] = 48
fmt.Println("The value:", m["Answer"])
delete(m, "Answer")
fmt.Println("The value:", m["Answer"])
v, ok := m["Answer"]
fmt.Println("The value:", v, "Present?", ok)
}
```
# Types
A `type` can be declared as a thin wrapper around a `map`:
``` go
import "fmt"
type Dictionary map[string]string
func (d Dictionary) Search(word string) string {
return d[word]
}
func main() {
d := Dictionary{"key": "This is the value"}
fmt.Println(d.Search("key"))
}
```

View file

@ -0,0 +1,65 @@
---
date: 2020-08-31
id: 03a6cd46-e6fb-46a8-96f7-16c37a6d140a
title: Golang methods
---
# Basics
In Go methods can be defined on [struct](20200828181259-structs) and
non-struct types. In this case a **receiver** argument ias passed
between \`func\` keyword and the method name (\`Abs\`):
``` go
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := Vertex{3, 4}
fmt.Println(v.Abs())
}
```
# Pointers
To modify struct values methods must be declared with pointer receivers:
``` go
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func main() {
v := Vertex{3, 4}
v.Scale(10)
fmt.Println(v.Abs())
}
```

View file

@ -0,0 +1,179 @@
---
date: 2020-08-31
id: 7ca10187-82d5-44fb-83a2-aa739c14cb24
title: Golang interfaces
---
# Basics
Go supports method interfaces:
``` go
package main
import (
"fmt"
"math"
)
type Abser interface {
Abs() float64
}
func main() {
var a Abser
f := MyFloat(-math.Sqrt2)
v := Vertex{3, 4}
a = f // a MyFloat implements Abser
a = &v // a *Vertex implements Abser
fmt.Println(a.Abs())
}
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
```
Interfaces are implemented implicitly:
``` go
package main
import "fmt"
type I interface {
M()
}
type T struct {
S string
}
// This method means type T implements the interface I,
// but we don't need to explicitly declare that it does so.
func (t T) M() {
fmt.Println(t.S)
}
func main() {
var i I = T{"hello"}
i.M()
}
```
# Handy interfaces to know about
## Stringer
``` go
package main
import "fmt"
type Person struct {
Name string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}
func main() {
a := Person{"Arthur Dent", 42}
z := Person{"Zaphod Beeblebrox", 9001}
fmt.Println(a, z)
}
```
## Error
``` go
package main
import (
"fmt"
"time"
)
type MyError struct {
When time.Time
What string
}
func (e *MyError) Error() string {
return fmt.Sprintf("at %v, %s",
e.When, e.What)
}
func run() error {
return &MyError{
time.Now(),
"it didn't work",
}
}
func main() {
if err := run(); err != nil {
fmt.Println(err)
}
}
```
## Reader
``` go
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("Hello, Reader!")
b := make([]byte, 8)
for {
n, err := r.Read(b)
fmt.Printf("n = %v err = %v b = %v\n", n, err, b)
fmt.Printf("b[:n] = %q\n", b[:n])
if err == io.EOF {
break
}
}
}
```
## Images
``` go
package main
import (
"fmt"
"image"
)
func main() {
m := image.NewRGBA(image.Rect(0, 0, 100, 100))
fmt.Println(m.Bounds())
fmt.Println(m.At(0, 0).RGBA())
}
```

View file

@ -0,0 +1,155 @@
---
date: 2020-08-31
id: 26048172-107d-4ad4-9906-acdf7935dfcb
title: Rust Structs Syntax
---
# Basics
``` rust
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn build_user(email: String, username: String) -> User {
// When struct field name and parameter name are the same shorthand syntax can be used
User {
email,
username,
active: true,
sign_in_count: 1,
}
}
fn print_data(user: User) {
println!("User email is: {}", user.email);
println!("User username is: {}", user.username);
println!("User sign in count is: {}", user.sign_in_count);
println!("User active is: {}", user.active);
}
fn main() {
let user1 = build_user(
String::from("someone@example.com"),
String::from("someusername123"),
);
println!("User 1");
print_data(user1);
let mut user2 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
user2.email = String::from("anotheremail@example.com");
println!("User 2");
print_data(user2);
}
```
``` rust
```
# Tuple Struct
``` rust
fn main() {
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
}
```
# Debug trait
To print out debugging information we have the [debug
trait](https://doc.rust-lang.org/std/fmt/trait.Debug.html):
``` rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("rect1 is {:?}", rect1);
}
```
# Methods
Methods are like functions, but for structs:
``` rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
rect1.area()
);
}
```
# Associated Functions
These are Rust's take on static functions. They **don't** take `self` as
a parameter
``` rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
fn square(size: u32) -> Rectangle {
Rectangle {
width: size,
height: size,
}
}
}
fn main() {
let rect1 = Rectangle::square(10);
println!(
"The area of the rectangle is {} square pixels.",
rect1.area()
);
}
```

View file

@ -0,0 +1,11 @@
---
date: 2020-09-01
id: 57c3cee1-22dd-4a11-8a21-a19c571913e9
title: JavaScript Error Handling
---
- [Exceptions](20201111092905-javascript_exceptions)
- [Error Sub Types](20201111093101-javascript_error_sub_types)
- [Strict Mode](20201111092510-javascript_strict_mode)
- [Custom Error Types](20201111093651-javascript_custom_error_types)
- [Finally](20201111094033-javascript_exceptions_finally)

View file

@ -0,0 +1,264 @@
---
date: 2020-09-01
id: 56b6e0d5-090d-4859-9f06-c54a1a116515
title: Goroutines
---
# Basics
A `goroutine` is a lightweight thread managed by the Go runtime.
``` go
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
```
# Channels
Channels are a typed conduit through whichyou can send and receive
values with the channel operator \`\<-\`. By default, sends and receives
block until the other side is ready. This allows goroutines to
synchronize without explicit locks or condition variables. Channels
should generally be used for [passing ownership of
data](https://github.com/golang/go/wiki/MutexOrChannel).
``` go
package main
import "fmt"
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // send sum to c
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y)
}
```
Channels can also be **buffered**. Provide the buffer length as the
second argument to \`make\` to initialize a buffered channel:
``` go
package main
import "fmt"
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println(<-ch)
fmt.Println(<-ch)
}
```
Sends to a buffered channel block only when the buffer is full. Receives
block when the buffer is empty.
# Range and close
A sender can close a channel to indicate that no more values will be
sent. Receivers can test whether a channel has been closed by assigning
a second parameter to the receive expression.
Only the sender should close a channel, never the receiver. Sending on a
closed channel will cause a panic. Channels aren't like files; you don't
usually need to close them. Closing is only necessary when the receiver
must be told there are no more values coming, such as to terminate a
range loop.
``` go
package main
import (
"fmt"
)
func fibonacci(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x+y
}
close(c)
}
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c)
for i := range c {
fmt.Println(i)
}
}
```
# Select
The select statement lets a goroutine wait on multiple communication
operations.
A select blocks until one of its cases can run, then it executes that
case. It chooses one at random if multiple are ready.
``` go
package main
import "fmt"
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
}
```
\`default\` case in \`select\` is run if no other case is ready, as one
would expect
``` go
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(100 * time.Millisecond)
boom := time.After(500 * time.Millisecond)
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
return
default:
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
}
```
## Timeout
Often you want to set a timeout value for `select` so it won't run
forver. [time.After](https://golang.org/pkg/time/#After) is a good way
of doing this:
``` go
package main
import (
"fmt"
"time"
)
var c chan int
func handle(int) {}
func main() {
select {
case m := <-c:
handle(m)
case <-time.After(10 * time.Second):
fmt.Println("timed out")
}
}
```
# sync.Mutex
TO make sure only one goroutine at a time can access a variable we can
use \`sync.Mutex\`
``` go
package main
import (
"fmt"
"sync"
"time"
)
// SafeCounter is safe to use concurrently.
type SafeCounter struct {
mu sync.Mutex
v map[string]int
}
// Inc increments the counter for the given key.
func (c *SafeCounter) Inc(key string) {
c.mu.Lock()
// Lock so only one goroutine at a time can access the map c.v.
c.v[key]++
c.mu.Unlock()
}
// Value returns the current value of the counter for the given key.
func (c *SafeCounter) Value(key string) int {
c.mu.Lock()
// Lock so only one goroutine at a time can access the map c.v.
defer c.mu.Unlock()
return c.v[key]
}
func main() {
c := SafeCounter{v: make(map[string]int)}
for i := 0; i < 1000; i++ {
go c.Inc("somekey")
}
time.Sleep(time.Second)
fmt.Println(c.Value("somekey"))
}
```

View file

@ -0,0 +1,263 @@
---
date: 2020-09-02
id: b95f09af-2cd0-46f2-872e-3cb542d2b2e9
title: Rust enums
---
# Basics
Rust also supports
[enums](https://doc.rust-lang.org/rust-by-example/custom_types/enum.html).
``` rust
use std::fmt::Debug;
#[derive(Debug)]
enum Message {
Write(String),
}
fn main() {
let m = Message::Write(String::from("Hello!"));
println!("{:?}", m)
}
```
# Methods
As with [structs](20200831193417-structs), methods can be defined as
well:
``` rust
use std::fmt::Debug;
#[derive(Debug)]
enum Message {
Write(String),
}
impl Message {
fn call(&self) {
println!("tralala");
println!("{:?}", self)
}
}
fn main() {
let m = Message::Write(String::from("Hello!"));
m.call();
}
```
# Standard library enums
## Option
Instead of \`null\` Rust has the
[Option](https://doc.rust-lang.org/std/option/enum.Option.html) enum
built in:
``` rust
fn main() {
let some_number = Some(5);
let some_string = Some("a string");
let absent_number: Option<i32> = None;
}
```
The cool thing about using Option is that \`Option\<T\>\` and \`T\` are
different types, therefore the programmer has to define if NULL is
acceptable beforehand. The following won't run:
``` rust
fn main() {
let x: i8 = 5;
let y: Option<i8> = Some(5);
let sum = x + y;
}
```
Huzzah, No more having to worry about incorrectly assuming a not null
value!
# Match control flow operator
Think of \`switch\`, but for enums.
``` rust
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => {
println!("Lucky penny!");
1
}
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
fn main() {}
```
## Patterns that bind to values
Another useful feature of match arms is that they can bind to the parts
of the values that match the pattern. This is how we can extract values
out of enum variants.
``` rust
#[derive(Debug)]
enum UsState {
Alabama,
Alaska,
// --snip--
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("State quarter from {:?}!", state);
25
}
}
}
fn main() {
value_in_cents(Coin::Quarter(UsState::Alaska));
}
```
## Matching with Option\<T\>
\`match\` also plays nice with \`Option\<t\>\`:
``` rust
fn main() {
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
}
let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);
}
```
## The \_ Placeholder
Rust also has a pattern we can use when we dont want to list all
possible values:
``` rust
fn main() {
let some_u8_value = 0u8;
match some_u8_value {
1 => println!("one"),
3 => println!("three"),
5 => println!("five"),
7 => println!("seven"),
_ => (),
}
}
```
## if let syntax suger
``` rust
fn main() {
let some_u8_value = Some(0u8);
match some_u8_value {
Some(3) => println!("three"),
_ => (),
}
}
```
is the same as
``` rust
fn main() {
let some_u8_value = Some(0u8);
if let Some(3) = some_u8_value {
println!("three");
}
}
```
and
``` rust
#[derive(Debug)]
enum UsState {
Alabama,
Alaska,
// --snip--
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
fn main() {
let coin = Coin::Penny;
let mut count = 0;
match coin {
Coin::Quarter(state) => println!("State quarter from {:?}!", state),
_ => count += 1,
}
}
```
is the same as
``` rust
#[derive(Debug)]
enum UsState {
Alabama,
Alaska,
// --snip--
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
fn main() {
let coin = Coin::Penny;
let mut count = 0;
if let Coin::Quarter(state) = coin {
println!("State quarter from {:?}!", state);
} else {
count += 1;
}
}
```

View file

@ -0,0 +1,38 @@
---
date: 2020-09-02
id: 9f63288d-8d70-4b20-a853-66c8f75418c0
title: JavaScript Regular Expressions
---
# Prototype Methods
- [test](20201104101723-javascript_regexp_test_method)
- [exec](20201104101924-javascript_regexp_exec_method)
- [match](20201104102212-javascript_regexp_match_method)
- [matchAll](20201116165324-matchall_expression)
- [replace](20201104102343-javascript_regexp_replace_method)
- [search](20201104102506-javascript_regexp_search_method)
# Groups
- [JavaScript RegExp Numbered Capture
Groups](20201104095851-javascript_regexp_numbered_capture_groups)
- [JavaScript RegExp Named Capture
Groups](20201104100431-javascript_regexp_named_capture_groups)
# Escapes
- [JavaScript RegExp Unicode Property
Escapes](20201106090634-javascript_regexp_unicode_property_escapes)
# Assertions
- [Lookahead
Assertions](20201109132457-javascript_lookahead_assertions)
- [Lookbehind
Assertions](20201109132944-javascript_lookbehind_assertions)
# Flags
- [JavaScript RegExp /s flag](20201110094807-javascript_regexp_s_flag)
- [JavaScript RegExp /u flag](20201110095139-javascript_regexp_u_flag)

View file

@ -0,0 +1,57 @@
---
date: 2020-09-09
id: 5114b51a-da22-4c9c-a12c-c416aeb984b6
title: Golang Errors
---
# Basics
Go supports Errors
``` go
import (
"errors"
"fmt"
)
func ThrowError(throwError bool) error {
if throwError {
return errors.New("This is an error")
}
fmt.Println("No error was thrown!")
return nil
}
func main() {
ThrowError(true)
ThrowError(false)
}
```
# Wrappers
It appears to be good practice to make errors a `const`. This example
uses the Error [interface](20200831171822-interfaces):
``` go
const (
ErrNotFound = DictionaryErr("could not find the word you were looking for")
ErrWordExists = DictionaryErr("cannot add word because it already exists")
)
type DictionaryErr string
func (e DictionaryErr) Error() string {
return string(e)
}
```
# Handy Links
- Constant errors[^1]
# Footnotes
[^1]: <https://dave.cheney.net/2016/04/07/constant-errors>

View file

@ -0,0 +1,27 @@
---
date: 2020-09-11
id: 6b091d50-aa10-4ba8-a652-43cd5433371e
title: JavaScript Callbacks
---
# Examples
## setTimeout
``` javascript
setTimeout(() => { console.log("This will echo after 2 seconds!"); }, 2000);
```
# ES6
## Best practices
### Prefer arrow functions as callbacks
As callbacks, [arrow functions](20201006111349-arrow_functions) have two
advantages over traditional functions:
- `this` is lexical and therefore safer to use.
- Their syntax is more compact. That matters especially in functional
programming, where there are many higher-order functions and methods
(functions and methods whose parameters are functions).

View file

@ -0,0 +1,39 @@
---
date: 2020-09-11
id: 14e0ce4b-b4b1-46fe-946a-c519550682ac
title: JavaScript Promises
---
# Introduction
A Promise[^1] is an asynchronous action that may complete at some point
and produce a value. It is able to notify anyone who is interested when
its value is available.
``` javascript
let fifteen = Promise.resolve(15);
fifteen.then(value => console.log(`Got ${value}`))
```
# Parallel
- [Executing Promises in Parallel
(Promises.all)](20201111094957-executing_promises_in_parallel_promises_all)
- [Promise.allSettled](20201116163327-promise_allsettled)
# Errors
- [Catching Promise Errors](20201111095100-catching_promise_errors)
- [Finally](20201111095454-javascript_promises_finally)
# Producing & Consuming
Use [Async functions](20201026103714-javascript_async_functions) instead
of this.
- [Producing Promises](20201111095230-producing_promises)
- [Consuming Promises](20201111095316-javascript_consuming_promises)
# Footnotes
[^1]: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>

View file

@ -0,0 +1,123 @@
---
date: 2020-09-11
id: b2b11ef2-898f-45c7-ad25-967ac7bc9d8b
title: JavaScript Generators
---
# ES6
## Introduction
Generators are processes that you can pause and resume. Generators are
defined with `function*`.
``` javascript
const foo = function* () {
yield 'a';
yield 'b';
yield 'c';
};
let str = '';
for (const val of foo()) {
str = str + val;
}
console.log(str);
```
## Generator Kinds
### Generator function declarations
``` javascript
function* genFunc() { }
const genObj = genFunc();
```
### Generator function expressions
``` javascript
const genFunc = function* () { };
const genObj = genFunc();
```
### Generator method definitions in object literals
``` javascript
const obj = {
* generatorMethod() {
}
};
const genObj = obj.generatorMethod();
```
### Generator method definitions in class definitions
``` javascript
class MyClass {
* generatorMethod() {
}
}
const myInst = new MyClass();
const genObj = myInst.generatorMethod();
```
# Examples
## Iterables
``` javascript
function* objectEntries(obj) {
const propKeys = Reflect.ownKeys(obj);
for (const propKey of propKeys) {
// `yield` returns a value and then pauses
// the generator. Later, execution continues
// where it was previously paused.
yield [propKey, obj[propKey]];
}
}
const jane = { first: 'Jane', last: 'Doe' };
for (const [key,value] of objectEntries(jane)) {
console.log(`${key}: ${value}`);
}
// Output:
// first: Jane
// last: Doe
```
## Async Iterables
``` javascript
async function* createAsyncIterable(syncIterable) {
for (const elem of syncIterable) {
yield elem;
}
}
```
## Asynchronous code
``` javascript
const fetchJson = co.wrap(function* (url) {
try {
let request = yield fetch(url);
let text = yield request.text();
return JSON.parse(text);
}
catch (error) {
console.log(`ERROR: ${error.stack}`);
}
});
fetchJson('http://example.com/some_file.json')
.then(obj => console.log(obj));
```
# Also see
- [Iterables](20201014092625-javascript_iterables)
- [Promises](20200911154351-promises)

View file

@ -0,0 +1,148 @@
---
date: 2020-09-15
id: 2eec2c96-e006-4a53-b5cc-fd39f466a6b7
title: Rust Vectors
---
# Traits
## std
### convert
- [TryInto](20201119171245-tryinto)
# Description
Vectors allow you to store more than one value in a single data
structure that puts all the values next to each other in memory. Vectors
can only store values of the same type. They are useful when you have a
list of items, such as the lines of text in a file or the prices of
items in a shopping cart.
# Creating a New Vector
``` rust
fn main() {
let v: Vec<i32> = Vec::new();
}
```
## vec! macro
Rust can often infer the type of value you want to store in the Vector.
For convenience one can also use the [vec!
macro](https://doc.rust-lang.org/std/macro.vec.html).
``` rust
fn main() {
let v = vec![1, 2, 3];
}
```
# Updating a Vector
``` rust
fn main() {
let mut v = Vec::new();
v.push(5);
v.push(6);
v.push(7);
v.push(8);
}
```
# Dropping a Vector
Like other [structs](20200831193417-structs), vectors are freed when
they go out of scope, along with the vector contents:
``` rust
fn main() {
{
let v = vec![1, 2, 3, 4];
// do stuff with v
} // <- v goes out of scope and is freed here
}
```
# Read Vector elements
There are two ways to reference a value stored in a vector:
``` rust
fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("The third element is {}", third);
match v.get(2) {
Some(third) => println!("The third element is {}", third),
None => println!("There is no third element."),
}
}
```
Using
[get](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.get)
together with
[match](https://doc.rust-lang.org/rust-by-example/flow_control/match.html)
seems preferable, as trying to get non existant elements with method \#1
will cause an \`index out of bounds\` panic:
``` rust
fn main() {
let v = vec![1, 2, 3, 4, 5];
let does_not_exist = &v[100];
let does_not_exist = v.get(100);
}
```
When the `get` method is passed an index that is outside the vector, it
returns `None` without panicking.
# Iteration
## Immutable references
``` rust
fn main() {
let v = vec![100, 32, 57];
for i in &v {
println!("{}", i);
}
}
```
## Mutable references
``` rust
fn main() {
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
}
}
```
# Using Enums to store multiple types
``` rust
fn main() {
enum SpreadsheetCell {
Int(i32),
Float(f64),
Text(String),
}
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Text(String::from("blue")),
SpreadsheetCell::Float(10.12),
];
}
```

View file

@ -0,0 +1,145 @@
---
date: 2020-09-15
id: 490f0710-971d-4150-a339-4a8c2f5d19a8
title: Rust Strings
---
# Description
The `String` type, which is provided by Rusts standard library rather
than coded into the core language, is a growable, mutable, owned, UTF-8
encoded string type. When Rustaceans refer to “strings” in Rust, they
usually mean the `String` and the string slice `&str` types, not just
one of those types. Although this section is largely about `String`,
both types are used heavily in Rusts standard library, and both
`String` and string slices are UTF-8 encoded.
# Creating a New String
Many [Vector operations](20200915140449-vectors) are also available for
Strings.
``` rust
fn main() {
let mut s = String::new();
}
```
## to~string~
To generate a `String` with initial data we can use the
[to~string~](https://doc.rust-lang.org/std/string/trait.ToString.html#tymethod.to_string)
method:
``` rust
fn main() {
let data = "initial contents";
let s = data.to_string();
// the method also works on a literal directly:
let s = "initial contents".to_string();
}
```
## String::from
The same can be accomplished with `String::from`:
``` rust
fn main() {
let s = String::from("initial contents");
}
```
# Updating a String
## push~str~
``` rust
fn main() {
let mut s = String::from("foo");
s.push_str("bar");
println!("s is {}", s)
}
```
## push
`push` adds a single character to a string:
``` rust
fn main() {
let mut s = String::from("lo");
s.push('l');
println!("s is {}", s)
}
```
# Concatentation
``` rust
fn main() {
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used
println!("s3 is {}", s3)
}
```
## Concatenate multiple strings
### With +
``` rust
fn main() {
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = s1 + "-" + &s2 + "-" + &s3;
println!("s is {}", s)
}
```
### With format!
``` rust
fn main() {
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = format!("{}-{}-{}", s1, s2, s3);
println!("s is {}", s)
}
```
# Iteration
## Chars
``` rust
#![allow(unused)]
fn main() {
for c in "नमस्ते".chars() {
println!("{}", c);
}
}
```
## Bytes
``` rust
#![allow(unused)]
fn main() {
for b in "नमस्ते".bytes() {
println!("{}", b);
}
}
```

View file

@ -0,0 +1,137 @@
---
date: 2020-09-15
id: 2b38c21d-4971-42fb-9b87-5d68468e95e0
title: Rust Hash Maps
---
# Description
The type `HashMap<K, V>` stores a mapping of keys of type `K` to values
of type `V`. It does this via a hashing function, which determines how
it places these keys and values into memory. Many programming languages
support this kind of data structure, but they often use a different
name, such as hash, map, object, hash table, dictionary, or associative
array, just to name a few.
## Creating a New Hash Maps
``` rust
fn main() {
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
println!("{}", scores["Blue"])
}
```
### collect
Another way of constructing a hash map is by using iterators and the
[collect](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect)
method on a vector of tuples, where each tuple consists of a key and its
value.
``` rust
fn main() {
use std::collections::HashMap;
let teams = vec![String::from("Blue"), String::from("Yellow")];
let initial_scores = vec![10, 50];
let scores: HashMap<_, _> = teams.into_iter().zip(initial_scores.into_iter()).collect();
println!("{}", scores["Blue"])
}
```
## Ownership
For types that implement the `Copy` trait, like `i32`, the values are
copied into the hash map. For owned values like `String`, the values
will be moved and the hash map will be the owner of those values:
``` rust
fn main() {
use std::collections::HashMap;
let field_name = String::from("Favorite color");
let field_value = String::from("Blue");
let mut map = HashMap::new();
map.insert(field_name, field_value);
// field_name and field_value are invalid at this point
}
```
## Accessing values
``` rust
fn main() {
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
for (key, value) in &scores {
println!("{}: {}", key, value);
}
}
```
## Updating
### Overwriting a Value
``` rust
fn main() {
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 25);
println!("{:?}", scores);
}
```
### Inserting a value only if the Key has no value
``` rust
fn main() {
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.entry(String::from("Yellow")).or_insert(50);
scores.entry(String::from("Blue")).or_insert(50);
println!("{:?}", scores);
}
```
### Updating a value based on the old value
``` rust
fn main() {
use std::collections::HashMap;
let text = "hello world wonderful world";
let mut map = HashMap::new();
for word in text.split_whitespace() {
let count = map.entry(word).or_insert(0);
*count += 1;
}
println!("{:?}", map);
}
```

View file

@ -0,0 +1,34 @@
---
date: 2020-09-16
id: 2a1d0b2f-9f23-4872-a83f-aa01a84756b5
title: Rust Unrecoverable Errors
---
# Unwinding vs Aborting
By default, when a panic occurs, the program starts *unwinding*, which
means Rust walks back up the stack and cleans up the data from each
function it encounters. But this walking back and cleanup is a lot of
work. The alternative is to immediately abort, which ends the program
without cleaning up. Memory that the program was using will then need to
be cleaned up by the operating system. If in your project you need to
make the resulting binary as small as possible, you can switch from
unwinding to aborting upon a panic by adding `panic = 'abort'` to the
appropriate `[profile]` sections in your *Cargo.toml* file. For example,
if you want to abort on panic in release mode, add this:
``` toml
[profile.release]
panic = 'abort'
```
# panic!
When doodie hits the fan and there's no way out, use the
[panic!](https://doc.rust-lang.org/std/macro.panic.html) macro:
``` rust
fn main() {
panic!("crash and burn");
}
```

View file

@ -0,0 +1,171 @@
---
date: 2020-09-16
id: cbdaa6b4-cf72-45fb-ac16-79afd8900478
title: Rust Recoverable Errors
---
# match
In Rust we use the [match](20201006102934-pattern_syntax) expression to
check for errors in the
[Result](https://doc.rust-lang.org/std/result/enum.Result.html):
``` rust
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {:?}", error),
};
}
```
Generally speaking you want to perform different actions depending on
the error type:
``` rust
use std::fs::File;
use std::io::ErrorKind;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => match error.kind() {
ErrorKind::NotFound => match File::create("hello.txt") {
Ok(fc) => fc,
Err(e) => panic!("Problem creating the file: {:?}", e),
},
other_error => panic!("Problem opening the file: {:?}", other_error),
},
};
}
```
## Ditching match altogether
A more elegant way of writing the above:
``` rust
use std::fs::File;
use std::io::ErrorKind;
fn main() {
let f = File::open("hello.txt").unwrap_or_else(|error| {
if error.kind() == ErrorKind::NotFound {
File::create("hello.txt").unwrap_or_else(|error| {
panic!("Problem creating the file: {:?}", error);
})
} else {
panic!("Problem opening the file: {:?}", error);
}
});
}
```
# Panic on Error shortcuts
## unwrap
If the `Result` value is `Ok`,
[unwrap](https://doc.rust-lang.org/std/option/enum.Option.html#method.unwrap)
will return the value inside the `Ok`. If the `Result` is of the `Err`
variant, unwrap will call the `panic!` macro
``` rust
use std::fs::File;
fn main() {
let f = File::open("hello.txt").unwrap();
}
```
## expect
[expect](https://doc.rust-lang.org/std/option/enum.Option.html#method.expect)
is almost the same as unwrap, the only difference being that it allws us
to choose the panic! error message:
``` rust
use std::fs::File;
fn main() {
let f = File::open("hello.txt").expect("Failed to open hello.txt");
}
```
# Propagating Errors
When youre writing a function whose implementation calls something that
might fail, instead of handling the error within this function, you can
return the error to the calling code so that it can decide what to do.
This is known as propagating the error and gives more control to the
calling code, where there might be more information or logic that
dictates how the error should be handled than what you have available in
the context of your code.
``` rust
#![allow(unused)]
fn main() {
use std::fs::File;
use std::io;
use std::io::Read;
fn read_username_from_file() -> Result<String, io::Error> {
let f = File::open("hello.txt");
let mut f = match f {
Ok(file) => file,
Err(e) => return Err(e),
};
let mut s = String::new();
match f.read_to_string(&mut s) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
}
}
```
This can of course be refactored to something nicer:
``` rust
#![allow(unused)]
fn main() {
use std::fs::File;
use std::io;
use std::io::Read;
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = File::open("hello.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}
}
```
And this can be refactored even more:
``` rust
#![allow(unused)]
fn main() {
use std::fs::File;
use std::io;
use std::io::Read;
fn read_username_from_file() -> Result<String, io::Error> {
let mut s = String::new();
File::open("hello.txt")?.read_to_string(&mut s)?;
Ok(s)
}
}
```

View file

@ -0,0 +1,31 @@
---
date: 2020-09-16
id: f41437f1-359e-41c9-894b-e5785c29d729
title: CommonJS
---
# Syntax
``` javascript
const ordinal = require("ordinal");
const {days, months} = require("date-names");
exports.formatDate = function(date, format) {
return format.replace(/YYYY|M(MMM)?|Do?|dddd/g, tag => {
if (tag == "YYYY") return date.getFullYear();
if (tag == "M") return date.getMonth();
if (tag == "MMMM") return months[date.getMonth()];
if (tag == "D") return date.getDate();
if (tag == "Do") return ordinal(date.getDate());
if (tag == "dddd") return days[date.getDay()];
});
};
```
``` javascript
const {formatDate} = require("./format-date");
console.log(formatDate(new Date(2017, 9, 13),
"dddd the Do"));
// → Friday the 13th
```

View file

@ -0,0 +1,20 @@
---
date: 2020-09-16
id: 7fa2a1e8-deae-47f9-83ee-e4f4f84eec16
title: ECMAScript Modules
---
# Syntax
``` javascript
import ordinal from "ordinal";
import {days, months} from "date-names";
export function formatDate(date, format) { /* ... */ }
```
## Default export
``` javascript
export default ["Winter", "Spring", "Summer", "Autumn"];
```

View file

@ -0,0 +1,9 @@
---
date: 2020-09-17
id: 8fdb1d27-7983-4ab0-bda3-120715000797
title: Reflection
---
# Everything you need to know about Reflection
Avoid at all costs!

View file

@ -0,0 +1,135 @@
---
date: 2020-09-17
id: 9062c9c0-b2d5-4719-b15b-6fe5122b6a9e
title: Rust Generics
---
# Function definitions
We read the following definition as: the function largest is generic
over some type T. This function has one parameter named list, which is a
slice of values of type T. The largest function will return a reference
to a value of the same type T.
``` rust
fn largest<T>(list: &[T]) -> &T {
let mut largest = list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
```
# Struct definitions
``` rust
struct Point<T> {
x: T,
y: T,
}
fn main() {
let integer = Point { x: 5, y: 10 };
let float = Point { x: 1.0, y: 4.0 };
}
```
A struct can also have multiple generic types:
``` rust
struct Point<T, U> {
x: T,
y: U,
}
fn main() {
let both_integer = Point { x: 5, y: 10 };
let both_float = Point { x: 1.0, y: 4.0 };
let integer_and_float = Point { x: 5, y: 4.0 };
}
```
# Enum Definitions
``` rust
#![allow(unused)]
fn main() {
enum Option<T> {
Some(T),
None,
}
}
```
And again with multiple generics:
``` rust
#![allow(unused)]
fn main() {
enum Result<T, E> {
Ok(T),
Err(E),
}
}
```
# Method Definitions
``` rust
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
fn y(&self) -> &T {
&self.y
}
}
fn main() {
let p = Point { x: 5, y: 10 };
println!("p.x = {} and p.y={}", p.x(), p.y());
}
```
And again with multiple generics:
``` rust
struct Point<T, U> {
x: T,
y: U,
}
impl<T, U> Point<T, U> {
fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
Point {
x: self.x,
y: other.y,
}
}
}
fn main() {
let p1 = Point { x: 5, y: 10.4 };
let p2 = Point { x: "Hello", y: 'c' };
let p3 = p1.mixup(p2);
println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
}
```
# Performance of Code Using Generics
The Rust compiler is very very clever and using generics has no
performance penalty

View file

@ -0,0 +1,198 @@
---
date: 2020-09-17
id: 84046151-f6e2-4051-a4c5-0c82834eaa41
title: Rust Traits Syntax
---
# Definition
``` rust
#![allow(unused)]
fn main() {
pub trait Summary {
fn summarize(&self) -> String;
}
}
```
# Implementation
``` rust
#![allow(unused)]
fn main() {
pub trait Summary {
fn summarize(&self) -> String;
}
pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}, by {} ({})", self.headline, self.author, self.location)
}
}
pub struct Tweet {
pub username: String,
pub content: String,
pub reply: bool,
pub retweet: bool,
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}
}
```
## Default Implementations
``` rust
#![allow(unused)]
fn main() {
pub trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}
impl Summary for NewsArticle {}
pub struct Tweet {
pub username: String,
pub content: String,
pub reply: bool,
pub retweet: bool,
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}
}
```
# Traits as Parameters
``` rust
pub trait Summary {
fn summarize(&self) -> String;
}
pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}, by {} ({})", self.headline, self.author, self.location)
}
}
pub struct Tweet {
pub username: String,
pub content: String,
pub reply: bool,
pub retweet: bool,
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}
pub fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
```
## Specifying Multiple Trait Bounds
``` rust
pub fn notify(item: &(impl Summary + Display)) {
```
This also works on generic types:
``` rust
pub fn notify<T: Summary + Display>(item: &T) {
```
### Clearer Trait Bounds
``` rust
fn some_function<T: Display + Clone, U: Clone + Debug>(t: &T, u: &U) -> i32 {
```
is the same as
``` rust
fn some_function<T, U>(t: &T, u: &U) -> i32
where T: Display + Clone,
U: Clone + Debug
{
```
# Return Types that Implement Traits
``` rust
pub trait Summary {
fn summarize(&self) -> String;
}
pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}, by {} ({})", self.headline, self.author, self.location)
}
}
pub struct Tweet {
pub username: String,
pub content: String,
pub reply: bool,
pub retweet: bool,
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}
fn returns_summarizable() -> impl Summary {
Tweet {
username: String::from("horse_ebooks"),
content: String::from(
"of course, as you probably already know, people",
),
reply: false,
retweet: false,
}
}
```

View file

@ -0,0 +1,37 @@
---
date: 2020-09-18
id: 56a802e2-3871-4746-aec4-fa4bdae4d4fd
title: Golang Mutex
---
# Description
[Mutex](https://golang.org/pkg/sync/#Mutex) allows up to add locks to
our data so it can be accessed safely in a concurrent manner. While
locked other threads can't access the data. `Mutexes` should generally
be used for [managing
state](https://github.com/golang/go/wiki/MutexOrChannel).
# Syntax
``` go
type Counter struct {
mu sync.Mutex
value int
}
func (c *Counter) Inc() {
c.mu.Lock()
defer c.mu.Unlock()
c.value++
}
func (c *Counter) Value() int {
return c.value
}
func NewCounter() *Counter {
return &Counter{}
}
```

View file

@ -0,0 +1,54 @@
---
date: 2020-09-18
id: 53c0ad13-0c19-4a84-9c67-cc31d036be4d
title: Golang WaitGroup
---
# Description
A [WaitGroup](https://golang.org/pkg/sync/#WaitGroup) waits for a
collection of goroutines to finish. The main goroutine calls Add to set
the number of goroutines to wait for. Then each of the goroutines runs
and calls Done when finished. At the same time, Wait can be used to
block until all goroutines have finished.
A WaitGroup must not be copied after first use.
# Syntax
``` go
type Counter struct {
mu sync.Mutex
value int
}
func (c *Counter) Inc() {
c.mu.Lock()
defer c.mu.Unlock()
c.value++
}
func (c *Counter) Value() int {
return c.value
}
func NewCounter() *Counter {
return &Counter{}
}
wantedCount := 1000
counter := NewCounter()
var wg sync.WaitGroup
wg.Add(wantedCount)
for i := 0; i < wantedCount; i++ {
go func(w *sync.WaitGroup) {
counter.Inc()
w.Done()
}(&wg)
}
wg.Wait()
```

View file

@ -0,0 +1,15 @@
---
date: 2020-09-18
id: 9089aff1-703d-4628-971a-5f655f7bf09f
title: Rustc
---
# Description
Rustc handles Rust compilation
# Syntax
``` shell
rustc main.rs
```

View file

@ -0,0 +1,151 @@
---
date: 2020-09-18
id: c409c0cd-5284-4333-ae99-bc351ff8ba0d
title: Cargo
---
# Description
Cargo is Rust's build system and package manager.
# Configuration
- [Cargo.toml](20201120094652-cargo_toml)
# Commands
## Create project
``` shell
cargo new hello_cargo
```
## Build & run project
``` shell
cargo run
```
### Backtrace
When you want to see an error backtrace set the `RUST_BACKTRACE`
environment variable:
``` shell
RUST_BACKTRACE=1 cargo run
```
## Publish to Crates.io
``` shell
cargo publish
```
## Install package
``` shell
cargo install ripgrep
```
## Linting & testing
Check code
``` shell
cargo check
```
Testing
``` shell
cargo test
```
1. Backtrace
To backtrace set the `RUST_BACKTRACE` environment variable:
``` shell
RUST_BACKTRACE=1 cargo run
```
2. Threads
By default cargo runs test in parallel. For more control over this
you can pass the number of threads you want to use. For example to
only use 1 thread:
``` shell
cargo test -- --test=threads=1
```
3. Show output for passing tests as well as failed tests
``` shell
cargo test -- --show-output
```
4. Pass test name to cargo (this equals test function name)
``` shell
cargo test one_hundred
```
5. Run ignored tests
``` shell
cargo test -- --ignored
```
Fix
The rustfix tool is included with Rust installations and can
automatically fix some compiler warnings.
``` shell
cargo fix
```
## Builds
### Profiles
In Rust, release profiles are predefined and customizable profiles with
different configurations that allow a programmer to have more control
over various options for compiling code. Each profile is configured
independently of the others.
Cargo has two main profiles: the `dev` profile Cargo uses when you run
cargo build and the release profile Cargo uses when you run
`cargo build --release`. The `dev` profile is defined with good defaults
for development, and the `release` profile has good defaults for release
builds.
1. dev
``` shell
cargo build
```
2. build
``` shell
cargo build --release
```
## Documentation
See [Rust Comments](20200827190035-rust_comments) for documentation
syntax.
### Generation
``` shell
cargo doc
```
### Open in browser
``` shell
cargo doc --open
```

View file

@ -0,0 +1,179 @@
---
date: 2020-09-18
id: 23e290f6-c964-4aee-a133-232291ecdba8
title: Tests in Rust
---
# Assertions
## assert!
``` rust
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
pub fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
pub struct Guess {
value: i32,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn larger_can_hold_smaller() {
let larger = Rectangle {
width: 8,
height: 7,
};
let smaller = Rectangle {
width: 5,
height: 1,
};
assert!(larger.can_hold(&smaller))
}
#[test]
fn smaller_cannot_hold_larger() {
let larger = Rectangle {
width: 8,
height: 7,
};
let smaller = Rectangle {
width: 5,
height: 1,
};
assert!(!smaller.can_hold(&larger))
}
}
```
## assert~eq~!
``` rust
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
```
# Results
## Contains
``` rust
pub fn greeting(name: &str) -> String {
format!("Hello {}!", name)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn greeting_contains_name() {
let result = greeting("Carrol");
assert!(
result.contains("Carrol"),
"Greeting did not countain name, value was `{}`",
result
)
}
}
```
# Annotations
## should~panic~
``` rust
pub struct Guess {
value: i32,
}
impl Guess {
pub fn new(value: i32) -> Guess {
if value < 1 {
panic!(
"Guess value must be greater than or equal to 1, got {}.",
value
);
} else if value > 100 {
panic!(
"Guess value must be less than or equal to 100, got {}.",
value
);
}
Guess { value }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic(expected = "Guess value must be less than or equal to 100")]
fn greater_than_100() {
Guess::new(200);
}
}
```
## ignore
This ignores tests unless specifically requested:
``` rust
#[test]
#[ignore]
fn expensive_test() {
// code that takes an hour to run
}
fn main() {}
```
# Integreation Tests
Integration tests are their own thing and I'm too lazy to take notes now
as it's 18:59 on a Friday. See relevant chapter in [the
book](https://doc.rust-lang.org/stable/book/ch11-03-test-organization.html)
for more information.
# Using Result \<T, E\> in Tests
This is possible for when you want to use the [question mark
operator](https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/the-question-mark-operator-for-easier-error-handling.html)
in your tests:
``` rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() -> Result<(), String> {
if 2 + 2 == 4 {
Ok(())
} else {
Err(String::from("two plus two does not equal four"))
}
}
}
```

View file

@ -0,0 +1,70 @@
---
date: 2020-09-21
id: ad20518c-1a42-4d02-8746-f42be6a46944
title: Golang Context
---
# Overview
Package context defines the Context type, which carries deadlines,
cancellation signals, and other request-scoped values across API
boundaries and between processes.
Incoming requests to a server should create a Context, and outgoing
calls to servers should accept a Context. The chain of function calls
between them must propagate the Context, optionally replacing it with a
derived Context created using WithCancel, WithDeadline, WithTimeout, or
WithValue. When a Context is canceled, all Contexts derived from it are
also canceled.
The WithCancel, WithDeadline, and WithTimeout functions take a Context
(the parent) and return a derived Context (the child) and a CancelFunc.
Calling the CancelFunc cancels the child and its children, removes the
parent's reference to the child, and stops any associated timers.
Failing to call the CancelFunc leaks the child and its children until
the parent is canceled or the timer fires. The go vet tool checks that
CancelFuncs are used on all control-flow paths.
Programs that use Contexts should follow these rules to keep interfaces
consistent across packages and enable static analysis tools to check
context propagation:
Do not store Contexts inside a struct type; instead, pass a Context
explicitly to each function that needs it. The Context should be the
first parameter, typically named ctx:
``` go
func DoSomething(ctx context.Context, arg Arg) error {
// ... use ctx ...
}
```
Do not pass a nil Context, even if a function permits it. Pass
context.TODO if you are unsure about which Context to use.
Use context Values only for request-scoped data that transits processes
and APIs, not for passing optional parameters to functions.
The same Context may be passed to functions running in different
goroutines; Contexts are safe for simultaneous use by multiple
goroutines.
See <https://blog.golang.org/context> for example code for a server that
uses Contexts.
# Googles take
> At Google, we require that Go programmers pass a Context parameter as
> the first argument to every function on the call path between incoming
> and outgoing requests. This allows Go code developed by many different
> teams to interoperate well. It provides simple control over timeouts
> and cancelation and ensures that critical values like security
> credentials transit Go programs properly.
# A saner take on this which I as a Go noob agree with
- Context should go away for Go 2[^1]
# Footnotes
[^1]: <https://faiface.github.io/post/context-should-go-away-go2/>

View file

@ -0,0 +1,16 @@
---
date: 2020-09-22
id: 53649586-d844-427a-a91b-0a353631cedc
title: JavaScript Destructuring
---
# Variants
- [Destructuring Arrays](20201103111509-destructuring_arrays)
- [Destructuring Objects](20201103111746-destructuring_objects)
- [Destructuring Iterables](20201103112001-destructuring_iterables)
# Default values
- [Destructuring Default
Values](20201103113124-destructuring_default_values)

View file

@ -0,0 +1,12 @@
---
date: 2020-09-22
id: d30a86d5-3788-47d0-a749-08e7edce2efd
title: JavaScript Parameter default values
---
# ES6
``` javascript
function foo(x=0, y=0) {
}
```

View file

@ -0,0 +1,26 @@
---
date: 2020-09-22
id: dedc9e64-fe57-4c60-95b9-7df6201f4949
title: JavaScript Named parameters
---
# Introduction
Introduced with [ES6](20201030093404-es6)
# Syntax
``` javascript
function selectEntries({ start=0, end=-1, step=1 } = {}) {
console.log(start)
console.log(end)
console.log(step)
}
selectEntries()
```
# See also
- [Rest Operator (…) in Object
Destructuring](20201103111357-rest_operator_in_object_destructuring)

View file

@ -0,0 +1,32 @@
---
date: 2020-09-22
id: 4236e165-bf8b-45fd-9a4c-6cbb66916c45
title: JavaScript Rest Parameters
---
# Introduction
Introduced in [ES6](20201030093404-es6)
# Syntax
``` javascript
function logAllArguments(...args) {
for (const arg of args) {
console.log(arg);
}
}
logAllArguments(1, 2, 3)
```
``` javascript
function logAllArguments(pattern, ...args) {
console.log(pattern)
for (const arg of args) {
console.log(arg);
}
}
logAllArguments("asdf", 1, 2, 3)
```

View file

@ -0,0 +1,24 @@
---
date: 2020-09-22
id: c613c25d-3bbe-45ca-9034-b7d602770cea
title: JavaScript Numbers
---
# Numbers
- [Fractional Numbers](20201116163755-fractional_numbers)
# Notations
- [Scientific Notation](20201116163844-scientific_notation)
- [Binary Notation](20201116164748-binary_notation)
- [Octal Notation](20201116164828-octal_notation)
# Special Numbers
- [Infinity](20201116163925-infinity)
- [NaN](20201116164007-nan)
# Size
JavaScript uses 64 bits to store number values

View file

@ -0,0 +1,31 @@
---
date: 2020-09-22
id: 02b70a4e-8f42-4de2-a536-dd42a42f7b47
title: JavaScript Strings
---
- [String Prototype
Methods](20201112095341-javascript_string_prototype_methods)
- [String Literals](20201112100548-javascript_string_literals)
- [String Escapes](20201112101218-javascript_string_escapes)
- [Unicode](20201112101637-unicode)
- [String Iteration](20201112101851-javascript_string_iteration)
- [String To Array
Conversion](20201112102537-javascript_string_to_array_conversion)
# Syntax
## Regular characters
``` javascript
console.log(`Down on the sea`)
console.log("Lie on the ocean")
console.log('Float on the ocean')
```
## Escaped characters
``` javascript
console.log("This is the first line\nAnd this is the second")
console.log("A newline character is written like \"\\n\".")
```

View file

@ -0,0 +1,40 @@
---
date: 2020-09-22
id: 19822398-201e-426a-86f0-48ef5a09acda
title: JavaScript Booleans
---
# Syntax
``` javascript
console.log(3 > 2)
console.log(3 < 2)
```
Strings can also be compared
``` javascript
console.log("Aardvark" < "Zoroaster")
```
Uppercase characters are always less than lower case characters, so "Z"
\< "a". Non alphabetic characters are less than alphabetic characters
``` javascript
console.log("Zebra" < "aardvark")
console.log("!" < "aardvark")
console.log("!" < "Zebra")
console.log("3" < "Zebra")
console.log("!" < "3")
```
## Empty values
There are two special empty values, null & undefined that denote the
absence of any meaningful value. They can be used interchangeably and
are an [accident of JavaScripts
design](https://medium.com/@stephenthecurt/a-brief-history-of-null-and-undefined-in-javascript-c283caab662e).
``` javascript
console.log(null == undefined);
```

View file

@ -0,0 +1,16 @@
---
date: 2020-09-22
id: e250130b-d112-4557-8ac1-77f40608d22c
title: Empty values
---
# Syntax
There are two special empty values, null & undefined that denote the
absence of any meaningful value. They can be used interchangeably and
are an [accident of JavaScripts
design](https://medium.com/@stephenthecurt/a-brief-history-of-null-and-undefined-in-javascript-c283caab662e).
``` javascript
console.log(null == undefined);
```

View file

@ -0,0 +1,45 @@
---
date: 2020-09-23
id: 8353cf5c-2d2d-480a-b957-0e90da847e1c
title: Rust Closures
---
# Syntax
## Long
``` rust
fn main() {
let double_closure = |num: u32| -> u32 { 2 * num };
println!("2 times 3 = {}", double_closure(3));
}
```
## Abbreviated
``` rust
fn main() {
let double_closure = |num| 2 * num;
println!("2 times 3 = {}", double_closure(3));
}
```
# Closure variable scope
Unlike [Rust functions](20200827170931-functions_macros) Closures can
capture their environment and access variables from the scope in which
they're defined:
``` rust
fn main() {
let x = 4;
let equal_to_x = |z| z == x;
let y = 4;
assert!(equal_to_x(y));
}
```

View file

@ -0,0 +1,141 @@
---
date: 2020-09-23
id: a01bfc26-dece-4741-829b-d164ba9522bb
title: Rust Iterators
---
# Syntax
``` rust
fn main() {
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
for val in v1_iter {
println!("Got: {}", val);
}
}
```
# Iterator Trait
All iterators implement a [trait](20200917163203-traits) named
[Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html)
``` rust
#![allow(unused)]
fn main() {
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
// methods with default implementations elided
}
}
```
# Iterator methods
## next
``` rust
#[cfg(test)]
mod tests {
#[test]
fn iterator_demonstration() {
let v1 = vec![1, 2, 3];
let mut v1_iter = v1.iter();
assert_eq!(v1_iter.next(), Some(&1));
assert_eq!(v1_iter.next(), Some(&2));
assert_eq!(v1_iter.next(), Some(&3));
assert_eq!(v1_iter.next(), None);
}
}
fn main() {}
```
## sum
``` rust
#[cfg(test)]
mod tests {
#[test]
fn iterator_sum() {
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
let total: i32 = v1_iter.sum();
assert_eq!(total, 6);
}
}
fn main() {}
```
# Methods that produce other Iterators
By their nature iterators are lazy so the following won't work:
``` rust
fn main() {
let v1: Vec<i32> = vec![1, 2, 3];
v1.iter().map(|x| x + 1);
}
```
The Iterator must be consumed, using the
[collect](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect)
method:
``` rust
fn main() {
let v1: Vec<i32> = vec![1, 2, 3];
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
assert_eq!(v2, vec![2, 3, 4]);
}
```
# Creating your own Iterators
``` rust
struct Counter {
count: u32,
}
impl Counter {
fn new() -> Counter {
Counter { count: 0 }
}
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.count < 5 {
self.count += 1;
Some(self.count)
} else {
None
}
}
}
fn main() {
let counter = Counter::new();
for val in counter {
println!("Got: {}", val);
}
}
```

View file

@ -0,0 +1,40 @@
---
date: 2020-09-23
id: adb898a3-6623-4bd5-92e6-408287d8cb31
title: JavaScript Number library
---
# ES6
## .EPSILON
Compares floating point numbers with a tolerance for rounding errors.
## .isInteger(num)
``` javascript
console.log(Number.isInteger(1.05)) // false
console.log(Number.isInteger(1)) // true
console.log(Number.isInteger(-3.1)) // false
console.log(Number.isInteger(-3)) // true
```
## .isNaN
Checks whether num is the value NaN. In contrast to the global function
isNaN(), it doesnt coerce its argument to a number and is therefore
safer for non-numbers:
``` javascript
console.log(isNaN('???')) // true
console.log(Number.isNaN('???')) // false
```
## .isFinite
Determines whether the passed value is a finite number
``` javascript
console.log(Number.isFinite(Infinity)) // false
console.log(Number.isFinite(123)) // true
```

View file

@ -0,0 +1,43 @@
---
date: 2020-09-23
id: 1accac75-7a5c-4847-977a-f0ae63454820
title: JavaScript Math library
---
# ES6
## .sign(x)
### Returns
- -1 if x is a negative number (including -Infinity).
- 0 if x is zero4.
- +1 if x is a positive number (including Infinity).
- NaN if x is NaN or not a number.
``` javascript
console.log(Math.sign(-8)) // -a
console.log(Math.sign(3)) // 1
console.log(Math.sign(0)) // 0
console.log(Math.sign(NaN)) // NaN
console.log(Math.sign(-Infinity)) // -1
console.log(Math.sign(Infinity)) // 1
```
## .trunc(x)
``` javascript
console.log(Math.trunc(3.1)) // 3
console.log(Math.trunc(3.9)) // 3
console.log(Math.trunc(-3.1)) // 3
console.log(Math.trunc(-3.9)) // 3
```
## .cbrt(x)
Returns the cube root of x:
``` javascript
console.log(Math.cbrt(8)) // 2
console.log(Math.cbrt(27)) // 3
```

View file

@ -0,0 +1,47 @@
---
date: 2020-09-28
id: 8f08356d-b0dc-465b-b7f5-5522b5133916
title: Golang Embedding
---
# Description
[Embedding](https://golang.org/doc/effective_go.html#embedding) is Gos
answer to subclasses. There's one caveat:
> There's an important way in which embedding differs from subclassing.
> When we embed a type, the methods of that type become methods of the
> outer type, but when they are invoked the receiver of the method is
> the inner type, not the outer one.
# Interfaces
``` go
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type ReadWriter interface {
Reader
Writer
}
```
`ReadWriter` "extends" `Reader` & `Writer` in the example above.
# Structs
``` go
type ReadWriter struct {
*Reader // *bufio.Reader
*Writer // *bufio.Writer
}
func (rw *ReadWriter) Read(p []byte) (n int, err error) {
return rw.reader.Read(p)
}
```

View file

@ -0,0 +1,86 @@
---
date: 2020-09-29
id: d20e0dd7-ac1d-4dbb-b4e7-a6780b77bd69
title: Box\<T\>
---
# Introduction
Boxes allow you to store data on the heap rather than the stack. What
remains on the stack is the pointer to the heap data.
Boxes dont have performance overhead, other than storing their data on
the heap instead of on the stack. But they dont have many extra
capabilities either. There are three typical user cases for Boxes:
- When you have a type whose size cant be known at compile time and
you want to use a value of that type in a context that requires an
exact size
- When you have a large amount of data and you want to transfer
ownership but ensure the data wont be copied when you do so
- When you want to own a value and you care only that its a type that
implements a particular trait rather than being of a specific type
``` rust
fn main() {
let b = Box::new(5);
println!("b = {}", b);
}
```
# Reason to choose Box\<T\>
`Box<T>` allows immutable or mutable borrows checked at compile time;
[Rc\<T\>](20200929145534-rc_t) allows only immutable borrows checked at
compile time; [RefCell\<T\>](20200929152628-refcell_t) allows immutable
or mutable borrows checked at runtime.
# Usercases
## Type whose size can't be known at compile time
When you have a type whose size cant be known at compile time and you
want to use a value of that type in a context that requires an exact
size.
The following won't compile as the `List` type doesn't have a known
size:
``` rust
enum List {
Cons(i32, List),
Nil,
}
fn main() {}
```
This won't fly either:
``` rust
enum List {
Cons(i32, List),
Nil,
}
use crate::List::{Cons, Nil};
fn main() {
let list = Cons(1, Cons(2, Cons(3, Nil)));
}
```
With pointers all things are possible, huzzah:
``` rust
enum List {
Cons(i32, Box<List>),
Nil,
}
use crate::List::{Cons, Nil};
fn main() {
let _list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
}
```

View file

@ -0,0 +1,109 @@
---
date: 2020-09-29
id: d2d028c8-733f-4cdb-b096-89cf8b3de961
title: Deref Trait
---
# Introduction
Implementing the `Deref` trait allows you to customize the behavior of
the *dereference operator*, \* (as opposed to the multiplication or glob
operator). By implementing `Deref` in such a way that a smart pointer
can be treated like a regular reference, you can write code that
operates on references and use that code with smart pointers too:
``` rust
fn main() {
let x = 5;
let y = &x;
assert_eq!(5, x);
assert_eq!(5, *y);
}
```
# Box
A [Box\<T\>](20200929135609-box_t) can also be used:
``` rust
fn main() {
let x = 5;
let y = Box::new(x);
assert_eq!(5, x);
assert_eq!(5, *y);
}
```
# Deref Trait
``` rust
use std::ops::Deref;
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
struct MyBox<T>(T);
impl<T> MyBox<T> {
fn new(x: T) -> MyBox<T> {
MyBox(x)
}
}
fn main() {
let x = 5;
let y = MyBox::new(x);
assert_eq!(5, x);
assert_eq!(5, *y);
}
```
# Deref Coercion
*Deref coercion* is a convenience that Rust performs on arguments to
functions and methods. Deref coercion works only on types that implement
the Deref trait. Deref coercion converts such a type into a reference to
another type. For example, deref coercion can convert `&String` to
`&str` because `String` implements the `Deref` trait such that it
returns `str`. Deref coercion happens automatically when we pass a
reference to a particular types value as an argument to a function or
method that doesnt match the parameter type in the function or method
definition. A sequence of calls to the `deref` method converts the type
we provided into the type the parameter needs.
``` rust
use std::ops::Deref;
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
struct MyBox<T>(T);
impl<T> MyBox<T> {
fn new(x: T) -> MyBox<T> {
MyBox(x)
}
}
fn hello(name: &str) {
println!("Hello, {}!", name);
}
fn main() {
let m = MyBox::new(String::from("Rust"));
hello(&m);
}
```

View file

@ -0,0 +1,34 @@
---
date: 2020-09-29
id: a5820942-f47a-4a5e-ba83-33916cc24674
title: Drop Trait
---
# Introduction
`Drop` lets you customize what happens when a value is about to go out
of scope, ie: to release resources like files or network connections.
# Example
``` rust
struct CustomSmartPointer {
data: String,
}
impl Drop for CustomSmartPointer {
fn drop(&mut self) {
println!("Dropping CustomSmartPointer with data `{}`!", self.data);
}
}
fn main() {
let _c = CustomSmartPointer {
data: String::from("my stuff"),
};
let _d = CustomSmartPointer {
data: String::from("other stuff"),
};
println!("CustomSmartPointers created.");
}
```

View file

@ -0,0 +1,63 @@
---
date: 2020-09-29
id: 13459bc1-66f2-4eed-b987-061bd0fbeb1c
title: Rc\<T\>
---
# Introduction
In the majority of cases, ownership is clear: you know exactly which
variable owns a given value. However, there are cases when a single
value might have multiple owners. For example, in graph data structures,
multiple edges might point to the same node, and that node is
conceptually owned by all of the edges that point to it. A node
shouldnt be cleaned up unless it doesnt have any edges pointing to it.
To enable multiple ownership, Rust has a type called `Rc<T>`, which is
an abbreviation for reference counting. The `Rc<T>` type keeps track of
the number of references to a value which determines whether or not a
value is still in use. If there are zero references to a value, the
value can be cleaned up without any references becoming invalid.
# Reason to choose Rc\<T\>
`Rc<T>` enables multiple owners of the same data;
[Box\<T\>](20200929135609-box_t) and
[RefCell\<T\>](20200929152628-refcell_t) have single owners.
# Example
This won't compile because b & c both share ownership of a:
``` rust
enum List {
Cons(i32, Box<List>),
Nil,
}
use crate::List::{Cons, Nil};
fn main() {
let a = Cons(5, Box::new(Cons(10, Box::new(Nil))));
let _b = Cons(3, Box::new(a));
let _c = Cons(4, Box::new(a));
}
```
The solution:
``` rust
enum List {
Cons(i32, Rc<List>),
Nil,
}
use crate::List::{Cons, Nil};
use std::rc::Rc;
fn main() {
let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
let _b = Cons(3, Rc::clone(&a));
let _c = Cons(4, Rc::clone(&a));
}
```

View file

@ -0,0 +1,63 @@
---
date: 2020-09-29
id: 16e7cc98-b9fb-40c3-b2cf-41d3035275be
title: RefCell\<T\>
---
# Introduction
*Interior mutability* is a design pattern in Rust that allows you to
mutate data even when there are immutable references to that data;
normally, this action is disallowed by the borrowing rules. To mutate
data, the pattern uses `unsafe` code inside a data structure to bend
Rusts usual rules that govern mutation and borrowing. We can use types
that use the interior mutability pattern when we can ensure that the
borrowing rules will be followed at runtime, even though the compiler
cant guarantee that. The `unsafe` code involved is then wrapped in a
safe API, and the outer type is still immutable.
# Reason to choose RefCell\<T\>
Because `RefCell<T>` allows mutable borrows checked at runtime, you can
mutate the value inside the `RefCell<T>` even when the `RefCell<T>` is
immutable.
# Example
This won't compile:
``` rust
fn main() {
let x = 5;
let y = &mut x;
}
```
This will:
``` rust
#[derive(Debug)]
enum List {
Cons(Rc<RefCell<i32>>, Rc<List>),
Nil,
}
use crate::List::{Cons, Nil};
use std::cell::RefCell;
use std::rc::Rc;
fn main() {
let value = Rc::new(RefCell::new(5));
let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil)));
let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a));
let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a));
*value.borrow_mut() += 10;
println!("a after = {:?}", a);
println!("b after = {:?}", b);
println!("c after = {:?}", c);
}
```

View file

@ -0,0 +1,49 @@
---
date: 2020-09-29
id: 89671783-1085-4a00-9147-a377db9b19bc
title: TypeScript
---
# Basic Annotations
- [Primitive Types](20200929161544-primitive_types)
- [Arrays](20200929162129-arrays)
- [Inline Type Annotation](20200929162417-inline_type_annotation)
# Type System
- [Ambient Declarations](20200930105954-ambient_declarations)
- [Interfaces](20200929162220-interfaces)
- [Enums](20200930110721-typescript_enums)
- [lib.d.ts](20201001105545-lib_d_ts)
- [Functions](20201001110806-typescript_functions)
- [Callable](20201001112126-typescript_callable)
- [Type Assertion](20201002101745-typescript_type_assertion)
- [Type Guard](20201002102455-typescript_type_guard)
- [Literal Types](20201002103357-typescript_literal_types)
- [Readonly](20201005171253-readonly)
- [Generics](20200929163051-typescript_generics)
- [Intersection Type](20200929163316-typescript_intersection_type)
- [Tuple Type](20200929163624-typescript_tuple_type)
- [TypeScript Type Alias](20200929163825-typescript_type_alias)
- [Never Type](20201007095614-typescript_never_type)
- [Index Signatures](20201008092225-index_signatures)
- [Classes](20201009104411-typescript_classes)
## Unions
- [Union Type](20200929163219-typescript_union_type)
- [Discriminated Union](20201007101133-typescript_discriminated_union)
# Related pages
- [JavaScript](20200613170905-javascript)
# Books
- [TypeScript Deep Dive](https://basarat.gitbook.io/typescript/)
- [Style Guide](https://basarat.gitbook.io/typescript/styleguide)
# Changes
- [TypeScript 4.0](20201009104050-typescript_4_0)

View file

@ -0,0 +1,67 @@
---
date: 2020-09-29
id: 547d6700-cedd-4273-9f12-1fd4da96b695
title: TypeScript
---
# Types
- [Arrays](20200929162129-arrays)
- [Enums](20200930110721-typescript_enums)
- [Generics](20200929163051-typescript_generics)
- [Intersection Type](20200929163316-typescript_intersection_type)
- [Literal Types](20201002103357-typescript_literal_types)
- [Mapped Type](20201124085335-typescript_mapped_type)
- [Never Type](20201007095614-typescript_never_type)
- [Primitive Types](20200929161544-primitive_types)
- [Recursive Conditional
Types](20201125085727-typescript_recursive_conditional_types)
- [Tuple Type](20200929163624-typescript_tuple_type)
- [Union Type](20200929163219-typescript_union_type)
# Objects
- [Classes](20201009104411-typescript_classes)
- [Inline Type Annotation](20200929162417-inline_type_annotation)
- [Interfaces](20200929162220-interfaces)
# Functions
- [Functions](20201001110806-typescript_functions)
# Declarations
- [Ambient Declarations](20200930105954-ambient_declarations)
- [lib.d.ts](20201001105545-lib_d_ts)
# Syntax
- [Callable](20201001112126-typescript_callable)
- [Discriminated Union](20201007101133-typescript_discriminated_union)
- [Index Signatures](20201008092225-index_signatures)
- [Readonly](20201005171253-readonly)
- [Type Alias](20200929163825-typescript_type_alias)
- [Type Assertion](20201002101745-typescript_type_assertion)
- [Type Guard](20201002102455-typescript_type_guard)
# Clauses
- [as](20201124095453-typescript_as_clause)
# Keywords
- [in](20201124090450-typescript_in_operator)
# Configuration
- [Flags](20201127101043-typescript_flags)
# Books
- [TypeScript Deep Dive](https://basarat.gitbook.io/typescript/)
- [Style Guide](https://basarat.gitbook.io/typescript/styleguide)
# Changes
- [4.0](20201009104050-typescript_4_0)
- [4.1](20201123094735-typescript_4_1)

View file

@ -0,0 +1,35 @@
---
date: 2020-09-29
id: 8809980a-615d-453f-bc63-2f890fca03b8
title: TypeScript primitive types
---
# Syntax
## Number
``` typescript
var num: number
num = 123
num = 123.24
num = '123' / Error
```
## String
``` typescript
var str: string
str = '123'
str = 123 // Error
```
## Boolean
``` typescript
var bool: boolean
bool = true
bool = false
bool = 'tralala' // Error
```

View file

@ -0,0 +1,21 @@
---
date: 2020-09-29
id: aea39282-589d-49ab-8b50-c55c7681f500
title: TypeScript Arrays
---
# Syntax
``` typescript
var boolArray: boolean[];
boolArray = [true, false];
console.log(boolArray[0]); // true
console.log(boolArray.length); // 2
boolArray[1] = true;
boolArray = [false, false];
boolArray[0] = 'false'; // Error!
boolArray = 'false'; // Error!
boolArray = [true, 'false']; // Error!
```

View file

@ -0,0 +1,40 @@
---
date: 2020-09-29
id: 1bdd832a-3dee-4b31-9192-c51cde8a4b66
title: TypeScript Interfaces
---
# Example
``` typescript
interface Name {
first: string;
second: string;
}
var name: Name;
name = {
first: 'John',
second: 'Doe'
};
name = { // Error : `second` is missing
first: 'John'
};
name = { // Error : `second` is the wrong type
first: 'John',
second: 1337
};
```
## Class implementing interface
``` typescript
interface Point {
x: number; y: number;
}
class MyPoint implements Point {
x: number; y: number; // Same as Point
}
```

View file

@ -0,0 +1,26 @@
---
date: 2020-09-29
id: 01e5c8e4-5227-4565-96e5-94a4bb6240ea
title: TypeScript Inline Type Annotation
---
# Syntax
``` typescript
var name: {
first: string;
second: string;
};
name = {
first: 'John',
second: 'Doe'
};
name = { // Error : `second` is missing
first: 'John'
};
name = { // Error : `second` is the wrong type
first: 'John',
second: 1337
};
```

View file

@ -0,0 +1,60 @@
---
date: 2020-09-29
id: aacdac15-4e00-4d75-9888-79b23bb47498
title: TypeScript Generics
---
# Examples
## Function level
``` typescript
function reverse<T>(items: T[]): T[] {
var toreturn = [];
for (let i = items.length - 1; i >= 0; i--) {
toreturn.push(items[i]);
}
return toreturn;
}
var sample = [1, 2, 3];
var reversed = reverse(sample);
console.log(reversed); // 3,2,1
// Safety!
reversed[0] = '1'; // Error!
reversed = ['1', '2']; // Error!
reversed[0] = 1; // Okay
reversed = [1, 2]; // Okay
```
## Class level
``` typescript
/** A class definition with a generic parameter */
class Queue<T> {
private data = [];
push(item: T) { this.data.push(item); }
pop(): T | undefined { return this.data.shift(); }
}
/** Again sample usage */
const queue = new Queue<number>();
queue.push(0);
queue.push("1"); // ERROR : cannot push a string. Only numbers allowed
```
## Member functions
``` typescript
class Utility {
reverse<T>(items: T[]): T[] {
var toreturn = [];
for (let i = items.length - 1; i >= 0; i--) {
toreturn.push(items[i]);
}
return toreturn;
}
}
```

Some files were not shown because too many files have changed in this diff Show more