]> gitweb.factorcode.org Git - factor-talks.git/blob - svfig-talk/svfig-talk.factor
4987b3ad9e7435d53bacc5b2c0c3d177758ed265
[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 "Destructors"
205         "Deterministic resource disposal"
206         "Any step can fail and we don't want to leak resources"
207         "We want to conditionally clean up sometimes"
208         { $code ": do-stuff ( -- )
209     [
210         256 malloc &free
211         256 malloc &free
212         ... work goes here ...
213     ] with-destructors ;"
214         }
215     }
216
217     { $slide "Profiling"
218         { $code
219             ": fib ( m -- n )"
220             "    dup 1 > ["
221             "        [ 1 - fib ] [ 2 - fib ] bi +"
222             "    ] when ;"
223         }
224         { $code "[ 40 fib ] time" }
225         "Very slow! Let's profile it..."
226         { $code "[ 40 fib ] profile" }
227         "Not tail recursive"
228         "Call tree is huge"
229     }
230
231     { $slide "Profiling - Typed"
232         { "Type declarations with " { $link POSTPONE: TYPED: } }
233         { $code
234             "TYPED: fib ( m: fixnum -- n )"
235             "    dup 1 > ["
236             "        [ 1 - fib ] [ 2 - fib ] bi +"
237             "    ] when ;"
238         }
239         "A bit faster"
240     }
241
242     { $slide "Profiling - Memoize"
243         { "Memoization using " { $link POSTPONE: MEMO: } }
244         { $code
245             "MEMO: fib ( m -- n )"
246             "    dup 1 > ["
247             "        [ 1 - fib ] [ 2 - fib ] bi +"
248             "    ] when ;"
249         }
250         "Much faster"
251         { $code "30,000 fib number>string "
252                 "80 group [ print ] each" }
253     }
254
255     { $slide "Macros"
256         "Expand at compile-time"
257         "Return a quotation to be compiled"
258         "Can express non-static stack effects"
259         { $code "MACRO: ndup ( n -- quot )"
260                 "    [ \\ dup ] [ ] replicate-as ;"
261         }
262         { $code "[ 5 ndup ] infer" }
263         { $code "[ 5 ndup ] expand-macros" }
264     }
265
266     { $slide "PEG / EBNF"
267         { { $link POSTPONE: EBNF: } ": a complex parsing word" }
268         "Implements a custom syntax for expressing parsers"
269         { "Example: " { $vocab-link "printf" } }
270         { $code "\"Factor\" 2003 <year> ago duration>years"
271                 "\"%s is %d years old\\n\" printf" }
272         { $code "[ \"%s monkeys\" printf ] expand-macros" }
273     }
274
275     { $slide "Objects"
276         "A tuple is a user-defined class which holds named values."
277         { $code
278             "TUPLE: rectangle width height ;"
279             ""
280             "TUPLE: circle radius ;"
281         }
282     }
283
284     { $slide "Objects"
285         "Constructing instances:"
286         { $code "rectangle new" }
287         { $code "rectangle boa" }
288         "Let's encapsulate:"
289         { $code
290             ": <rectangle> ( w h -- r ) rectangle boa ;"
291             ""
292             ": <circle> ( r -- c ) circle boa ;"
293         }
294     }
295
296     { $slide "Single Dispatch"
297         "Generic words and methods"
298         { $code "GENERIC: area ( shape -- n )" }
299         "Two methods:"
300         { $code
301             "M: rectangle area"
302             "    [ width>> ] [ height>> ] bi * ;"
303             ""
304             "M: circle area radius>> sq pi * ;"
305         }
306         "We can compute areas now."
307         { $code "100 20 <rectangle> area ." }
308         { $code "3 <circle> area ." }
309     }
310
311     { $slide "Multiple Dispatch"
312         { $code "SINGLETONS: rock paper scissors ;" }
313         "Win conditions:"
314         { $code "FROM: multi-methods => GENERIC: METHOD: ;"
315                 ""
316                 "GENERIC: beats? ( obj1 obj2 -- ? )"
317                 ""
318                 "METHOD: beats? { scissors paper } 2drop t ;"
319                 "METHOD: beats? { rock  scissors } 2drop t ;"
320                 "METHOD: beats? { paper     rock } 2drop t ;"
321                 "METHOD: beats? { object  object } 2drop f ;"
322         }
323     }
324
325     { $slide "Multiple Dispatch"
326         { $code ": play. ( obj -- )"
327                 "    { rock paper scissors } random {"
328                 "        { [ 2dup beats? ] [ \"WIN\" ] }"
329                 "        { [ 2dup = ] [ \"TIE\" ] }"
330                 "        [ \"LOSE\" ]"
331                 "    } cond \"%s vs. %s: %s\\n\" printf ;"
332         }
333         "A simple interface:"
334         { $code ": rock ( -- ) \\ rock play. ;"
335                 ": paper ( -- ) \\ paper play. ;"
336                 ": scissors ( -- ) \\ scissors play. ;"
337         }
338     }
339
340     { $slide "Object System"
341         "Supports \"duck typing\""
342         "Two tuples can have a slot with the same name"
343         "Code that uses accessors will work on both"
344         "Objects are not hashtables; slot access is very fast"
345         "Tuple slots can be reordered/redefined"
346         "Instances in memory will be updated"
347     }
348
349     { $slide "Object System"
350         "Predicate classes"
351         { $code
352             "PREDICATE: positive < integer 0 > ;"
353             "PREDICATE: negative < integer 0 < ;"
354             ""
355             "GENERIC: abs ( n -- )"
356             ""
357             "M: positive abs ;"
358             "M: negative abs -1 * ;"
359             "M: integer abs ;"
360         }
361     }
362     { $slide "Object System"
363         "And lots more features..."
364         "Inheritance, type declarations, read-only slots, union, intersection, singleton classes, reflection"
365         "Object system is entirely implemented in Factor"
366     }
367
368     { $slide "Assembly"
369         "Access the Time Stamp Counter"
370         { $code
371 "HOOK: rdtsc cpu ( -- n )
372
373 M: x86.64 rdtsc
374     longlong { } cdecl [
375         RAX 0 MOV
376         RDTSC
377         RDX 32 SHL
378         RAX RDX OR
379     ] alien-assembly ;" }
380     }
381
382     { $slide "FFI"
383         { $code "NAME
384      sqrt – square root function
385
386 SYNOPSIS
387      #include <math.h>
388
389      double
390      sqrt(double x);" }
391         "Let's use it!"
392         { $code "FUNCTION: double sqrt ( double x )" }
393     }
394
395     { $slide "Infix"
396         { "Syntax experiments with " { $vocab-link "infix" } }
397         "Infix word definitions:"
398         { $code "INFIX:: foo ( x y -- z ) sqrt(x)+y**3 ;" }
399         "Inline also:"
400         { $code "[let \"hello\" :> seq"
401                 "    [infix seq[::-1] infix]"
402                 "]"
403         }
404     }
405
406     { $slide "Implementation"
407         "VM in C++ (12,000 lines of code)"
408         "VM features primitives, garbage collection, etc."
409         "Lines of code: 300,000"
410         "Lines of tests: 80,000"
411         "Lines of docs: 70,000"
412         "One big repository, and we love contributions!"
413     }
414
415     { $slide "Project Infrastructure"
416         { $url "http://factorcode.org" }
417         { $url "http://concatenative.org" }
418         { $url "http://docs.factorcode.org" }
419         { $url "http://planet.factorcode.org" }
420         { $url "http://paste.factorcode.org" }
421         "Uses our HTTP server, SSL, DB, Atom libraries..."
422     }
423
424     { $slide "Project Infrastructure"
425         "Build farm, written in Factor"
426         "Multiple OS and architecture"
427         "Builds Factor and all libraries, runs tests, makes binaries"
428         "Saves us from the burden of making releases by hand"
429         "Maintains stability"
430     }
431
432     { $slide "Demo"
433         "Let's look at a real program!"
434     }
435
436     { $slide "Questions"
437         "It is hard to cover everything in a single talk"
438         "Factor has many cool things that I didn't talk about"
439         "Questions?"
440     }
441
442     { $slide "Cool Things"
443         { $code
444             "USE: xkcd"
445             "XKCD: 138"
446         }
447         { $code
448             "USE: reddit"
449             "\"programming\" subreddit."
450         }
451     }
452
453     { $slide "Cool Things"
454         { $vocab-link "minesweeper" }
455         { $vocab-link "game-of-life" }
456         { $vocab-link "boids" }
457         { $vocab-link "pong" }
458     }
459
460     { $slide "Cool Things"
461         "8080 cpu emulator"
462         { $code
463             "\"resource:roms\" rom-root set-global"
464         }
465         { $vocab-link "roms.space-invaders" }
466     }
467
468     { $slide "Cool Things"
469         { $vocab-link "bloom-filters" }
470         { $vocab-link "cuckoo-filters" }
471         { $vocab-link "persistent" }
472         { $vocab-link "trees" }
473         { $vocab-link "tuple-arrays" }
474         { $vocab-link "specialized-arrays" }
475     }
476
477     { $slide "Cool Things"
478         { $code
479             "USE: text-to-speech"
480             "\"hello\" speak-text"
481         }
482         { $code
483             "USE: morse"
484             "\"hello\" play-as-morse"
485         }
486         { $code
487             "USE flip-text"
488             "\"hello\" flip-text ."
489         }
490         { $code
491             "USE: emojify"
492             "\"I :heart: Factor! :+1!\" emojify ."
493         }
494     }
495
496     { $slide "Cool Things"
497         { $code
498             "USE: google.charts"
499             "\"x = \\\\frac{-b \\\\pm \\\\sqrt {b^2-4ac}}{2a}\""
500             "<formula> 200 >>width 75 >>height chart."
501         }
502         { $code
503             "100 [ 100 random ] replicate"
504             "100 [ 100 random ] replicate"
505             "zip <scatter> chart."
506         }
507         { $code
508             "\"/usr/share/dict/words\" utf8 file-lines"
509             "[ >lower 1 head ] histogram-by"
510             "sort-keys <bar>"
511             "    COLOR: green >>foreground"
512             "    400 >>width"
513             "    10 >>bar-width"
514             "chart."
515         }
516     }
517
518     { $slide "Cool Things"
519         "Tab completion"
520         { $code
521             "http"
522         }
523         { $code
524             "P\" vocab:math"
525         }
526         { $code
527             "COLOR: "
528         }
529     }
530
531     { $slide "Cool things"
532         { $code "./factor -run=file-server" }
533         { $code "./factor -run=file-monitor" }
534         { $code "./factor -run=tools.dns microsoft.com" }
535         { $code "./factor -run=tools.cal" }
536     }
537 }
538
539 : svfig-talk ( -- ) svfig-slides "SVFIG Talk" slides-window ;
540
541 MAIN: svfig-talk