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