(* FILE: joytut.joy *) "tutlib" libload. LIBRA toc-of-tutorial == [ [ [sec0] "Interactive tutorial on JOY" ] [ [sec1] "1 - Numbers and Lists" ] [ [sec2] "2 - The map and filter combinators" ] [ [sec3] "3 - The ifte and linrec combinators"] ]; (* utilities: *) q1 == "What will the program " putchars putchars " leave on the stack ?\n" putchars i expecting; q2 == "What will the dots ... have to be, so that\n\t" putchars putchars "\nleaves " putchars putchars " on the stack ?\n" putchars i expecting; (* main sections: *) sec0 == toc-of-tutorial rest [first i] step; sec1 == 1 toc-one-heading ini-stats [ "One of the data types in Joy is the type of integers.\n" "Literal integers are written in ordinary decimal notation.\n" "The usual binary operators are: + - * /\n" "But these operators are written after their arguments.\n" ] putstrings [get-integer 5 ] "2 3 +" q1 [get-integer 42 ] "7 6 *" q1 [get-integer 37 ] "7 6 * 2 3 + -" q1 [ "The most important aggregate datatype is that of lists.\n" "These are written inside square brackets, like this:\n" " [42 17 3 9 35]\n" "Some important operators for lists are:\n" " first rest cons concat\n" ] putstrings [get-integer 5 ] "[5 4 2 7] first" q1 [get-list [4 2 7] ] "[5 4 2 7] rest" q1 [get-list [8 9 3] ] "8 [9 3] cons" q1 [get-list [5 3 5 3] ] "[5 3] dup concat" q1 [get-list [[5 3] 5 3] ] "[5 3] dup cons" q1 [get-list [7 3] ] "[7 3 3 2 4]" "... [3 2 4] concat" q2 put-stats; sec2 == 2 toc-one-heading ini-stats [ "Combinators are similar to operators, they expect something\n" "on the stack. But combinators always expect a quoted program\n" "and perhaps something else. For example, the map combinator\n" "expects a single program and below that an aggregate, e.g. a list.\n" ] putstrings [get-list [6 4 8] ] "[3 2 4] [dup +] map" q1 [get-quote [10 + ] ] "[13 12 14]" "[3 2 4] ... map" q2 [ "Another example is the filter combinator, which expects\n" "a program that computes a truth value, and below that an aggregate.\n" ] putstrings [get-list [5 3 7] ] "\n\t[5 16 3 7 14] [10 <] filter" q1 "For the next question, provide the shortest answer\n" putchars [get-quote [20 <] ] "[15 19 12]" "[5 10 9 11 2] [10 +] map ... filter" q2 put-stats; sec3 == 3 toc-one-heading ini-stats [ "Two more complicated combinators are the ifte and the linrec\n" "combinators. The ifte combinator expects three quotation parameters\n" "on the stack. In most cases they have been pushed just beforehand.\n" ] putstrings [get-integer 15 ] "5 [7 <] [10 +] [10 -] ifte" q1 [get-integer -2 ] "8 [7 <] [10 +] [10 -] ifte" q1 [ "A programmer wants to write a recursive definition of the\n" "factorial function, which has the form:\n" " factorial ==\n" " ... (* first quote *)\n" " ... (* second quote *)\n" " ... (* third quote *)\n" " ifte\n" ] putstrings "What could be used as the first quote?\n" putchars get-quote [[null][0 =][1 <]] expecting-from "What could be used as the second quote?\n" putchars get-quote [[pop 1][succ][1 +]] expecting-from "This question is harder:\n" putchars "What could be used as the third quote?\n" putchars get-quote [[dup pred factorial *][dup 1 - factorial *]] expecting-from [ "Later the programmer realises that the factorial function\n" "is only needed in one place of the program, so it would be good\n" "not to have the definition at all, by using the linrec combinator:\n" " [ null ] (* first quote *)\n" " [ succ ] (* second quote *)\n" " ... (* third quote *)\n" " ... (* fourth quote *)\n" " linrec\n" ] putstrings "What could be used as the third quote ?\n" putchars get-quote [[dup pred][dup 1 -]] expecting-from "What could be used as the fourth quote ?\n" putchars get-quote [*] expecting put-stats; joytut == toc-do-sec0-loop; JOYTUT == "joytut.joy - " toc-of-tutorial first second concat. (* end LIBRA *) (* END joytut.joy *)