IN: help\r
USING: gadgets generic kernel lists math matrices namespaces sdl\r
-sequences styles ;\r
+sequences strings styles ;\r
\r
: <title> ( text -- gadget )\r
<label> dup 36 font-size set-paint-prop ;\r
dup << gradient f { 1 0 0 } [ 64 64 64 ] [ 255 255 255 ] >> interior set-paint-prop\r
{ 0 10 0 } over set-gadget-dim ;\r
\r
+GENERIC: tutorial-line ( object -- gadget )\r
+\r
+M: string tutorial-line <label> ;\r
+\r
+M: general-list tutorial-line\r
+ car dup <label> dup rot [ pane get pane-input set-editor-text drop ] cons\r
+ button-gestures\r
+ dup "Monospaced" font set-paint-prop ;\r
+\r
: <page> ( list -- gadget )\r
0 1 <pile>\r
over car <title> over add-gadget\r
<underline> over add-gadget\r
- swap cdr [ <label> over add-gadget ] each\r
+ swap cdr [ tutorial-line over add-gadget ] each\r
empty-border ;\r
\r
: tutorial-pages\r
"Factor is interactive, which means you can test out the code"\r
"in this tutorial immediately."\r
""\r
+ "Code examples will insert themselves in the listener's input"\r
+ "area when clicked:"\r
+ ""\r
+ [ "\"hello world\" print" ]\r
+ ""\r
+ "You can then press ENTER to execute the code, or edit it first."\r
+ ""\r
"http://factor.sourceforge.net"\r
] [\r
"The view from 10,000 feet"\r
] [\r
"Basic syntax"\r
"Factor code is made up of whitespace-speparated tokens."\r
- "Here is a program that prints ``Hello world'':"\r
+ "Recall the example from the first slide:"\r
""\r
- " \"hello world\" print"\r
+ [ "\"hello world\" print" ]\r
""\r
"The first token (\"hello world\") is a string."\r
"The second token (print) is a word."\r
""\r
"Here is another code example:"\r
""\r
- " 2 3 + ."\r
+ [ "2 3 + ." ]\r
""\r
"Try running it in the listener now."\r
] [\r
"Colon definitions"\r
"We can define new words in terms of existing words."\r
""\r
- " : twice 2 * ;"\r
+ [ ": twice 2 * ;" ]\r
""\r
"This defines a new word named ``twice'' that calls ``2 *''."\r
"Try the following in the listener:"\r
""\r
- " 3 twice twice ."\r
+ [ "3 twice twice ." ]\r
""\r
"The result is the same as if you wrote:"\r
""\r
- " 3 2 * 2 * ."\r
+ [ "3 2 * 2 * ." ]\r
] [\r
"Stack effects"\r
"When we look at the definition of the ``twice'' word,"\r
"The squared word"\r
"Try entering the following word definition:"\r
""\r
- " : squared ( n -- n*n ) dup * ;"\r
+ [ ": squared ( n -- n*n ) dup * ;" ]\r
""\r
"Shuffle words solve the problem where we need to compose"\r
"two words, but their stack effects do not ``fit''."\r
"Now let us write a word that negates a number."\r
"Start by entering the following in the listener"\r
""\r
- " 0 10 - ."\r
+ [ "0 10 - ." ]\r
""\r
"It will print -10, as expected. Now notice that this the same as:"\r
""\r
- " 10 0 swap - ."\r
+ [ "10 0 swap - ." ]\r
""\r
"So indeed, we can factor out the definition ``0 swap -'':"\r
""\r
- " : negate ( n -- -n ) 0 swap - ;"\r
+ [ ": negate ( n -- -n ) 0 swap - ;" ]\r
] [\r
"Seeing words"\r
"If you have entered every definition in this tutorial,"\r
"You can look at previously-entered word definitions using 'see'."\r
"Try the following:"\r
""\r
- " \ negated see"\r
+ [ "\\ negated see" ]\r
""\r
- "Prefixing a word with \ pushes it on the stack, instead of"\r
+ "Prefixing a word with \\ pushes it on the stack, instead of"\r
"executing it. So the see word has stack effect ( word -- )."\r
] [\r
"Booleans"\r
""\r
"Here is a word that outputs a boolean:"\r
""\r
- " : negative? ( n -- ? ) 0 < ;"\r
+ [ ": negative? ( n -- ? ) 0 < ;" ]\r
] [\r
"Branches"\r
"Now suppose we want to write a word that computes the"\r
"absolute value of a number; that is, if it is less than 0,"\r
"the number will be negated to yield a positive result."\r
""\r
- " : absolute ( x -- |x| )"\r
- " dup negative? [ negated ] when ;"\r
+ [ ": absolute ( x -- |x| ) dup 0 < [ negated ] when ;" ]\r
""\r
"It duplicates the top of the stack, since negative? pops it."\r
"Then if the top of the stack was found to be negative,"\r
"More branches"\r
"On the previous slide, you saw the 'when' conditional:"\r
""\r
- " ... condition ... [ ... code to run if true ... ] when"\r
+ [ " ... condition ... [ ... code to run if true ... ] when" ]\r
""\r
"Another commonly-used form is 'unless':"\r
""\r
- " ... condition ... [ ... code to run if true ... ] unless"\r
+ [ " ... condition ... [ ... code to run if true ... ] unless" ]\r
""\r
"The 'ifte' conditional takes action on both branches:"\r
""\r
- " ... condition ... [ ... ] [ ... ] ifte"\r
+ [ " ... condition ... [ ... ] [ ... ] ifte" ]\r
] [\r
"Combinators"\r
"ifte, when, unless are words that take lists of code as input."\r
""\r
"Try this:"\r
""\r
- " 10 [ \"Hello combinators\" print ] times"\r
+ [ "10 [ \"Hello combinators\" print ] times" ]\r
] [\r
"Sequences"\r
"You have already seen strings, very briefly:"\r
""\r
"Try this:"\r
""\r
- " [ 10 20 30 ] [ . ] each"\r
+ [ "[ 10 20 30 ] [ . ] each" ]\r
""\r
"A closely-related combinator is map ( seq quot -- seq )."\r
"It also calls a quotation with each element."\r
""\r
"Try this:"\r
""\r
- " [ 10 20 30 ] [ 3 + ] map ."\r
+ [ "[ 10 20 30 ] [ 3 + ] map ." ]\r
"==> [ 13 23 33 ]"\r
] [\r
"Numbers - integers and ratios"\r
""\r
"Try the following:"\r
""\r
- " : factorial ( n -- n! ) 0 <range> product ;"\r
- " 100 factorial ."\r
+ [ ": factorial ( n -- n! ) 0 <range> product ;" ]\r
+ [ "100 factorial ." ]\r
""\r
- " 1 3 / 1 2 / + ."\r
- "==> 5/6"\r
+ [ "1 3 / 1 2 / + ." ]\r
""\r
"Rational numbers are added, multiplied and reduced to"\r
"lowest terms in the same way you learned in grade school."\r
] [\r
"Numbers - higher math"\r
- " 2 sqrt ."\r
- "==> 1.414213562373095"\r
""\r
- " -1 sqrt ."\r
- "==> #{ 0 1.0 }#"\r
+ [ "2 sqrt ." ]\r
+ ""\r
+ [ "-1 sqrt ." ]\r
""\r
- " M[ [ 10 3 ] [ 7 5 ] [ -2 0 ] ]M M[ [ 11 2 ] [ 4 8 ] ]M"\r
- "==> M[ [ 122 44 ] [ 97 54 ] [ -22 -4 ] ]M"\r
+ [ "M[ [ 10 3 ] [ 7 5 ] [ -2 0 ] ]M M[ [ 11 2 ] [ 4 8 ] ]M m." ]\r
""\r
- "... and there is much more."\r
+ "... and there is much more for the math geeks."\r
] [\r
"Object oriented programming"\r
"Each object belongs to a class."\r
"Generic words act differently based on an object's class."\r
""\r
- " GENERIC: describe ( object -- )"\r
- " M: integer describe \"The integer \" write . ;"\r
- " M: string describe \"The string \" write . ;"\r
- " M: object describe drop \"Unknown object\" print ;"\r
+ [ "GENERIC: describe ( object -- )" ]\r
+ [ "M: integer describe \"The integer \" write . ;" ]\r
+ [ "M: string describe \"The string \" write . ;" ]\r
+ [ "M: object describe drop \"Unknown object\" print ;" ]\r
""\r
"Each M: line defines a ``method.''"\r
"Method definitions may appear in independent source files."\r
""\r
"integer, string, object are built-in classes."\r
] [\r
- "Defining new classes with tuples"\r
+ "Defining new classes"\r
"New classes can be defined:"\r
""\r
- " TUPLE: point x y ;"\r
- " M: point describe"\r
- " \"x =\" write dup point-x ."\r
- " \"y =\" write point-y . ;"\r
- " 100 200 <point> describe"\r
+ [ "TUPLE: point x y ;" ]\r
+ [ "M: point describe" ]\r
+ [ " \"x =\" write dup point-x ." ]\r
+ [ " \"y =\" write point-y . ;" ]\r
+ [ "100 200 <point> describe" ]\r
""\r
"A tuple is a collection of named slots."\r
""\r