%!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