summaryrefslogtreecommitdiff
path: root/otug-talk/otug-talk.factor
blob: f56feb67b2871165a204adedd001d185f89e9012 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
! Copyright (C) 2008 Slava Pestov.
! See https://factorcode.org/license.txt for BSD license.
USING: slides help.markup math arrays hashtables namespaces
kernel sequences parser memoize io.encodings.binary
locals kernel.private help.vocabs assocs quotations
tools.annotations tools.crossref help.topics math.functions
compiler.tree.optimizer compiler.cfg.optimizer fry
ui.gadgets.panes tetris tetris.game combinators generalizations
multiline sequences.private ;
IN: otug-talk

: $tetris ( element -- )
    drop [ <default-tetris> <tetris-gadget> gadget. ] ($block) ;

CONSTANT: otug-slides
{
    { $slide "Factor!"
        { $url "https://factorcode.org" }
        "Development started in 2003"
        "Open source (BSD license)"
        "Influenced by Forth, Lisp, and Smalltalk"
        "Blurs the line between language and library"
        "Interactive development"
    }
    { $slide "Part 1: the language" }
    { $slide "Basics"
        "Stack based, dynamically typed"
        { "A " { $emphasis "word" } " is a named piece of code" }
        { "Values are passed between words on a " { $emphasis "stack" } }
        "Code evaluates left to right"
        "Example:"
        { $code "2 3 + ." }
    }
    { $slide "Quotations"
        { "A " { $emphasis "quotation" } " is a block of code pushed on the stack" }
        { "Syntax: " { $snippet "[ ... ]" } }
        "Example:"
        { $code
            "\"/etc/passwd\" ascii file-lines"
            "[ \"#\" head? ] reject"
            "[ \":\" split first ] map"
            "."
        }
    }
    { $slide "Words"
        { "We can define new words with " { $snippet ": name ... ;" } " syntax" }
        { $code ": remove-comments ( lines -- lines' )" "    [ \"#\" head? ] reject ;" }
        { "Words are grouped into " { $emphasis "vocabularies" } }
        { $link "vocab-index" }
        "Libraries and applications are vocabularies"
        { $vocab-link "spheres" }
    }
    { $slide "Constructing quotations"
        { "Suppose we want a " { $snippet "remove-comments*" } " word" }
        { $code ": remove-comments* ( lines string -- lines' )" "    [ ??? head? ] reject ;" }
        { "We use " { $link POSTPONE: '[ } " instead of " { $link POSTPONE: [ } }
        { "Create “holes” with " { $link POSTPONE: _ } }
        "Holes filled in left to right when quotation pushed on the stack"
    }
    { $slide "Constructing quotations"
        { $code ": remove-comments* ( lines string -- lines' )" "    '[ _ head? ] reject ;" "" ": remove-comments ( lines -- lines' )" "    \"#\" remove-comments* ;" }
        { { $link POSTPONE: @ } " inserts a quotation" }
        { $code ": replicate ( n quot -- seq )" "    '[ drop @ ] map ;" }
        { $code "10 [ 1 10 [a,b] random ] replicate ." }
    }
    { $slide "Combinators"
        { "A " { $emphasis "combinator" } " is a word taking quotations as input" }
        { "Used for control flow, data flow, iteration" }
        { $code "100 <iota> [ 5 mod 3 = [ \"Fizz!\" print ] when ] each" }
        { "Control flow: " { $link if } ", " { $link when } ", " { $link unless } ", " { $link cond } }
        { "Iteration: " { $link map } ", " { $link filter } ", " { $link all? } ", ..." }
    }
    { $slide "Data flow combinators - simple example"
        "All examples so far used “pipeline style”"
        "What about using a value more than once, or operating on values not at top of stack?"
        { $code "{ 10 70 54 } [ sum ] [ length ] bi / ." }
        { $code "5 [ 1 + ] [ sqrt ] [ 1 - ] tri 3array ." }
    }
    { $slide "Data flow combinators - cleave family"
        { { $link bi } ", " { $link tri } ", " { $link cleave } }
        { $image "vocab:otug-talk/bi.tiff" }
    }
    { $slide "Data flow combinators - cleave family"
        { { $link 2bi } ", " { $link 2tri } ", " { $link 2cleave } }
        { $image "vocab:otug-talk/2bi.tiff" }
    }
    { $slide "Data flow combinators"
        "First, let's define a data type:"
        { $code "TUPLE: person first-name last-name ;" }
        "Make an instance:"
        { $code "person new" "    \"Joe\" >>first-name" "    \"Sixpack\" >>last-name" }
    }
    { $slide "Data flow combinators"
        "Let's do stuff with it:"
        { $code
            "[ first-name>> ] [ last-name>> ] bi"
            "[ 2 head ] [ 5 head ] bi*"
            "[ >upper ] bi@"
            "\".\" glue ."
        }
    }
    { $slide "Data flow combinators - spread family"
        { { $link bi* } ", " { $link tri* } ", " { $link spread } }
        { $image "vocab:otug-talk/bi_star.tiff" }
    }
    { $slide "Data flow combinators - spread family"
        { { $link 2bi* } }
        { $image "vocab:otug-talk/2bi_star.tiff" }
    }
    { $slide "Data flow combinators - apply family"
        { { $link bi@ } ", " { $link tri@ } ", " { $link napply } }
        { $image "vocab:otug-talk/bi_at.tiff" }
    }
    { $slide "Data flow combinators - apply family"
        { { $link 2bi@ } }
        { $image "vocab:otug-talk/2bi_at.tiff" }
    }
    { $slide "Shuffle words"
        "When data flow combinators are not enough"
        { $link "shuffle-words" }
        "Lower-level, Forth/PostScript-style stack manipulation"
    }
    { $slide "Locals"
        "When data flow combinators and shuffle words are not enough"
        "Name your input parameters"
        "Used in about 1% of all words"
    }
    { $slide "Locals example"
        "Area of a triangle using Heron's formula"
        { $code
            ":: area ( a b c -- x )
    a b c + + 2 / :> p
    p
    p a - *
    p b - *
    p c - * sqrt ;"
        }
    }
    { $slide "Previous example without locals"
        "A bit unwieldy..."
        { $code
            ": area ( a b c -- x )
    [ ] [ + + 2 / ] 3bi
    [ '[ _ - ] tri@ ] [ neg ] bi
    * * * sqrt ;" }
    }
    { $slide "More idiomatic version"
        "But there's a trick: put the points in an array"
        { $code ": v-n ( v n -- w ) '[ _ - ] map ;

: area ( points -- x )
    [ 0 suffix ] [ sum 2 / ] bi
    v-n product sqrt ;" }
    }
    ! { $slide "The parser"
    !     "All data types have a literal syntax"
    !     "Literal hashtables and arrays are very useful in data-driven code"
    !     { $code "H{ { \"cookies\" 12 } { \"milk\" 10 } }" }
    !     "Libraries can define new parsing words"
    ! }
    { $slide "Programming without named values"
        "Minimal glue between words"
        "Easy multiple return values"
        { "Avoid useless variable names: " { $snippet "x" } ", " { $snippet "n" } ", " { $snippet "a" } ", ..." }
        { { $link at } " and " { $link at* } }
        { $code "at* [ ... ] [ ... ] if" }
    }
    { $slide "Stack language idioms"
        "Enables new idioms not possible before"
        "We get the effect of “keyword parameters” for free"
        { $vocab-link "smtp-example" }
    }
    { $slide "“Perfect” factoring"
        { $table
            { { $link head } { $link head-slice } }
            { { $link tail } { $link tail-slice } }
        }
        { "Modifier: " { $link from-end } }
        { "Modifier: " { $link short } }
        "4*2*2=16 operations, 6 words!"
    }
    { $slide "Modifiers"
        "“Modifiers” can express MN combinations using M+N words"
        { $code
            "\"Hello, Joe\" 4 head ."
            "\"Hello, Joe\" 3 tail ."
            "\"Hello, Joe\" 3 from-end tail ."
        }
        { $code
            "\"Hello world\" 5 short head ."
            "\"Hi\" 5 short tail ."
        }
    }
    { $slide "Modifiers"
        { "C-style " { $snippet "while" } " and " { $snippet "do while" } " loops" }
    }
    { $slide "Modifiers"
        { $code ": bank ( n -- n )" "    readln string>number +" "    dup \"Balance: $\" write . ;" }
        { $code "0 [ dup 0 > ] [ bank ] while" }
    }
    { $slide "Modifiers"
        { $code "0 [ dup 0 > ] [ bank ] [ ] do while" }
        { { $link do } " executes one iteration of a " { $link while } " loop" }
        { { $link while } " calls " { $link do } }
    }
    { $slide "More “pipeline style” code"
        { "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):" }
        { $code
            "dup [ orders>> ] when"
            "dup [ first ] when"
            "dup [ price>> ] when"
        }
    }
    { $slide "This is hard with mainstream syntax!"
        { $code
            "var customer = ...;
var orders = (customer == null ? null : customer.orders);
var order = (orders == null ? null : orders[0]);
var price = (order == null ? null : order.price);" }
    }
    { $slide "An ad-hoc solution"
        "Something like..."
        { $code "var price = customer.?orders.?[0].?price;" }
    }
    ! { $slide "Stack languages are fundamental"
    !     "Very simple semantics"
    !     "Easy to generate stack code programmatically"
    !     "Everything is almost entirely library code in Factor"
    !     "Factor is easy to extend"
    ! }
    { $slide "Part 2: the implementation" }
    { $slide "Interactive development"
        { $tetris }
    }
    { $slide "Application deployment"
        { $vocab-link "webkit-demo" }
        "Demonstrates Cocoa binding"
        "Let's deploy a stand-alone binary with the deploy tool"
        "Deploy tool generates binaries with no external dependencies"
    }
    { $slide "The UI"
        "Renders with OpenGL"
        "Backends for Cocoa, Windows, X11: managing windows, input events, clipboard"
        "Cross-platform API"
    }
    { $slide "UI example"
        { $code
    "<pile>
    { 5 5 } >>gap
    1 >>fill
    \"Hello world!\" <label> add-gadget
    \"Click me!\" [ drop beep ]
    <border-button> add-gadget
    <editor> <scroller> add-gadget
\"UI test\" open-window" }
    }
    { $slide "Help system"
        "Help markup is just literal data"
        { "Look at the help for " { $link T{ link f + } } }
        "These slides are built with the help system and a custom style sheet"
        { $vocab-link "otug-talk" }
    }
    { $slide "The VM"
        "Lowest level is the VM: ~12,000 lines of C"
        "Generational garbage collection"
        "Non-optimizing compiler"
        "Loads an image file and runs it"
        "Initial image generated from another Factor instance:"
        { $code "\"x86.32\" make-image" }
    }
    { $slide "The core library"
        "Core library, ~9,000 lines of Factor"
        "Source parser, arrays, strings, math, hashtables, basic I/O, ..."
        "Packaged into boot image because VM doesn't have a parser"
    }
    { $slide "The basis library"
        "Basis library, ~80,000 lines of Factor"
        "Bootstrap process loads code from basis, runs compiler, saves image"
        "Loaded by default: optimizing compiler, tools, help system, UI, ..."
        "Optional: HTTP server, XML, database access, ..."
    }
    { $slide "Non-optimizing compiler"
        "Glues together chunks of machine code"
        "Most words compiled as calls, some inlined"
        "Used for listener interactions, and bootstrap"
    }
    { $slide "Optimizing compiler"
        "Converts Factor code into high-level SSA form"
        "Performs global optimizations"
        "Converts high-level SSA into low-level SSA"
        "Performs local optimizations"
        "Register allocation"
        "Machine code generation: x86, x86-64, PowerPC"
    }
    { $slide "Optimizing compiler"
        "Makes high-level language features cheap to use"
        "Eliminate redundant method dispatch by inferring types"
        "Eliminate redundant integer overflow checks by inferring ranges"
    }
    { $slide "Optimizing compiler"
        "Eliminate redundant memory allocation (escape analysis)"
        "Eliminate redundant loads/stores (alias analysis)"
        "Eliminate redundant computations (value numbering)"
    }
    { $slide "Project infrastructure"
        { $url "https://factorcode.org" }
        { $url "https://concatenative.org" }
        { $url "https://docs.factorcode.org" }
        { $url "https://planet.factorcode.org" }
        "Uses our HTTP server, SSL, DB, Atom libraries..."
    }
    { $slide "Project infrastructure"
        "Build farm, written in Factor"
        "12 platforms"
        "Builds Factor and all libraries, runs tests, makes binaries"
        "Good for increasing stability"
    }
    { $slide "Community"
        "#concatenative irc.freenode.net: 60-70 users"
        "factor-talk@lists.sf.net: 189 subscribers"
        "About 30 people have code in the Factor repository"
        "Easy to get started: binaries, lots of docs, friendly community..."
    }
    { $slide "Selling points"
        "Expressive language"
        "Comprehensive library"
        "Efficient implementation"
        "Powerful interactive tools"
        "Stand-alone application deployment"
        "Moving fast"
    }
    { $slide "That's all, folks"
        "It is hard to cover everything in a single talk"
        "Factor has many cool things that I didn't talk about"
        "Questions?"
    }
}

: otug-talk ( -- )
      otug-slides "OTUG talk" slides-window ;

MAIN: otug-talk