]> gitweb.factorcode.org Git - factor-talks.git/blob - svfig-talk/svfig-talk.factor
svfig-talk: more 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     }
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.32 rdtsc
374     longlong { } cdecl [
375         RDTSC
376     ] alien-assembly ;
377
378 M: x86.64 rdtsc
379     longlong { } cdecl [
380         RAX 0 MOV
381         RDTSC
382         RDX 32 SHL
383         RAX RDX OR
384     ] alien-assembly ;" }
385     }
386
387     { $slide "FFI"
388         { $code "NAME
389      sqrt – square root function
390
391 SYNOPSIS
392      #include <math.h>
393
394      double
395      sqrt(double x);" }
396         "Let's use it!"
397         { $code "FUNCTION: double sqrt ( double x )" }
398     }
399
400     { $slide "Infix"
401         { "Syntax experiments with " { $vocab-link "infix" } }
402         "Infix word definitions:"
403         { $code "INFIX:: foo ( x y -- z ) sqrt(x)+y**3 ;" }
404         "Inline also:"
405         { $code "[let \"hello\" :> seq"
406                 "    [infix seq[::-1] infix]"
407                 "]"
408         }
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 "Demo"
438         "Let's look at a real program!"
439     }
440
441     { $slide "Questions"
442         "It is hard to cover everything in a single talk"
443         "Factor has many cool things that I didn't talk about"
444         "Questions?"
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