]> gitweb.factorcode.org Git - factor-talks.git/commitdiff
Adding all the talks.
authorJohn Benediktsson <mrjbq7@gmail.com>
Wed, 17 Mar 2021 04:35:26 +0000 (21:35 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Wed, 17 Mar 2021 04:35:26 +0000 (21:35 -0700)
41 files changed:
README.md [new file with mode: 0644]
chicago-talk/authors.txt [new file with mode: 0644]
chicago-talk/chicago-talk.factor [new file with mode: 0644]
chicago-talk/deploy.factor [new file with mode: 0644]
chicago-talk/summary.txt [new file with mode: 0644]
chicago-talk/tags.txt [new file with mode: 0644]
galois-talk/authors.txt [new file with mode: 0644]
galois-talk/galois-talk.factor [new file with mode: 0644]
galois-talk/summary.txt [new file with mode: 0644]
galois-talk/tags.txt [new file with mode: 0644]
google-tech-talk/authors.txt [new file with mode: 0644]
google-tech-talk/google-tech-talk.factor [new file with mode: 0644]
google-tech-talk/summary.txt [new file with mode: 0644]
google-tech-talk/tags.txt [new file with mode: 0644]
hmc-talk/hmc-talk.factor [new file with mode: 0644]
jvm-summit-talk/authors.txt [new file with mode: 0644]
jvm-summit-talk/jvm-summit-talk.factor [new file with mode: 0644]
jvm-summit-talk/summary.txt [new file with mode: 0644]
jvm-summit-talk/tags.txt [new file with mode: 0644]
minneapolis-talk/authors.txt [new file with mode: 0644]
minneapolis-talk/deploy.factor [new file with mode: 0644]
minneapolis-talk/minneapolis-talk.factor [new file with mode: 0644]
minneapolis-talk/summary.txt [new file with mode: 0644]
minneapolis-talk/tags.txt [new file with mode: 0644]
otug-talk/2bi.tiff [new file with mode: 0644]
otug-talk/2bi_at.tiff [new file with mode: 0644]
otug-talk/2bi_star.tiff [new file with mode: 0644]
otug-talk/authors.txt [new file with mode: 0644]
otug-talk/bi.tiff [new file with mode: 0644]
otug-talk/bi_at.tiff [new file with mode: 0644]
otug-talk/bi_star.tiff [new file with mode: 0644]
otug-talk/otug-talk.factor [new file with mode: 0644]
otug-talk/summary.txt [new file with mode: 0644]
otug-talk/tags.txt [new file with mode: 0644]
tc-lisp-talk/authors.txt [new file with mode: 0644]
tc-lisp-talk/tags.txt [new file with mode: 0644]
tc-lisp-talk/tc-lisp-talk.factor [new file with mode: 0644]
vpri-talk/authors.txt [new file with mode: 0644]
vpri-talk/summary.txt [new file with mode: 0644]
vpri-talk/tags.txt [new file with mode: 0644]
vpri-talk/vpri-talk.factor [new file with mode: 0644]

diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..a5aa3e8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,12 @@
+# Factor
+
+The Factor project is maintained and mirrored at
+[https://github.com/factor/factor](https://github.com/factor/factor)
+
+## Talks and Presentations
+
+Various talks and presentations that have been given are included here as
+runnable vocabularies.
+
+If you'd like to run these, you can add this directory as a ``vocab-root``
+and then ``"name-of-the-talk-to-launch" run``.
diff --git a/chicago-talk/authors.txt b/chicago-talk/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/chicago-talk/chicago-talk.factor b/chicago-talk/chicago-talk.factor
new file mode 100644 (file)
index 0000000..02ddc42
--- /dev/null
@@ -0,0 +1,53 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: slides help.markup ;
+IN: talks.chicago-talk
+
+CONSTANT: chicago-slides
+{
+    { $slide "factor"
+      { $url "http://factorcode.org" }
+    }
+    { $slide "goals"
+      "high level language"
+      "expressive and extensible"
+      "reasonable performance"
+      "interactive development with arbitrary redefinition"
+      "standalone app deployment (strip out compiler and REPL)"
+    }
+    { $slide "challenges"
+
+      "higher-order functions"
+      "dynamic typing"
+      "memory allocation"
+      "float boxing/unboxing"
+      "integer overflow checks"
+      "user-defined abstractions"
+    }
+    { $slide "implementation"
+      "VM: 12 kloc of C, library: >100 kloc of Factor"
+      "generational copying garbage collection, card marking write barrier"
+      "full continuations, tail calls"
+      "simple non-optimizing “bootstrap” compiler"
+      "optimizing compiler"
+    }
+    { $slide "optimizing compiler"
+      "about 12,000 lines of Factor code"
+      "targets x86-32, x86-64, PowerPC"
+      "factor code ⇒ high-level SSA ⇒ low-level SSA ⇒ machine code"
+    }
+    { $slide "high-level optimizer"
+      "macro expansion, defunctionalization"
+      "type and interval inference, sparse conditional constant propagation, method inlining"
+      "escape analysis and tuple unboxing"
+    }
+    { $slide "low-level optimizer"
+      "alias analysis, value numbering, write barrier elimination"
+      "linear scan register allocation"
+    }
+}
+
+: chicago-talk ( -- )
+    chicago-slides "Chicago talk" slides-window ;
+
+MAIN: chicago-talk
diff --git a/chicago-talk/deploy.factor b/chicago-talk/deploy.factor
new file mode 100644 (file)
index 0000000..ce8739e
--- /dev/null
@@ -0,0 +1,11 @@
+USING: tools.deploy.config ;
+V{
+    { deploy-ui? t }
+    { deploy-io 3 }
+    { deploy-reflection 1 }
+    { deploy-math? t }
+    { deploy-word-props? f }
+    { deploy-c-types? f }
+    { "stop-after-last-window?" t }
+    { deploy-name "Chicago Talk" }
+}
diff --git a/chicago-talk/summary.txt b/chicago-talk/summary.txt
new file mode 100644 (file)
index 0000000..229e1a3
--- /dev/null
@@ -0,0 +1 @@
+Slides for a talk at the Pycon VM Summit, Chicago, IL, March 2009
diff --git a/chicago-talk/tags.txt b/chicago-talk/tags.txt
new file mode 100644 (file)
index 0000000..8ee64cd
--- /dev/null
@@ -0,0 +1 @@
+talks
diff --git a/galois-talk/authors.txt b/galois-talk/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/galois-talk/galois-talk.factor b/galois-talk/galois-talk.factor
new file mode 100644 (file)
index 0000000..87e7914
--- /dev/null
@@ -0,0 +1,312 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: slides help.markup math arrays hashtables namespaces
+sequences kernel parser memoize io.encodings.binary
+locals kernel.private help.vocabs assocs quotations
+urls peg.ebnf tools.annotations tools.crossref
+help.topics math.functions compiler.tree.optimizer
+compiler.cfg.optimizer fry ;
+IN: talks.galois-talk
+
+CONSTANT: galois-slides
+{
+    { $slide "Factor!"
+        { $url "http://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 "Words and the stack"
+        "Stack based, dynamically typed"
+        { $code "{ 1 1 3 4 4 8 9 9 } dup duplicates diff ." }
+        "Words: named code snippets"
+        { $code ": remove-duplicates ( seq -- seq' )" "    dup duplicates diff ;" }
+        { $code "{ 1 1 3 4 4 8 9 9 } remove-duplicates ." }
+    }
+    { $slide "Vocabularies"
+        "Vocabularies: named sets of words"
+        { $link "vocab-index" }
+        { { $link POSTPONE: USING: } " loads dependencies" }
+        "Source, docs, tests in one place"
+    }
+    { $slide "Interactive development"
+        "Programming is hard, let's play tetris"
+        { $vocab-link "tetris" }
+        "Tetris is hard too... let's cheat"
+        "Factor workflow: change code, F2, test, repeat"
+    }
+    { $slide "Quotations"
+        "Quotation: unnamed block of code"
+        "Combinators: words taking quotations"
+        { $code "10 dup 0 < [ 1 - ] [ 1 + ] if ." }
+        { $code "{ -1 1 -2 0 3 } [ 0 max ] map ." }
+        "Partial application:"
+        { $code ": clamp ( seq n -- seq' ) '[ _ max ] map ;" "{ -1 1 -2 0 3 } 0 clamp" }
+    }
+    { $slide "Object system"
+        "CLOS with single dispatch"
+        "A tuple is a user-defined class which holds named values."
+        { $code
+            "TUPLE: rectangle width height ;"
+            "TUPLE: circle radius ;"
+        }
+    }
+    { $slide "Object system"
+        "Constructing instances:"
+        { $code "rectangle new" }
+        { $code "rectangle boa" }
+        "Let's encapsulate:"
+        { $code
+            ": <rectangle> ( w h -- r ) rectangle boa ;"
+            ": <circle> ( r -- c ) circle boa ;"
+        }
+    }
+    { $slide "Object system"
+        "Generic words and methods"
+        { $code "GENERIC: area ( shape -- n )" }
+        "Two methods:"
+        { $code
+            "USE: math.constants"
+            ""
+            "M: rectangle area"
+            "    [ width>> ] [ height>> ] bi * ;"
+            ""
+            "M: circle area radius>> sq pi * ;"
+        }
+    }
+    { $slide "Object system"
+        "We can compute areas now."
+        { $code "100 20 <rectangle> area ." }
+        { $code "3 <circle> area ." }
+    }
+    { $slide "Object system"
+        "Object system handles dynamic redefinition very well"
+        { $code "TUPLE: person name age occupation ;" }
+        "Make an instance..."
+    }
+    { $slide "Object system"
+        "Let's add a new slot:"
+        { $code "TUPLE: person name age address occupation ;" }
+        "Fill it in with inspector..."
+        "Change the order:"
+        { $code "TUPLE: person name occupation address ;" }
+    }
+    { $slide "Object system"
+        "How does it work?"
+        "Objects are not hashtables; slot access is very fast"
+        "Redefinition walks the heap; expensive but rare"
+    }
+    { $slide "Object system"
+        "Supports \"duck typing\""
+        "Two tuples can have a slot with the same name"
+        "Code that uses accessors will work on both"
+        "Accessors are auto-generated generic words"
+    }
+    { $slide "Object system"
+        "Predicate classes"
+        { $code
+            "PREDICATE: positive < integer 0 > ;"
+            "PREDICATE: negative < integer 0 < ;"
+            ""
+            "GENERIC: abs ( n -- )"
+            ""
+            "M: positive abs ;"
+            "M: negative abs -1 * ;"
+            "M: integer abs ;"
+        }
+    }
+    { $slide "Object system"
+        "More: inheritance, type declarations, read-only slots, union, intersection, singleton classes, reflection"
+        "Object system is entirely implemented in Factor"
+    }
+    { $slide "The parser"
+        "All data types have a literal syntax"
+        "Literal hashtables and arrays are very useful in data-driven code"
+        "\"Code is data\" because quotations are objects (enables Lisp-style macros)"
+        { $code "H{ { \"cookies\" 12 } { \"milk\" 10 } }" }
+        "Libraries can define new parsing words"
+    }
+    { $slide "Example: regexp"
+        { $vocab-link "regexp" }
+        "Pre-compiles regexp at parse time"
+        "Implemented with library code"
+        { $code "USE: regexp" }
+        { $code "\"ababbc\" \"[ab]+c\" <regexp> matches? ." }
+        { $code "\"ababbc\" R/ [ab]+c/ matches? ." }
+    }
+    { $slide "Example: memoization"
+        { "Memoization with " { $link POSTPONE: MEMO: } }
+        { $code
+            ": fib ( m -- n )"
+            "    dup 1 > ["
+            "        [ 1 - fib ] [ 2 - fib ] bi +"
+            "    ] when ;"
+        }
+        "Very slow! Let's profile it..."
+    }
+    { $slide "Example: memoization"
+        { "Let's use " { $link POSTPONE: MEMO: } " instead of " { $link POSTPONE: : } }
+        { $code
+            "MEMO: fib ( m -- n )"
+            "    dup 1 > ["
+            "        [ 1 - fib ] [ 2 - fib ] bi +"
+            "    ] when ;"
+        }
+        "Much faster"
+    }
+    { $slide "Meta-circularity"
+        { { $link POSTPONE: MEMO: } " is just a library word" }
+        { "But so is " { $link POSTPONE: : } }
+        "Factor's parser is written in Factor"
+        { "All syntax is just parsing words: " { $link POSTPONE: [ } ", " { $link POSTPONE: " } }
+    }
+    { $slide "Extensible syntax, DSLs"
+        "Most parsing words fall in one of two categories"
+        "First category: literal syntax for new data types"
+        "Second category: defining new types of words"
+        "Some parsing words are more complicated"
+    }
+    { $slide "Example: printf"
+        { { $link POSTPONE: EBNF: } ": a complex parsing word" }
+        "Implements a custom syntax for expressing parsers: like OMeta!"
+        { "Example: " { $vocab-link "printf-example" } }
+        { $code "\"cheese\" \"vegan\" \"%s is not %s\\n\" printf" }
+        { $code "\"Factor\" 5 \"%s is %d years old\\n\" printf" }
+    }
+    { $slide "Example: simple web browser"
+        { $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 "Locals and lexical scope"
+        "Sometimes, there's no good stack solution to a problem"
+        "Or, you're porting existing code in a quick-and-dirty way"
+        "Our solution: implement named locals as a DSL in Factor"
+        "Influenced by Scheme and Lisp"
+    }
+    { $slide "Locals and lexical scope"
+        { "Define lambda words with " { $link POSTPONE: :: } }
+        { "Establish bindings with " { $link POSTPONE: [let } " and " { $snippet "[let*" } }
+        "Mutable bindings with correct semantics"
+        { "Named inputs for quotations with " { $link POSTPONE: [| } }
+        "Full closures"
+    }
+    { $slide "Locals and lexical scope"
+        "Combinator with 5 parameters!"
+        { $code
+            ":: branch ( a b neg zero pos -- )"
+            "    a b = zero [ a b < neg pos if ] if ; inline"
+        }
+        "Unwieldy with the stack"
+    }
+    { $slide "Locals and lexical scope"
+        { $code
+            ": check-drinking-age ( age -- )"
+            "    21"
+            "    [ \"You're underage!\" print ]"
+            "    [ \"Grats, you're now legal\" print ]"
+            "    [ \"Go get hammered\" print ]"
+            "    branch ;"
+        }
+    }
+    { $slide "Locals and lexical scope"
+        "Locals are entirely implemented in Factor"
+        "Example of compile-time meta-programming"
+        "No performance penalty -vs- using the stack"
+        "In the base image, only 59 words out of 13,000 use locals"
+    }
+    { $slide "More about partial application"
+        { { $link POSTPONE: '[ } " is \"fry syntax\"" }
+        { $code "'[ _ + ] == [ + ] curry" }
+        { $code "'[ @ t ] == [ t ] compose" }
+        { $code "'[ _ nth @ ] == [ [ nth ] curry ] dip compose" }
+        { $code "'[ [ _ ] dip nth ] == [ [ ] curry dip nth ] curry" }
+        { "Fry and locals desugar to " { $link curry } ", " { $link compose } }
+    }
+    { $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 "talks.galois-talk" }
+    }
+    { $slide "Why stack-based?"
+        "Because nobody else is doing it"
+        "Interesting properties: concatenation is composition, chaining functions together, \"fluent\" interfaces, new combinators"
+        { $vocab-link "smtp-example" }
+        { $code
+            "{ \"chicken\" \"beef\" \"pork\" \"turkey\" }"
+            "[ 5 short head ] map ."
+        }
+    }
+    { $slide "Implementation"
+        "VM: garbage collection, bignums, ..."
+        "Bootstrap image: parser, hashtables, object system, ..."
+        "Non-optimizing compiler"
+        "Stage 2 bootstrap: optimizing compiler, UI, ..."
+        "Full image contains machine code"
+    }
+    { $slide "Compiler"
+        { "Let's look at " { $vocab-link "benchmark.mandel" } }
+        "A naive implementation would be very slow"
+        "Combinators, partial application"
+        "Boxed complex numbers"
+        "Boxed floats"
+        { "Redundancy in " { $link absq } " and " { $link sq } }
+    }
+    { $slide "Compiler: high-level optimizer"
+        "High-level SSA IR"
+        "Type inference (classes, intervals, arrays with a fixed length, literals, ...)"
+        "Escape analysis and tuple unboxing"
+    }
+    { $slide "Compiler: high-level optimizer"
+        "Loop index becomes a fixnum, complex numbers unboxed, generic arithmetic inlined, higher-order code become first-order..."
+        { $code "[ c pixel ] optimized." }
+    }
+    { $slide "Compiler: low-level optimizer"
+        "Low-level SSA IR"
+        "Alias analysis"
+        "Value numbering"
+        "Linear scan register allocation"
+    }
+    { $slide "Compiler: low-level optimizer"
+        "Redundant stack operations eliminated, intermediate floats unboxed..."
+        { $code "[ c pixel ] regs." }
+    }
+    { $slide "Garbage collection"
+        "All roots are identified precisely"
+        "Generational copying for data"
+        "Mark sweep for native code"
+    }
+    { $slide "Project infrastructure"
+        { $url "http://factorcode.org" }
+        { $url "http://concatenative.org" }
+        { $url "http://docs.factorcode.org" }
+        { $url "http://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"
+        "Saves us from the burden of making releases by hand"
+        "Maintains stability"
+    }
+    { $slide "Community"
+        "#concatenative irc.freenode.net: 50-60 members"
+        "factor-talk@lists.sf.net: 180 subscribers"
+        "About 30 people have code in the Factor repository"
+        "Easy to get started: binaries, lots of docs, friendly community..."
+    }
+    { $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?"
+    }
+}
+
+: galois-talk ( -- ) galois-slides "Galois talk" slides-window ;
+
+MAIN: galois-talk
diff --git a/galois-talk/summary.txt b/galois-talk/summary.txt
new file mode 100644 (file)
index 0000000..00f30ac
--- /dev/null
@@ -0,0 +1 @@
+Slides from a talk at Galois by Slava Pestov, October 2008
diff --git a/galois-talk/tags.txt b/galois-talk/tags.txt
new file mode 100644 (file)
index 0000000..8ee64cd
--- /dev/null
@@ -0,0 +1 @@
+talks
diff --git a/google-tech-talk/authors.txt b/google-tech-talk/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/google-tech-talk/google-tech-talk.factor b/google-tech-talk/google-tech-talk.factor
new file mode 100644 (file)
index 0000000..a0b511f
--- /dev/null
@@ -0,0 +1,570 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://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
+urls peg.ebnf tools.annotations tools.crossref
+help.topics math.functions compiler.tree.optimizer
+compiler.cfg.optimizer fry ;
+IN: talks.google-tech-talk
+
+CONSTANT: google-slides
+{
+    { $slide "Factor!"
+        { $url "http://factorcode.org" }
+        "Development started in 2003"
+        "Open source (BSD license)"
+        "First result for \"Factor\" on Google :-)"
+        "Influenced by Forth, Lisp, and Smalltalk (but don't worry if you don't know them)"
+    }
+    { $slide "Language overview"
+        "Words operate on a stack"
+        "Functional"
+        "Object-oriented"
+        "Rich collections library"
+        "Rich input/output library"
+        "Optional named local variables"
+        "Extensible syntax"
+    }
+    { $slide "Example: factorial"
+        "Lame example, but..."
+        { $code "USE: math.ranges" ": factorial ( n -- n! )" "    1 [a,b] product ;" }
+        { $code "100 factorial ." }
+    }
+    { $slide "Example: sending an e-mail"
+        { $vocab-link "smtp-example" }
+        "Demonstrates basic stack syntax and tuple slot setters"
+    }
+    { $slide "Functional programming"
+        "Code is data in Factor"
+        { { $snippet "[ ... ]" } " is a block of code pushed on the stack" }
+        { "We call them " { $emphasis "quotations" } }
+        { "Words which take quotations as input are called " { $emphasis "combinators" } }
+    }
+    { $slide "Functional programming"
+        { $code "10 dup 0 < [ 1 - ] [ 1 + ] if ." }
+        { $code "10 [ \"Hello Googlers!\" print ] times" }
+        { $code
+            "USING: io.encodings.ascii unicode ;"
+            "{ \"tomato\" \"orange\" \"banana\" }"
+            "\"out.txt\" ascii ["
+            "    [ >upper print ] each"
+            "] with-file-writer"
+        }
+    }
+    { $slide "Object system: motivation"
+        "Encapsulation, polymorphism, inheritance"
+        "Smalltalk, Python, Java approach: methods inside classes"
+        "Often the \"message sending\" metaphor is used to describe such systems"
+    }
+    { $slide "Object system: motivation"
+        { $code
+            "class Rect {"
+            "  int x, y;"
+            "  int area() { ... }"
+            "  int perimeter() { ... }"
+            "}"
+            ""
+            "class Circle {"
+            "  int radius;"
+            "  int area() { ... }"
+            "  int perimeter() { ... }"
+            "}"
+        }
+    }
+    { $slide "Object system: motivation"
+        "Classical functional language approach: functions switch on a type"
+        { $code
+            "data Shape = Rect w h | Circle r"
+            ""
+            "area s = s of"
+            "  (Rect w h) = ..."
+            "| (Circle r) = ..."
+            ""
+            "perimeter s = s of"
+            "  (Rect w h) = ..."
+            "| (Circle r) = ..."
+        }
+    }
+    { $slide "Object system: motivation"
+        "First approach: hard to extend existing types with new operations (open classes, etc are a hack)"
+        "Second approach: hard to extend existing operations with new types"
+        "Common Lisp Object System (CLOS): decouples classes from methods."
+        "Factor's object system is a simplified CLOS"
+    }
+    { $slide "Object system"
+        "A tuple is a user-defined class which holds named values."
+        { $code
+            "TUPLE: rectangle width height ;"
+            "TUPLE: circle radius ;"
+        }
+    }
+    { $slide "Object system"
+        "Constructing instances:"
+        { $code "rectangle new" }
+        { $code "rectangle boa" }
+        "Let's encapsulate:"
+        { $code
+            ": <rectangle> ( w h -- r ) rectangle boa ;"
+            ": <circle> ( r -- c ) circle boa ;"
+        }
+    }
+    { $slide "Object system"
+        "Generic words and methods"
+        { $code "GENERIC: area ( shape -- n )" }
+        "Two methods:"
+        { $code
+            "USE: math.constants"
+            ""
+            "M: rectangle area"
+            "    [ width>> ] [ height>> ] bi * ;"
+            ""
+            "M: circle area radius>> sq pi * ;"
+        }
+    }
+    { $slide "Object system"
+        "We can compute areas now."
+        { $code "100 20 <rectangle> area ." }
+        { $code "3 <circle> area ." }
+    }
+    { $slide "Object system"
+        "New operation, existing types:"
+        { $code
+            "GENERIC: perimeter ( shape -- n )"
+            ""
+            "M: rectangle perimeter"
+            "    [ width>> ] [ height>> ] bi + 2 * ;"
+            ""
+            "M: circle perimeter"
+            "    radius>> 2 * pi * ;"
+        }
+    }
+    { $slide "Object system"
+        "We can compute perimeters now."
+        { $code "100 20 <rectangle> perimeter ." }
+        { $code "3 <circle> perimeter ." }
+    }
+    { $slide "Object system"
+        "New type, extending existing operations:"
+        { $code
+            "TUPLE: triangle base height ;"
+            ""
+            ": <triangle> ( b h -- t ) triangle boa ;"
+            ""
+            "M: triangle area"
+            "    [ base>> ] [ height>> ] bi * 2 / ;"
+        }
+    }
+    { $slide "Object system"
+        "New type, extending existing operations:"
+        { $code
+            ": hypotenuse ( x y -- z ) [ sq ] bi@ + sqrt ;"
+            ""
+            "M: triangle perimeter"
+            "    [ base>> ] [ height>> ] bi"
+            "    [ + ] [ hypotenuse ] 2bi + ;"
+        }
+    }
+    { $slide "Object system"
+        "We can ask an object if its a rectangle:"
+        { $code "70 65 <rectangle> rectangle? ." }
+        { $code "13 <circle> rectangle? ." }
+        { "How do we tell if something is a " { $emphasis "shape" } "?" }
+    }
+    { $slide "Object system"
+        "We define a mixin class for shapes, and add our existing data types as instances:"
+        { $code
+            "MIXIN: shape"
+            "INSTANCE: rectangle shape"
+            "INSTANCE: circle shape"
+            "INSTANCE: triangle shape"
+        }
+    }
+    { $slide "Object system"
+        "Now, we can ask objects if they are shapes or not:"
+        { $code "13 <circle> shape? ." }
+        { $code "3.14 shape? ." }
+    }
+    { $slide "Object system"
+        "Or put methods on shapes:"
+        { $code
+            "GENERIC: tell-me ( obj -- )"
+            ""
+            "M: shape tell-me"
+            "    \"My area is \" write area . ;"
+            ""
+            "M: integer tell-me"
+            "    \"I am \" write"
+            "    even? \"even\" \"odd\" ? print ;"
+        }
+    }
+    { $slide "Object system"
+        "Let's test our new generic word:"
+        { $code "13 <circle> tell-me" }
+        { $code "103 76 <rectangle> tell-me" }
+        { $code "101 tell-me" }
+        { { $link integer } ", " { $link array } ", and others are built-in classes" }
+    }
+    { $slide "Object system"
+        "Anyone can define new shapes..."
+        { $code
+            "TUPLE: parallelogram ... ;"
+            ""
+            "INSTANCE: parallelogram shape"
+            ""
+            "M: parallelogram area ... ;"
+            ""
+            "M: parallelogram perimeter ... ;"
+        }
+    }
+    { $slide "Object system"
+        "More: inheritance, type declarations, read-only slots, predicate, intersection, singleton classes, reflection"
+        "Object system is entirely implemented in Factor: 2184 lines"
+        { { $vocab-link "generic" } ", " { $vocab-link "classes" } ", " { $vocab-link "slots" } }
+    }
+    { $slide "Collections"
+        "Sequences (arrays, vector, strings, ...)"
+        "Associative mappings (hashtables, ...)"
+        { "More: deques, heaps, purely functional structures, disjoint sets, and more: "
+        { $link T{ vocab-tag f "collections" } } }
+    }
+    { $slide "Sequences"
+        { "Protocol: " { $link length } ", " { $link set-length } ", " { $link nth } ", " { $link set-nth } }
+        { "Combinators: " { $link each } ", " { $link map } ", " { $link filter } ", " { $link produce } ", and more: " { $link "sequences-combinators" } }
+        { "Utilities: " { $link append } ", " { $link reverse } ", " { $link first } ",  " { $link second } ", ..." }
+    }
+    { $slide "Example: bin packing"
+        { "We have " { $emphasis "m" } " objects and " { $emphasis "n" } " bins, and we want to distribute these objects as evenly as possible." }
+        { $vocab-link "distribute-example" }
+        "Demonstrates various sequence utilities and vector words"
+        { $code "20 13 distribute ." }
+    }
+    { $slide "Unicode strings"
+        "Strings are sequences of 21-bit Unicode code points"
+        "Efficient implementation: ASCII byte string unless it has chars > 127"
+        "If a byte char has high bit set, the remaining 14 bits come from auxiliary vector"
+    }
+    { $slide "Unicode strings"
+        "Unicode-aware case conversion, char classes, collation, word breaks, and so on..."
+        { $code "USE: unicode" "\"ß\" >upper ." }
+    }
+    { $slide "Unicode strings"
+        "All external byte I/O is encoded/decoded"
+        "ASCII, UTF8, UTF16, EBCDIC..."
+        { $code "USE: io.encodings.utf8" "\"document.txt\" utf8" "[ readln ] with-file-reader" }
+        { "Binary I/O is supported as well with the " { $link binary } " encoding" }
+    }
+    { $slide "Associative mappings"
+        { "Protocol: " { $link assoc-size } ", " { $link at* } ", " { $link set-at } ", " { $link delete-at } }
+        { "Combinators: " { $link assoc-each } ", " { $link assoc-map } ", " { $link assoc-filter } ", and more: " { $link "assocs-combinators" } }
+        { "Utilities: " { $link at } ", " { $link key? } ", ..." }
+    }
+    ! { $slide "Example: soundex"
+    !     { $vocab-link "soundex" }
+    !     "From Wikipedia: \"Soundex is a phonetic algorithm for indexing names by sound, as pronounced in English.\""
+    !     "Factored into many small words, uses sequence and assoc operations, no explicit loops"
+    ! }
+    { $slide "Locals and lexical scope"
+        "Sometimes, there's no good stack solution to a problem"
+        "Or, you're porting existing code in a quick-and-dirty way"
+        "Our solution: implement named locals as a DSL in Factor"
+        "Influenced by Scheme and Lisp"
+    }
+    { $slide "Locals and lexical scope"
+        { "Define lambda words with " { $link POSTPONE: :: } }
+        { "Establish bindings with " { $link POSTPONE: [let } " and " { $snippet "[let*" } }
+        "Mutable bindings with correct semantics"
+        { "Named inputs for quotations with " { $link POSTPONE: [| } }
+        "Full closures"
+    }
+    { $slide "Locals and lexical scope"
+        "Two examples:"
+        { $vocab-link "lambda-quadratic" }
+        { $vocab-link "closures-example" }
+    }
+    { $slide "Locals and lexical scope"
+        "Locals are entirely implemented in Factor: 477 lines"
+        "Example of compile-time meta-programming"
+        "No performance penalty -vs- using the stack"
+        "In the base image, only 59 words out of 13,000 use locals"
+    }
+    { $slide "The parser"
+        "All data types have a literal syntax"
+        "Literal hashtables and arrays are very useful in data-driven code"
+        "\"Code is data\" because quotations are objects (enables Lisp-style macros)"
+        { $code "H{ { \"cookies\" 12 } { \"milk\" 10 } }" }
+        "Libraries can define new parsing words"
+    }
+    { $slide "The parser"
+        { "Example: URLs define a " { $link POSTPONE: URL" } " word" }
+        { $code "URL\" http://paste.factorcode.org/paste?id=81\"" }
+    }
+    { $slide "Example: memoization"
+        { "Memoization with " { $link POSTPONE: MEMO: } }
+        { $code
+            ": fib ( m -- n )"
+            "    dup 1 > ["
+            "        [ 1 - fib ] [ 2 - fib ] bi +"
+            "    ] when ;"
+        }
+        "Very slow! Let's profile it..."
+    }
+    { $slide "Example: memoization"
+        { "Let's use " { $link POSTPONE: : } " instead of " { $link POSTPONE: MEMO: } }
+        { $code
+            "MEMO: fib ( m -- n )"
+            "    dup 1 > ["
+            "        [ 1 - fib ] [ 2 - fib ] bi +"
+            "    ] when ;"
+        }
+        "Much faster"
+    }
+    { $slide "Meta-circularity"
+        { { $link POSTPONE: MEMO: } " is just a library word" }
+        { "But so is " { $link POSTPONE: : } }
+        "Factor's parser is written in Factor"
+        { "All syntax is just parsing words: " { $link POSTPONE: [ } ", " { $link POSTPONE: " } }
+    }
+    { $slide "Extensible syntax, DSLs"
+        "Most parsing words fall in one of two categories"
+        "First category: literal syntax for new data types"
+        "Second category: defining new types of words"
+        "Some parsing words are more complicated"
+    }
+    { $slide "Parser expression grammars"
+        { { $link POSTPONE: EBNF: } ": a complex parsing word" }
+        "Implements a custom syntax for expressing parsers"
+        { "Example: " { $vocab-link "printf-example" } }
+        { $code "\"cheese\" \"vegan\" \"%s is not %s\\n\" printf" }
+        { $code "\"Factor\" 5 \"%s is %d years old\\n\" printf" }
+    }
+    { $slide "Input/output library"
+        "One of Factor's strongest points: portable, full-featured, efficient"
+        { $vocab-link "io.files" }
+        { $vocab-link "io.launcher" }
+        { $vocab-link "io.monitors" }
+        { $vocab-link "io.mmap" }
+        { $vocab-link "http.client" }
+        "... and so on"
+    }
+    { $slide "Example: file system monitors"
+        { $code
+            "USE: io.monitors"
+            ""
+            ": forever ( quot -- ) '[ @ t ] loop ; inline"
+            ""
+            "\"/tmp\" t <monitor>"
+            "'[ _ next-change . ] forever"
+        }
+    }
+    { $slide "Example: time server"
+        { $vocab-link "time-server" }
+        { "Demonstrates " { $vocab-link "io.servers" } " vocabulary, threads" }
+    }
+    { $slide "Example: what is my IP?"
+        { $vocab-link "webapps.ip" }
+        "Simple web app, defines a single action, use an XHTML template"
+        "Web framework supports more useful features: sessions, SSL, form validation, ..."
+    }
+    { $slide "Example: Yahoo! web search"
+        { $vocab-link "yahoo" }
+        { "Demonstrates " { $vocab-link "http.client" } ", " { $vocab-link "xml" } }
+    }
+    { $slide "Example: simple web browser"
+        { $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 "Example: environment variables"
+        { $vocab-link "environment" }
+        "Hooks are generic words which dispatch on dynamically-scoped variables"
+        { "Implemented in an OS-specific way: " { $vocab-link "environment.unix" } ", " { $vocab-link "environment.windows" } }
+    }
+    { $slide "Example: environment variables"
+        "Implementations use C FFI"
+        "Call C functions, call function pointers, call Factor from C, structs, floats, ..."
+        "No need to write C wrapper code"
+    }
+    { $slide "Implementation"
+        "VM: 12,000 lines of C"
+        "Generational garbage collection"
+        "core: 9,000 lines of Factor"
+        "Optimizing native code compiler for x86, PowerPC"
+        "basis: 80,000 lines of Factor"
+    }
+    { $slide "Compiler"
+        { "Let's look at " { $vocab-link "benchmark.mandel" } }
+        "A naive implementation would be very slow"
+        "Combinators, currying, partial application"
+        "Boxed complex numbers"
+        "Boxed floats"
+        { "Redundancy in " { $link absq } " and " { $link sq } }
+    }
+    { $slide "Compiler: front-end"
+        "Builds high-level tree SSA IR"
+        "Stack code with uniquely-named values"
+        "Inlines combinators and calls to quotations"
+        { $code "USING: compiler.tree.builder compiler.tree.debugger ;" "[ c pixel ] build-tree nodes>quot ." }
+    }
+    { $slide "Compiler: high-level optimizer"
+        "12 optimization passes"
+        { $link optimize-tree }
+        "Some passes collect information, others use the results of past analysis to rewrite the code"
+    }
+    { $slide "Compiler: propagation pass"
+        "Propagation pass computes types with type function"
+        { "Example: output type of " { $link + } " depends on the types of inputs" }
+        "Type: can be a class, a numeric interval, array with a certain length, tuple with certain type slots, literal value, ..."
+        "Mandelbrot: we infer that we're working on complex floats"
+    }
+    { $slide "Compiler: propagation pass"
+        "Propagation also supports \"constraints\""
+        { $code "[ dup array? [ first ] when ] optimized." }
+        { $code "[ >fixnum dup 0 < [ 1 + ] when ] optimized." }
+        { $code
+            "["
+            "    >fixnum"
+            "    dup [ -10 > ] [ 10 < ] bi and"
+            "    [ 1 + ] when"
+            "] optimized."
+        }
+    }
+    { $slide "Compiler: propagation pass"
+        "Eliminates method dispatch, inlines method bodies"
+        "Mandelbrot: we infer that integer indices are fixnums"
+        "Mandelbrot: we eliminate generic arithmetic"
+    }
+    { $slide "Compiler: escape analysis"
+        "We identify allocations for tuples which are never returned or passed to other words (except slot access)"
+        { "Partial application with " { $link POSTPONE: '[ } }
+        "Complex numbers"
+    }
+    { $slide "Compiler: escape analysis"
+        { "Virtual sequences: " { $link <slice> } ", " { $link <reversed> } }
+        { $code "[ <reversed> [ . ] each ] optimized." }
+        { "Mandelbrot: we unbox " { $link curry } ", complex number allocations" }
+    }
+    { $slide "Compiler: dead code elimination"
+        "Cleans up the mess from previous optimizations"
+        "After inlining and dispatch elimination, dead code comes up because of unused generality"
+        { "No-ops like " { $snippet "0 +" } ", " { $snippet "1 *" } }
+        "Literals which are never used"
+        "Side-effect-free words whose outputs are dropped"
+    }
+    { $slide "Compiler: low level IR"
+        "Register-based SSA"
+        "Stack operations expand into low-level instructions"
+        { $code "[ 5 ] regs." }
+        { $code "[ swap ] regs." }
+        { $code "[ append reverse ] regs." }
+    }
+    { $slide "Compiler: low-level optimizer"
+        "5 optimization passes"
+        { $link optimize-cfg }
+        "Gets rid of redundancy which is hidden in high-level stack code"
+    }
+    { $slide "Compiler: optimize memory"
+        "First pass optimizes stack and memory operations"
+        { "Example: " { $link 2array } }
+        { { $link <array> } " fills array with initial value" }
+        "What if we immediately store new values into the array?"
+        { $code "\\ 2array regs." }
+        "Mandelbrot: we optimize stack operations"
+    }
+    { $slide "Compiler: value numbering"
+        "Identifies expressions which are computed more than once in a basic block"
+        "Simplifies expressions with various identities"
+        "Mandelbrot: redundant float boxing and unboxing, redundant arithmetic"
+    }
+    { $slide "Compiler: dead code elimination"
+        "Dead code elimination for low-level IR"
+        "Again, cleans up results of prior optimizations"
+    }
+    { $slide "Compiler: register allocation"
+        "IR assumes an infinite number of registers which are only assigned once"
+        "Real CPUs have a finite set of registers which can be assigned any number of times"
+        "\"Linear scan register allocation with second-chance binpacking\""
+    }
+    { $slide "Compiler: register allocation"
+        "3 steps:"
+        "Compute live intervals"
+        "Allocate registers"
+        "Assign registers and insert spills"
+    }
+    { $slide "Compiler: register allocation"
+        "Step 1: compute live intervals"
+        "We number all instructions consecutively"
+        "A live interval associates a virtual register with a list of usages"
+    }
+    { $slide "Compiler: register allocation"
+        "Step 2: allocate registers"
+        "We scan through sorted live intervals"
+        "If a physical register is available, assign"
+        "Otherwise, find live interval with furthest away use, split it, look at both parts again"
+    }
+    { $slide "Compiler: register allocation"
+        "Step 3: assign registers and insert spills"
+        "Simple IR rewrite step"
+        "After register allocation, one vreg may have several live intervals, and different physical registers at different points in time"
+        "Hence, \"second chance\""
+        { "Mandelbrot: " { $code "[ c pixel ] regs." } }
+    }
+    { $slide "Compiler: code generation"
+        "Iterate over list of instructions"
+        "Extract tuple slots and call hooks"
+        { $vocab-link "cpu.architecture" }
+        "Finally, we hand the code to the VM"
+        { $code "\\ 2array disassemble" }
+    }
+    { $slide "Garbage collection"
+        "All roots are identified precisely"
+        "Generational copying for data"
+        "Mark sweep for native code"
+    }
+    { $slide "Project infrastructure"
+        { $url "http://factorcode.org" }
+        { $url "http://concatenative.org" }
+        { $url "http://docs.factorcode.org" }
+        { $url "http://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"
+        "Saves us from the burden of making releases by hand"
+        "Maintains stability"
+    }
+    { $slide "Community"
+        "#concatenative irc.freenode.net: 50-60 members"
+        "factor-talk@lists.sf.net: 180 subscribers"
+        "About 30 people have code in the Factor repository"
+        "Easy to get started: binaries, lots of docs, friendly community..."
+    }
+    { $slide "Future direction: Factor 1.0"
+        "Continue doing what we're doing:"
+        "Polish off some language features"
+        "Stability"
+        "Performance"
+        "Documentation"
+        "Developer tools"
+    }
+    { $slide "Future direction: Factor 2.0"
+        "Native threads"
+        "Syntax-aware Factor editor"
+        "Embedding Factor in C apps"
+        "Cross-compilation for smaller devices"
+    }
+    { $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"
+        "Put your prejudices aside and give it a shot!"
+    }
+    { $slide "Questions?" }
+}
+
+: google-talk ( -- )
+    google-slides "Google Tech talk" slides-window ;
+
+MAIN: google-talk
diff --git a/google-tech-talk/summary.txt b/google-tech-talk/summary.txt
new file mode 100644 (file)
index 0000000..1747a56
--- /dev/null
@@ -0,0 +1 @@
+Slides from Google Tech Talk by Slava Pestov, October 2008
diff --git a/google-tech-talk/tags.txt b/google-tech-talk/tags.txt
new file mode 100644 (file)
index 0000000..8ee64cd
--- /dev/null
@@ -0,0 +1 @@
+talks
diff --git a/hmc-talk/hmc-talk.factor b/hmc-talk/hmc-talk.factor
new file mode 100644 (file)
index 0000000..9a225f9
--- /dev/null
@@ -0,0 +1,491 @@
+USING: fry help.markup help.topics kernel locals math
+math.functions memoize peg.ebnf slides ;
+IN: talks.hmc-talk
+
+CONSTANT: hmc-slides
+{
+    { $slide "Factor!"
+        { $url "http://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 "Concepts"
+        "Concatenative"
+        "Dynamic types"
+        "Extensible syntax"
+        "Fully-compiled"
+        "Cross-platform"
+        "Interactive Development"
+        "Code is data"
+        "Pervasive unit testing"
+        "Clickable"
+    }
+
+    { $slide "Words and the stack"
+        "Stack based, dynamically typed"
+        { $code "{ 1 1 3 4 4 8 9 9 } dup duplicates diff ." }
+        "Words: named code snippets"
+        { $code ": remove-duplicates ( seq -- seq' )" "    dup duplicates diff ;" }
+        { $code "{ 1 1 3 4 4 8 9 9 } remove-duplicates ." }
+    }
+
+    { $slide "Words and the stack"
+        { $code
+            "\"/usr/local/opt/fortune/share/games/fortunes/science\""
+            "ascii file-lines"
+            "{ \"%\" } split random"
+            "[ print ] each"
+        }
+        { $code
+            ": fortune ( -- )"
+            "    \"/usr/local/opt/fortune/share/games/fortunes/science\""
+            "    ascii file-lines"
+            "    { \"%\" } split random"
+            "    [ print ] each ;"
+        }
+        { $code
+            "5 [ fortune nl ] times"
+        }
+    }
+
+    { $slide "Vocabularies"
+        "Vocabularies: named sets of words"
+        { $link "vocab-index" }
+        { { $link POSTPONE: USING: } " loads dependencies" }
+        "Source, docs, tests in one place"
+    }
+    { $slide "Interactive development"
+        "Programming is hard, let's play tetris"
+        { $vocab-link "tetris" }
+        "Tetris is hard too... let's cheat"
+        "Factor workflow: change code, F2, test, repeat"
+    }
+    { $slide "Quotations"
+        "Quotation: unnamed block of code"
+        "Combinators: words taking quotations"
+        { $code "10 dup 0 < [ 1 - ] [ 1 + ] if ." }
+        { $code "{ -1 1 -2 0 3 } [ 0 max ] map ." }
+        "Partial application:"
+        { $code ": clamp ( seq n -- seq' ) '[ _ max ] map ;" "{ -1 1 -2 0 3 } 0 clamp" }
+    }
+    { $slide "Object system"
+        "CLOS with single dispatch"
+        "A tuple is a user-defined class which holds named values."
+        { $code
+            "TUPLE: rectangle width height ;"
+            "TUPLE: circle radius ;"
+        }
+    }
+    { $slide "Object system"
+        "Constructing instances:"
+        { $code "rectangle new" }
+        { $code "rectangle boa" }
+        "Let's encapsulate:"
+        { $code
+            ": <rectangle> ( w h -- r ) rectangle boa ;"
+            ": <circle> ( r -- c ) circle boa ;"
+        }
+    }
+    { $slide "Object system"
+        "Generic words and methods"
+        { $code "GENERIC: area ( shape -- n )" }
+        "Two methods:"
+        { $code
+            "USE: math.constants"
+            ""
+            "M: rectangle area"
+            "    [ width>> ] [ height>> ] bi * ;"
+            ""
+            "M: circle area radius>> sq pi * ;"
+        }
+    }
+    { $slide "Object system"
+        "We can compute areas now."
+        { $code "100 20 <rectangle> area ." }
+        { $code "3 <circle> area ." }
+    }
+    { $slide "Object system"
+        "Object system handles dynamic redefinition very well"
+        { $code "TUPLE: person name age occupation ;" }
+        "Make an instance..."
+    }
+    { $slide "Object system"
+        "Let's add a new slot:"
+        { $code "TUPLE: person name age address occupation ;" }
+        "Fill it in with inspector..."
+        "Change the order:"
+        { $code "TUPLE: person name occupation address ;" }
+    }
+    { $slide "Object system"
+        "How does it work?"
+        "Objects are not hashtables; slot access is very fast"
+        "Redefinition walks the heap; expensive but rare"
+    }
+    { $slide "Object system"
+        "Supports \"duck typing\""
+        "Two tuples can have a slot with the same name"
+        "Code that uses accessors will work on both"
+        "Accessors are auto-generated generic words"
+    }
+    { $slide "Object system"
+        "Predicate classes"
+        { $code
+            "PREDICATE: positive < integer 0 > ;"
+            "PREDICATE: negative < integer 0 < ;"
+            ""
+            "GENERIC: abs ( n -- )"
+            ""
+            "M: positive abs ;"
+            "M: negative abs -1 * ;"
+            "M: integer abs ;"
+        }
+    }
+    { $slide "Object system"
+        "More: inheritance, type declarations, read-only slots, union, intersection, singleton classes, reflection"
+        "Object system is entirely implemented in Factor"
+    }
+    { $slide "The parser"
+        "All data types have a literal syntax"
+        "Literal hashtables and arrays are very useful in data-driven code"
+        "\"Code is data\" because quotations are objects (enables Lisp-style macros)"
+        { $code "H{ { \"cookies\" 12 } { \"milk\" 10 } }" }
+        "Libraries can define new parsing words"
+    }
+    { $slide "Example: regexp"
+        { $vocab-link "regexp" }
+        "Pre-compiles regexp at parse time"
+        "Implemented with library code"
+        { $code "USE: regexp" }
+        { $code "\"ababbc\" \"[ab]+c\" <regexp> matches? ." }
+        { $code "\"ababbc\" R/ [ab]+c/ matches? ." }
+    }
+    { $slide "Example: memoization"
+        { "Memoization with " { $link POSTPONE: MEMO: } }
+        { $code
+            ": fib ( m -- n )"
+            "    dup 1 > ["
+            "        [ 1 - fib ] [ 2 - fib ] bi +"
+            "    ] when ;"
+        }
+        "Very slow! Let's profile it..."
+    }
+    { $slide "Example: memoization"
+        { "Let's use " { $link POSTPONE: MEMO: } " instead of " { $link POSTPONE: : } }
+        { $code
+            "MEMO: fib ( m -- n )"
+            "    dup 1 > ["
+            "        [ 1 - fib ] [ 2 - fib ] bi +"
+            "    ] when ;"
+        }
+        "Much faster"
+    }
+    { $slide "Meta-circularity"
+        { { $link POSTPONE: MEMO: } " is just a library word" }
+        { "But so is " { $link POSTPONE: : } }
+        "Factor's parser is written in Factor"
+        { "All syntax is just parsing words: " { $link POSTPONE: [ } ", " { $link POSTPONE: " } }
+    }
+    { $slide "Extensible syntax, DSLs"
+        "Most parsing words fall in one of two categories"
+        "First category: literal syntax for new data types"
+        "Second category: defining new types of words"
+        "Some parsing words are more complicated"
+    }
+
+    { $slide "Example: printf"
+        { { $link POSTPONE: EBNF: } ": a complex parsing word" }
+        "Implements a custom syntax for expressing parsers: like OMeta!"
+        { "Example: " { $vocab-link "printf" } }
+        { $code "\"cheese\" \"vegan\" \"%s is not %s\\n\" printf" }
+        { $code "\"Factor\" 5 \"%s is %d years old\\n\" printf" }
+        { $code "[ \"%s monkeys\" printf ] expand-macros" }
+    }
+    { $slide "Locals and lexical scope"
+        "Sometimes, there's no good stack solution to a problem"
+        "Or, you're porting existing code in a quick-and-dirty way"
+        "Our solution: implement named locals as a DSL in Factor"
+        "Influenced by Scheme and Lisp"
+    }
+    { $slide "Locals and lexical scope"
+        { "Define lambda words with " { $link POSTPONE: :: } }
+        { "Establish bindings with " { $link POSTPONE: [let } " and " { $snippet "[let*" } }
+        "Mutable bindings with correct semantics"
+        { "Named inputs for quotations with " { $link POSTPONE: [| } }
+        "Full closures"
+    }
+    { $slide "Locals and lexical scope"
+        "Combinator with 5 parameters!"
+        { $code
+            ":: branch ( a b neg zero pos -- )"
+            "    a b = zero [ a b < neg pos if ] if ; inline"
+        }
+        "Unwieldy with the stack"
+    }
+    { $slide "Locals and lexical scope"
+        { $code
+            ": check-drinking-age ( age -- )"
+            "    21"
+            "    [ \"You're underage!\" print ]"
+            "    [ \"Grats, you're now legal\" print ]"
+            "    [ \"Go get hammered\" print ]"
+            "    branch ;"
+        }
+    }
+    { $slide "Locals and lexical scope"
+        "Locals are entirely implemented in Factor"
+        "Example of compile-time meta-programming"
+        "No performance penalty -vs- using the stack"
+        "In the base image, only 59 words out of 13,000 use locals"
+    }
+    { $slide "More about partial application"
+        { { $link POSTPONE: '[ } " is \"fry syntax\"" }
+        { $code "'[ _ + ] == [ + ] curry" }
+        { $code "'[ @ t ] == [ t ] compose" }
+        { $code "'[ _ nth @ ] == [ [ nth ] curry ] dip compose" }
+        { $code "'[ [ _ ] dip nth ] == [ [ ] curry dip nth ] curry" }
+        { "Fry and locals desugar to " { $link curry } ", " { $link compose } }
+    }
+    { $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 "talks.hmc-talk" }
+    }
+    { $slide "Why stack-based?"
+        "Because nobody else is doing it"
+        "Interesting properties: concatenation is composition, chaining functions together, \"fluent\" interfaces, new combinators"
+        { $vocab-link "simple-rpg" }
+        { $code
+            "{ \"chicken\" \"beef\" \"pork\" \"turkey\" }"
+            "[ 5 short head ] map ."
+        }
+    }
+    { $slide "Implementation"
+        "VM: garbage collection, bignums, ..."
+        "Bootstrap image: parser, hashtables, object system, ..."
+        "Non-optimizing compiler"
+        "Stage 2 bootstrap: optimizing compiler, UI, ..."
+        "Full image contains machine code"
+    }
+    { $slide "Compiler"
+        { "Let's look at " { $vocab-link "benchmark.mandel" } }
+        "A naive implementation would be very slow"
+        "Combinators, partial application"
+        "Boxed complex numbers"
+        "Boxed floats"
+        { "Redundancy in " { $link absq } " and " { $link sq } }
+    }
+    { $slide "Compiler: high-level optimizer"
+        "High-level SSA IR"
+        "Type inference (classes, intervals, arrays with a fixed length, literals, ...)"
+        "Escape analysis and tuple unboxing"
+    }
+    { $slide "Compiler: high-level optimizer"
+        "Loop index becomes a fixnum, complex numbers unboxed, generic arithmetic inlined, higher-order code become first-order..."
+        { $code "[ c pixel ] optimized." }
+    }
+    { $slide "Compiler: low-level optimizer"
+        "Low-level SSA IR"
+        "Alias analysis"
+        "Value numbering"
+        "Linear scan register allocation"
+    }
+    { $slide "Compiler: low-level optimizer"
+        "Redundant stack operations eliminated, intermediate floats unboxed..."
+        { $code "[ c pixel ] regs." }
+    }
+    { $slide "Compiler: assembly"
+        "Generic assembly generated..."
+        { $code "[ c pixel ] disassemble" }
+    }
+    { $slide "Compiler: assembly"
+        "Efficient assembly generated..."
+        { $code "[ { fixnum fixnum } declare c pixel ] disassemble" }
+    }
+    { $slide "Garbage collection"
+        "All roots are identified precisely"
+        "Generational copying for data"
+        "Mark sweep for native code"
+    }
+
+    { $slide "Project infrastructure"
+        { $url "http://factorcode.org" }
+        { $url "http://concatenative.org" }
+        { $url "http://docs.factorcode.org" }
+        { $url "http://planet.factorcode.org" }
+        { $url "http://paste.factorcode.org" }
+        "Uses our HTTP server, SSL, DB, Atom libraries..."
+    }
+    { $slide "Project infrastructure"
+        "Build farm, written in Factor"
+        "Multiple OS and architecture"
+        "Builds Factor and all libraries, runs tests, makes binaries"
+        "Saves us from the burden of making releases by hand"
+        "Maintains stability"
+    }
+
+    { $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?"
+    }
+
+    { $slide "Cool things"
+        { $code
+            "USE: xkcd"
+            "XKCD: 138"
+        }
+        { $code
+            "USE: reddit"
+            "\"programming\" subreddit."
+        }
+    }
+
+    { $slide "Cool things"
+        { $vocab-link "minesweeper" }
+        { $vocab-link "game-of-life" }
+        { $vocab-link "boids" }
+    }
+
+    { $slide "Cool things"
+        "8080 cpu emulator"
+        { $code
+            "\"resource:roms\" rom-root set-global"
+        }
+        { $vocab-link "roms.space-invaders" }
+    }
+
+    { $slide "Cool things"
+        { $vocab-link "bloom-filters" }
+        { $vocab-link "cuckoo-filters" }
+        { $vocab-link "persistent" }
+        { $vocab-link "trees" }
+        { $vocab-link "tuple-arrays" }
+        { $vocab-link "specialized-arrays" }
+    }
+
+    { $slide "Cool things"
+        { $code
+            "USE: text-to-speech"
+            "\"hello\" speak-text"
+        }
+        { $code
+            "USE: morse"
+            "\"hello\" play-as-morse"
+        }
+        { $code
+            "USE flip-text"
+            "\"hello\" flip-text ."
+        }
+    }
+
+    { $slide "Cool things"
+        { $code
+            "{ 12 18 24 72 }"
+            "[ \"Bigger\" swap font-size associate format nl ] each"
+        }
+
+        { $code
+            "10 <iota> ["
+            "   \"Hello world\""
+            "   swap 10 / 1 over - over 1 <rgba>"
+            "   background associate format nl"
+            "] each"
+        }
+    }
+
+    { $slide "Cool things"
+        { $code
+            "USE: google.charts"
+            "\"x = \\\\frac{-b \\\\pm \\\\sqrt {b^2-4ac}}{2a}\""
+            "<formula> 200 >>width 75 >>height chart."
+        }
+        { $code
+            "100 [ 100 random ] replicate"
+            "100 [ 100 random ] replicate"
+            "zip <scatter> chart."
+        }
+        { $code
+            "\"/usr/share/dict/words\" utf8 file-lines"
+            "[ >lower 1 head ] histogram-by"
+            "sort-keys <bar>"
+            "    COLOR: green >>foreground"
+            "    400 >>width"
+            "    10 >>bar-width"
+            "chart."
+        }
+    }
+
+    { $slide "Cool things"
+        { $code
+            "USE: http.client"
+            "\\ http-get see"
+        }
+        { $code
+            "\"http\" apropos"
+        }
+        { $code
+            "USE: images.http"
+            "\"https://factorcode.org/logo.png\" http-image."
+        }
+    }
+
+    { $slide "Cool things"
+        "Tab completion"
+        { $code
+            "http"
+        }
+        { $code
+            "P\" vocab:math"
+        }
+        { $code
+            "COLOR: "
+        }
+    }
+
+    { $slide "Cool things"
+        { $code
+            "USE: emojify"
+            "\"I :heart: Factor! :+1!\" emojify ."
+        }
+        { $code
+            "USE: dice"
+            "ROLL: 2d8+4"
+            "\"You do %s points of damage!\" printf"
+        }
+    }
+
+    { $slide "Cool things"
+        { $code
+            "USING: sequences xml.syntax xml.writer ;"
+            "{ \"three\" \"blind\" \"mice\" }"
+            "[ [XML <li><-></li> XML] ] map"
+            "[XML <ul><-></ul> XML]"
+            "pprint-xml"
+        }
+    }
+
+    { $slide "Cool things"
+        { $code
+            "USE: io.streams.256color"
+            "[ listener ] with-256color"
+            "\"math\" about"
+        }
+    }
+
+    { $slide "Cool things"
+        { $code "./factor -run=tetris" }
+        { $code "./factor -run=file-server" }
+        { $code "./factor -run=file-monitor" }
+        { $code "./factor -run=tools.dns microsoft.com" }
+        { $code "./factor -run=tools.cal" }
+    }
+}
+
+: hmc-talk ( -- ) hmc-slides "HMC Talk" slides-window ;
+
+MAIN: hmc-talk
diff --git a/jvm-summit-talk/authors.txt b/jvm-summit-talk/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/jvm-summit-talk/jvm-summit-talk.factor b/jvm-summit-talk/jvm-summit-talk.factor
new file mode 100644 (file)
index 0000000..b91bf01
--- /dev/null
@@ -0,0 +1,358 @@
+! Copyright (C) 2009 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: slides help.markup math math.private kernel sequences
+slots.private ;
+IN: talks.jvm-summit-talk
+
+CONSTANT: jvm-summit-slides
+{
+    { $slide "Factor language implementation"
+        "Goals: expressiveness, metaprogramming, performance"
+        "We want a language for anything from scripting DSLs to high-performance numerics"
+        "I assume you know a bit about compiler implementation: parser -> frontend -> optimizer -> codegen"
+        { "This is " { $strong "not" } " a talk about the Factor language" }
+        { "Go to " { $url "http://factorcode.org" } " to learn the language" }
+    }
+    { $slide "Why are dynamic languages slow?"
+        "Branching and indirection!"
+        "Runtime type checks and dispatch"
+        "Integer overflow checks"
+        "Boxed integers and floats"
+        "Lots of allocation of temporary objects"
+    }
+    { $slide "Interactive development"
+        "Code can be reloaded at any time"
+        "Class hierarchy might change"
+        "Slots may be added and removed"
+        "Functions might be redefined"
+    }
+    { $slide "Factor's solution"
+        "Factor implements most of the library in Factor"
+        "Library contains very generic, high-level code"
+        "Always compiles to native code"
+        "Compiler removes unused generality from high-level code"
+        "Inlining, specialization, partial evaluation"
+        "And deoptimize when assumptions change"
+    }
+    { $slide "Introduction: SSA form"
+        "Every identifier only has one global definition"
+        {
+            "Not SSA:"
+            { $code
+                "x = 1"
+                "y = 2"
+                "x = x + y"
+                "if(z < 0)"
+                "    t = x + y"
+                "else"
+                "    t = x - y"
+                "print(t)"
+            }
+        }
+    }
+    { $slide "Introduction: SSA form"
+        "Rename re-definitions and subsequent usages"
+        {
+            "Still not SSA:"
+            { $code
+                "x = 1"
+                "y = 2"
+                "x1 = x + y"
+                "if(z < 0)"
+                "    t = x1 + y"
+                "else"
+                "    t = x1 - y"
+                "print(t)"
+            }
+        }
+    }
+    { $slide "Introduction: SSA form"
+        "Introduce “φ functions” at control-flow merge points"
+        {
+            "This is SSA:"
+            { $code
+                "x = 1"
+                "y = 2"
+                "x1 = x + y"
+                "if(z < 0)"
+                "    t1 = x1 + y"
+                "else"
+                "    t2 = x1 - y"
+                "t3 = φ(t1,t2)"
+                "print(t3)"
+            }
+        }
+    }
+    { $slide "Why SSA form?"
+        {
+            "Def-use chains:"
+            { $list
+                "Defs-of: instructions that define a value"
+                "Uses-of: instructions that use a value"
+            }
+            "With SSA, defs-of has exactly one element"
+        }
+    }
+    { $slide "Def-use chains"
+        "Simpler def-use makes analysis more accurate."
+        {
+            "Non-SSA example:"
+            { $code
+                "if(x < 0)"
+                "    s = new Circle"
+                "    a = area(s1)"
+                "else"
+                "    s = new Rectangle"
+                "    a = area(s2)"
+            }
+        }
+    }
+    { $slide "Def-use chains"
+        {
+            "SSA example:"
+            { $code
+                "if(x < 0)"
+                "    s1 = new Circle"
+                "    a1 = area(s1)"
+                "else"
+                "    s2 = new Rectangle"
+                "    a2 = area(s2)"
+                "a = φ(a1,a2)"
+            }
+
+        }
+    }
+    { $slide "Factor compiler overview"
+        "High-level SSA IR constructed from stack code"
+        "High level optimizer transforms high-level IR"
+        "Low-level SSA IR is constructed from high-level IR"
+        "Low level optimizer transforms low-level IR"
+        "Register allocator runs on low-level IR"
+        "Machine IR is constructed from low-level IR"
+        "Code generation"
+    }
+    { $slide "High-level optimizer"
+        "Frontend: expands macros, inline higher order functions"
+        "Propagation: inline methods, constant folding"
+        "Escape analysis: unbox tuples"
+        "Dead code elimination: clean up"
+    }
+    { $slide "Higher-order functions"
+        "Almost all control flow is done with higher-order functions"
+        { { $link if } ", " { $link times } ", " { $link each } }
+        "Calling a block is an indirect jump"
+        "Solution: inline higher order functions at the call site"
+        "Inline the block body at the higher order call site in the function"
+        "Record inlining in deoptimization database"
+    }
+    { $slide "Generic functions"
+        "A generic function contains multiple method bodies"
+        "Dispatches on the class of argument(s)"
+        "In Factor, generic functions are single dispatch"
+        "Almost equivalent to message passing"
+    }
+    { $slide "Tuple slot access"
+        "Slot readers and writers are generic functions"
+        "Generated automatically when you define a tuple class"
+        { "The generated methods call " { $link slot } ", " { $link set-slot } " primitives" }
+        "These primitives are not type safe; the generic dispatch performs the type checking for us"
+        "If class of dispatch value known statically, inline method"
+        "This may result in more methods inlining from additional specialization"
+    }
+    { $slide "Generic arithmetic"
+        { { $link + } ", " { $link * } ", etc perform a double dispatch on arguments" }
+        { "Fixed-precision integers (" { $link fixnum } "s) upgrade to " { $link bignum } "s automatically" }
+        "Floats and complex numbers are boxed, heap-allocated"
+        "Propagation of classes helps for floats"
+        "But not for fixnums, because of overflow checks"
+        "So we also propagate integer intervals"
+        "Interval arithmetic: etc, [a,b] + [c,d] = [a+c,b+d]"
+    }
+    { $slide "Slot value propagation"
+        "Complex numbers are even trickier"
+        "We can have a complex number with integer components, float components"
+        "Even if we inline complex arithmetic methods, still dispatching on components"
+        "Solution: propagate slot info"
+    }
+    { $slide "Constraint propagation"
+        "Contrieved example:"
+        { $code
+            "x = •"
+            "b = isa(x,array)"
+            "if(b)"
+            "    a = length(x)"
+            "else"
+            "    b = length(x)"
+            "c = φ(a,b)"
+        }
+        { "We should be able to inline the call to " { $snippet "length" } " in the true branch" }
+    }
+    { $slide "Constraint propagation"
+        "We build a table:"
+        { $code
+            "b true => x is array"
+            "b false => x is ~array"
+        }
+        { "In true branch, apply all " { $snippet "b true" } " constraints" }
+        { "In false branch, apply all " { $snippet "b false" } " constraints" }
+    }
+    { $slide "Going further"
+        "High-level optimizer eliminates some dispatch overhead and allocation"
+        {
+            { "Let's take a look at the " { $link float+ } " primitive" }
+            { $list
+                "No type checking anymore... but"
+                "Loads two tagged pointers from operand stack"
+                "Unboxes floats"
+                "Adds two floats"
+                "Boxes float result and perform a GC check"
+            }
+        }
+    }
+    { $slide "Low-level optimizer"
+        "Frontend: construct LL SSA IR from HL SSA IR"
+        "Alias analysis: remove redundant slot loads/stores"
+        "Value numbering: simplify arithmetic"
+        "Representation selection: eliminate boxing"
+        "Dead code elimination: clean up"
+        "Register allocation"
+    }
+    { $slide "Constructing low-level IR"
+        { "Low-level IR is a " { $emphasis "control flow graph" } " of " { $emphasis "basic blocks" } }
+        "A basic block is a list of instructions"
+        "Register-based IR; infinite, uniform register file"
+        { "Instructions:"
+            { $list
+                "Subroutine calls"
+                "Machine arithmetic"
+                "Load/store values on operand stack"
+                "Box/unbox values"
+            }
+        }
+    }
+    { $slide "Inline allocation and GC checks"
+        {
+            "Allocation of small objects can be done in a few instructions:"
+            { $list
+                "Bump allocation pointer"
+                "Write object header"
+                "Fill in payload"
+            }
+        }
+        "Multiple allocations in the same basic block only need a single GC check; saves on a conditional branch"
+    }
+    { $slide "Alias analysis"
+        "Factor constructors are just ordinary functions"
+        { "They call a primitive constructor: " { $link new } }
+        "When a new object is constructed, it has to be initialized"
+        "... but the user's constructor probably fills in all the slots again with actual values"
+        "Local alias analysis eliminates redundant slot loads and stores"
+    }
+    { $slide "Value numbering"
+        { "A form of " { $emphasis "redundancy elimination" } }
+        "Requires use of SSA form in order to work"
+        "Define an equivalence relation over SSA values"
+        "Assign a “value number” to each SSA value"
+        "If two values have the same number, they will always be equal at runtime"
+    }
+    { $slide "Types of value numbering"
+        "Many variations: algebraic simplifications, various rewrite rules can be tacked on"
+        "Local value numbering: in basic blocks"
+        "Global value numbering: entire procedure"
+        "Factor only does local value numbering"
+    }
+    { $slide "Value graph and expressions"
+        { $table
+            {
+                {
+                    "Basic block:"
+                    { $code
+                        "x = •"
+                        "y = •"
+                        "a = x + 1"
+                        "b = a + 1"
+                        "c = x + 2"
+                        "d = b - c"
+                        "e = y + d"
+                    }
+                }
+                {
+                    "Value numbers:"
+                    { $code
+                        "V1: •"
+                        "V2: •"
+                        "V3: 1"
+                        "V4: 2"
+                        "V5: (V1 + V3)"
+                        "V6: (V5 + V3)"
+                        "V7: (V3 + V4)"
+                        "V8: (V6 - V7)"
+                        "V9: (V2 + V8)"
+                    }
+                }
+            }
+        }
+    }
+    { $slide "Expression simplification"
+        {
+            "Constant folding: if V1 and V2 are constants "
+            { $snippet "(V1 op V2)" }
+            " can be evaluated at compile-time"
+        }
+        {
+            "Reassociation: if V2 and V3 are constants "
+            { $code "((V1 op V2) op V3) => (V1 op (V2 op V3))" }
+        }
+        {
+            "Algebraic identities: if V2 is constant 0, "
+            { $code "(V1 + V2) => V1" }
+        }
+        {
+            "Strength reduction: if V2 is a constant power of two, "
+            { $code "(V1 * V2) => (V1 << log2(V2))" }
+        }
+        "etc, etc, etc"
+    }
+    { $slide "Representation selection overview"
+        "Floats and SIMD vectors need to be boxed"
+        "Representation: tagged pointer, unboxed float, unboxed SIMD value..."
+        "When IR is built, no boxing or unboxing instructions inserted"
+        "Representation selection pass makes IR consistent"
+    }
+    { $slide "Representation selection algorithm"
+        {
+            "For each SSA value:"
+            { $list
+                "Compute possible representations"
+                "Compute cost of each representation"
+                "Pick representation with minimum cost"
+            }
+        }
+        {
+            "For each instruction:"
+            { $list
+                "If it expects a value to be in a different representation, insert box or unbox code"
+            }
+        }
+    }
+    { $slide "Register allocation"
+        "Linear scan algorithm used in Java HotSpot Client"
+        "Described in Christian Wimmer's masters thesis"
+        "Works fine on x86-64, not too great on x86-32"
+        "Good enough since basic blocks tend to be short, with lots of procedure calls"
+        "Might switch to graph coloring eventually"
+    }
+    { $slide "Compiler tools"
+        "Printing high level IR"
+        "Printing low level IR"
+        "Disassembly"
+        "Display call tree"
+        "Display control flow graph"
+        "Display dominator tree"
+    }
+}
+
+: jvm-summit-talk ( -- )
+    jvm-summit-slides "JVM Summit talk" slides-window ;
+
+MAIN: jvm-summit-talk
diff --git a/jvm-summit-talk/summary.txt b/jvm-summit-talk/summary.txt
new file mode 100644 (file)
index 0000000..769abbc
--- /dev/null
@@ -0,0 +1 @@
+Slides from Slava's talk at JVM Language Summit 2009
diff --git a/jvm-summit-talk/tags.txt b/jvm-summit-talk/tags.txt
new file mode 100644 (file)
index 0000000..8ee64cd
--- /dev/null
@@ -0,0 +1 @@
+talks
diff --git a/minneapolis-talk/authors.txt b/minneapolis-talk/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/minneapolis-talk/deploy.factor b/minneapolis-talk/deploy.factor
new file mode 100644 (file)
index 0000000..ea200ce
--- /dev/null
@@ -0,0 +1,11 @@
+USING: tools.deploy.config ;
+V{
+    { deploy-ui? t }
+    { deploy-io 3 }
+    { deploy-reflection 1 }
+    { deploy-math? t }
+    { deploy-word-props? f }
+    { deploy-c-types? f }
+    { "stop-after-last-window?" t }
+    { deploy-name "Minnesota Talk" }
+}
diff --git a/minneapolis-talk/minneapolis-talk.factor b/minneapolis-talk/minneapolis-talk.factor
new file mode 100644 (file)
index 0000000..4cae92b
--- /dev/null
@@ -0,0 +1,183 @@
+USING: slides help.markup math arrays hashtables namespaces
+sequences kernel parser memoize ;
+IN: talks.minneapolis-talk
+
+CONSTANT: minneapolis-slides
+{
+    { $slide "What is Factor?"
+        "Dynamically typed, stack language"
+        "Have our cake and eat it too"
+        "Research -vs- production"
+        "High level -vs- performance"
+        "Interactive -vs- stand-alone apps"
+    }
+    { $slide "The view from 10,000 feet"
+        "Influenced by Forth, Lisp, Joy, Smalltalk, even Java..."
+        "Vocabularies: modules"
+        "Words: named functions, classes, variables"
+        "Combinators: higher-order functions"
+        "Quotations: anonymous functions"
+    }
+    { $slide "Stack-based programming"
+        { "Most languages are " { $emphasis "applicative" } }
+        "Words pop inputs from the stack and push outputs on the stack"
+        "Literals are pushed on the stack"
+        { $code "{ 1 2 } { 7 } append reverse sum ." }
+    }
+    { $slide "Stack-based programming"
+        "With the stack you can omit unnecessary names"
+        "You can still name things: lexical/dynamic variables, sequences, associations, objects, ..."
+    }
+    { $slide "Functional programming"
+        "A quotation is a sequence of literals and words"
+        "Combinators replace imperative-style loops"
+        "A simple example:"
+        { $code "10 [ \"Hello world\" print ] times" }
+        { "Partial application: " { $link curry } }
+        { $code "{ 3 1 3 3 7 } [ 5 + ] map ." }
+        { $code "{ 3 1 3 3 7 } 5 [ + ] curry map ." }
+    }
+    { $slide "Word definitions"
+        { $code ": name ( inputs -- outputs )"
+        "    definition ;" }
+        "Stack effect comments document stack inputs and outputs."
+        "Example from previous slide:"
+        { $code ": add-each ( seq n -- newseq )"
+        "    [ + ] curry map ;" }
+        { $code "{ 3 1 3 3 7 } 5 add-each ." }
+    }
+    { $slide "Object-oriented programming"
+        { "Define a tuple class and a constructor:"
+        { $code
+            "TUPLE: person name address ;"
+            "C: <person> person"
+        } }
+        { "Create an instance:"
+        { $code
+            "\"Cosmo Kramer\""
+            "\"100 Blah blah St, New York\""
+            "<person>"
+        } }
+    }
+    { $slide "Object-oriented programming"
+        "We can inspect it and edit objects"
+        "We can reshape the class!"
+        { $code "TUPLE: person" "name address age phone-number ;" }
+        { $code "TUPLE: person" "name address phone-number age ;" }
+    }
+    { $slide "An example"
+        { $code
+            "TUPLE: square dimension ;"
+            "C: <square> square"
+            ""
+            "TUPLE: circle radius ;"
+            "C: <circle> circle"
+            ""
+            "TUPLE: rectangle width height ;"
+            "C: <rectangle> rectangle"
+        }
+    }
+    STRIP-TEASE:
+        $slide "An example"
+        { $code
+            "USE: math.constants"
+            "GENERIC: area ( shape -- meters^2 )"
+            "M: square area square-dimension sq ;"
+            "M: circle area circle-radius sq pi * ;"
+            "M: rectangle area"
+            "    dup rectangle-width"
+            "    swap rectangle-height * ;"
+        }
+    ;
+
+    { $slide "An example"
+        { $code "10 <square> area ." }
+        { $code "18 <circle> area ." }
+        { $code "20 40 <rectangle> area ." }
+    }
+    { $slide "Meta language"
+        "Here's fibonacci:"
+        { $code
+            ": fib ( x -- y )"
+            "    dup 1 > ["
+            "        1 - dup fib swap 1 - fib +"
+            "    ] when ;"
+        }
+        "It is slow:"
+        { $code
+            "35 <iota> [ fib ] map ."
+        }
+        "Let's profile it!"
+    }
+    { $slide "Memoization"
+        { { $link POSTPONE: : } " is just another word" }
+        "What if we could define a word which caches its results?"
+        { "The " { $vocab-link "memoize" } " library provides such a feature" }
+        { "Just change " { $link POSTPONE: : } " to " { $link POSTPONE: MEMO: } }
+    }
+    { $slide "Memoization"
+        { $code
+            "USE: memoize"
+            ""
+            "MEMO: fib ( x -- y )"
+            "    dup 1 > ["
+            "        1 - dup fib swap 1 - fib +"
+            "    ] when ;"
+        }
+        "It is faster:"
+        { $code
+            "35 <iota> [ fib ] map ."
+        }
+    }
+    { $slide "The Factor UI"
+        "Written in Factor"
+        "Renders with OpenGL"
+        "Backends for Windows, X11, Cocoa"
+        "You can call Windows, X11, Cocoa APIs directly too"
+        "OpenGL 2.1 shaders, OpenAL 3D audio..."
+    }
+    { $slide "Live coding demo"
+
+    }
+    { $slide "C library interface"
+        "Efficient"
+        "No need to write C code"
+        "Supports floats, structs, unions, ..."
+        "Function pointers, callbacks"
+    }
+    { $slide "Live coding demo"
+
+    }
+    { $slide "Deployment"
+        { "Let's play " { $vocab-link "tetris" } }
+    }
+    { $slide "Implementation"
+        "Portable: Windows, Mac OS X, Linux"
+        "Non-optimizing compiler"
+        "Optimizing compiler: x86, x86-64, PowerPC, ARM"
+        "Generational garbage collector"
+        "Non-blocking I/O"
+    }
+    { $slide "Some statistics"
+        "VM: 11,800 lines of C"
+        "Core library: 22,600 lines of Factor"
+        "Docs, tests, extra libraries: 117,000 lines of Factor"
+    }
+    { $slide "But wait, there's more!"
+        "Web server and framework, syntax highlighting, Ogg Theora video, SMTP, embedded Prolog, efficient unboxed arrays, XML, Unicode 5.0, memory mapped files, regular expressions, LDAP, database access, coroutines, Factor->JavaScript compiler, JSON, pattern matching, advanced math, parser generators, serialization, RSS/Atom, ..."
+    }
+    { $slide "Community"
+        "Factor development began in 2003"
+        "About a dozen contributors"
+        "Handful of \"core contributors\""
+        { "Web site: " { $url "http://factorcode.org" } }
+        "IRC: #concatenative on irc.freenode.net"
+        "Mailing list: factor-talk@lists.sf.net"
+    }
+    { $slide "Questions?" }
+}
+
+: minneapolis-talk ( -- )
+    minneapolis-slides "Minneapolis talk" slides-window ;
+
+MAIN: minneapolis-talk
diff --git a/minneapolis-talk/summary.txt b/minneapolis-talk/summary.txt
new file mode 100644 (file)
index 0000000..ef8d1bd
--- /dev/null
@@ -0,0 +1 @@
+Slides for a talk at Ruby.mn, Minneapolis, MN, January 2008
diff --git a/minneapolis-talk/tags.txt b/minneapolis-talk/tags.txt
new file mode 100644 (file)
index 0000000..8ee64cd
--- /dev/null
@@ -0,0 +1 @@
+talks
diff --git a/otug-talk/2bi.tiff b/otug-talk/2bi.tiff
new file mode 100644 (file)
index 0000000..16c0777
Binary files /dev/null and b/otug-talk/2bi.tiff differ
diff --git a/otug-talk/2bi_at.tiff b/otug-talk/2bi_at.tiff
new file mode 100644 (file)
index 0000000..e41ab98
Binary files /dev/null and b/otug-talk/2bi_at.tiff differ
diff --git a/otug-talk/2bi_star.tiff b/otug-talk/2bi_star.tiff
new file mode 100644 (file)
index 0000000..f457ce5
Binary files /dev/null and b/otug-talk/2bi_star.tiff differ
diff --git a/otug-talk/authors.txt b/otug-talk/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/otug-talk/bi.tiff b/otug-talk/bi.tiff
new file mode 100644 (file)
index 0000000..ad0ce97
Binary files /dev/null and b/otug-talk/bi.tiff differ
diff --git a/otug-talk/bi_at.tiff b/otug-talk/bi_at.tiff
new file mode 100644 (file)
index 0000000..07d25bc
Binary files /dev/null and b/otug-talk/bi_at.tiff differ
diff --git a/otug-talk/bi_star.tiff b/otug-talk/bi_star.tiff
new file mode 100644 (file)
index 0000000..17f3350
Binary files /dev/null and b/otug-talk/bi_star.tiff differ
diff --git a/otug-talk/otug-talk.factor b/otug-talk/otug-talk.factor
new file mode 100644 (file)
index 0000000..bb18d72
--- /dev/null
@@ -0,0 +1,342 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://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: talks.otug-talk
+
+: $tetris ( element -- )
+    drop [ <default-tetris> <tetris-gadget> gadget. ] ($block) ;
+
+CONSTANT: otug-slides
+{
+    { $slide "Factor!"
+        { $url "http://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 "resource:extra/talks/otug-talk/bi.tiff" }
+    }
+    { $slide "Data flow combinators - cleave family"
+        { { $link 2bi } ", " { $link 2tri } ", " { $link 2cleave } }
+        { $image "resource:extra/talks/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 "resource:extra/talks/otug-talk/bi_star.tiff" }
+    }
+    { $slide "Data flow combinators - spread family"
+        { { $link 2bi* } }
+        { $image "resource:extra/talks/otug-talk/2bi_star.tiff" }
+    }
+    { $slide "Data flow combinators - apply family"
+        { { $link bi@ } ", " { $link tri@ } ", " { $link napply } }
+        { $image "resource:extra/talks/otug-talk/bi_at.tiff" }
+    }
+    { $slide "Data flow combinators - apply family"
+        { { $link 2bi@ } }
+        { $image "resource:extra/talks/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 "talks.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 "http://factorcode.org" }
+        { $url "http://concatenative.org" }
+        { $url "http://docs.factorcode.org" }
+        { $url "http://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
diff --git a/otug-talk/summary.txt b/otug-talk/summary.txt
new file mode 100644 (file)
index 0000000..571a4c2
--- /dev/null
@@ -0,0 +1 @@
+Slides from a talk at OTUG by Slava Pestov, December 2008
diff --git a/otug-talk/tags.txt b/otug-talk/tags.txt
new file mode 100644 (file)
index 0000000..8ee64cd
--- /dev/null
@@ -0,0 +1 @@
+talks
diff --git a/tc-lisp-talk/authors.txt b/tc-lisp-talk/authors.txt
new file mode 100644 (file)
index 0000000..7c1b2f2
--- /dev/null
@@ -0,0 +1 @@
+Doug Coleman
diff --git a/tc-lisp-talk/tags.txt b/tc-lisp-talk/tags.txt
new file mode 100644 (file)
index 0000000..8ee64cd
--- /dev/null
@@ -0,0 +1 @@
+talks
diff --git a/tc-lisp-talk/tc-lisp-talk.factor b/tc-lisp-talk/tc-lisp-talk.factor
new file mode 100644 (file)
index 0000000..8d60e10
--- /dev/null
@@ -0,0 +1,535 @@
+! Copyright (C) 2009 Doug Coleman.
+! See http://factorcode.org/license.txt for BSD license.
+USING: assocs combinators constructors eval help.markup kernel
+multiline namespaces parser sequences sequences.private slides
+vocabs.refresh words fry ;
+IN: talks.tc-lisp-talk
+
+CONSTANT: tc-lisp-slides
+{
+    { $slide "Factor!"
+        { $url "http://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 "First, some examples"
+        { $code "3 weeks ago noon monday ." }
+        { $code "USE: roman 2009 >roman ." }
+        { $code ": average ( seq -- x )
+    [ sum ] [ length ] bi / ;" }
+        { $code "1 miles [ km ] undo >float ." }
+        { $code "[ readln eval>string print t ] loop" }
+    }
+    { $slide "XML Literals"
+        { $code
+        "USING: splitting xml.writer xml.syntax ;
+{ \"one\" \"two\" \"three\" }
+[ [XML <item><-></item> XML] ] map
+<XML <doc><-></doc> XML> pprint-xml"
+        }
+    }
+    { $slide "Differences between Factor and Lisp"
+        "Single-implementation language"
+        "Less nesting, shorter word length"
+        { "Dynamic reloading of code from files with " { $link refresh-all } }
+        "More generic protocols -- sequences, assocs, streams"
+        "More cross-platform"
+        "No standard for the language"
+        "Evaluates left to right"
+    }
+    { $slide "Terminology"
+        { "Words - functions" }
+        { "Vocabularies - collections of code in the same namespace" }
+        { "Quotations - blocks of code" { $code "[ dup reverse append ]" } }
+        { "Combinators - higher order functions" }
+        { "Static stack effect - known stack effect at compile-time" }
+    }
+    { $slide "Defining a word"
+        "Defined at parse time"
+        "Parts: name, stack effect, definition"
+        "Composed of tokens separated by whitespace"
+        { $code ": palindrome? ( string -- ? ) dup reverse = ;" }
+    }
+    { $slide "Non-static stack effect"
+        "Not a good practice, nor useful"
+        "Not compiled by the optimizing compiler"
+        { $code "100 <iota> [ ] each" }
+    }
+    { $slide "Module system"
+        "Code divided up into vocabulary roots"
+        "core/ -- just enough code to bootstrap Factor"
+        "basis/ -- optimizing compiler, the UI, tools, libraries"
+        "extra/ -- demos, unpolished code, experiments"
+        "work/ -- your works in progress"
+    }
+    { $slide "Module system (part 2)"
+        "Each vocabulary corresponds to a directory on disk, with documentation and test files"
+        { "Code for the " { $snippet "math" } " vocabulary: " { $snippet "~/factor/core/math/math.factor" } }
+        { "Documentation for the " { $snippet "math" } " vocabulary: " { $snippet "~/factor/core/math/math-docs.factor" } }
+        { "Unit tests for the " { $snippet "math" } " vocabulary: " { $snippet " ~/factor/core/math/math-tests.factor" } }
+    }
+    { $slide "Using a library"
+        "Each file starts with a USING: list"
+        "To use a library, simply include it in this list"
+        "Refreshing code loads dependencies correctly"
+    }
+    { $slide "Object system"
+        "Based on CLOS"
+        { "We define generic words that operate on the top of the stack with " { $link POSTPONE: GENERIC:  } " or on an implicit parameter with " { $link POSTPONE: HOOK: } }
+    }
+    { $slide "Object system example: shape protocol"
+        "In ~/factor/work/shapes/shapes.factor"
+        { $code "IN: shapes
+
+GENERIC: area ( shape -- x )
+GENERIC: perimeter ( shape -- x )"
+        }
+    }
+    { $slide "Implementing the shape protocol: circles"
+        "In ~/factor/work/shapes/circle/circle.factor"
+        { $code "USING: shapes constructors math
+math.constants ;
+IN: shapes.circle
+
+TUPLE: circle radius ;
+CONSTRUCTOR: <circle> circle ( radius -- obj ) ;
+M: circle area radius>> sq pi * ;
+M: circle perimeter radius>> pi * 2 * ;"
+        }
+    }
+    { $slide "Dynamic variables"
+        "Implemented as a stack of hashtables"
+        { "Useful words are " { $link get } ", " { $link set } }
+        "Input, output, error streams are stored in dynamic variables"
+        { $code "\"Today is the first day of the rest of your life.\"
+[
+    readln print
+] with-string-reader"
+        }
+    }
+    { $slide "The global namespace"
+        "The global namespace is just the namespace at the bottom of the namespace stack"
+        { "Useful words are " { $link get-global } ", " { $link set-global } }
+        "Factor idiom for changing a particular namespace"
+        { $code "SYMBOL: king
+global [ \"Henry VIII\" king set ] with-variables"
+        }
+        { $code "with-scope" }
+        { $code "namestack" }
+    }
+    { $slide "Hooks"
+        "Dispatch on a dynamic variable"
+        { $code "HOOK: computer-name os ( -- string )
+M: macosx computer-name uname first ;
+macosx \ os set-global
+computer-name"
+        }
+    }
+    { $slide "Interpolate"
+        "Replaces variables in a string"
+        { $code
+"\"Dawg\" \"name\" set
+\"rims\" \"noun\" set
+\"bling\" \"verb1\" set
+\"roll\" \"verb2\" set
+[
+    \"Sup ${name}, we heard you liked ${noun}, so we put ${noun} on your car so you can ${verb1} while you ${verb2}.\"
+    interpolate
+] with-string-writer print "
+        }
+    }
+    { $slide "Sequence protocol"
+        "All sequences obey a protocol of generics"
+        { "Is an object a " { $link sequence? } }
+        { "Getting the " { $link length } }
+        { "Accessing the " { $link nth  } " element" }
+        { "Setting an element - " { $link set-nth } }
+    }
+    { $slide "Examples of sequences in Factor"
+        "Arrays are mutable"
+        "Vectors are mutable and growable"
+        { "Arrays " { $code "{ \"abc\" \"def\" 50 }" } }
+        { "Vectors " { $code "V{ \"abc\" \"def\" 50 }" } }
+        { "Byte-arrays " { $code "B{ 1 2 3 }" } }
+        { "Byte-vectors " { $code "BV{ 11 22 33 }" } }
+    }
+    { $slide "Specialized arrays and vectors"
+        { "Specialized int arrays " { $code "int-array{ -20 -30 40 }" } }
+        { "Specialized uint arrays " { $code "uint-array{ 20 30 40 }" } }
+        { "Specialized float vectors " { $code "float-vector{ 20 30 40 }" } }
+        "35 others C-type arrays"
+    }
+    { $slide "Specialized arrays code"
+        "One line per array/vector"
+        { "In ~/factor/basis/specialized-arrays/float/float.factor"
+            { $code "<< \"float\" define-array >>" }
+        }
+        { "In ~/factor/basis/specialized-vectors/float/float.factor"
+            { $code "<< \"float\" define-vector >>" }
+        }
+    }
+
+    { $slide "Specialized arrays are implemented using functors"
+        "Like C++ templates"
+        "Eliminate boilerplate in ways other abstractions don't"
+        "Contains a definition section and a functor body"
+        "Uses the interpolate vocabulary"
+    }
+    { $slide "Functor for sorting"
+        { $code
+            "<FUNCTOR: define-sorting ( NAME QUOT -- )
+
+NAME<=> DEFINES ${NAME}<=>
+NAME>=< DEFINES ${NAME}>=<
+
+WHERE
+
+: NAME<=> ( obj1 obj2 -- <=> ) QUOT compare ;
+: NAME>=< ( obj1 obj2 -- >=< )
+    NAME<=> invert-comparison ;
+
+;FUNCTOR>"
+        }
+    }
+    { $slide "Example of sorting functor"
+        { $code "USING: sorting.functor ;
+<< \"length\" [ length ] define-sorting >>"
+        }
+        { $code
+            "{ { 1 2 3 } { 1 2 } { 1 } }
+[ length<=> ] sort"
+        }
+    }
+    { $slide "Combinators"
+        "Used to implement higher order functions (dataflow and control flow)"
+        "Compiler optimizes away quotations completely"
+        "Optimized code is just tight loops in registers"
+        "Most loops can be expressed with combinators or tail-recursion"
+    }
+    { $slide "Combinators that act on one value"
+        { $link bi }
+        { $code "10 [ 1 - ] [ 1 + ] bi" }
+        { $link tri }
+        { $code "10 [ 1 - ] [ 1 + ] [ 2 * ] tri" }
+    }
+    { $slide "Combinators that act on two values"
+        { $link 2bi }
+        { $code "10 1 [ - ] [ + ] 2bi" }
+        { $link bi* }
+        { $code "10 20 [ 1 - ] [ 1 + ] bi*" }
+        { $link bi@ }
+        { $code "5 9 [ sq ] bi@" }
+    }
+    { $slide "Sequence combinators"
+
+        { $link each }
+        { $code "{ 1 2 3 4 5 } [ sq . ] each" }
+        { $link map }
+        { $code "{ 1 2 3 4 5 } [ sq ] map" }
+        { $link filter }
+        { $code "{ 1 2 3 4 5 } [ even? ] filter" }
+    }
+    { $slide "Multiple sequence combinators"
+
+        { $link 2each }
+        { $code "{ 1 2 3 } { 10 20 30 } [ + . ] 2each" }
+        { $link 2map }
+        { $code "{ 1 2 3 } { 10 20 30 } [ + ] 2map" }
+    }
+    { $slide "Control flow: if"
+        { $link if }
+        { $code "10 random dup even? [ 2 / ] [ 1 - ] if" }
+        { $link when }
+        { $code "10 random dup even? [ 2 / ] when" }
+        { $link unless }
+        { $code "10 random dup even? [ 1 - ] unless" }
+    }
+    { $slide "Control flow: case"
+        { $link case }
+        { $code "ERROR: not-possible obj ;
+10 random 5 <=> {
+    { +lt+ [ \"Less\" ] }
+    { +gt+ [ \"More\" ] }
+    { +eq+ [ \"Equal\" ] }
+    [ not-possible ]
+} case"
+        }
+    }
+    { $slide "Fry"
+        "Used to construct quotations"
+        { "'Holes', represented by " { $snippet "_" } " are filled left to right" }
+        { $code "10 4 '[ _ + ] call" }
+        { $code "3 4 '[ _ sq _ + ] call" }
+    }
+    { $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 lengths in an array"
+        { $code ": v-n ( v n -- w ) '[ _ - ] map ;
+
+: area ( seq -- x )
+    [ 0 suffix ] [ sum 2 / ] bi
+    v-n product sqrt ;" }
+    }
+    { $slide "Implementing an abstraction"
+        { "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 "Macros in Factor"
+        "Expand at compile-time"
+        "Return a quotation to be compiled"
+        "Can express non-static stack effects"
+        "Not as widely used as combinators, 60 macros so far"
+        { $code "{ 1 2 3 4 5 } 5 firstn" }
+    }
+    { $slide "A macro solution"
+        "Returns a quotation to the compiler"
+        "Constructed using map, fry, and concat"
+        { $code "MACRO: plox ( seq -- quot )
+    [
+        '[ dup _ when ]
+    ] map [ ] concat-as ;"
+        }
+    }
+    { $slide "Macro example"
+        "Return the caaar of a sequence"
+        { "Return " { $snippet "f" } " on failure" }
+        { $code ": caaar ( seq/f -- x/f )
+    {
+        [ first ]
+        [ first ]
+        [ first ]
+    } plox ;"
+        }
+        { $code "{ { f } } caaar" }
+        { $code "{ { { 1 2 3 } } } caaar" }
+    }
+    { $slide "Smart combinators"
+        "Use stack checker to infer inputs and outputs"
+        "Even fewer uses than macros"
+        { $code "{ 1 10 20 34 } sum" }
+        { $code "[ 1 10 20 34 ] sum-outputs" }
+        { $code "[ 2 2 [ even? ] both? ] [ + ] [ - ] smart-if" }
+    }
+    { $slide "Fibonacci"
+        "Not tail recursive"
+        "Call tree is huge"
+        { $code ": fib ( n -- x )
+    dup 1 <= [
+        [ 1 - fib ] [ 2 - fib ] bi +
+    ] unless ;"
+        }
+        { $code "36 <iota> [ fib ] map ." }
+    }
+    { $slide "Memoized Fibonacci"
+        "Change one word and it's efficient"
+        { $code "MEMO: fib ( n -- x )
+    dup 1 <= [
+        [ 1 - fib ] [ 2 - fib ] bi +
+    ] unless ;"
+        }
+        { $code "36 <iota> [ fib ] map ." }
+    }
+    { $slide "Destructors"
+        "Deterministic resource disposal"
+        "Any step can fail and we don't want to leak resources"
+        "We want to conditionally clean up sometimes -- if everything succeeds, we might wish to retain the buffer"
+    }
+
+    { $slide "Example in C"
+        { $code
+"void do_stuff()
+{
+    void *obj1, *obj2;
+    if(!(*obj1 = malloc(256))) goto end;
+    if(!(*obj2 = malloc(256))) goto cleanup1;
+    ... work goes here...
+cleanup2: free(*obj2);
+cleanup1: free(*obj1);
+end: return;
+}"
+    }
+    }
+    { $slide "Example: allocating and disposing two buffers"
+        { $code ": do-stuff ( -- )
+    [
+        256 malloc &free
+        256 malloc &free
+        ... work goes here ...
+    ] with-destructors ;"
+        }
+    }
+    { $slide "Example: allocating two buffers for later"
+        { $code ": do-stuff ( -- )
+    [
+        256 malloc |free
+        256 malloc |free
+        ... work goes here ...
+    ] with-destructors ;"
+        }
+    }
+    { $slide "Example: disposing of an output port"
+        { $code "M: output-port dispose*
+    [
+        {
+            [ handle>> &dispose drop ]
+            [ buffer>> &dispose drop ]
+            [ port-flush ]
+            [ handle>> shutdown ]
+        } cleave
+    ] with-destructors ;"
+        }
+    }
+    { $slide "Rapid application development"
+        "We lost the dice to Settlers of Catan: Cities and Knights"
+        "Two regular dice, one special die"
+        { $vocab-link "dice" }
+    }
+    { $slide "The essence of Factor"
+        "Nicely named words abstract away the stack, leaving readable code"
+        { $code ": surround ( seq left right -- seq' )
+    swapd 3append ;"
+        }
+        { $code ": glue ( left right middle -- seq' )
+    swap 3append ;"
+        }
+        { $code HEREDOC: xyz
+"a" "b" "c" 3append
+"a" """""""" surround
+"a" "b" ", " glue
+xyz
+        }
+    }
+    { $slide "C FFI demo"
+        "Easy to call C functions from Factor"
+        "Handles C structures, C types, callbacks"
+        "Used extensively in the Windows and Unix backends"
+        { $code
+            "FUNCTION: double pow ( double x, double y ) ;
+2 5.0 pow ."
+        }
+    }
+    { $slide "Windows win32 example"
+        { $code
+"M: windows gmt-offset
+    ( -- hours minutes seconds )
+    \"TIME_ZONE_INFORMATION\" <c-object>
+    dup GetTimeZoneInformation {
+        { TIME_ZONE_ID_INVALID [
+            win32-error
+        ] }
+        { TIME_ZONE_ID_STANDARD [
+            TIME_ZONE_INFORMATION-Bias
+        ] }
+    } case neg 60 /mod 0 ;"
+        }
+    }
+    { $slide "Struct and function"
+        { $code "C-STRUCT: TIME_ZONE_INFORMATION
+    { \"LONG\" \"Bias\" }
+    { { \"WCHAR\" 32 } \"StandardName\" }
+    { \"SYSTEMTIME\" \"StandardDate\" }
+    { \"LONG\" \"StandardBias\" }
+    { { \"WCHAR\" 32 } \"DaylightName\" }
+    { \"SYSTEMTIME\" \"DaylightDate\" }
+    { \"LONG\" \"DaylightBias\" } ;"
+        }
+        { $code "FUNCTION: DWORD GetTimeZoneInformation (
+    LPTIME_ZONE_INFORMATION
+        lpTimeZoneInformation
+) ;"
+        }
+
+    }
+    { $slide "Cocoa FFI"
+        { $code "IMPORT: NSAlert [
+    NSAlert -> new
+    [ -> retain ] [
+        \"Raptor\" <CFString> &CFRelease
+        -> setMessageText:
+    ] [
+        \"Look out!\" <CFString> &CFRelease
+        -> setInformativeText:
+    ] tri -> runModal drop
+] with-destructors"
+        }
+    }
+    { $slide "Deployment demo"
+        "Vocabularies can be deployed"
+        "Standalone .app on Mac"
+        "An executable and dll on Windows"
+        { $vocab-link "webkit-demo" }
+    }
+    { $slide "Interesting programs"
+        { $vocab-link "terrain" }
+        { $vocab-link "gpu.demos.raytrace" }
+        { $vocab-link "gpu.demos.bunny" }
+    }
+    { $slide "Factor's source tree"
+        "Lines of code in core/: 9,500"
+        "Lines of code in basis/: 120,000"
+        "Lines of code in extra/: 51,000"
+        "Lines of tests: 44,000"
+        "Lines of documentation: 44,500"
+    }
+    { $slide "VM trivia"
+        "Lines of C++ code: 12860"
+        "Generational garbage collection"
+        "Non-optimizing compiler"
+        "Loads an image file and runs it"
+    }
+    { $slide "Why should I use Factor?"
+        "More abstractions over time"
+        "We fix reported bugs quickly"
+        "Stackable, fluent language"
+        "Supports extreme programming"
+        "Beer-friendly programming"
+    }
+    { $slide "Questions?"
+    }
+}
+
+: tc-lisp-talk ( -- )
+    tc-lisp-slides "TC Lisp talk" slides-window ;
+
+MAIN: tc-lisp-talk
diff --git a/vpri-talk/authors.txt b/vpri-talk/authors.txt
new file mode 100644 (file)
index 0000000..1901f27
--- /dev/null
@@ -0,0 +1 @@
+Slava Pestov
diff --git a/vpri-talk/summary.txt b/vpri-talk/summary.txt
new file mode 100644 (file)
index 0000000..1ebcc4b
--- /dev/null
@@ -0,0 +1 @@
+Slides from a talk at VPRI by Slava Pestov, October 2008
diff --git a/vpri-talk/tags.txt b/vpri-talk/tags.txt
new file mode 100644 (file)
index 0000000..8ee64cd
--- /dev/null
@@ -0,0 +1 @@
+talks
diff --git a/vpri-talk/vpri-talk.factor b/vpri-talk/vpri-talk.factor
new file mode 100644 (file)
index 0000000..9903d22
--- /dev/null
@@ -0,0 +1,492 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://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 urls
+peg.ebnf tools.annotations tools.crossref help.topics
+math.functions compiler.tree.optimizer compiler.cfg.optimizer
+fry ;
+IN: talks.vpri-talk
+
+CONSTANT: vpri-slides
+{
+    { $slide "Factor!"
+        { $url "http://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 "Programming is hard"
+        "Let's play tetris instead"
+        { $vocab-link "tetris" }
+        "Tetris is hard too... let's cheat"
+        "Factor workflow: change code, F2, test, repeat"
+    }
+    { $slide "Basics"
+        "Stack based, dynamically typed"
+        { $code "{ 1 1 3 4 4 8 9 9 } dup duplicates diff ." }
+        "Words: named code snippets"
+        { $code ": remove-duplicates ( seq -- seq' )" "    dup duplicates diff ;" }
+        { $code "{ 1 1 3 4 4 8 9 9 } remove-duplicates ." }
+        "Vocabularies: named sets of words"
+        { $link "vocab-index" }
+    }
+    { $slide "Quotations"
+        "Quotation: unnamed block of code"
+        "Combinators: words taking quotations"
+        { $code "{ 1 1 3 4 4 8 9 9 }" "[ { 1 3 8 } member? ] filter ." }
+        { $code "{ -1 1 -2 0 3 } [ 0 max ] map" }
+        "Partial application:"
+        { $code ": clamp ( seq n -- seq' ) '[ _ max ] map" "{ -1 1 -2 0 3 } 0 clamp ;" }
+    }
+    { $slide "Object system"
+        "CLOS with single dispatch"
+        "A tuple is a user-defined class which holds named values."
+        { $code
+            "TUPLE: rectangle width height ;"
+            "TUPLE: circle radius ;"
+        }
+    }
+    { $slide "Object system"
+        "Constructing instances:"
+        { $code "rectangle new" }
+        { $code "rectangle boa" }
+        "Let's encapsulate:"
+        { $code
+            ": <rectangle> ( w h -- r ) rectangle boa ;"
+            ": <circle> ( r -- c ) circle boa ;"
+        }
+    }
+    { $slide "Object system"
+        "Generic words and methods"
+        { $code "GENERIC: area ( shape -- n )" }
+        "Two methods:"
+        { $code
+            "USE: math.constants"
+            ""
+            "M: rectangle area"
+            "    [ width>> ] [ height>> ] bi * ;"
+            ""
+            "M: circle area radius>> sq pi * ;"
+        }
+    }
+    { $slide "Object system"
+        "We can compute areas now."
+        { $code "100 20 <rectangle> area ." }
+        { $code "3 <circle> area ." }
+    }
+    { $slide "Object system"
+        "New operation, existing types:"
+        { $code
+            "GENERIC: perimeter ( shape -- n )"
+            ""
+            "M: rectangle perimeter"
+            "    [ width>> ] [ height>> ] bi + 2 * ;"
+            ""
+            "M: circle perimeter"
+            "    radius>> 2 * pi * ;"
+        }
+    }
+    { $slide "Object system"
+        "We can compute perimeters now."
+        { $code "100 20 <rectangle> perimeter ." }
+        { $code "3 <circle> perimeter ." }
+    }
+    { $slide "Object system"
+        "New type, extending existing operations:"
+        { $code
+            "TUPLE: triangle base height ;"
+            ""
+            ": <triangle> ( b h -- t ) triangle boa ;"
+            ""
+            "M: triangle area"
+            "    [ base>> ] [ height>> ] bi * 2 / ;"
+        }
+    }
+    { $slide "Object system"
+        "New type, extending existing operations:"
+        { $code
+            ": hypotenuse ( x y -- z ) [ sq ] bi@ + sqrt ;"
+            ""
+            "M: triangle perimeter"
+            "    [ base>> ] [ height>> ] bi"
+            "    [ + ] [ hypotenuse ] 2bi + ;"
+        }
+    }
+    { $slide "Object system"
+        "Object system handles dynamic redefinition very well"
+        { $code "TUPLE: person name age occupation ;" }
+        "Make an instance..."
+    }
+    { $slide "Object system"
+        "Let's add a new slot:"
+        { $code "TUPLE: person name age address occupation ;" }
+        "Fill it in with inspector..."
+        "Change the order:"
+        { $code "TUPLE: person name occupation address ;" }
+    }
+    { $slide "Object system"
+        "How does it work?"
+        "Objects are not hashtables; slot access is very fast"
+        "Redefinition walks the heap; expensive but rare"
+    }
+    { $slide "Object system"
+        "Supports \"duck typing\""
+        "Two tuples can have a slot with the same name"
+        "Code that uses accessors will work on both"
+        "Accessors are auto-generated generic words"
+    }
+    { $slide "Object system"
+        "More: inheritance, type declarations, read-only slots, predicate, intersection, singleton classes, reflection"
+        "Object system is entirely implemented in Factor"
+        { { $vocab-link "generic" } ", " { $vocab-link "classes" } ", " { $vocab-link "slots" } }
+    }
+    { $slide "The parser"
+        "All data types have a literal syntax"
+        "Literal hashtables and arrays are very useful in data-driven code"
+        "\"Code is data\" because quotations are objects (enables Lisp-style macros)"
+        { $code "H{ { \"cookies\" 12 } { \"milk\" 10 } }" }
+        "Libraries can define new parsing words"
+    }
+    { $slide "Example: float arrays"
+        { $vocab-link "specialized-arrays.float" }
+        "Avoids boxing and unboxing overhead"
+        "Implemented with library code"
+        { $code "float-array{ 3.14 7.6 10.3 }" }
+    }
+    { $slide "Example: memoization"
+        { "Memoization with " { $link POSTPONE: MEMO: } }
+        { $code
+            ": fib ( m -- n )"
+            "    dup 1 > ["
+            "        [ 1 - fib ] [ 2 - fib ] bi +"
+            "    ] when ;"
+        }
+        "Very slow! Let's profile it..."
+    }
+    { $slide "Example: memoization"
+        { "Let's use " { $link POSTPONE: : } " instead of " { $link POSTPONE: MEMO: } }
+        { $code
+            "MEMO: fib ( m -- n )"
+            "    dup 1 > ["
+            "        [ 1 - fib ] [ 2 - fib ] bi +"
+            "    ] when ;"
+        }
+        "Much faster"
+    }
+    { $slide "Meta-circularity"
+        { { $link POSTPONE: MEMO: } " is just a library word" }
+        { "But so is " { $link POSTPONE: : } }
+        "Factor's parser is written in Factor"
+        { "All syntax is just parsing words: " { $link POSTPONE: [ } ", " { $link POSTPONE: " } }
+    }
+    { $slide "Extensible syntax, DSLs"
+        "Most parsing words fall in one of two categories"
+        "First category: literal syntax for new data types"
+        "Second category: defining new types of words"
+        "Some parsing words are more complicated"
+    }
+    { $slide "Example: printf"
+        { { $link POSTPONE: EBNF: } ": a complex parsing word" }
+        "Implements a custom syntax for expressing parsers: like OMeta!"
+        { "Example: " { $vocab-link "printf-example" } }
+        { $code "\"cheese\" \"vegan\" \"%s is not %s\\n\" printf" }
+        { $code "\"Factor\" 5 \"%s is %d years old\\n\" printf" }
+    }
+    { $slide "Example: simple web browser"
+        { $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 "Locals and lexical scope"
+        "Sometimes, there's no good stack solution to a problem"
+        "Or, you're porting existing code in a quick-and-dirty way"
+        "Our solution: implement named locals as a DSL in Factor"
+        "Influenced by Scheme and Lisp"
+    }
+    { $slide "Locals and lexical scope"
+        { "Define lambda words with " { $link POSTPONE: :: } }
+        { "Establish bindings with " { $link POSTPONE: [let } " and " { $snippet "[let*" } }
+        "Mutable bindings with correct semantics"
+        { "Named inputs for quotations with " { $link POSTPONE: [| } }
+        "Full closures"
+    }
+    { $slide "Locals and lexical scope"
+        "Combinator with 5 parameters!"
+        { $code
+            ":: branch ( a b neg zero pos -- )"
+            "    a b = zero [ a b < neg pos if ] if ; inline"
+        }
+        "Unwieldy with the stack"
+    }
+    { $slide "Locals and lexical scope"
+        { $code
+            "ERROR: underage-exception ;"
+            ""
+            ": check-drinking-age ( age -- )"
+            "    21"
+            "    [ underage-exception ]"
+            "    [ \"Grats, you're now legal\" print ]"
+            "    [ \"Go get hammered\" print ]"
+            "    branch ;"
+        }
+    }
+    { $slide "Locals and lexical scope"
+        "Locals are entirely implemented in Factor"
+        "Example of compile-time meta-programming"
+        "No performance penalty -vs- using the stack"
+        "In the base image, only 59 words out of 13,000 use locals"
+    }
+    { $slide "More about partial application"
+        { { $link POSTPONE: '[ } " is \"fry syntax\"" }
+        { $code "'[ _ + ] == [ + ] curry" }
+        { $code "'[ @ t ] == [ t ] compose" }
+        { $code "'[ _ nth @ ] == [ [ nth ] curry ] dip compose" }
+        { $code "'[ [ _ ] dip nth ] == [ [ ] curry dip nth ] curry" }
+        { "Fry and locals desugar to " { $link curry } ", " { $link compose } }
+    }
+    { $slide "More about partial application"
+        { { $link call } " is fundamental" }
+        { { $link quotation } ", " { $link curry } " and " { $link compose } " are classes" }
+        { $code
+            "GENERIC: call ( quot -- )"
+            "M: curried call uncurry call ;"
+            "M: composed call uncompose slip call ;"
+            "M: quotation call (call) ;"
+        }
+        { "So " { $link curry } ", " { $link compose } " are library features" }
+    }
+    { $slide "Why stack-based?"
+        "Because nobody else is doing it"
+        "Interesting properties: concatenation is composition, chaining functions together, \"fluent\" interfaces, new combinators"
+        { $vocab-link "smtp-example" }
+        { $code
+            "{ \"chicken\" \"beef\" \"pork\" \"turkey\" }"
+            "[ 5 short head ] map ."
+        }
+        "To rattle people's cages"
+    }
+    { $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 "talks.vpri-talk" }
+    }
+    { $slide "Some line counts"
+        "VM: 12,000 lines of C"
+        "core: 9,000 lines of Factor"
+        "basis: 80,000 lines of Factor"
+    }
+    { $slide "More line counts"
+        "Object system (core): 2184 lines"
+        "Dynamic variables (core): 40 lines"
+        "Deterministic scoped destructors (core): 56 lines"
+        "Optimizing compiler (basis): 12938 lines"
+        "Lexical variables and closures (basis): 477 lines"
+        "Fry (basis): 51 lines"
+        "Help system (basis): 1831 lines"
+    }
+    { $slide "Implementation"
+        "VM: garbage collection, bignums, ..."
+        "Bootstrap image: parser, hashtables, object system, ..."
+        "Non-optimizing compiler"
+        "Stage 2 bootstrap: optimizing compiler, UI, ..."
+        "Full image contains machine code"
+    }
+    { $slide "Compiler"
+        { "Let's look at " { $vocab-link "benchmark.mandel" } }
+        "A naive implementation would be very slow"
+        "Combinators, currying, partial application"
+        "Boxed complex numbers"
+        "Boxed floats"
+        { "Redundancy in " { $link absq } " and " { $link sq } }
+    }
+    { $slide "Compiler: front-end"
+        "Builds high-level tree SSA IR"
+        "Stack code with uniquely-named values"
+        "Inlines combinators and calls to quotations"
+        { $code "USING: compiler.tree.builder compiler.tree.debugger ;" "[ c pixel ] build-tree nodes>quot ." }
+    }
+    { $slide "Compiler: high-level optimizer"
+        "12 optimization passes"
+        { $link optimize-tree }
+        "Some passes collect information, others use the results of past analysis to rewrite the code"
+    }
+    { $slide "Compiler: propagation pass"
+        "Propagation pass computes types with type function"
+        { "Example: output type of " { $link + } " depends on the types of inputs" }
+        "Type: can be a class, a numeric interval, array with a certain length, tuple with certain type slots, literal value, ..."
+        "Mandelbrot: we infer that we're working on complex floats"
+    }
+    { $slide "Compiler: propagation pass"
+        "Propagation also supports \"constraints\""
+        { $code "[ dup array? [ first ] when ] optimized." }
+        { $code "[ >fixnum dup 0 < [ 1 + ] when ] optimized." }
+        { $code
+            "["
+            "    >fixnum"
+            "    dup [ -10 > ] [ 10 < ] bi and"
+            "    [ 1 + ] when"
+            "] optimized."
+        }
+    }
+    { $slide "Compiler: propagation pass"
+        "Eliminates method dispatch, inlines method bodies"
+        "Mandelbrot: we infer that integer indices are fixnums"
+        "Mandelbrot: we eliminate generic arithmetic"
+    }
+    { $slide "Compiler: escape analysis"
+        "We identify allocations for tuples which are never returned or passed to other words (except slot access)"
+        { "Partial application with " { $link curry } " and " { $link compose } }
+        "Complex numbers"
+    }
+    { $slide "Compiler: escape analysis"
+        { "Virtual sequences: " { $link <slice> } ", " { $link <reversed> } }
+        { $code "[ <reversed> [ . ] each ] optimized." }
+        { "Mandelbrot: we unbox " { $link curry } ", complex number allocations" }
+    }
+    { $slide "Compiler: dead code elimination"
+        "Cleans up the mess from previous optimizations"
+        "After inlining and dispatch elimination, dead code comes up because of unused generality"
+        { "No-ops like " { $snippet "0 +" } ", " { $snippet "1 *" } }
+        "Literals which are never used"
+        "Side-effect-free words whose outputs are dropped"
+        { $code "[ c pixel ] optimized." }
+    }
+    { $slide "Compiler: low level IR"
+        "Register-based SSA"
+        "Stack operations expand into low-level instructions"
+        { $code "[ 5 ] regs." }
+        { $code "[ swap ] regs." }
+        { $code "[ append reverse ] regs." }
+    }
+    { $slide "Compiler: low-level optimizer"
+        "5 optimization passes"
+        { $link optimize-cfg }
+        "Gets rid of redundancy which is hidden in high-level stack code"
+    }
+    { $slide "Compiler: optimize memory"
+        "First pass optimizes stack and memory operations"
+        { "Example: " { $link 2array } }
+        { { $link <array> } " fills array with initial value" }
+        "What if we immediately store new values into the array?"
+        { $code "\\ 2array regs." }
+        "Mandelbrot: we optimize stack operations"
+    }
+    { $slide "Compiler: value numbering"
+        "Identifies expressions which are computed more than once in a basic block"
+        "Simplifies expressions with various identities"
+        "Mandelbrot: redundant float boxing and unboxing, redundant arithmetic"
+    }
+    { $slide "Compiler: dead code elimination"
+        "Dead code elimination for low-level IR"
+        "Again, cleans up results of prior optimizations"
+    }
+    { $slide "Compiler: register allocation"
+        "IR assumes an infinite number of registers which are only assigned once"
+        "Real CPUs have a finite set of registers which can be assigned any number of times"
+        "\"Linear scan register allocation with second-chance binpacking\""
+    }
+    { $slide "Compiler: register allocation"
+        "3 steps:"
+        "Compute live intervals"
+        "Allocate registers"
+        "Assign registers and insert spills"
+    }
+    { $slide "Compiler: register allocation"
+        "Step 1: compute live intervals"
+        "We number all instructions consecutively"
+        "A live interval associates a virtual register with a list of usages"
+    }
+    { $slide "Compiler: register allocation"
+        "Step 2: allocate registers"
+        "We scan through sorted live intervals"
+        "If a physical register is available, assign"
+        "Otherwise, find live interval with furthest away use, split it, look at both parts again"
+    }
+    { $slide "Compiler: register allocation"
+        "Step 3: assign registers and insert spills"
+        "Simple IR rewrite step"
+        "After register allocation, one vreg may have several live intervals, and different physical registers at different points in time"
+        "Hence, \"second chance\""
+        { "Mandelbrot: " { $code "[ c pixel ] regs." } }
+    }
+    { $slide "Compiler: code generation"
+        "Iterate over list of instructions"
+        "Extract tuple slots and call hooks"
+        { $vocab-link "cpu.architecture" }
+        "Finally, we hand the code to the VM"
+        { $code "\\ 2array disassemble" }
+    }
+    { $slide "Garbage collection"
+        "All roots are identified precisely"
+        "Generational copying for data"
+        "Mark sweep for native code"
+    }
+    { $slide "History"
+        "Started in 2003, implemented in Java"
+        "Scripting language for a 2D shooter game"
+        "Interactive development is addictive"
+        "I wanted to write entire applications in Factor"
+        "Added JVM bytecode compiler pretty early on"
+    }
+    { $slide "History"
+        "Wrote native C implementation, mid-2004"
+        "Added native compiler at some point"
+        "Added an FFI, SDL bindings, then UI"
+        "Switched UI to OpenGL and native APIs"
+        "Generational GC"
+        "Got rid of interpreter"
+    }
+    { $slide "Project infrastructure"
+        { $url "http://factorcode.org" }
+        { $url "http://concatenative.org" }
+        { $url "http://docs.factorcode.org" }
+        { $url "http://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"
+        "Saves us from the burden of making releases by hand"
+        "Maintains stability"
+    }
+    { $slide "Community"
+        "#concatenative irc.freenode.net: 50-60 members"
+        "factor-talk@lists.sf.net: 180 subscribers"
+        "About 30 people have code in the Factor repository"
+        "Easy to get started: binaries, lots of docs, friendly community..."
+    }
+    { $slide "Future direction: Factor 1.0"
+        "Continue doing what we're doing:"
+        "Polish off some language features"
+        "Stability"
+        "Performance"
+        "Documentation"
+        "Developer tools"
+    }
+    { $slide "Future direction: Factor 2.0"
+        "Native threads"
+        "Syntax-aware Factor editor"
+        "Embedding Factor in C apps"
+        "Cross-compilation for smaller devices"
+    }
+    { $slide "Research areas"
+        "Identify areas where stack languages are lacking, and try to find idioms, abstractions or DSLs to solve these problems"
+        "Factor is a good platform for DSLs (fry, locals, EBNF, help, ...); what about implementing a complete language on top?"
+        "Static typing, soft typing, for stack-based languages"
+    }
+    { $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?"
+    }
+}
+
+: vpri-talk ( -- ) vpri-slides "VPRI talk" slides-window ;
+
+MAIN: vpri-talk