]> gitweb.factorcode.org Git - factor-talks.git/blob - svfig-talk/svfig-talk.factor
svfig-talk: final updates
[factor-talks.git] / svfig-talk / svfig-talk.factor
1 USING: help.markup namespaces peg.ebnf slides typed ;
2 IN: svfig-talk
3
4 CONSTANT: svfig-slides
5 {
6     { $slide "Factor!"
7         { $url "https://factorcode.org" }
8         "Development started in 2003"
9         "Open source (BSD license)"
10         "Influenced by Forth, Lisp, and Smalltalk"
11         "Blurs the line between language and library"
12         "Interactive development"
13         "Upcoming release: 0.99, then... 0.100?"
14     }
15
16     { $slide "Concepts"
17         "Concatenative"
18         "Dynamic types"
19         "Extensible syntax"
20         "Fully-compiled"
21         "Cross-platform"
22         "Clickable"
23         "Useful?"
24     }
25
26     { $slide "Concatenative"
27         { $code "1 2 + ." }
28         { $code "3 weeks ago noon ." }
29         { $code "\"hello\" rot13 ." }
30         { $code "URL\" https://factorcode.org\" http-get" }
31         { $code "10 [ \"Hello, Factor\" print ] times" }
32         { $code "{ 4 8 15 16 23 42 } [ sum ] [ length ] bi / ." }
33     }
34
35     { $slide "Words"
36         "Defined at parse time"
37         "Parts: name, stack effect, definition"
38         "Composed of tokens separated by whitespace"
39         { $code ": palindrome? ( string -- ? ) dup reverse = ;" }
40         "Unit tests"
41         { $code "{ f } [ \"hello\" palindrome? ] unit-test"
42                 ""
43                 "{ t } [ \"racecar\" palindrome? ] unit-test"
44         }
45     }
46
47     { $slide "Quotations"
48         "Quotation: un-named blocks of code"
49         { $code "[ \"Hello, World\" print ]" }
50         "Combinators: words taking quotations"
51         { $code "10 dup 0 < [ 1 - ] [ 1 + ] if ." }
52         { $code "{ -1 1 -2 0 3 } [ 0 max ] map ." }
53     }
54
55     { $slide "Vocabularies"
56         "Vocabularies: named sets of words"
57         { $link "vocab-index" }
58         { { $link POSTPONE: USING: } " loads dependencies" }
59         "Source, docs, tests in one place"
60     }
61
62     { $slide "Debugging Tools"
63         { "Let's implement the " { $snippet "fortune" } " program" }
64         { $code
65             "\"/usr/local/share/games/fortunes/science\""
66             "ascii file-lines"
67             "{ \"%\" } split random"
68             "[ print ] each"
69         }
70         "Let's try it out!"
71     }
72
73     { $slide "Native Performance"
74         { $snippet "wc -l factor.image" }
75         "Counting lines is reasonably fast..."
76         { $code
77             ": simple-wc ( path -- n )"
78             "    binary <file-reader> ["
79             "        0 swap ["
80             "            [ CHAR: \\n = ] count +"
81             "        ] each-stream-block-slice"
82             "    ] with-disposal ;"
83         }
84         { $code "[ \"factor.image\" simple-wc ] time" }
85     }
86
87     { $slide "Native Performance"
88         "But it can be even faster!"
89         { $code
90             "USE: tools.wc"
91             "[ \"factor.image\" wc ] time"
92         }
93         "Deploy as binary"
94         { $code "\"tools.wc\" deploy" }
95     }
96
97     { $slide "Visual Tools"
98         { $code
99             "\"Bigger\" { 12 18 24 72 } ["
100             "    font-size associate format nl"
101             "] with each"
102         }
103         { $code
104             "10 <iota> ["
105             "    \"Hello, World!\""
106             "    swap 10 / 1 over - over 1 <rgba>"
107             "    background associate format nl"
108             "] each"
109         }
110         { $code
111             "USE: images.http"
112             "\"https://factorcode.org/logo.png\" http-image."
113         }
114         { $code
115             "USE: lcd"
116             "<time-display> gadget."
117         }
118     }
119
120     { $slide "Interactive Development"
121         "Programming is hard, let's play tetris"
122         { $vocab-link "tetris" }
123         "Tetris is hard too... let's cheat"
124         { $code "\"tetris.tetromino\" edit" }
125         { "Factor workflow: change code, " { $snippet "F2" } ", test, repeat" }
126     }
127
128     { $slide "Parsing Words"
129         "Extensible syntax, DSLs"
130         "Most parsing words fall in one of two categories"
131         "First category: literal syntax for new data types"
132         "Second category: defining new types of words"
133         "Some parsing words are more complicated"
134     }
135
136     { $slide "Parsing Words - Pairs"
137         "Generic array syntax"
138         { $code "{ 1 2 }" }
139         { $code "\\ { see" }
140         "Custom pair syntax"
141         { $code "SYNTAX: => dup pop scan-object 2array suffix! ;" }
142         { $code "1 => 2" }
143     }
144
145     { $slide "Parsing Words - Dice"
146         { $vocab-link "dice" }
147         { $code "ROLL: 2d8+5"
148                 ""
149                 "\"You do %s points of damage!\\n\" printf" }
150         { $code "\\ ROLL: see" }
151         { $code "[ ROLL: 2d8+5 ] ." }
152     }
153
154     { $slide "Parsing Words - Regexp"
155         { $vocab-link "regexp" }
156         "Pre-compiles regexp at parse time"
157         "Implemented with library code"
158         { $code "\"ababbc\" \"[ab]+c\" <regexp> matches? ." }
159         { $code "\"ababbc\" R/ [ab]+c/ matches? ." }
160     }
161
162     { $slide "Parsing Words - XML"
163         { $vocab-link "xml" }
164         "Implemented with library code"
165         "Useful syntax forms"
166         { $code
167             "{ \"three\" \"blind\" \"mice\" }"
168             "[ [XML <li><-></li> XML] ] map"
169             "[XML <ul><-></ul> XML]"
170             "pprint-xml"
171         }
172     }
173
174     { $slide "Local Variables"
175         "Sometimes, there's no good stack solution to a problem"
176         "Or, you're porting existing code in a quick-and-dirty way"
177         "Combinator with 5 parameters!"
178         { $code
179             ":: branch ( a b neg zero pos -- )"
180             "    a b = zero [ a b < neg pos if ] if ; inline"
181         }
182         "Unwieldy with the stack"
183     }
184
185     { $slide "Local Variables"
186         { $code
187             ": check-voting-age ( age -- )"
188             "    18"
189             "    [ \"You're underage, sorry...\" print ]"
190             "    [ \"Yay, register to vote!\" print ]"
191             "    [ \"Participate in democracy!\" print ]"
192             "    branch ;"
193         }
194         "Locals are entirely implemented in Factor"
195         "Example of compile-time meta-programming"
196         "No performance penalty -vs- using the stack"
197     }
198
199     { $slide "Dynamic Variables"
200         "Implemented as a stack of hashtables"
201         { "Useful words are " { $link get } ", " { $link set } }
202         "Input, output, error streams are stored in dynamic variables"
203         "Read from a string..."
204         { $code "\"cat\\ndog\\nfish\" [ readln ] with-string-reader" }
205         "Read from a file..."
206         { $code "\"LICENSE.txt\" utf8 [ readln ] with-file-reader" }
207     }
208
209     { $slide "Destructors"
210         "Deterministic resource disposal"
211         "Any step can fail and we don't want to leak resources"
212         "We want to conditionally clean up sometimes"
213         { $code ": do-stuff ( -- )
214     [
215         256 malloc &free
216         256 malloc &free
217         ... work goes here ...
218     ] with-destructors ;"
219         }
220     }
221
222     { $slide "Profiling"
223         { $code
224             ": fib ( m -- n )"
225             "    dup 1 > ["
226             "        [ 1 - fib ] [ 2 - fib ] bi +"
227             "    ] when ;"
228         }
229         { $code "[ 40 fib ] time" }
230         "Very slow! Let's profile it..."
231         { $code "[ 40 fib ] profile" }
232         "Not tail recursive"
233         "Call tree is huge"
234     }
235
236     { $slide "Profiling - Typed"
237         { "Type declarations with " { $link POSTPONE: TYPED: } }
238         { $code
239             "TYPED: fib ( m: fixnum -- n )"
240             "    dup 1 > ["
241             "        [ 1 - fib ] [ 2 - fib ] bi +"
242             "    ] when ;"
243         }
244         "A bit faster"
245     }
246
247     { $slide "Profiling - Memoize"
248         { "Memoization using " { $link POSTPONE: MEMO: } }
249         { $code
250             "MEMO: fib ( m -- n )"
251             "    dup 1 > ["
252             "        [ 1 - fib ] [ 2 - fib ] bi +"
253             "    ] when ;"
254         }
255         "Much faster"
256         { $code "10,000 fib number>string "
257                 "80 group [ print ] each" }
258     }
259
260     { $slide "Macros"
261         "Expand at compile-time"
262         "Return a quotation to be compiled"
263         "Can express non-static stack effects"
264         { $code "MACRO: ndup ( n -- quot )"
265                 "    [ \\ dup ] [ ] replicate-as ;"
266         }
267         { $code "[ 5 ndup ] infer" }
268         { $code "[ 5 ndup ] expand-macros" }
269     }
270
271     { $slide "PEG / EBNF"
272         { { $link POSTPONE: EBNF: } ": a complex parsing word" }
273         "Implements a custom syntax for expressing parsers"
274         { "Example: " { $vocab-link "printf" } }
275         { $code "\"Factor\""
276                 "2003 <year> ago duration>years"
277                 ""
278                 "\"%s is %d years old\\n\" printf" }
279         { $code "[ \"%s monkeys\" printf ] expand-macros" }
280     }
281
282     { $slide "Objects"
283         "A tuple is a user-defined class which holds named values."
284         { $code
285             "TUPLE: rectangle width height ;"
286             ""
287             "TUPLE: circle radius ;"
288         }
289     }
290
291     { $slide "Objects"
292         "Constructing instances:"
293         { $code "rectangle new" }
294         { $code "rectangle boa" }
295         "Let's encapsulate:"
296         { $code
297             ": <rectangle> ( w h -- r ) rectangle boa ;"
298             ""
299             ": <circle> ( r -- c ) circle boa ;"
300         }
301     }
302
303     { $slide "Single Dispatch"
304         ! "Generic words and methods"
305         { $code "GENERIC: area ( shape -- n )" }
306         "Two methods:"
307         { $code
308             "M: rectangle area"
309             "    [ width>> ] [ height>> ] bi * ;"
310             ""
311             "M: circle area radius>> sq pi * ;"
312         }
313         "We can compute areas now."
314         { $code "100 20 <rectangle> area ." }
315         { $code "3 <circle> area ." }
316     }
317
318     { $slide "Multiple Dispatch"
319         { $code "SINGLETONS: rock paper scissors ;" }
320         "Win conditions:"
321         { $code "FROM: multi-methods => GENERIC: METHOD: ;"
322                 ""
323                 "GENERIC: beats? ( obj1 obj2 -- ? )"
324                 ""
325                 "METHOD: beats? { scissors paper } 2drop t ;"
326                 "METHOD: beats? { rock  scissors } 2drop t ;"
327                 "METHOD: beats? { paper     rock } 2drop t ;"
328                 "METHOD: beats? { object  object } 2drop f ;"
329         }
330     }
331
332     { $slide "Multiple Dispatch"
333         "Let's play a game..."
334         { $code ": play. ( obj -- )"
335                 "    { rock paper scissors } random {"
336                 "        { [ 2dup beats? ] [ \"WIN\" ] }"
337                 "        { [ 2dup = ] [ \"TIE\" ] }"
338                 "        [ \"LOSE\" ]"
339                 "    } cond \"%s vs. %s: %s\\n\" printf ;"
340         }
341         "With a simple interface:"
342         { $code ": rock ( -- ) \\ rock play. ;"
343                 ": paper ( -- ) \\ paper play. ;"
344                 ": scissors ( -- ) \\ scissors play. ;"
345         }
346     }
347
348     { $slide "Object System"
349         "Supports \"duck typing\""
350         "Two tuples can have a slot with the same name"
351         "Code that uses accessors will work on both"
352         "Objects are not hashtables; slot access is very fast"
353         "Tuple slots can be reordered/redefined"
354         "Instances in memory will be updated"
355     }
356
357     { $slide "Object System"
358         "Predicate classes"
359         { $code
360             "PREDICATE: positive < integer 0 > ;"
361             "PREDICATE: negative < integer 0 < ;"
362             ""
363             "GENERIC: abs ( m -- n )"
364             ""
365             "M: positive abs ;"
366             "M: negative abs -1 * ;"
367             "M: integer abs ;"
368         }
369     }
370     { $slide "Object System"
371         "And lots more features..."
372         "Inheritance, type declarations, read-only slots, union, intersection, singleton classes, reflection"
373         "Object system is entirely implemented in Factor"
374     }
375
376     { $slide "Assembly"
377         "Access the Time Stamp Counter"
378         { $code
379 "HOOK: rdtsc cpu ( -- n )
380
381 M: x86.64 rdtsc
382     longlong { } cdecl [
383         RAX 0 MOV
384         RDTSC
385         RDX 32 SHL
386         RAX RDX OR
387     ] alien-assembly ;" }
388     }
389
390     { $slide "FFI"
391         { $code "NAME
392      sqrt – square root function
393
394 SYNOPSIS
395      #include <math.h>
396
397      double
398      sqrt(double x);" }
399         "Let's use it!"
400         { $code "FUNCTION: double sqrt ( double x )" }
401     }
402
403     { $slide "Infix"
404         { "Syntax experiments with " { $vocab-link "infix" } }
405         "Infix word definitions:"
406         { $code "INFIX:: foo ( x y -- z ) sqrt(x)+y**3 ;" }
407         "Inline also:"
408         { $code "[let \"hello\" :> seq"
409                 "    [infix seq[::-1] infix]"
410                 "]"
411         }
412     }
413
414     { $slide "Implementation"
415         "VM in C++ (12,000 lines of code)"
416         "VM features primitives, garbage collection, etc."
417         "Lines of code: 300,000"
418         "Lines of tests: 80,000"
419         "Lines of docs: 70,000"
420         "One big repository, and we love contributions!"
421     }
422
423     { $slide "Project Infrastructure"
424         { $url "https://factorcode.org" }
425         { $url "https://concatenative.org" }
426         { $url "https://docs.factorcode.org" }
427         { $url "https://planet.factorcode.org" }
428         { $url "https://paste.factorcode.org" }
429         "Uses our HTTP server, SSL, DB, Atom libraries..."
430     }
431
432     { $slide "Project Infrastructure"
433         "Build farm, written in Factor"
434         "Multiple OS and architecture"
435         "Builds Factor and all libraries, runs tests, makes binaries"
436         "Saves us from the burden of making releases by hand"
437         "Maintains stability"
438     }
439
440     { $slide "Demo"
441         "It is hard to cover everything in a single talk"
442         "Factor has many cool things that I didn't talk about"
443         { $code "\"demos\" run" }
444         "Let's look at a real program!"
445     }
446
447     { $slide "Cool Things"
448         { $code
449             "USE: xkcd"
450             "XKCD: 138"
451         }
452         { $code
453             "USE: reddit"
454             "\"programming\" subreddit."
455         }
456     }
457
458     { $slide "Cool Things"
459         { $vocab-link "minesweeper" }
460         { $vocab-link "game-of-life" }
461         { $vocab-link "boids" }
462         { $vocab-link "pong" }
463     }
464
465     { $slide "Cool Things"
466         "8080 cpu emulator"
467         { $code
468             "\"resource:roms\" rom-root set-global"
469         }
470         { $vocab-link "roms.space-invaders" }
471     }
472
473     { $slide "Cool Things"
474         { $vocab-link "bloom-filters" }
475         { $vocab-link "cuckoo-filters" }
476         { $vocab-link "persistent" }
477         { $vocab-link "trees" }
478         { $vocab-link "tuple-arrays" }
479         { $vocab-link "specialized-arrays" }
480     }
481
482     { $slide "Cool Things"
483         { $code
484             "USE: text-to-speech"
485             "\"hello\" speak-text"
486         }
487         { $code
488             "USE: morse"
489             "\"hello\" play-as-morse"
490         }
491         { $code
492             "USE flip-text"
493             "\"hello\" flip-text ."
494         }
495         { $code
496             "USE: emojify"
497             "\"I :heart: Factor! :+1!\" emojify ."
498         }
499     }
500
501     { $slide "Cool Things"
502         { $code
503             "USE: google.charts"
504             "\"x = \\\\frac{-b \\\\pm \\\\sqrt {b^2-4ac}}{2a}\""
505             "<formula> 200 >>width 75 >>height chart."
506         }
507         { $code
508             "100 [ 100 random ] replicate"
509             "100 [ 100 random ] replicate"
510             "zip <scatter> chart."
511         }
512         { $code
513             "\"/usr/share/dict/words\" utf8 file-lines"
514             "[ >lower 1 head ] histogram-by"
515             "sort-keys <bar>"
516             "    COLOR: green >>foreground"
517             "    400 >>width"
518             "    10 >>bar-width"
519             "chart."
520         }
521     }
522
523     { $slide "Cool Things"
524         "Tab completion"
525         { $code
526             "http"
527         }
528         { $code
529             "P\" vocab:math"
530         }
531         { $code
532             "COLOR: "
533         }
534     }
535
536     { $slide "Cool things"
537         { $code "./factor -run=file-server" }
538         { $code "./factor -run=file-monitor" }
539         { $code "./factor -run=tools.dns microsoft.com" }
540         { $code "./factor -run=tools.cal" }
541     }
542 }
543
544 : svfig-talk ( -- ) svfig-slides "SVFIG Talk" slides-window ;
545
546 MAIN: svfig-talk