diff options
author | EuAndreh <eu@euandre.org> | 2024-11-17 19:49:05 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2024-11-17 19:49:05 -0300 |
commit | 08c9bcb3fed37d9483258bd97aaebc47b54b3fa3 (patch) | |
tree | 7b114f79c44d347a5ecd1082943d2ba8c95dac5c /v2/src/content/en | |
parent | mv src/content/styles.css src/content/style.css (diff) | |
download | euandre.org-08c9bcb3fed37d9483258bd97aaebc47b54b3fa3.tar.gz euandre.org-08c9bcb3fed37d9483258bd97aaebc47b54b3fa3.tar.xz |
rm -rf v2/
Diffstat (limited to '')
-rw-r--r-- | v2/src/content/en/about.page | 7 | ||||
-rw-r--r-- | v2/src/content/en/pastebin/guix-shebang.md | 15 | ||||
-rw-r--r-- | v2/src/content/en/pastebin/raku-tuple-type-annotation.md | 33 | ||||
-rw-r--r-- | v2/src/content/en/pastebin/sicp-exercise-3-19.md | 109 | ||||
-rw-r--r-- | v2/src/content/en/remembering-ann.md | 186 | ||||
-rw-r--r-- | v2/src/content/en/slide/local-first.ps | 522 | ||||
-rw-r--r-- | v2/src/content/en/slide/local-first.slides | 204 | ||||
-rw-r--r-- | v2/src/content/en/slide/rollouts.ps | 500 | ||||
-rw-r--r-- | v2/src/content/en/slide/rollouts.slides | 208 | ||||
-rw-r--r-- | v2/src/content/en/til/lisp-three-way-conditional.md | 59 |
10 files changed, 0 insertions, 1843 deletions
diff --git a/v2/src/content/en/about.page b/v2/src/content/en/about.page deleted file mode 100644 index aac3e67..0000000 --- a/v2/src/content/en/about.page +++ /dev/null @@ -1,7 +0,0 @@ ---- - -title: About - ---- - -It's all about me, baby! diff --git a/v2/src/content/en/pastebin/guix-shebang.md b/v2/src/content/en/pastebin/guix-shebang.md deleted file mode 100644 index 5be9ada..0000000 --- a/v2/src/content/en/pastebin/guix-shebang.md +++ /dev/null @@ -1,15 +0,0 @@ ---- - -title: Guix shebang - -date: 2020-02-14 - ---- - -```shell -#!/usr/bin/env -S guix environment --ad-hoc bash -- bash -set -Eeuo pipefail -cd "$(dirname "${BASH_SOURCE[0]}")" - -pwd -``` diff --git a/v2/src/content/en/pastebin/raku-tuple-type-annotation.md b/v2/src/content/en/pastebin/raku-tuple-type-annotation.md deleted file mode 100644 index 6c13b39..0000000 --- a/v2/src/content/en/pastebin/raku-tuple-type-annotation.md +++ /dev/null @@ -1,33 +0,0 @@ ---- - -title: Raku tuple type annotation - -date: 2019-12-29 - -categories: raku programming-languages - ---- - -```perl -# Single Str return value: this works -sub f1(Str $in --> Str) { - $in; -} - -# Tuple of Str as return value: this works -sub f2(Str $in) { - ($in, $in); -} - -# Tuple of Str as return value with type annotation: this doesn't works -sub f2(Str $in --> (Str, Str)) { - ($in, $in); -} -``` - -Error log is: - -```perl -===SORRY!=== Error while compiling /path/to/my/file -Malformed return value -``` diff --git a/v2/src/content/en/pastebin/sicp-exercise-3-19.md b/v2/src/content/en/pastebin/sicp-exercise-3-19.md deleted file mode 100644 index 32f7aa9..0000000 --- a/v2/src/content/en/pastebin/sicp-exercise-3-19.md +++ /dev/null @@ -1,109 +0,0 @@ ---- - -title: SICP exercise 3.19 - -date: 2021-09-02 - -categories: lisp programming-languages - ---- - -Some content here, before: - -```scheme -(define (cycle? l) - (define (rec l x) - (cond - ((null? x) false) - ((eq? l x) true) - (true (rec l (cdr x))))) - (rec l (cdr l))) -``` - -Sample interactive session: - -```scheme -scheme@(guile-user)> (define true #t) -scheme@(guile-user)> (define false #f) -scheme@(guile-user)> -(define (cycle? l) - (define (rec l x) - (cond - ((null? x) false) - ((eq? l x) true) - (true (rec l (cdr x))))) - (rec l (cdr l))) -scheme@(guile-user)> (cycle? '(1 2 3)) -$9 = #f -scheme@(guile-user)> (cycle? (make-cycle '(1 2 3))) -$10 = #t -``` - -# An h1 - -a list: - -1. one -2. two -3. three - -some content. - -- item -- another -- yet another - -## An h2 - -Xablau: - -``` -xupliu 1 - -3 -4 - - - - - -dez -``` - -Foi `wikiwiu`. - -a very long code block: - -``` -wef -wef wef wef wef -wef wef wef wef we fwef wef wef wef wef -``` - -Someone said: - -> Xablau, xupliu. - -### A repeated header -### A repeated header - -a big list: - -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a -1. a diff --git a/v2/src/content/en/remembering-ann.md b/v2/src/content/en/remembering-ann.md deleted file mode 100644 index 9013ad4..0000000 --- a/v2/src/content/en/remembering-ann.md +++ /dev/null @@ -1,186 +0,0 @@ ---- - -title: ANN: remembering - Add memory to dmenu, fzf and similar tools - -date: 2021-01-26 - -categories: ann - ---- - -Today I pushed v0.1.0 of [remembering][remembering], a tool to enhance the interactive usability of menu-like tools, such as [dmenu][dmenu] and [fzf][fzf]. - -## Previous solution - -I previously used [yeganesh][yeganesh] fill this gap, but as I started to rely less on Emacs, I added fzf as my go-to tool for doing fuzzy searching on the terminal. -But I didn't like that fzf always showed the same order of things, when I would only need 3 or 4 commonly used files. - -For those who don't know: yeganesh is a wrapper around dmenu that will remember your most used programs and put them on the beginning of the list of executables. -This is very convenient for interactive prolonged use, as with time the things you usually want are right at the very beginning. - -But now I had this thing, yeganesh, that solved this problem for dmenu, but didn't for fzf. - -I initially considered patching yeganesh to support it, but I found it more coupled to dmenu than I would desire. -I'd rather have something that knows nothing about dmenu, fzf or anything, but enhances tools like those in a useful way. - -[remembering]: https://euandreh.xyz/remembering/ -[dmenu]: https://tools.suckless.org/dmenu/ -[fzf]: https://github.com/junegunn/fzf -[yeganesh]: http://dmwit.com/yeganesh/ - -## Implementation - -Other than being decoupled from dmenu, another improvement I though that could be made on top of yeganesh is the programming language choice. -Instead of Haskell, I went with POSIX sh. -Sticking to POSIX sh makes it require less build-time dependencies. There aren't any, actually. Packaging is made much easier due to that. - -The good thing is that the program itself is small enough ([119 lines][119-lines] on v0.1.0) that POSIX sh does the job just fine, combined with other POSIX utilities such as [getopts][getopts], [sort][sort] and [awk][awk]. - -[119-lines]: https://euandre.org/git/remembering/tree/remembering?id=v0.1.0 -[getopts]: http://www.opengroup.org/onlinepubs/9699919799/utilities/getopts.html -[sort]: http://www.opengroup.org/onlinepubs/9699919799/utilities/sort.html -[awk]: http://www.opengroup.org/onlinepubs/9699919799/utilities/awk.html - -The behaviour is: given a program that will read from STDIN and write a single entry to STDOUT, `remembering` wraps that program, and rearranges STDIN so that previous choices appear at the beginning. - -Where you would do: - -```shell -$ seq 5 | fzf - - 5 - 4 - 3 - 2 -> 1 - 5/5 -> -``` - -And every time get the same order of numbers, now you can write: - -```shell -$ seq 5 | remembering -p seq-fzf -c fzf - - 5 - 4 - 3 - 2 -> 1 - 5/5 -> -``` - -On the first run, everything is the same. If you picked 4 on the previous example, the following run would be different: - -```shell -$ seq 5 | remembering -p seq-fzf -c fzf - - 5 - 3 - 2 - 1 -> 4 - 5/5 -> -``` - -As time passes, the list would adjust based on the frequency of your choices. - -I aimed for reusability, so that I could wrap diverse commands with `remembering` and it would be able to work. To accomplish that, a "profile" (the `-p something` part) stores data about different runs separately. - -I took the idea of building something small with few dependencies to other places too: -- the manpages are written in troff directly; -- the tests are just more POSIX sh files; -- and a POSIX Makefile to `check` and `install`. - -I was aware of the value of sticking to coding to standards, but I had past experience mostly with programming language standards, such as ECMAScript, Common Lisp, Scheme, or with IndexedDB or DOM APIs. -It felt good to rediscover these nice POSIX tools, which makes me remember of a quote by [Henry Spencer][poor-unix]: - -> Those who do not understand Unix are condemned to reinvent it, poorly. - -[poor-unix]: https://en.wikipedia.org/wiki/Henry_Spencer#cite_note-3 - -## Usage examples - -Here are some functions I wrote myself that you may find useful: - -### Run a command with fzf on `$PWD` - -```shellcheck -f() { - profile="$f-shell-function(pwd | sed -e 's_/_-_g')" - file="$(git ls-files | \ - remembering -p "$profile" \ - -c "fzf --select-1 --exit -0 --query \"$2\" --preview 'cat {}'")" - if [ -n "$file" ]; then - # shellcheck disable=2068 - history -s f $@ - history -s "$1" "$file" - "$1" "$file" -fi -} -``` - -This way I can run `f vi` or `f vi config` at the root of a repository, and the list of files will always appear on the most used order. -Adding `pwd` to the profile allows it to not mix data for different repositories. - -### Copy password to clipboard - -```shell -choice="$(find "$HOME/.password-store" -type f | \ - grep -Ev '(.git|.gpg-id)' | \ - sed -e "s|$HOME/.password-store/||" -e 's/\.gpg$//' | \ - remembering -p password-store \ - -c 'dmenu -l 20 -i')" - - -if [ -n "$choice" ]; then - pass show "$choice" -c -fi -``` - -Adding the above to a file and binding it to a keyboard shortcut, I can access the contents of my [password store][password-store], with the entries ordered by usage. - -[password-store]: https://www.passwordstore.org/ - -### Replacing yeganesh - -Where I previously had: - -```shell -exe=$(yeganesh -x) && exec $exe -``` - -Now I have: - -```shell -exe=$(dmenu_path | remembering -p dmenu-exec -c dmenu) && exec $exe -``` - -This way, the executables appear on order of usage. - -If you don't have `dmenu_path`, you can get just the underlying `stest` tool that looks at the executables available in your `$PATH`. Here's a juicy one-liner to do it: - -```shell -$ wget -O- https://dl.suckless.org/tools/dmenu-5.0.tar.gz | \ - tar Ozxf - dmenu-5.0/arg.h dmenu-5.0/stest.c | \ - sed 's|^#include "arg.h"$|// #include "arg.h"|' | \ - cc -xc - -o stest -``` - -With the `stest` utility you'll be able to list executables in your `$PATH` and pipe them to dmenu or something else yourself: -```shell -$ (IFS=:; ./stest -flx $PATH;) | sort -u | remembering -p another-dmenu-exec -c dmenu | sh -``` - -In fact, the code for `dmenu_path` is almost just like that. - -## Conclusion - -For my personal use, I've [packaged] `remembering` for GNU Guix and Nix. Packaging it to any other distribution should be trivial, or just downloading the tarball and running `[sudo] make install`. - -Patches welcome! - -[packaged]: https://euandre.org/git/package-repository/ -[nix-file]: https://euandre.org/git/dotfiles/tree/nixos/not-on-nixpkgs/remembering.nix?id=0831444f745cf908e940407c3e00a61f6152961f diff --git a/v2/src/content/en/slide/local-first.ps b/v2/src/content/en/slide/local-first.ps deleted file mode 100644 index 44c5858..0000000 --- a/v2/src/content/en/slide/local-first.ps +++ /dev/null @@ -1,522 +0,0 @@ -%!PS-Adobe-3.0 -%%DocumentMedia: SLIDE 842 595 0 () () -%%EndComments -%%BeginDefaults -%%PageMedia: SLIDE -%%EndDefaults -<< /PageSize [842 595] /ImagingBBox null >> setpagedevice - -/reencode { - exch - findfont - dup length dict - begin - { - 1 index /FID ne - { def } - { pop pop } - ifelse - } forall - /Encoding ISOLatin1Encoding def - currentdict - end - definefont pop -} def -/Courier /Courier reencode -/Helvetica /Helvetica reencode -/Times /Times reencode -/Times-Italic /Times-Italic reencode - - -/headerheight 77 def - -/frontfontsz 60 def -/authorfontsz 40 def -/titlefontsz 40 def -/mainfontsz 30 def -/codefontsz 18 def -/tinyfontsz 18 def - -/titlefont /Helvetica findfont titlefontsz scalefont def -/mainfont /Courier findfont mainfontsz scalefont def -/codefont /Courier findfont codefontsz scalefont def -/tinyfont /Times findfont tinyfontsz scalefont def -/frontfont /Helvetica findfont frontfontsz scalefont def -/authorfont /Times-Italic findfont authorfontsz scalefont def -/authorfonttwo /Times findfont authorfontsz scalefont def - - -/pagewidth 842 def -/pageheight 595 def -/leftmargin 30 def -/topmargin 595 def - -/pad 10 def - -/titlefonth titlefontsz pad add def -/mainfonth mainfontsz pad add def -/codefonth codefontsz pad add def -/tinyfonth tinyfontsz pad add def -/frontfonth frontfontsz pad add def -/authorfonth authorfontsz pad add def - -/headermargin - pageheight headerheight titlefonth sub 2 div titlefontsz add sub -def -/rightmargin pagewidth leftmargin sub def -/tbtop topmargin def -/ypos topmargin def - -/xcur { currentpoint pop } def -/ycur { currentpoint exch pop } def - -/wordbreak ( ) def -/linewrap { - /proc exch def - /linelength exch def - /textstring exch def - /breakwidth wordbreak stringwidth pop def - /curwidth 0 def - /lastwordbreak 0 def - /startchar 0 def - /restoftext textstring def - { - restoftext wordbreak search - { - /nextword exch def pop - /restoftext exch def - /wordwidth nextword stringwidth pop def - curwidth wordwidth add linelength gt - { - textstring startchar - lastwordbreak startchar sub - getinterval proc - /startchar lastwordbreak def - /curwidth wordwidth breakwidth add def - } - { - /curwidth curwidth wordwidth add - breakwidth add def - } ifelse - /lastwordbreak lastwordbreak - nextword length add 1 add def - } - { - pop exit - } ifelse - } loop - /lastchar textstring length def - textstring startchar lastchar startchar sub - getinterval proc -} def - -/line { - 0 0 0 setrgbcolor - 0.5 setlinewidth - leftmargin ypos moveto - rightmargin ypos lineto - stroke -} def - -/center { - dup - /str exch def - /sw str stringwidth pop def - /xpos pagewidth sw sub 2 div xcur sub def - xpos 0 rmoveto -} def - -/objcenter { - pagewidth exch sub 2 div 0 translate -} def - -/s { - /tbtop topmargin def - /ypos topmargin def - 1 1 1 setrgbcolor - 0 setlinewidth - newpath - 0 pageheight moveto - pagewidth pageheight lineto - pagewidth 0 lineto - 0 0 lineto - closepath - fill - stroke -} def - -/l { - /h exch def - /ypos ypos h sub def - leftmargin ypos moveto -} def - -/title { - frontfonth l - frontfont setfont - 0.5 0.5 0.9 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { frontfonth l center show } - linewrap - frontfonth 2 div l - frontfonth l -} def - -/author { - authorfont setfont - 0 0 0 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { authorfonth l center show } - linewrap -} def - -/authortwo { - authorfonttwo setfont - 0 0 0 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { authorfonth l center show } - linewrap -} def - -/header { - /ypos pageheight headerheight sub def - 0 0 0 setrgbcolor - 0 setlinewidth - newpath - 0 pageheight moveto - pagewidth pageheight lineto - pagewidth ypos lineto - 0 ypos lineto - closepath - fill - stroke - leftmargin headermargin moveto - titlefont setfont - 0.5 0.5 0.9 setrgbcolor - center show - leftmargin ypos moveto -} def - -/n { - mainfont setfont - 0 0 0 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { mainfonth l show } - linewrap -} def - -/cn { - codefont setfont - 0 0 0 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { codefonth l show } - linewrap -} def - -/tn { - tinyfont setfont - 0 0 0 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { tinyfonth l show } - linewrap -} def - -/is { - /level1 save def - /showpage {} def -} def - -/ie { - level1 restore -} def - -/bs { - /tbtop ypos def -} def - -/be { - /tm tbtop pad sub def - /bm ypos pad sub def - newpath - leftmargin 10 sub tm moveto - rightmargin tm lineto - rightmargin bm lineto - leftmargin 10 sub bm lineto - closepath - 0 0 0 setrgbcolor - 0.5 setlinewidth - stroke -} def -( On "local-first") title -(Beyond the CRDT silver bullet) authortwo -showpage -%%Page: 1 1 -s -( Part 1) header -( Exposition) title -showpage -%%Page: 2 2 -s -( Target) header -() n -() n -() n -(- documents) n -(- files) n -(- personal data repositories) n -() n -() n -(Not: banking services, e-commerce, social networking, ride-sharing, etc.) n -showpage -%%Page: 3 3 -s -() n -() n -() n -( 7 ideals for local-first software) title -showpage -%%Page: 4 4 -s -() n -() n -() n -( 1 - no spinners: your work at your fingertips) title -showpage -%%Page: 5 5 -s -() n -() n -() n -( 2 - your work is not trapped on one device) title -showpage -%%Page: 6 6 -s -() n -() n -() n -( 3 - the network is optional) title -showpage -%%Page: 7 7 -s -() n -() n -() n -( 4 - seamless collaboration with your colleagues) title -showpage -%%Page: 8 8 -s -() n -() n -() n -( 5 - the long now) title -showpage -%%Page: 9 9 -s -() n -() n -() n -( 6 - security and privacy by default ) title -showpage -%%Page: 10 10 -s -() n -() n -() n -( 7 - you retain ultimate ownership and control) title -showpage -%%Page: 11 11 -s -( Towards a better future) header -() n -() n -() n -() n -( CRDTs \(Conflict-free Replicated Data Types\) as a Foundational Technology) authortwo -showpage -%%Page: 12 12 -s -( Use case) header -() n -bs -(# in node A and node B) cn -(s = "Hello, World") cn -() cn -(# in node A) cn -(s = "Hello, Alice") cn -() cn -(# in node B) cn -(s = "Hello, Bob") cn -be -(How to reconcile those?) n -(- Hello, ABloibce) n -(- Hello, AliceBob) n -(- Hello, BobAlice) n -(- Hello, Alice) n -(...) n -showpage -%%Page: 13 13 -s -( Existing CRDTs differ) title -(- performance) n -(- storage) n -(- compression) n -(- metadata overhead) n -showpage -%%Page: 14 14 -s -() n -() n -() n -( Hint towards the "automerge" CRDT) title -showpage -%%Page: 15 15 -s -() n -() n -() n -() n -() n -() n -(show comparison table, page 9) author -showpage -%%Page: 16 16 -s -( Part 2) header -( Critique) title -showpage -%%Page: 17 17 -s -( Software license) header -() n -() n -() n -("In our opinion, maintaining control and ownership of data does not mean that the software must necessarily be open source.") author -showpage -%%Page: 18 18 -s -( Example 1 - intentional restriction) header -() n -bs -(#!/bin/sh) cn -(TODAY="$\(date +%s\)") cn -(LICENSE_EXPIRATION="$\(date -d 2020-10-27 +%s\)") cn -(if [ "$TODAY" -ge "$LICENSE_EXPIRATION" ]; then) cn -( echo 'License expired!') cn -( exit 1) cn -(fi) cn -(echo $\(\(2 + 2\)\)) cn -be -() n -bs -(# today) cn -($ ./useful-adder.sh) cn -(4) cn -(# tomorrow) cn -($ ./useful-adder.sh) cn -(License expired!) cn -be -showpage -%%Page: 19 19 -s -( Example 2 - unintentional restriction) header -() n -bs -(# today) cn -($ useful-program) cn -(# ... useful output ...) cn -() cn -(# tomorrow, with more data) cn -($ useful-program) cn -(ERROR: Panic! Stack overflow!) cn -be -showpage -%%Page: 20 20 -s -() n -() n -( local-first *requires* free software ) title -(Otherwise "The Long Now" \(ideal nº5\) is lost) n -showpage -%%Page: 21 21 -s -( Denial of existing solutions) header -() n -() n -("In principle it is possible to collaborate without a repository service, e.g. by sending patch files by email, but the majority of Git users rely on GitHub." ) author -() n -(Solution: either GitHub+CRDTs or git send-email ) n -showpage -%%Page: 22 22 -s -( Plain-text formats) header -() n -("Git is highly optimized for code and similar line-based text file") author -() n -(It even pulls software to the plain text directtion, e.g.:) n -(- delivery-templates) n -(- common-core.protocols.config) n -() n -(Why not exploit that more?) n -showpage -%%Page: 23 23 -s -( Ditching of web applications) header -() n -() n -("The architecture of web apps remains fundamentally server-centric) author -() n -(Disagree. Contrast PouchDB with Android Instant Apps) n -showpage -%%Page: 24 24 -s -( Costs are underrated) header -() n -(- storage) n -(- backups) n -(- maintenance) n -() n -(Example: blog vs vlog) n -showpage -%%Page: 25 25 -s -( Real-time collaboration a bit overrated) header -() n -(It is only possible on the presence of reliable, medium-quality network connection) n -() n -() n -("X also works when inside an elevator, subway or plane!") author -showpage -%%Page: 26 26 -s -( On CRDTs and developer experience) header -() n -("For an app developer, how does the use of a CRDT-based data layer compare to existing storage layers like a SQL database, a filesystem, or CoreData? Is a distributed system harder to write software for?) author -() n -(YES.) authortwo -() n -(See "A Note on Distributed Computing") n -showpage -%%Page: 27 27 -s -( Conclusion) header -() n -(Why this is a "paper I love": it took offline-first and ran with it.) n -() n -(But a pinch of CRDT won't make the world local-first. ) n -() n -(The tricky part is the end of the sentence: "in spite of the Cloud".) n -showpage -%%Page: 28 28 -s -( References) header -() n -(1. "Local-First Software: You Own Your Data, in spite of the Cloud", by M. Kleppmann, A. Wiggins, P. Van Hardenberg and M. F. McGranaghan) n -(2. The Morning Paper article) n -(3. "A Note on Distributed Compiting", by J. Waldo, G. Wyant, A. Wollrath and S. Kendall) n -(4. these slides: euandre.org/slide/) n -(5. prose version of this presentation) n -(6. view source) n - -showpage - -%%EOF diff --git a/v2/src/content/en/slide/local-first.slides b/v2/src/content/en/slide/local-first.slides deleted file mode 100644 index fd83115..0000000 --- a/v2/src/content/en/slide/local-first.slides +++ /dev/null @@ -1,204 +0,0 @@ -# On "local-first" - -@Beyond the CRDT silver bullet - ---- -## Part 1 -# Exposition - ---- -## Target -... -- documents -- files -- personal data repositories -.. -Not: banking services, e-commerce, social networking, ride-sharing, etc. - ---- -... -# 7 ideals for local-first software - ---- -... -# 1 - no spinners: your work at your fingertips - ---- -... -# 2 - your work is not trapped on one device - ---- -... -# 3 - the network is optional - ---- -... -# 4 - seamless collaboration with your colleagues - ---- -... -# 5 - the long now - ---- -... -# 6 - security and privacy by default - ---- -... -# 7 - you retain ultimate ownership and control - ---- -## Towards a better future -.... -@ CRDTs (Conflict-free Replicated Data Types) as a Foundational Technology - ---- -## Use case -. - # in node A and node B - s = "Hello, World" - - # in node A - s = "Hello, Alice" - - # in node B - s = "Hello, Bob" - -How to reconcile those? -- Hello, ABloibce -- Hello, AliceBob -- Hello, BobAlice -- Hello, Alice -\... - ---- -# Existing CRDTs differ -- performance -- storage -- compression -- metadata overhead - ---- -... -# Hint towards the "automerge" CRDT - ---- -...... -@@show comparison table, page 9 - ---- -## Part 2 -# Critique - ---- -## Software license -... -@@"In our opinion, maintaining control and ownership of data does not mean that the software must necessarily be open source." - ---- -## Example 1 - intentional restriction -. - #!/bin/sh - TODAY="$(date +%s)" - LICENSE_EXPIRATION="$(date -d 2020-10-27 +%s)" - if [ "$TODAY" -ge "$LICENSE_EXPIRATION" ]; then - echo 'License expired!' - exit 1 - fi - echo $((2 + 2)) -. - # today - $ ./useful-adder.sh - 4 - - # tomorrow - $ ./useful-adder.sh - License expired! ---- -## Example 2 - unintentional restriction -. - # today - $ useful-program - # ... useful output ... - - # tomorrow, with more data - $ useful-program - ERROR: Panic! Stack overflow! - ---- -.. -# local-first *requires* free software - -Otherwise "The Long Now" (ideal nº5) is lost - ---- -## Denial of existing solutions -.. -@@"In principle it is possible to collaborate without a repository service, e.g. by sending patch files by email, but the majority of Git users rely on GitHub." -. -Solution: either GitHub+CRDTs or git send-email - ---- -## Plain-text formats -. -@@"Git is highly optimized for code and similar line-based text file" -. -It even pulls software to the plain text directtion, e.g.: -- delivery-templates -- common-core.protocols.config -. -Why not exploit that more? - ---- -## Ditching of web applications -.. -@@"The architecture of web apps remains fundamentally server-centric -. -% FIXME: links -Disagree. Contrast PouchDB with Android Instant Apps - ---- -## Costs are underrated -. -- storage -- backups -- maintenance -. -Example: blog vs vlog - ---- -## Real-time collaboration a bit overrated -. -It is only possible on the presence of reliable, medium-quality network connection -.. -@@"X also works when inside an elevator, subway or plane!" - ---- -## On CRDTs and developer experience -. -@@"For an app developer, how does the use of a CRDT-based data layer compare to existing storage layers like a SQL database, a filesystem, or CoreData? Is a distributed system harder to write software for? -. -@YES. -. -% FIXME: link -See "A Note on Distributed Computing" - ---- -## Conclusion -. -Why this is a "paper I love": it took offline-first and ran with it. -. -But a pinch of CRDT won't make the world local-first. -. -The tricky part is the end of the sentence: "in spite of the Cloud". - ---- -## References -. -% FIXME: links -1. "Local-First Software: You Own Your Data, in spite of the Cloud", by M. Kleppmann, A. Wiggins, P. Van Hardenberg and M. F. McGranaghan -2. The Morning Paper article -3. "A Note on Distributed Compiting", by J. Waldo, G. Wyant, A. Wollrath and S. Kendall -4. these slides: euandre.org/slide/ -5. prose version of this presentation -6. view source diff --git a/v2/src/content/en/slide/rollouts.ps b/v2/src/content/en/slide/rollouts.ps deleted file mode 100644 index 0a8b39f..0000000 --- a/v2/src/content/en/slide/rollouts.ps +++ /dev/null @@ -1,500 +0,0 @@ -%!PS-Adobe-3.0 -%%DocumentMedia: SLIDE 842 595 0 () () -%%EndComments -%%BeginDefaults -%%PageMedia: SLIDE -%%EndDefaults -<< /PageSize [842 595] /ImagingBBox null >> setpagedevice - -/reencode { - exch - findfont - dup length dict - begin - { - 1 index /FID ne - { def } - { pop pop } - ifelse - } forall - /Encoding ISOLatin1Encoding def - currentdict - end - definefont pop -} def -/Times /Times reencode -/Courier /Courier reencode -/Times-Italic /Times-Italic reencode -/Helvetica /Helvetica reencode - - -/headerheight 75 def - -/frontfontsz 60 def -/authorfontsz 40 def -/titlefontsz 40 def -/mainfontsz 30 def -/codefontsz 18 def -/tinyfontsz 18 def - -/titlefont /Helvetica findfont titlefontsz scalefont def -/mainfont /Courier findfont mainfontsz scalefont def -/codefont /Courier findfont codefontsz scalefont def -/tinyfont /Times findfont tinyfontsz scalefont def -/frontfont /Helvetica findfont frontfontsz scalefont def -/authorfont /Times-Italic findfont authorfontsz scalefont def -/authorfonttwo /Times findfont authorfontsz scalefont def - - -/pagewidth 842 def -/pageheight 595 def -/leftmargin 30 def -/topmargin 595 def - -/pad 10 def - -/titlefonth titlefontsz pad add def -/mainfonth mainfontsz pad add def -/codefonth codefontsz pad add def -/tinyfonth tinyfontsz pad add def -/frontfonth frontfontsz pad add def -/authorfonth authorfontsz pad add def - -/headermargin - pageheight headerheight titlefonth sub 2 div titlefontsz add sub -def -/rightmargin pagewidth leftmargin sub def -/tbtop topmargin def -/ypos topmargin def - -/xcur { currentpoint pop } def -/ycur { currentpoint exch pop } def - -/wordbreak ( ) def -/linewrap { - /proc exch def - /linelength exch def - /textstring exch def - /breakwidth wordbreak stringwidth pop def - /curwidth 0 def - /lastwordbreak 0 def - /startchar 0 def - /restoftext textstring def - { - restoftext wordbreak search - { - /nextword exch def pop - /restoftext exch def - /wordwidth nextword stringwidth pop def - curwidth wordwidth add linelength gt - { - textstring startchar - lastwordbreak startchar sub - getinterval proc - /startchar lastwordbreak def - /curwidth wordwidth breakwidth add def - } - { - /curwidth curwidth wordwidth add - breakwidth add def - } ifelse - /lastwordbreak lastwordbreak - nextword length add 1 add def - } - { - pop exit - } ifelse - } loop - /lastchar textstring length def - textstring startchar lastchar startchar sub - getinterval proc -} def - -/line { - 0 0 0 setrgbcolor - 0.5 setlinewidth - leftmargin ypos moveto - rightmargin ypos lineto - stroke -} def - -/center { - dup - /str exch def - /sw str stringwidth pop def - /xpos pagewidth sw sub 2 div xcur sub def - xpos 0 rmoveto -} def - -/objcenter { - pagewidth exch sub 2 div 0 translate -} def - -/s { - /tbtop topmargin def - /ypos topmargin def - 1 1 1 setrgbcolor - 0 setlinewidth - newpath - 0 pageheight moveto - pagewidth pageheight lineto - pagewidth 0 lineto - 0 0 lineto - closepath - fill - stroke -} def - -/l { - /h exch def - /ypos ypos h sub def - leftmargin ypos moveto -} def - -/title { - frontfonth l - frontfont setfont - 0.5 0.5 0.9 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { frontfonth l center show } - linewrap - frontfonth 2 div l - frontfonth l -} def - -/author { - authorfont setfont - 0 0 0 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { authorfonth l center show } - linewrap -} def - -/authortwo { - authorfonttwo setfont - 0 0 0 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { authorfonth l center show } - linewrap -} def - -/header { - /ypos pageheight headerheight sub def - 0 0 0 setrgbcolor - 0 setlinewidth - newpath - 0 pageheight moveto - pagewidth pageheight lineto - pagewidth ypos lineto - 0 ypos lineto - closepath - fill - stroke - leftmargin headermargin moveto - titlefont setfont - 0.5 0.5 0.9 setrgbcolor - center show - leftmargin ypos moveto -} def - -/n { - mainfont setfont - 0 0 0 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { mainfonth l show } - linewrap -} def - -/cn { - codefont setfont - 0 0 0 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { codefonth l show } - linewrap -} def - -/tn { - tinyfont setfont - 0 0 0 setrgbcolor - { pagewidth leftmargin 2 mul sub } - { tinyfonth l show } - linewrap -} def - -/is { - /level1 save def - /showpage {} def -} def - -/ie { - level1 restore -} def - -/bs { - /tbtop ypos def -} def - -/be { - /tm tbtop pad sub def - /bm ypos pad sub def - newpath - leftmargin 10 sub tm moveto - rightmargin tm lineto - rightmargin bm lineto - leftmargin 10 sub bm lineto - closepath - 0 0 0 setrgbcolor - 0.5 setlinewidth - stroke -} def -showpage -%%Page: 1 1 -s -( Rollout, feature flag, experiment, operational toggle) title -(Different use cases for backend, frontend and mobile ) authortwo -showpage -%%Page: 2 2 -s -() n -() n -() n -( "Feature flags" tend to come up when talking about continuous deployment) title -showpage -%%Page: 3 3 -s -() n -() n -() n -() n -(CI: continuous integration) authortwo -() n -(CD: continuous delivery) authortwo -() n -(CD: continuous deployment) authortwo -showpage -%%Page: 4 4 -s -( Types) header -() n -() n -() n -(1. rollout) n -(2. feature flag) n -(3. experiment) n -(4. operational toggle) n -showpage -%%Page: 5 5 -s -( Rollout) header -( For *rolling out* a new version of software) title -(Short-lived using percentages) n -(- a new deployment of kubernetes) n -(- new APK released to the Play Store) n -showpage -%%Page: 6 6 -s -( Feature flag) header -( For turning a feature *on* or *off* ) title -(Medium-lived using allow list, A/B test, percentage, app version, etc.) n -(- :new-chargeback-flow) n -(- :new-debit-card-activation-screen) n -showpage -%%Page: 7 7 -s -( Experiment) header -( For analysing behaviour) title -(Medium-lived using allow list and A/B test) n -(- :debit-withdrawal-test) n -showpage -%%Page: 8 8 -s -( Operational toggle) header -( For disabling features in #crash-like situations) title -(Long-lived using percentage) n -(- :bank-barcode-payment) n -(- :savings-bank-barcode-query-provider) n -showpage -%%Page: 9 9 -s -() n -() n -(We know know about the types) authortwo -( But they have different relevance for backend, frontend and mobile) title -showpage -%%Page: 10 10 -s -( backend) header -() n -() n -(1. rollout: k8s blue/green, canary and ~common-rollout~ common-xp) n -(2. feature flag: ~common-rollout~ common-xp and datasets) n -(3. experiment: common-xp) n -(4. operational toggle: ~common-rollout~ common-xp ) n -showpage -%%Page: 11 11 -s -( frontend) header -() n -() n -(1. rollout: CDN and page refreshes) n -(2. feature flag: percentages and maybe IPs \(no :customer/id on the website\)) n -(3. experiment: via dynamic backend control) n -(4. operational toggle: via dynamic backend control ) n -showpage -%%Page: 12 12 -s -( backend) header -() n -() n -(1. rollout: app stores) n -(2. feature flag: via dynamic backend control) n -(3. experiment: via dynamic backend control) n -(4. operational toggle: via dynamic backend control ) n -showpage -%%Page: 13 13 -s -() n -() n -(Key differentiator is) authortwo -( how much *control* we have over the environment) title -showpage -%%Page: 14 14 -s -( backend) header -( full control) title -showpage -%%Page: 15 15 -s -( frontend) header -( partial control) title -(We choose when to make a new version available ) n -showpage -%%Page: 16 16 -s -( mobile) header -( very limited control) title -(- app stores can restrict updates \(worse for iOS\)) n -(- customers still have to download new versions ) n -showpage -%%Page: 17 17 -s -( Costs) title -(- more complex code) n -(- compatibility with old app versions) n -(- nesting is exponential) n -showpage -%%Page: 18 18 -s -( Benefits) title -(- dynamicity) n -showpage -%%Page: 19 19 -s -( weighting costs × benefits) header -( The less control we have, the more we value dynamicity ) title -showpage -%%Page: 20 20 -s -( weighting costs × benefits) header -() n -() n -() n -(- backend: sometimes worth the cost) n -(- frontend: almost always worth the cost) n -(- mobile: *always* worth the cost) n -showpage -%%Page: 21 21 -s -() n -() n -() n -( Best practices) title -showpage -%%Page: 22 22 -s -( dynamic content > feature flag) title -(Always true for mobile, almost always for frontend ) n -showpage -%%Page: 23 23 -s -( Use :include-list for named groups ) title -(Always true for backend, frontend and mobile ) n -bs -({:rules) cn -( #{{:types :include-list) cn -( :content {:filename "debit-team-members.txt"}}}}) cn -be -showpage -%%Page: 24 24 -s -( Always use :app-version) title -(Only for mobile) n -bs -({:rules) cn -( #{{:types :app-version) cn -( :content {:min-version #{{:platform :android) cn -( :code 1000000}) cn -( {:platform :ios) cn -( :code 2000000}}}}}}) cn -be -showpage -%%Page: 25 25 -s -( Extend ~common-rollout~ common-xp if required) title -(That's how :include-list, :app-version, etc. were born) n -showpage -%%Page: 26 26 -s -( Beware of many nested feature flags) title -(True for backend, frontend and mobile) n -showpage -%%Page: 27 27 -s -( Don't delete app-facing feature flags) title -(True for mobile) n -showpage -%%Page: 28 28 -s -() n -() n -() n -( Include a feature flag on the whiteboarding phase) title -showpage -%%Page: 29 29 -s -() n -() n -() n -( Include deleting/retiring the feature flag at the end) title -showpage -%%Page: 30 30 -s -( Avoid renaming a feature flag) title -(Use :app-version with :min-version instead) n -showpage -%%Page: 31 31 -s -() n -() n -() n -( And most importantly...) title -showpage -%%Page: 32 32 -s -( *Always* rely on a feature flag on the app) title -(Never do a hotfix, avoid expedited releases at all costs) n -showpage -%%Page: 33 33 -s -( References) header -() n -(1. "Feature Toggles \(aka Feature Flags\)", by Pete Hodgson) n -(2. "Continuous integration vs. delivery vs. deployment", by Sten Pittet) n -(3. Accelerate, by N. Forsgren, J. Humble and G. Kim) n -(4. these slides: euandre.org/slide/) n -(5. prose version of this presentation) n -(6. view source) n - -showpage - -%%EOF diff --git a/v2/src/content/en/slide/rollouts.slides b/v2/src/content/en/slide/rollouts.slides deleted file mode 100644 index aed745e..0000000 --- a/v2/src/content/en/slide/rollouts.slides +++ /dev/null @@ -1,208 +0,0 @@ ---- -# Rollout, feature flag, experiment, operational toggle - -@Different use cases for backend, frontend and mobile - ---- -... -# "Feature flags" tend to come up when talking about continuous deployment - ---- -.... -@CI: continuous integration -. -@CD: continuous delivery -. -@CD: continuous deployment - ---- -## Types -... -1. rollout -2. feature flag -3. experiment -4. operational toggle - -% {favicon.svg} ---- -## Rollout - -# For *rolling out* a new version of software - -Short-lived using percentages - -% FIXME: links -- a new deployment of kubernetes -- new APK released to the Play Store - ---- -## Feature flag - -# For turning a feature *on* or *off* - -Medium-lived using allow list, A/B test, percentage, app version, etc. - -- :new-chargeback-flow -- :new-debit-card-activation-screen - ---- -## Experiment - -# For analysing behaviour - -Medium-lived using allow list and A/B test - -- :debit-withdrawal-test - ---- -## Operational toggle - -# For disabling features in #crash-like situations - -Long-lived using percentage - -- :bank-barcode-payment -- :savings-bank-barcode-query-provider - ---- -.. -@We know know about the types -# But they have different relevance for backend, frontend and mobile - ---- -## backend -.. -1. rollout: k8s blue/green, canary and ~common-rollout~ common-xp -2. feature flag: ~common-rollout~ common-xp and datasets -3. experiment: common-xp -4. operational toggle: ~common-rollout~ common-xp - ---- -## frontend -.. -1. rollout: CDN and page refreshes -2. feature flag: percentages and maybe IPs (no :customer/id on the website) -3. experiment: via dynamic backend control -4. operational toggle: via dynamic backend control - ---- -## backend -.. -1. rollout: app stores -2. feature flag: via dynamic backend control -3. experiment: via dynamic backend control -4. operational toggle: via dynamic backend control - ---- -.. -@Key differentiator is -# how much *control* we have over the environment - ---- -## backend -# full control -% FIXME: emoji -% 🎉 - ---- -## frontend -# partial control -We choose when to make a new version available - ---- -## mobile -# very limited control -- app stores can restrict updates (worse for iOS) -- customers still have to download new versions - ---- -# Costs -- more complex code -- compatibility with old app versions -- nesting is exponential - ---- -# Benefits -- dynamicity - ---- -## weighting costs × benefits -# The less control we have, the more we value dynamicity - ---- -## weighting costs × benefits -... -- backend: sometimes worth the cost -- frontend: almost always worth the cost -- mobile: *always* worth the cost - ---- -... -# Best practices - ---- -# dynamic content > feature flag -Always true for mobile, almost always for frontend - ---- -# Use :include-list for named groups -Always true for backend, frontend and mobile - - {:rules - #{{:types :include-list - :content {:filename "debit-team-members.txt"}}}} - ---- -# Always use :app-version -Only for mobile - - {:rules - #{{:types :app-version - :content {:min-version #{{:platform :android - :code 1000000} - {:platform :ios - :code 2000000}}}}}} - ---- -# Extend ~common-rollout~ common-xp if required - -That's how :include-list, :app-version, etc. were born - ---- -# Beware of many nested feature flags -True for backend, frontend and mobile - ---- -# Don't delete app-facing feature flags -True for mobile - ---- -... -# Include a feature flag on the whiteboarding phase - ---- -... -# Include deleting/retiring the feature flag at the end - ---- -# Avoid renaming a feature flag -Use :app-version with :min-version instead - ---- -... -# And most importantly... - ---- -# *Always* rely on a feature flag on the app -Never do a hotfix, avoid expedited releases at all costs - ---- -## References -. -% FIXME: links -1. "Feature Toggles (aka Feature Flags)", by Pete Hodgson -2. "Continuous integration vs. delivery vs. deployment", by Sten Pittet -3. Accelerate, by N. Forsgren, J. Humble and G. Kim -4. these slides: euandre.org/slide/ -5. prose version of this presentation -6. view source diff --git a/v2/src/content/en/til/lisp-three-way-conditional.md b/v2/src/content/en/til/lisp-three-way-conditional.md deleted file mode 100644 index 20fbd09..0000000 --- a/v2/src/content/en/til/lisp-three-way-conditional.md +++ /dev/null @@ -1,59 +0,0 @@ ---- - -title: Three-way conditional for number signs on Lisp - -date: 2021-04-24 3 - -update: 2021-08-14 - -categories: lisp scheme common-lisp - ---- - -A useful macro from Paul Graham's [On Lisp][on-lisp] book: - -```lisp -(defmacro nif (expr pos zero neg) - (let ((g (gensym))) - `(let ((,g ,expr)) - (cond ((plusp ,g) ,pos) - ((zerop ,g) ,zero) - (t ,neg))))) -``` - -After I looked at this macro, I started seeing opportunities to using it in many places, and yet I didn't see anyone else using it. - -The latest example I can think of is section 1.3.3 of [Structure and Interpretation of Computer Programs][sicp], which I was reading recently: - -```scheme -(define (search f neg-point pos-point) - (let ((midpoint (average neg-point pos-point))) - (if (close-enough? neg-point post-point) - midpoint - (let ((test-value (f midpoint))) - (cond ((positive? test-value) - (search f neg-point midpoint)) - ((negative? test-value) - (search f midpoint pos-point)) - (else midpoint)))))) -``` - -Not that the book should introduce such macro this early, but I couldn't avoid feeling bothered by not using the `nif` macro, which could even remove the need for the intermediate `test-value` variable: - -```scheme -(define (search f neg-point pos-point) - (let ((midpoint (average neg-point pos-point))) - (if (close-enough? neg-point post-point) - midpoint - (nif (f midpoint) - (search f neg-point midpoint) - (midpoint) - (search f midpoint pos-point))))) -``` - -It also avoids `cond`'s extra clunky parentheses for grouping, which is unnecessary but built-in. - -As a macro, I personally feel it tilts the balance towards expressivenes despite its extra cognitive load toll. - -[on-lisp]: http://www.paulgraham.com/onlisptext.html -[sicp]: https://mitpress.mit.edu/sites/default/files/sicp/index.html |