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