IN: gadgets USING: generic kernel lists math matrices namespaces sdl sequences styles ; : ( text -- gadget ) <label> dup 36 font-size set-paint-prop ; : <underline> ( -- gadget ) <gadget> dup << gradient f { 1 0 0 } [ 64 64 64 ] [ 255 255 255 ] >> interior set-paint-prop { 0 10 0 } over set-gadget-dim ; : <page> ( list -- gadget ) 0 1 <pile> over car <title> over add-gadget <underline> over add-gadget swap cdr [ <label> over add-gadget ] each empty-border ; : tutorial-pages [ [ "Factor: a dynamic language" "This series of slides presents a quick overview of Factor." "" "Factor is interactive, which means you can test out the code" "in this tutorial immediately." "" "http://factor.sourceforge.net" ] [ "The view from 10,000 feet" "- Everything is an object" "- A word is a basic unit of code" "- Words are identified by names, and organized in vocabularies" "- Words pass parameters on the stack" "- Code blocks can be passed as parameters to words" "- Word definitions are very short with very high code reuse" ] [ "Basic syntax" "Factor code is made up of whitespace-speparated tokens." "Here is a program that prints ``Hello world'':" "" " \"hello world\" print" "" "The first token (\"hello world\") is a string." "The second token (print) is a word." "The string is pushed on the stack, and the print word prints it." ] [ "The stack" "- The stack is like a pile of papers." "- You can ``push'' papers on the top of the pile," " and ``pop'' papers from the top of the pile." "" "Here is another code example:" "" " 2 3 + ." "" "Try running it in the listener now." ] [ "Postfix arithmetic" "What happened when you ran it?" "" "The two numbers (2 3) are pushed on the stack." "Then, the + word pops them and pushes the result (5)." "Then, the . word prints this result." "" "This is called postfix arithmetic." "Traditional arithmetic is called infix: 3 + (6 * 2)" "Lets translate this into postfix: 3 6 2 * + ." ] [ "Colon definitions" "We can define new words in terms of existing words." "" " : twice 2 * ;" "" "This defines a new word named ``twice'' that calls ``2 *''." "Try the following in the listener:" "" " 3 twice twice ." "" "The result is the same as if you wrote:" "" " 3 2 * 2 * ." ] [ "Stack effects" "When we look at the definition of the ``twice'' word," "it is intuitively obvious that it takes one value from the stack," "and leaves one value behind. However, with more complex" "definitions, it is better to document this so-called" "``stack effect''." "" "A stack effect comment is written between ( and )." "Factor ignores stack effect comments. Don't you!" "" "The stack effect of twice is ( x -- 2*x )." "The stack effect of + is ( x y -- x+y )." "The stack effect of . is ( object -- )." ] [ "Shuffle words" "The word ``twice'' we defined is useless." "Let's try something more useful: squaring a number." "" "We want a word with stack effect ( n -- n*n )." "However, we cannot use * by itself, since its stack effect" "is ( x y -- x*y ); it expects two inputs." "" "However, we can use the word ``dup''. It has stack effect" "( object -- object object ), and it does exactly what we" "need. The ``dup'' word is known as a shuffle word." ] [ "The squared word" "Try entering the following word definition:" "" " : squared ( n -- n*n ) dup * ;" "" "Shuffle words solve the problem where we need to compose" "two words, but their stack effects do not ``fit''." "" "Some of the most commonly-used shuffle words:" "" "drop ( object -- )" "swap ( obj1 obj2 -- obj2 obj1 )" "over ( obj1 obj2 -- obj1 obj2 obj1 )" ] [ "Another shuffle example" "Now let us write a word that negates a number." "Start by entering the following in the listener" "" " 0 10 - ." "" "It will print -10, as expected. Now notice that this the same as:" "" " 10 0 swap - ." "" "So indeed, we can factor out the definition ``0 swap -'':" "" " : negate ( n -- -n ) 0 swap - ;" ] [ "Seeing words" "If you have entered every definition in this tutorial," "you will now have several new colon definitions:" "" " twice" " squared" " negated" "" "You can look at previously-entered word definitions using 'see'." "Try the following:" "" " \ negated see" "" "Prefixing a word with \ pushes it on the stack, instead of" "executing it. So the see word has stack effect ( word -- )." ] [ "Booleans" "In Factor, any object can be used as a truth value." "- The f object is false." "- Anything else is true." "" "Here is a word that outputs a boolean:" "" " : negative? ( n -- ? ) 0 < ;" ] [ "Branches" "Now suppose we want to write a word that computes the" "absolute value of a number; that is, if it is less than 0," "the number will be negated to yield a positive result." "" " : absolute ( x -- |x| )" " dup negative? [ negated ] when ;" "" "It duplicates the top of the stack, since negative? pops it." "Then if the top of the stack was found to be negative," "it is negated, yielding a postive result." ] [ "More branches" "On the previous slide, you saw the 'when' conditional:" "" " ... condition ... [ ... code to run if true ... ] when" "" "Another commonly-used form is 'unless':" "" " ... condition ... [ ... code to run if true ... ] unless" "" "The 'ifte' conditional takes action on both branches:" "" " ... condition ... [ ... ] [ ... ] ifte" ] [ "Combinators" "ifte, when, unless are words that take lists of code as input." "" "Lists of code are called ``quotations''." "Words that take quotations are called ``combinators''." "" "Another combinator is times ( n quot -- )." "It calls a quotation n times." "" "Try this:" "" " 10 [ \"Hello combinators\" print ] times" ] [ "Sequences" "You have already seen strings, very briefly:" "" " \"Hello world\"" "" "Strings are part of a class of objects called sequences." "Two other types of sequences you will use a lot are:" "" " Lists: [ 1 3 \"hi\" 10 2 ]" " Vectors: { \"the\" [ \"quick\" \"brown\" ] \"fox\" }" "" "As you can see in the second example, lists and vectors" "can contain any type of object, including other lists" "and vectors." ] [ "Sequences and combinators" "A very useful combinator is each ( seq quot -- )." "It calls a quotation with each element of the sequence in turn." "" "Try this:" "" " [ 10 20 30 ] [ . ] each" "" "A closely-related combinator is map ( seq quot -- seq )." "It also calls a quotation with each element." "However, it then collects the outputs of the quotation" "into a new sequence." "" "Try this:" "" " [ 10 20 30 ] [ 3 + ] map ." "==> [ 13 23 33 ]" ] [ "Numbers - integers and ratios" "Factor's supports arbitrary-precision integers and ratios." "" "Try the following:" "" " : factorial ( n -- n! ) 0 <range> product ;" " 100 factorial ." "" " 1 3 / 1 2 / + ." "==> 5/6" "" "Rational numbers are added, multiplied and reduced to" "lowest terms in the same way you learned in grade school." ] [ "Numbers - higher math" " 2 sqrt ." "==> 1.414213562373095" "" " -1 sqrt ." "==> #{ 0 1.0 }#" "" " M[ [ 10 3 ] [ 7 5 ] [ -2 0 ] ]M M[ [ 11 2 ] [ 4 8 ] ]M" "==> M[ [ 122 44 ] [ 97 54 ] [ -22 -4 ] ]M" "" "... and there is much more." ] [ "Object oriented programming" "Each object belongs to a class." "Generic words act differently based on an object's class." "" " GENERIC: describe ( object -- )" " M: integer describe \"The integer \" write . ;" " M: string describe \"The string \" write . ;" " M: object describe drop \"Unknown object\" print ;" "" "Each M: line defines a ``method.''" "Method definitions may appear in independent source files." "" "integer, string, object are built-in classes." ] [ "Defining new classes with tuples" "New classes can be defined:" "" " TUPLE: point x y ;" " M: point describe" " \"x =\" write dup point-x ." " \"y =\" write point-y . ;" " 100 200 <point> describe" "" "A tuple is a collection of named slots." "" "Tuples support custom constructors, delegation..." "see the developer's handbook for details." ] [ "The library" "Offers a good selection of highly-reusable words:" "- Operations on sequences" "- Variety of mathematical functions" "- Web server and web application framework" "- Graphical user interface framework" "Browsing the library:" "- To list all vocabularies:" " vocabs ." "- To list all words in a vocabulary:" " \"sequences\" words ." "- To show a word definition:" " \ reverse see" ] [ "Learning more" "Hopefully this tutorial has sparked your interest in Factor." "" "You can learn more by reading the Factor developer's handbook:" "" "http://factor.sourceforge.net/handbook.pdf" "" "Also, point your IRC client to irc.freenode.net and hop in the" "#concatenative channel to chat with other Factor geeks." ] ] ; : <tutorial> ( pages -- browser ) tutorial-pages [ <page> ] map <book> dup [ 204 204 255 ] background set-paint-prop dup << gradient f { 0 1 0 } [ 204 204 255 ] [ 255 204 255 ] >> interior set-paint-prop dup "Sans Serif" font set-paint-prop dup 18 font-size set-paint-prop <book-browser> ; : tutorial <tutorial> gadget. ;