]> gitweb.factorcode.org Git - factor.git/blob - extra/otug-talk/otug-talk.factor
Merge branch 'for-slava' of git://git.rfc1149.net/factor
[factor.git] / extra / otug-talk / otug-talk.factor
1 ! Copyright (C) 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: slides help.markup math arrays hashtables namespaces
4 sequences kernel sequences parser memoize io.encodings.binary
5 locals kernel.private tools.vocabs.browser assocs quotations
6  tools.vocabs tools.annotations tools.crossref
7 help.topics math.functions compiler.tree.optimizer
8 compiler.cfg.optimizer fry
9 ui.gadgets.panes tetris tetris.game combinators generalizations
10 multiline sequences.private ;
11 IN: otug-talk
12
13 USING: cairo cairo.ffi cairo.gadgets accessors
14 io.backend ui.gadgets ;
15
16 TUPLE: png-gadget < cairo-gadget surface ;
17
18 : <png-gadget> ( file -- gadget )
19     png-gadget new-gadget
20     swap normalize-path
21     cairo_image_surface_create_from_png >>surface ; inline
22
23 M: png-gadget pref-dim* ( gadget -- )
24     surface>>
25     [ cairo_image_surface_get_width ]
26     [ cairo_image_surface_get_height ]
27     bi 2array ;
28
29 M: png-gadget render-cairo* ( gadget -- )
30     cr swap surface>> 0 0 cairo_set_source_surface
31     cr cairo_paint ;
32
33 M: png-gadget ungraft* ( gadget -- )
34     surface>> cairo_surface_destroy ;
35
36 : $bitmap ( element -- )
37     [ first <png-gadget> gadget. ] ($block) ;
38
39 : $tetris ( element -- )
40     drop [ <default-tetris> <tetris-gadget> gadget. ] ($block) ;
41
42 CONSTANT: otug-slides
43 {
44     { $slide "Factor!"
45         { $url "http://factorcode.org" }
46         "Development started in 2003"
47         "Open source (BSD license)"
48         "Influenced by Forth, Lisp, and Smalltalk"
49         "Blurs the line between language and library"
50         "Interactive development"
51     }
52     { $slide "Part 1: the language" }
53     { $slide "Basics"
54         "Stack based, dynamically typed"
55         { "A " { $emphasis "word" } " is a named piece of code" }
56         { "Values are passed between words on a " { $emphasis "stack" } }
57         "Code evaluates left to right"
58         "Example:"
59         { $code "2 3 + ." }
60     }
61     { $slide "Quotations"
62         { "A " { $emphasis "quotation" } " is a block of code pushed on the stack" }
63         { "Syntax: " { $snippet "[ ... ]" } }
64         "Example:"
65         { $code
66             "\"/etc/passwd\" ascii file-lines"
67             "[ \"#\" head? not ] filter"
68             "[ \":\" split first ] map"
69             "."
70         }
71     }
72     { $slide "Words"
73         { "We can define new words with " { $snippet ": name ... ;" } " syntax" }
74         { $code ": remove-comments ( lines -- lines' )" "    [ \"#\" head? not ] filter ;" }
75         { "Words are grouped into " { $emphasis "vocabularies" } }
76         { $link "vocab-index" }
77         "Libraries and applications are vocabularies"
78         { $vocab-link "spheres" }
79     }
80     { $slide "Constructing quotations"
81         { "Suppose we want a " { $snippet "remove-comments*" } " word" }
82         { $code ": remove-comments* ( lines string -- lines' )" "    [ ??? head? not ] filter ;" }
83         { "We use " { $link POSTPONE: '[ } " instead of " { $link POSTPONE: [ } }
84         { "Create “holes” with " { $link _ } }
85         "Holes filled in left to right when quotation pushed on the stack"
86     }
87     { $slide "Constructing quotations"
88         { $code ": remove-comments* ( lines string -- lines' )" "    '[ _ head? not ] filter ;" "" ": remove-comments ( lines -- lines' )" "    \"#\" remove-comments* ;" }
89         { { $link @ } " inserts a quotation" }
90         { $code ": replicate ( n quot -- seq )" "    '[ drop @ ] map ;" }
91         { $code "10 [ 1 10 [a,b] random ] replicate ." }
92     }
93     { $slide "Combinators"
94         { "A " { $emphasis "combinator" } " is a word taking quotations as input" }
95         { "Used for control flow, data flow, iteration" }
96         { $code "100 [ 5 mod 3 = [ \"Fizz!\" print ] when ] each" }
97         { "Control flow: " { $link if } ", " { $link when } ", " { $link unless } ", " { $link cond } }
98         { "Iteration: " { $link map } ", " { $link filter } ", " { $link all? } ", ..." }
99     }
100     { $slide "Data flow combinators - simple example"
101         "All examples so far used “pipeline style”"
102         "What about using a value more than once, or operating on values not at top of stack?"
103         { $code "{ 10 70 54 } [ sum ] [ length ] bi / ." }
104         { $code "5 [ 1 + ] [ sqrt ] [ 1 - ] tri 3array ." }
105     }
106     { $slide "Data flow combinators - cleave family"
107         { { $link bi } ", " { $link tri } ", " { $link cleave } }
108         { $bitmap "resource:extra/otug-talk/bi.png" }
109     }
110     { $slide "Data flow combinators - cleave family"
111         { { $link 2bi } ", " { $link 2tri } ", " { $link 2cleave } }
112         { $bitmap "resource:extra/otug-talk/2bi.png" }
113     }
114     { $slide "Data flow combinators"
115         "First, let's define a data type:"
116         { $code "TUPLE: person first-name last-name ;" }
117         "Make an instance:"
118         { $code "person new" "    \"Joe\" >>first-name" "    \"Sixpack\" >>last-name" }
119     }
120     { $slide "Data flow combinators"
121         "Let's do stuff with it:"
122         { $code
123             "[ first-name>> ] [ last-name>> ] bi"
124             "[ 2 head ] [ 5 head ] bi*"
125             "[ >upper ] bi@"
126             "\".\" glue ."
127         }
128     }
129     { $slide "Data flow combinators - spread family"
130         { { $link bi* } ", " { $link tri* } ", " { $link spread } }
131         { $bitmap "resource:extra/otug-talk/bi_star.png" }
132     }
133     { $slide "Data flow combinators - spread family"
134         { { $link 2bi* } }
135         { $bitmap "resource:extra/otug-talk/2bi_star.png" }
136     }
137     { $slide "Data flow combinators - apply family"
138         { { $link bi@ } ", " { $link tri@ } ", " { $link napply } }
139         { $bitmap "resource:extra/otug-talk/bi_at.png" }
140     }
141     { $slide "Data flow combinators - apply family"
142         { { $link 2bi@ } }
143         { $bitmap "resource:extra/otug-talk/2bi_at.png" }
144     }
145     { $slide "Shuffle words"
146         "When data flow combinators are not enough"
147         { $link "shuffle-words" }
148         "Lower-level, Forth/PostScript-style stack manipulation"
149     }
150     { $slide "Locals"
151         "When data flow combinators and shuffle words are not enough"
152         "Name your input parameters"
153         "Used in about 1% of all words"
154     }
155     { $slide "Locals example"
156         "Area of a triangle using Heron's formula"
157         { $code
158             <" :: area ( a b c -- x )
159     a b c + + 2 / :> p
160     p
161     p a - *
162     p b - *
163     p c - * sqrt ;">
164         }
165     }
166     { $slide "Previous example without locals"
167         "A bit unwieldy..."
168         { $code
169             <" : area ( a b c -- x )
170     [ ] [ + + 2 / ] 3bi
171     [ '[ _ - ] tri@ ] [ neg ] bi
172     * * * sqrt ;"> }
173     }
174     { $slide "More idiomatic version"
175         "But there's a trick: put the points in an array"
176         { $code <" : v-n ( v n -- w ) '[ _ - ] map ;
177
178 : area ( points -- x )
179     [ 0 suffix ] [ sum 2 / ] bi
180     v-n product sqrt ;"> }
181     }
182     ! { $slide "The parser"
183     !     "All data types have a literal syntax"
184     !     "Literal hashtables and arrays are very useful in data-driven code"
185     !     { $code "H{ { \"cookies\" 12 } { \"milk\" 10 } }" }
186     !     "Libraries can define new parsing words"
187     ! }
188     { $slide "Programming without named values"
189         "Minimal glue between words"
190         "Easy multiple return values"
191         { "Avoid useless variable names: " { $snippet "x" } ", " { $snippet "n" } ", " { $snippet "a" } ", ..." }
192         { { $link at } " and " { $link at* } }
193         { $code "at* [ ... ] [ ... ] if" }
194     }
195     { $slide "Stack language idioms"
196         "Enables new idioms not possible before"
197         "We get the effect of “keyword parameters” for free"
198         { $vocab-link "smtp-example" }
199     }
200     { $slide "“Perfect” factoring"
201         { $table
202             { { $link head } { $link head-slice } }
203             { { $link tail } { $link tail-slice } }
204         }
205         { "Modifier: " { $link from-end } }
206         { "Modifier: " { $link short } }
207         "4*2*2=16 operations, 6 words!"
208     }
209     { $slide "Modifiers"
210         "“Modifiers” can express MN combinations using M+N words"
211         { $code
212             "\"Hello, Joe\" 4 head ."
213             "\"Hello, Joe\" 3 tail ."
214             "\"Hello, Joe\" 3 from-end tail ."
215         }
216         { $code
217             "\"Hello world\" 5 short head ."
218             "\"Hi\" 5 short tail ."
219         }
220     }
221     { $slide "Modifiers"
222         { "C-style " { $snippet "while" } " and " { $snippet "do while" } " loops" }
223     }
224     { $slide "Modifiers"
225         { $code ": bank ( n -- n )" "    readln string>number +" "    dup \"Balance: $\" write . ;" }
226         { $code "0 [ dup 0 > ] [ bank ] while" }
227     }
228     { $slide "Modifiers"
229         { $code "0 [ dup 0 > ] [ bank ] [ ] do while" }
230         { { $link do } " executes one iteration of a " { $link while } " loop" }
231         { { $link while } " calls " { $link do } }
232     }
233     { $slide "More “pipeline style” code"
234         { "Suppose we want to get the price of the customer's first order, but any one of the steps along the way could be a nil value (" { $link f } " in Factor):" }
235         { $code
236             "dup [ orders>> ] when"
237             "dup [ first ] when"
238             "dup [ price>> ] when"
239         }
240     }
241     { $slide "This is hard with mainstream syntax!"
242         { $code
243             <" var customer = ...;
244 var orders = (customer == null ? null : customer.orders);
245 var order = (orders == null ? null : orders[0]);
246 var price = (order == null ? null : order.price);"> }
247     }
248     { $slide "An ad-hoc solution"
249         "Something like..."
250         { $code "var price = customer.?orders.?[0].?price;" }
251     }
252     ! { $slide "Stack languages are fundamental"
253     !     "Very simple semantics"
254     !     "Easy to generate stack code programatically"
255     !     "Everything is almost entirely library code in Factor"
256     !     "Factor is easy to extend"
257     ! }
258     { $slide "Part 2: the implementation" }
259     { $slide "Interactive development"
260         { $tetris }
261     }
262     { $slide "Application deployment"
263         { $vocab-link "webkit-demo" }
264         "Demonstrates Cocoa binding"
265         "Let's deploy a stand-alone binary with the deploy tool"
266         "Deploy tool generates binaries with no external dependencies"
267     }
268     { $slide "The UI"
269         "Renders with OpenGL"
270         "Backends for Cocoa, Windows, X11: managing windows, input events, clipboard"
271         "Cross-platform API"
272     }
273     { $slide "UI example"
274         { $code
275     <" <pile>
276     { 5 5 } >>gap
277     1 >>fill
278     "Hello world!" <label> add-gadget
279     "Click me!" [ drop beep ]
280     <bevel-button> add-gadget
281     <editor> <scroller> add-gadget
282 "UI test" open-window "> }
283     }
284     { $slide "Help system"
285         "Help markup is just literal data"
286         { "Look at the help for " { $link T{ link f + } } }
287         "These slides are built with the help system and a custom style sheet"
288         { $vocab-link "otug-talk" }
289     }
290     { $slide "The VM"
291         "Lowest level is the VM: ~12,000 lines of C"
292         "Generational garbage collection"
293         "Non-optimizing compiler"
294         "Loads an image file and runs it"
295         "Initial image generated from another Factor instance:"
296         { $code "\"x86.32\" make-image" }
297     }
298     { $slide "The core library"
299         "Core library, ~9,000 lines of Factor"
300         "Source parser, arrays, strings, math, hashtables, basic I/O, ..."
301         "Packaged into boot image because VM doesn't have a parser"
302     }
303     { $slide "The basis library"
304         "Basis library, ~80,000 lines of Factor"
305         "Bootstrap process loads code from basis, runs compiler, saves image"
306         "Loaded by default: optimizing compiler, tools, help system, UI, ..."
307         "Optional: HTTP server, XML, database access, ..."
308     }
309     { $slide "Non-optimizing compiler"
310         "Glues together chunks of machine code"
311         "Most words compiled as calls, some inlined"
312         "Used for listener interactions, and bootstrap"
313     }
314     { $slide "Optimizing compiler"
315         "Converts Factor code into high-level SSA form"
316         "Performs global optimizations"
317         "Converts high-level SSA into low-level SSA"
318         "Performs local optimizations"
319         "Register allocation"
320         "Machine code generation: x86, x86-64, PowerPC"
321     }
322     { $slide "Optimizing compiler"
323         "Makes high-level language features cheap to use"
324         "Eliminate redundant method dispatch by inferring types"
325         "Eliminate redundant integer overflow checks by inferring ranges"
326     }
327     { $slide "Optimizing compiler"
328         "Eliminate redundant memory allocation (escape analysis)"
329         "Eliminate redundant loads/stores (alias analysis)"
330         "Eliminate redundant computations (value numbering)"
331     }
332     { $slide "Project infrastructure"
333         { $url "http://factorcode.org" }
334         { $url "http://concatenative.org" }
335         { $url "http://docs.factorcode.org" }
336         { $url "http://planet.factorcode.org" }
337         "Uses our HTTP server, SSL, DB, Atom libraries..."
338     }
339     { $slide "Project infrastructure"
340         "Build farm, written in Factor"
341         "12 platforms"
342         "Builds Factor and all libraries, runs tests, makes binaries"
343         "Good for increasing stability"
344     }
345     { $slide "Community"
346         "#concatenative irc.freenode.net: 60-70 users"
347         "factor-talk@lists.sf.net: 189 subscribers"
348         "About 30 people have code in the Factor repository"
349         "Easy to get started: binaries, lots of docs, friendly community..."
350     }
351     { $slide "Selling points"
352         "Expressive language"
353         "Comprehensive library"
354         "Efficient implementation"
355         "Powerful interactive tools"
356         "Stand-alone application deployment"
357         "Moving fast"
358     }
359     { $slide "That's all, folks"
360         "It is hard to cover everything in a single talk"
361         "Factor has many cool things that I didn't talk about"
362         "Questions?"
363     }
364 }
365
366 : otug-talk ( -- ) otug-slides slides-window ;
367
368 MAIN: otug-talk