From: John Benediktsson Date: Wed, 17 Mar 2021 04:35:26 +0000 (-0700) Subject: Adding all the talks. X-Git-Url: https://gitweb.factorcode.org/gitweb.cgi?p=factor-talks.git;a=commitdiff_plain;h=33e869d5385c7efbc6eb097b2f98613fb3a52bfa Adding all the talks. --- diff --git a/README.md b/README.md new file mode 100644 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 index 0000000..1901f27 --- /dev/null +++ b/chicago-talk/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/chicago-talk/chicago-talk.factor b/chicago-talk/chicago-talk.factor new file mode 100644 index 0000000..02ddc42 --- /dev/null +++ b/chicago-talk/chicago-talk.factor @@ -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 index 0000000..ce8739e --- /dev/null +++ b/chicago-talk/deploy.factor @@ -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 index 0000000..229e1a3 --- /dev/null +++ b/chicago-talk/summary.txt @@ -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 index 0000000..8ee64cd --- /dev/null +++ b/chicago-talk/tags.txt @@ -0,0 +1 @@ +talks diff --git a/galois-talk/authors.txt b/galois-talk/authors.txt new file mode 100644 index 0000000..1901f27 --- /dev/null +++ b/galois-talk/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/galois-talk/galois-talk.factor b/galois-talk/galois-talk.factor new file mode 100644 index 0000000..87e7914 --- /dev/null +++ b/galois-talk/galois-talk.factor @@ -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 + ": ( w h -- r ) rectangle boa ;" + ": ( 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 area ." } + { $code "3 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\" 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 index 0000000..00f30ac --- /dev/null +++ b/galois-talk/summary.txt @@ -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 index 0000000..8ee64cd --- /dev/null +++ b/galois-talk/tags.txt @@ -0,0 +1 @@ +talks diff --git a/google-tech-talk/authors.txt b/google-tech-talk/authors.txt new file mode 100644 index 0000000..1901f27 --- /dev/null +++ b/google-tech-talk/authors.txt @@ -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 index 0000000..a0b511f --- /dev/null +++ b/google-tech-talk/google-tech-talk.factor @@ -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 + ": ( w h -- r ) rectangle boa ;" + ": ( 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 area ." } + { $code "3 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 perimeter ." } + { $code "3 perimeter ." } + } + { $slide "Object system" + "New type, extending existing operations:" + { $code + "TUPLE: triangle base height ;" + "" + ": ( 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? ." } + { $code "13 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 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 tell-me" } + { $code "103 76 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 " + "'[ _ 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 } ", " { $link } } + { $code "[ [ . ] 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 } " 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 index 0000000..1747a56 --- /dev/null +++ b/google-tech-talk/summary.txt @@ -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 index 0000000..8ee64cd --- /dev/null +++ b/google-tech-talk/tags.txt @@ -0,0 +1 @@ +talks diff --git a/hmc-talk/hmc-talk.factor b/hmc-talk/hmc-talk.factor new file mode 100644 index 0000000..9a225f9 --- /dev/null +++ b/hmc-talk/hmc-talk.factor @@ -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 + ": ( w h -- r ) rectangle boa ;" + ": ( 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 area ." } + { $code "3 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\" 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 [" + " \"Hello world\"" + " swap 10 / 1 over - over 1 " + " background associate format nl" + "] each" + } + } + + { $slide "Cool things" + { $code + "USE: google.charts" + "\"x = \\\\frac{-b \\\\pm \\\\sqrt {b^2-4ac}}{2a}\"" + " 200 >>width 75 >>height chart." + } + { $code + "100 [ 100 random ] replicate" + "100 [ 100 random ] replicate" + "zip chart." + } + { $code + "\"/usr/share/dict/words\" utf8 file-lines" + "[ >lower 1 head ] histogram-by" + "sort-keys " + " 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
  • <->
  • XML] ] map" + "[XML
      <->
    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 index 0000000..1901f27 --- /dev/null +++ b/jvm-summit-talk/authors.txt @@ -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 index 0000000..b91bf01 --- /dev/null +++ b/jvm-summit-talk/jvm-summit-talk.factor @@ -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 index 0000000..769abbc --- /dev/null +++ b/jvm-summit-talk/summary.txt @@ -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 index 0000000..8ee64cd --- /dev/null +++ b/jvm-summit-talk/tags.txt @@ -0,0 +1 @@ +talks diff --git a/minneapolis-talk/authors.txt b/minneapolis-talk/authors.txt new file mode 100644 index 0000000..1901f27 --- /dev/null +++ b/minneapolis-talk/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/minneapolis-talk/deploy.factor b/minneapolis-talk/deploy.factor new file mode 100644 index 0000000..ea200ce --- /dev/null +++ b/minneapolis-talk/deploy.factor @@ -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 index 0000000..4cae92b --- /dev/null +++ b/minneapolis-talk/minneapolis-talk.factor @@ -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" + } } + { "Create an instance:" + { $code + "\"Cosmo Kramer\"" + "\"100 Blah blah St, New York\"" + "" + } } + } + { $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" + "" + "TUPLE: circle radius ;" + "C: circle" + "" + "TUPLE: rectangle width height ;" + "C: 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 area ." } + { $code "18 area ." } + { $code "20 40 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 [ 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 [ 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 index 0000000..ef8d1bd --- /dev/null +++ b/minneapolis-talk/summary.txt @@ -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 index 0000000..8ee64cd --- /dev/null +++ b/minneapolis-talk/tags.txt @@ -0,0 +1 @@ +talks diff --git a/otug-talk/2bi.tiff b/otug-talk/2bi.tiff new file mode 100644 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 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 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 index 0000000..1901f27 --- /dev/null +++ b/otug-talk/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/otug-talk/bi.tiff b/otug-talk/bi.tiff new file mode 100644 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 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 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 index 0000000..bb18d72 --- /dev/null +++ b/otug-talk/otug-talk.factor @@ -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 [ 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 [ 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 + " + { 5 5 } >>gap + 1 >>fill + \"Hello world!\"