]> gitweb.factorcode.org Git - factor.git/blob - doc/devel-guide.lyx
b6d9eed6d65e5097c4854e65cc947adab08be623
[factor.git] / doc / devel-guide.lyx
1 #LyX 1.3 created this file. For more info see http://www.lyx.org/
2 \lyxformat 221
3 \textclass article
4 \language english
5 \inputencoding auto
6 \fontscheme default
7 \graphics default
8 \paperfontsize default
9 \spacing single 
10 \papersize Default
11 \paperpackage a4
12 \use_geometry 0
13 \use_amsmath 0
14 \use_natbib 0
15 \use_numerical_citations 0
16 \paperorientation portrait
17 \secnumdepth 3
18 \tocdepth 2
19 \paragraph_separation skip
20 \defskip medskip
21 \quotes_language english
22 \quotes_times 2
23 \papercolumns 1
24 \papersides 1
25 \paperpagestyle headings
26
27 \layout Title
28
29 Factor Developer's Guide
30 \layout Author
31
32 Slava Pestov
33 \layout Standard
34
35
36 \begin_inset LatexCommand \tableofcontents{}
37
38 \end_inset 
39
40
41 \layout Section*
42 \pagebreak_top 
43 Introduction
44 \layout Standard
45
46 Factor is an imperitive programming language with functional and object-oriented
47  influences.
48  Its primary goal is to be used for web-based server-side applications.
49  Factor is interpreted by a virtual machine that provides garbage collection
50  and prohibits pointer arithmetic.
51 \begin_inset Foot
52 collapsed false
53
54 \layout Standard
55
56 Two releases of Factor are available -- a virtual machine written in C,
57  and an interpreter written in Java that runs on the Java virtual machine.
58  This guide targets the C version of Factor.
59 \end_inset 
60
61
62 \layout Standard
63
64 Factor borrows heavily from Forth, Joy and Lisp.
65  From Forth it inherits a flexible syntax defined in terms of 
66 \begin_inset Quotes eld
67 \end_inset 
68
69 parsing words
70 \begin_inset Quotes erd
71 \end_inset 
72
73  and an execution model based on a data stack and call stack.
74  From Joy and Lisp it inherits a virtual machine prohibiting direct pointer
75  arithmetic, and the use of 
76 \begin_inset Quotes eld
77 \end_inset 
78
79 cons cells
80 \begin_inset Quotes erd
81 \end_inset 
82
83  to represent code and data struture.
84 \layout Section
85
86 Fundamentals
87 \layout Standard
88
89 A "word" is the main unit of program organization in Factor -- it corresponds
90  to a "function", "procedure" or "method" in other languages.
91 \layout Standard
92
93 When code examples are given, the input is in a roman font, and any output
94  from the interpreter is in italics:
95 \layout LyX-Code
96
97
98 \begin_inset Quotes eld
99 \end_inset 
100
101 Hello, world!
102 \begin_inset Quotes erd
103 \end_inset 
104
105  print
106 \layout LyX-Code
107
108
109 \emph on 
110 Hello, world!
111 \layout Subsection
112
113 The stack
114 \layout Standard
115
116 The stack is used to exchange data between words.
117  When a number is executed, it is pushed on the stack.
118  When a word is executed, it receives input parameters by removing successive
119  elements from the top of the stack.
120  Results are then pushed back to the top of the stack.
121  
122 \layout Standard
123
124 The word 
125 \family typewriter 
126 .s
127 \family default 
128  prints the contents of the stack, leaving the contents of the stack unaffected.
129  The top of the stack is the rightmost element in the printout:
130 \layout LyX-Code
131
132 2 3 .s
133 \layout LyX-Code
134
135
136 \emph on 
137 { 2 3 }
138 \layout Standard
139
140 The word 
141 \family typewriter 
142 .
143
144 \family default 
145  removes the object at the top of the stack, and prints it:
146 \layout LyX-Code
147
148 1 2 3 .
149  .
150  .
151 \layout LyX-Code
152
153
154 \emph on 
155 3
156 \layout LyX-Code
157
158
159 \emph on 
160 2
161 \layout LyX-Code
162
163
164 \emph on 
165 1
166 \layout Standard
167
168 The usual arithmetic operators 
169 \family typewriter 
170 + - * /
171 \family default 
172  all take two parameters from the stack, and push one result back.
173  Where the order of operands matters (
174 \family typewriter 
175 -
176 \family default 
177  and 
178 \family typewriter 
179 /
180 \family default 
181 ), the operands are taken from the stack in the natural order.
182  For example:
183 \layout LyX-Code
184
185 10 17 + .
186 \layout LyX-Code
187
188
189 \emph on 
190 27
191 \layout LyX-Code
192
193 111 234 - .
194 \layout LyX-Code
195
196
197 \emph on 
198 -123
199 \layout LyX-Code
200
201 333 3 / .
202 \layout LyX-Code
203
204
205 \emph on 
206 111
207 \layout Standard
208
209 This type of arithmetic is called 
210 \emph on 
211 postfix
212 \emph default 
213 , because the operator follows the operands.
214  Contrast this with 
215 \emph on 
216 infix
217 \emph default 
218  notation used in many other languages, so-called because the operator is
219  in-between the two operands.
220 \layout Standard
221
222 More complicated infix expressions can be translated into postfix by translating
223  the inner-most parts first.
224  Grouping parantheses are never necessary:
225 \layout LyX-Code
226
227 ! Postfix equivalent of (2 + 3) * 6
228 \layout LyX-Code
229
230 2 3 + 6 *
231 \layout LyX-Code
232
233
234 \emph on 
235 36
236 \layout LyX-Code
237
238 ! Postfix equivalent of 2 + (3 * 6)
239 \layout LyX-Code
240
241 2 3 6 * +
242 \layout LyX-Code
243
244
245 \emph on 
246 20
247 \layout Subsection
248
249 Factoring
250 \layout Standard
251
252 New words can be defined in terms of existing words using the 
253 \emph on 
254 colon definition
255 \emph default 
256  syntax:
257 \layout LyX-Code
258
259
260 \emph on 
261 name
262 \emph default 
263  (
264 \emph on 
265  inputs 
266 \emph default 
267 --
268 \emph on 
269  outputs
270 \emph default 
271  )
272 \layout LyX-Code
273
274     #! 
275 \emph on 
276 Description
277 \layout LyX-Code
278
279     
280 \emph on 
281 factors ...
282  
283 \emph default 
284 ;
285 \layout Standard
286
287 When the new word is executed, each one of its factors gets executed, in
288  turn.
289  The comment delimited by 
290 \family typewriter 
291 (
292 \family default 
293  and 
294 \family typewriter 
295 )
296 \family default 
297  is called a stack effect comment and is described later.
298  The stack effect comment, as well as the documentation comment starting
299  with 
300 \family typewriter 
301 #!
302 \family default 
303  are both optional, and can be placed anywhere in the source code, not just
304  in colon definitions.
305 \layout Standard
306
307 Note that in a source file, a word definition can span multiple lines.
308  However, the interactive interpreter expects each line of input to be 
309 \begin_inset Quotes eld
310 \end_inset 
311
312 complete
313 \begin_inset Quotes erd
314 \end_inset 
315
316 , so interactively, colon definitions must be entered all on one line.
317 \layout Standard
318
319 For example, lets assume we are designing some software for an aircraft
320  navigation system.
321  Lets assume that internally, all lengths are stored in meters, and all
322  times are stored in seconds.
323  We can define words for converting from kilometers to meters, and hours
324  and minutes to seconds:
325 \layout LyX-Code
326
327 : kilometers 1000 * ;
328 \layout LyX-Code
329
330 : minutes 60 * ;
331 \layout LyX-Code
332
333 : hours 60 * 60 * ;
334 \layout LyX-Code
335
336 2 km .
337 \layout LyX-Code
338
339
340 \emph on 
341 2000
342 \layout LyX-Code
343
344 10 minutes .
345 \layout LyX-Code
346
347
348 \emph on 
349 600
350 \layout LyX-Code
351
352 2 hours .
353 \layout LyX-Code
354
355
356 \emph on 
357 7200
358 \layout Standard
359
360 Now, suppose we need a word that takes the flight time, the aircraft velocity,
361  and the tailwind velocity, and returns the distance travelled.
362  If the parameters are given on the stack in that order, all we do is add
363  the top two elements (aircraft velocity, tailwind velocity) and multiply
364  it by the element underneath (flight time).
365  So the definition looks like this, this time with a stack effect comment
366  since its slightly less obvious what the operands are:
367 \layout LyX-Code
368
369 : distance ( time aircraft tailwind -- distance ) + * ;
370 \layout LyX-Code
371
372 2 900 36 distance .
373 \layout LyX-Code
374
375
376 \emph on 
377 1872
378 \layout Standard
379
380 Note that we are not using any units here.
381  We could, if we defined some words for velocity units first.
382  The only non-trivial thing here is the implementation of 
383 \family typewriter 
384 km/hour
385 \family default 
386  -- we have to divide the 
387 \family typewriter 
388 km/sec
389 \family default 
390  velocity by the number of seconds in one hour to get the desired result:
391 \layout LyX-Code
392
393 : km/hour kilometers 1 hours / ;
394 \layout LyX-Code
395
396 2 hours 900 km/hour 36 km/hour distance .
397 \layout LyX-Code
398
399
400 \emph on 
401 1872000
402 \layout Subsection
403
404 Stack effects
405 \layout Standard
406
407 A stack effect comment contains a description of inputs to the left of 
408 \family typewriter 
409 --
410 \family default 
411 , and a description of outputs to the right.
412  As always, the top of the stack is on the right side.
413  Lets try writing a word to compute the cube of a number.
414 \begin_inset Foot
415 collapsed false
416
417 \layout Standard
418
419 I'd use the somewhat simpler example of a word that squares a number, but
420  such a word already exists in the standard library.
421  Its in the 
422 \family typewriter 
423 arithmetic
424 \family default 
425  vocabulary, named 
426 \family typewriter 
427 sq
428 \family default 
429 .
430 \end_inset 
431
432  
433 \layout Standard
434
435 Three numbers on the stack can be multiplied together using 
436 \family typewriter 
437 * *
438 \family default 
439 :
440 \layout LyX-Code
441
442 2 4 8 * * .
443 \layout LyX-Code
444
445
446 \emph on 
447 64
448 \layout Standard
449
450 However, the stack effect of 
451 \family typewriter 
452 * *
453 \family default 
454  is 
455 \family typewriter 
456 ( a b c -- a*b*c )
457 \family default 
458 .
459  We would like to write word that takes 
460 \emph on 
461 one
462 \emph default 
463  input only.
464  To achive this, we need to be able to duplicate the top stack element twice.
465  As it happends, there is a word 
466 \family typewriter 
467 dup ( x -- x x )
468 \family default 
469  for precisely this purpose.
470  Now, we are able to define the 
471 \family typewriter 
472 cube
473 \family default 
474  word:
475 \layout LyX-Code
476
477 : cube dup dup * * ;
478 \layout LyX-Code
479
480 10 cube .
481 \layout LyX-Code
482
483
484 \emph on 
485 1000
486 \layout LyX-Code
487
488 -2 cube .
489 \layout LyX-Code
490
491
492 \emph on 
493 -8
494 \layout Standard
495
496 It is quite often the case that we want to compose two factors in a colon
497  definition, but their stack effects don't 
498 \begin_inset Quotes eld
499 \end_inset 
500
501 match up
502 \begin_inset Quotes erd
503 \end_inset 
504
505 .
506 \layout Standard
507
508 There is a set of 
509 \emph on 
510 shuffle words
511 \emph default 
512  for solving precisely this problem.
513  These words are so-called because they simply rearrange stack elements
514  in some fashion, without modifying them in any way.
515  Lets take a look at the most frequently-used shuffle words:
516 \layout Standard
517
518
519 \family typewriter 
520 drop ( x -- )
521 \family default 
522  Discard the top stack element.
523  Used when a return value is not needed.
524 \layout Standard
525
526
527 \family typewriter 
528 dup ( x -- x x )
529 \family default 
530  Duplicate the top stack element.
531  Used when a value is needed more than once.
532 \layout Standard
533
534
535 \family typewriter 
536 swap ( x y -- y x )
537 \family default 
538  Swap top two stack elements.
539  Used when a word expects parameters in a different order.
540 \layout Standard
541
542
543 \family typewriter 
544 rot ( x y z -- y z x )
545 \family default 
546  Rotate top three stack elements to the left.
547 \layout Standard
548
549
550 \family typewriter 
551 -rot ( x y z -- z x y )
552 \family default 
553  Rotate top three stack elements to the right.
554 \layout Standard
555
556
557 \family typewriter 
558 over ( x y -- x y x )
559 \family default 
560  Bring the second stack element 
561 \begin_inset Quotes eld
562 \end_inset 
563
564 over
565 \begin_inset Quotes erd
566 \end_inset 
567
568  the top element.
569 \layout Standard
570
571
572 \family typewriter 
573 nip ( x y -- y )
574 \family default 
575  Remove the second stack element.
576 \layout Standard
577
578
579 \family typewriter 
580 tuck ( x y -- y x y )
581 \family default 
582  Tuck the top stack element under the second stack element.
583 \layout Standard
584
585 You can try all these words out -- push some numbers on the stack, execute
586  a word, and look at how the stack contents was changed using 
587 \family typewriter 
588 .s
589 \family default 
590 .
591  Compare the stack contents with the stack effects above.
592 \layout Standard
593
594 Note the order of the shuffle word descriptions above.
595  The ones at the top are used most often because they are easy to understand.
596  The more complex ones such as rot should be avoided as possible, because
597  they make the flow of data in a word definition harder to understand.
598 \layout Standard
599
600 If you find yourself using too many shuffle words, or you're writing a stack
601  effect comment in the middle of a colon definition, it is a good sign that
602  the word should probably be factored into two or more words.
603  Effective factoring is like riding a bicycle -- it is hard at first, but
604  then you 
605 \begin_inset Quotes eld
606 \end_inset 
607
608 get it
609 \begin_inset Quotes erd
610 \end_inset 
611
612 , and writing small, clear and reusable word definitions becomes second-nature.
613 \layout Subsection
614
615 Combinators
616 \layout Standard
617
618 A quotation a list of objects that can be executed.
619  Words that operate on quotations are called 
620 \emph on 
621 combinators
622 \emph default 
623 .
624  Quotations are input using the following syntax:
625 \layout LyX-Code
626
627 [ 2 3 + .
628  ]
629 \layout Standard
630
631 When input, a quotation is not executed immediately -- rather, it becomes
632  one object on the stack.
633  Try evaluating the following:
634 \layout LyX-Code
635
636 [ 1 2 3 + * ] .s
637 \layout LyX-Code
638
639
640 \emph on 
641 { [ 1 2 3 + * ] }
642 \layout LyX-Code
643
644 call .s
645 \layout LyX-Code
646
647
648 \emph on 
649 { 5 }
650 \layout Standard
651
652
653 \family typewriter 
654 call
655 \family default 
656  
657 \family typewriter 
658 ( quot -- )
659 \family default 
660  executes the quotation at the top of the stack.
661  Using 
662 \family typewriter 
663 call
664 \family default 
665  with a literal quotation is useless; writing out the elements of the quotation
666  has the same effect.
667  However, the 
668 \family typewriter 
669 call
670 \family default 
671  combinator is a building block of more powerful combinators, since quotations
672  can be passed around arbitrarily and even modified before being called.
673 \layout Standard
674
675
676 \family typewriter 
677 ifte
678 \family default 
679  
680 \family typewriter 
681 ( cond true false -- )
682 \family default 
683  executes either the 
684 \family typewriter 
685 true
686 \family default 
687  or 
688 \family typewriter 
689 false
690 \family default 
691  quotations, depending on the boolean value of 
692 \family typewriter 
693 cond
694 \family default 
695 .
696  In Factor, there is no real boolean data type -- instead, a special object
697  
698 \family typewriter 
699 f
700 \family default 
701  is the only object with a 
702 \begin_inset Quotes eld
703 \end_inset 
704
705 false
706 \begin_inset Quotes erd
707 \end_inset 
708
709  boolean value.
710  Every other object is a boolean 
711 \begin_inset Quotes eld
712 \end_inset 
713
714 true
715 \begin_inset Quotes erd
716 \end_inset 
717
718 .
719  The special object 
720 \family typewriter 
721 t
722 \family default 
723  is the 
724 \begin_inset Quotes eld
725 \end_inset 
726
727 canonical
728 \begin_inset Quotes erd
729 \end_inset 
730
731  truth value.
732 \layout Standard
733
734 Here is an example of 
735 \family typewriter 
736 ifte
737 \family default 
738  usage:
739 \layout LyX-Code
740
741 1 2 < [ 
742 \begin_inset Quotes eld
743 \end_inset 
744
745 1 is less than 2.
746 \begin_inset Quotes erd
747 \end_inset 
748
749  print ] [ 
750 \begin_inset Quotes eld
751 \end_inset 
752
753 bug!
754 \begin_inset Quotes erd
755 \end_inset 
756
757  print ] ifte
758 \layout Standard
759
760 Compare the order of operands here, and the order of arguments in the stack
761  effect of 
762 \family typewriter 
763 ifte
764 \family default 
765 .
766 \layout Standard
767
768 That the stack effects of the two 
769 \family typewriter 
770 ifte
771 \family default 
772  branches should be the same.
773  If they differ, the word becomes harder to document and debug.
774 \layout Standard
775
776
777 \family typewriter 
778 times ( num quot -- )
779 \family default 
780  executes a quotation a number of times.
781  It is good style to have the quotation always consume as many values from
782  the stack as it produces.
783  This ensures the stack effect of the entire 
784 \family typewriter 
785 times
786 \family default 
787  expression stays constant regardless of the number of iterations.
788 \layout Standard
789
790 More combinators will be introduced later.
791 \layout Subsection
792
793 Vocabularies
794 \layout Standard
795
796 The dictionary of words is not a flat list -- rather, it is separated into
797  a number of 
798 \emph on 
799 vocabularies
800 \emph default 
801 .
802  Each vocabulary is a named list of words that have something in common
803  -- for example, the 
804 \begin_inset Quotes eld
805 \end_inset 
806
807 lists
808 \begin_inset Quotes erd
809 \end_inset 
810
811  vocabulary contains words for working with linked lists.
812 \layout Standard
813
814 When a word is read by the parser, the 
815 \emph on 
816 vocabulary search path
817 \emph default 
818  determines which vocabularies to search.
819  In the interactive interpreter, the default search path contains a large
820  number of vocabularies.
821  Contrast this to the situation when a file is being parsed -- the search
822  path has a minimal set of vocabularies containing basic parsing words.
823 \begin_inset Foot
824 collapsed false
825
826 \layout Standard
827
828 The rationale here is that the interactive interpreter should have a large
829  number of words available by default, for convinience, whereas source files
830  should specify their external dependencies explicitly.
831 \end_inset 
832
833
834 \layout Standard
835
836 New vocabularies are added to the search path using the 
837 \family typewriter 
838 USE:
839 \family default 
840  parsing word.
841  For example:
842 \layout LyX-Code
843
844
845 \begin_inset Quotes eld
846 \end_inset 
847
848 /home/slava/.factor-rc
849 \begin_inset Quotes erd
850 \end_inset 
851
852  exists? .
853 \layout LyX-Code
854
855
856 \emph on 
857 ERROR: <interactive>:1: Undefined: exists?
858 \layout LyX-Code
859
860 USE: streams
861 \layout LyX-Code
862
863
864 \begin_inset Quotes eld
865 \end_inset 
866
867 /home/slava/.factor-rc
868 \begin_inset Quotes erd
869 \end_inset 
870
871  exists? .
872 \layout LyX-Code
873
874
875 \emph on 
876 t
877 \layout Standard
878
879 How do you know which vocabulary contains a word? Vocabularies can either
880  be listed, or an 
881 \begin_inset Quotes eld
882 \end_inset 
883
884 apropos
885 \begin_inset Quotes erd
886 \end_inset 
887
888  search can be performed:
889 \layout LyX-Code
890
891 "init" words.
892 \layout LyX-Code
893
894
895 \emph on 
896 [ ?run-file boot cli-arg cli-param init-environment
897 \layout LyX-Code
898
899
900 \emph on 
901 init-gc init-interpreter init-scratchpad init-search-path
902 \layout LyX-Code
903
904
905 \emph on 
906 init-stdio init-toplevel parse-command-line parse-switches
907 \layout LyX-Code
908
909
910 \emph on 
911 run-files run-user-init stdin stdout ] 
912 \layout LyX-Code
913
914 \layout LyX-Code
915
916 "map" apropos.
917 \layout LyX-Code
918
919
920 \emph on 
921 IN: lists
922 \layout LyX-Code
923
924
925 \emph on 
926 map
927 \layout LyX-Code
928
929
930 \emph on 
931 IN: strings
932 \layout LyX-Code
933
934
935 \emph on 
936 str-map
937 \layout LyX-Code
938
939
940 \emph on 
941 IN: vectors
942 \layout LyX-Code
943
944
945 \emph on 
946 (vector-map)
947 \layout LyX-Code
948
949
950 \emph on 
951 (vector-map-step)
952 \layout LyX-Code
953
954
955 \emph on 
956 vector-map 
957 \layout Standard
958
959 New words are defined in the 
960 \emph on 
961 input vocabulary
962 \emph default 
963 .
964  The input vocabulary can be changed at the interactive prompt, or in a
965  source file, using the 
966 \family typewriter 
967 IN:
968 \family default 
969  parsing word.
970  For example:
971 \layout LyX-Code
972
973 IN: music-database
974 \layout LyX-Code
975
976 : random-playlist ...
977  ;
978 \layout Standard
979
980 It is a convention (although it is not enforced by the parser) that the
981  
982 \family typewriter 
983 IN:
984 \family default 
985  directive is the first statement in a source file, and all 
986 \family typewriter 
987 USE:
988 \family default 
989  follow, before any other definitions.
990 \layout Section
991
992 PRACTICAL: Numbers game
993 \layout Standard
994
995 In this section, basic input/output and flow control is introduced.
996  We construct a program that repeatedly prompts the user to guess a number
997  -- they are informed if their guess is correct, too low, or too high.
998  The game ends on a correct guess.
999 \layout LyX-Code
1000
1001 numbers-game
1002 \layout LyX-Code
1003
1004
1005 \emph on 
1006 I'm thinking of a number between 0 and 100.
1007 \layout LyX-Code
1008
1009
1010 \emph on 
1011 Enter your guess:
1012 \emph default 
1013  25
1014 \layout LyX-Code
1015
1016
1017 \emph on 
1018 Too low
1019 \layout LyX-Code
1020
1021
1022 \emph on 
1023 Enter your guess:
1024 \emph default 
1025  38
1026 \layout LyX-Code
1027
1028
1029 \emph on 
1030 Too high
1031 \layout LyX-Code
1032
1033
1034 \emph on 
1035 Enter your guess:
1036 \emph default 
1037  31
1038 \layout LyX-Code
1039
1040
1041 \emph on 
1042 Correct - you win!
1043 \layout Subsection
1044
1045 Development methodology
1046 \layout Standard
1047
1048 A typical Factor development session involves a text editor
1049 \begin_inset Foot
1050 collapsed false
1051
1052 \layout Standard
1053
1054 Try jEdit, which has Factor syntax highlighting out of the box.
1055 \end_inset 
1056
1057  and Factor interpreter running side by side.
1058  Instead of the edit/compile/run cycle, the development process becomes
1059  an 
1060 \begin_inset Quotes eld
1061 \end_inset 
1062
1063 edit cycle
1064 \begin_inset Quotes erd
1065 \end_inset 
1066
1067  -- you make some changes to the source file and reload it in the interpreter
1068  using a command like this:
1069 \layout LyX-Code
1070
1071   
1072 \begin_inset Quotes eld
1073 \end_inset 
1074
1075 numbers-game.factor
1076 \begin_inset Quotes erd
1077 \end_inset 
1078
1079  run-file
1080 \layout Standard
1081
1082 Then the changes can be tested, either by hand, or using a test harness.
1083  There is no need to compile anything, or to lose interpreter state by restartin
1084 g.
1085  Additionally, words with 
1086 \begin_inset Quotes eld
1087 \end_inset 
1088
1089 throw-away
1090 \begin_inset Quotes erd
1091 \end_inset 
1092
1093  definitions that you do not intend to keep can also be entered directly
1094  at this interpreter prompt.
1095 \layout Standard
1096
1097 Each word should do one useful task.
1098  New words can be defined in terms of existing, already-tested words.
1099  You design a set of reusable words that model the problem domain.
1100  Then, the problem is solved in terms of a 
1101 \emph on 
1102 domain-specific vocabulary
1103 \emph default 
1104 .
1105  This is called
1106 \emph on 
1107  bottom-up design.
1108 \layout Subsection
1109
1110 Getting started
1111 \layout Standard
1112
1113 Start a text editor and create a file named 
1114 \family typewriter 
1115 numbers-game.factor
1116 \family default 
1117 .
1118 \layout Standard
1119
1120 At the top of the file, write a comment.
1121  Comments are a feature that can be found in almost any programming language;
1122  in Factor, they are implemented as parsing words.
1123  An example of commenting follows:
1124 \layout LyX-Code
1125
1126 ! The word ! discards input until the end of the line
1127 \layout LyX-Code
1128
1129 ( The word ( discards input until the next )
1130 \layout Standard
1131
1132 It is always a good idea to comment your code.
1133  Try to write simple code that does not need detailed comments to describe;
1134  similarly, avoid redundant comments.
1135  These two principles are hard to quantify in a concrete way, and will become
1136  more clear as your skills with Factor increase.
1137 \layout Standard
1138
1139 We will be defining new words in the numbers-game vocabulary; add an 
1140 \family typewriter 
1141 IN:
1142 \family default 
1143  statement at the top of the source file:
1144 \layout LyX-Code
1145
1146 IN: numbers-game
1147 \layout Standard
1148
1149 Also in order to be able to test the words, issue a 
1150 \family typewriter 
1151 USE:
1152 \family default 
1153  statement in the interactive interpreter:
1154 \layout LyX-Code
1155
1156 USE: numbers-game
1157 \layout Standard
1158
1159 This section will develop the numbers game in an incremental fashion.
1160  After each addition, issue a command like the following to load the source
1161  file into the Factor interpreter:
1162 \layout LyX-Code
1163
1164
1165 \begin_inset Quotes eld
1166 \end_inset 
1167
1168 numbers-game.factor
1169 \begin_inset Quotes erd
1170 \end_inset 
1171
1172  run-file
1173 \layout Subsection
1174
1175 Reading a number from the keyboard
1176 \layout Standard
1177
1178 A fundamental operation required for the numbers game is to be able to read
1179  a number from the keyboard.
1180  The 
1181 \family typewriter 
1182 read
1183 \family default 
1184  word 
1185 \family typewriter 
1186 ( -- str )
1187 \family default 
1188  reads a line of input and pushes it on the stack as a string.
1189  The 
1190 \family typewriter 
1191 parse-number
1192 \family default 
1193  word 
1194 \family typewriter 
1195 ( str -- n )
1196 \family default 
1197  takes a string from the stack, and parses it, pushing an integer.
1198  These two words can be combined into a single colon definition:
1199 \layout LyX-Code
1200
1201 : read-number ( -- n ) read parse-number ;
1202 \layout Standard
1203
1204 You should add this definition to the source file, and try loading the file
1205  into the interpreter.
1206  As you will soon see, this raises an error! The problem is that the two
1207  words 
1208 \family typewriter 
1209 read
1210 \family default 
1211  and 
1212 \family typewriter 
1213 parse-number
1214 \family default 
1215  are not part of the default, minimal, vocabulary search path used when
1216  reading files.
1217  The solution is to use 
1218 \family typewriter 
1219 apropos.
1220
1221 \family default 
1222  to find out which vocabularies contain those words, and add the appropriate
1223  USE: statements to the source file:
1224 \layout LyX-Code
1225
1226 USE: parser
1227 \layout LyX-Code
1228
1229 USE: stdio
1230 \layout Standard
1231
1232 After adding the above two statements, the file should now parse, and testing
1233  should confirm that the read-number word works correctly.
1234 \begin_inset Foot
1235 collapsed false
1236
1237 \layout Standard
1238
1239 There is the possibility of an invalid number being entered at the keyboard.
1240  In this case, 
1241 \family typewriter 
1242 print-number
1243 \family default 
1244  returns 
1245 \family typewriter 
1246 f
1247 \family default 
1248 , the boolean false value.
1249  For the sake of simplicity, we ignore this case in the numbers game example.
1250  However, proper error handling is an essential part of any large program
1251  and is covered later.
1252 \end_inset 
1253
1254
1255 \layout Subsection
1256
1257 Printing some messages
1258 \layout Standard
1259
1260 Now we need to make some words for printing various messages.
1261  They are given here without further ado:
1262 \layout LyX-Code
1263
1264 : guess-banner
1265 \layout LyX-Code
1266
1267     
1268 \begin_inset Quotes eld
1269 \end_inset 
1270
1271 I'm thinking of a number between 0 and 100.
1272 \begin_inset Quotes erd
1273 \end_inset 
1274
1275  print ;
1276 \layout LyX-Code
1277
1278 : guess-prompt 
1279 \begin_inset Quotes eld
1280 \end_inset 
1281
1282 Enter your guess: 
1283 \begin_inset Quotes erd
1284 \end_inset 
1285
1286  write ;
1287 \layout LyX-Code
1288
1289 : too-high 
1290 \begin_inset Quotes eld
1291 \end_inset 
1292
1293 Too high
1294 \begin_inset Quotes erd
1295 \end_inset 
1296
1297  print ;
1298 \layout LyX-Code
1299
1300 : too-low 
1301 \begin_inset Quotes eld
1302 \end_inset 
1303
1304 Too low
1305 \begin_inset Quotes erd
1306 \end_inset 
1307
1308  print ;
1309 \layout LyX-Code
1310
1311 : correct 
1312 \begin_inset Quotes eld
1313 \end_inset 
1314
1315 Correct - you win!
1316 \begin_inset Quotes erd
1317 \end_inset 
1318
1319  print ;
1320 \layout Standard
1321
1322 Note that in the above, stack effect comments are omitted, since they are
1323  obvious from context.
1324  You should ensure the words work correctly after loading the source file
1325  into the interpreter.
1326 \layout Subsection
1327
1328 Taking action based on a guess
1329 \layout Standard
1330
1331 The next logical step is to write a word 
1332 \family typewriter 
1333 judge-guess
1334 \family default 
1335  that takes the user's guess along with the actual number to be guessed,
1336  and prints one of the messages 
1337 \family typewriter 
1338 too-high
1339 \family default 
1340
1341 \family typewriter 
1342 too-low
1343 \family default 
1344 , or 
1345 \family typewriter 
1346 correct
1347 \family default 
1348 .
1349  This word will also push a boolean flag, indicating if the game should
1350  continue or not -- in the case of a correct guess, the game does not continue.
1351 \layout Standard
1352
1353 This description of judge-guess is a mouthful -- and it suggests that it
1354  may be best to split it into two words.
1355  So the first word we write handles the more specific case of an 
1356 \emph on 
1357 inexact
1358 \emph default 
1359  guess -- so it prints either 
1360 \family typewriter 
1361 too-low
1362 \family default 
1363  or 
1364 \family typewriter 
1365 too-high
1366 \family default 
1367 .
1368 \layout LyX-Code
1369
1370 : inexact-guess ( guess actual -- )
1371 \layout LyX-Code
1372
1373      > [ too-high ] [ too-low ] ifte ;
1374 \layout Standard
1375
1376 Note that the word gives incorrect output if the two parameters are equal.
1377  However, it will never be called this way.
1378 \layout Standard
1379
1380 With this out of the way, the implementation of judge-guess is an easy task
1381  to tackle.
1382  Using the words 
1383 \family typewriter 
1384 inexact-guess
1385 \family default 
1386
1387 \family typewriter 
1388 =
1389 \family default 
1390 , and 
1391 \family typewriter 
1392 2dup
1393 \family default 
1394 , we can write:
1395 \layout LyX-Code
1396
1397 : judge-guess ( actual guess -- ? )
1398 \layout LyX-Code
1399
1400     2dup = [
1401 \layout LyX-Code
1402
1403         correct f
1404 \layout LyX-Code
1405
1406     ] [
1407 \layout LyX-Code
1408
1409         inexact-guess t
1410 \layout LyX-Code
1411
1412     ] ifte ;
1413 \layout Standard
1414
1415 Note the use of 
1416 \family typewriter 
1417 2dup ( x y -- x y x y )
1418 \family default 
1419 .
1420  Since 
1421 \family typewriter 
1422 =
1423 \family default 
1424  consumes both its parameters, we must make copies of them to pass to 
1425 \family typewriter 
1426 correct
1427 \family default 
1428  and 
1429 \family typewriter 
1430 inexact-guess
1431 \family default 
1432 .
1433  Try the following at the interpreter to see what's going on:
1434 \layout LyX-Code
1435
1436 clear 1 2 2dup = .s
1437 \layout LyX-Code
1438
1439
1440 \emph on 
1441 { 1 2 f }
1442 \layout LyX-Code
1443
1444 clear 4 4 2dup = .s
1445 \layout LyX-Code
1446
1447
1448 \emph on 
1449 { 4 4 t }
1450 \layout Standard
1451
1452 Test 
1453 \family typewriter 
1454 judge-guess
1455 \family default 
1456  with a few inputs:
1457 \layout LyX-Code
1458
1459 1 10 judge-guess .
1460 \layout LyX-Code
1461
1462
1463 \emph on 
1464 Too low
1465 \layout LyX-Code
1466
1467
1468 \emph on 
1469 t
1470 \layout LyX-Code
1471
1472 89 43 judge-guess .
1473 \layout LyX-Code
1474
1475
1476 \emph on 
1477 Too high
1478 \layout LyX-Code
1479
1480
1481 \emph on 
1482 t
1483 \layout LyX-Code
1484
1485 64 64 judge-guess .
1486 \layout LyX-Code
1487
1488
1489 \emph on 
1490 Correct
1491 \layout LyX-Code
1492
1493
1494 \emph on 
1495 f
1496 \layout Subsection
1497
1498 Generating random numbers
1499 \layout Standard
1500
1501 The 
1502 \family typewriter 
1503 random-int 
1504 \family default 
1505 word 
1506 \family typewriter 
1507 ( min max -- n )
1508 \family default 
1509  pushes a random number in a specified range.
1510  The range is inclusive, so both the minimum and maximum indices are candidate
1511  random numbers.
1512  Use 
1513 \family typewriter 
1514 apropos.
1515
1516 \family default 
1517  to determine that this word is in the 
1518 \family typewriter 
1519 random
1520 \family default 
1521  vocabulary.
1522  For the purposes of this game, random numbers will be in the range of 0
1523  to 100, so we can define a word that generates a random number in the range
1524  of 0 to 100:
1525 \layout LyX-Code
1526
1527 : number-to-guess ( -- n ) 0 100 random-int ;
1528 \layout Standard
1529
1530 Add the word definition to the source file, along with the appropriate 
1531 \family typewriter 
1532 USE:
1533 \family default 
1534  statement.
1535  Load the source file in the interpreter, and confirm that the word functions
1536  correctly, and that its stack effect comment is accurate.
1537 \layout Subsection
1538
1539 The game loop
1540 \layout Standard
1541
1542 The game loop consists of repeated calls to 
1543 \family typewriter 
1544 guess-prompt
1545 \family default 
1546
1547 \family typewriter 
1548 read-number
1549 \family default 
1550  and 
1551 \family typewriter 
1552 judge-guess
1553 \family default 
1554 .
1555  If 
1556 \family typewriter 
1557 judge-guess
1558 \family default 
1559  pushes 
1560 \family typewriter 
1561 f
1562 \family default 
1563 , the loop stops, otherwise it continues.
1564  This is realized with a recursive implementation:
1565 \layout LyX-Code
1566
1567 : numbers-game-loop ( actual -- )
1568 \layout LyX-Code
1569
1570     dup guess-prompt read-number judge-guess [
1571 \layout LyX-Code
1572
1573         numbers-game-loop
1574 \layout LyX-Code
1575
1576     ] [
1577 \layout LyX-Code
1578
1579         drop
1580 \layout LyX-Code
1581
1582     ] ifte ;
1583 \layout Standard
1584
1585 In Factor, tail-recursive words consume a bounded amount of call stack space.
1586  This means you are free to pick recursion or iteration based on their own
1587  merits when solving a problem.
1588  In many other languages, the usefulness of recursion is severely limited
1589  by the lack of tail-recursive call optimization.
1590 \layout Subsection
1591
1592 Finishing off
1593 \layout Standard
1594
1595 The last task is to combine everything into the main 
1596 \family typewriter 
1597 numbers-game
1598 \family default 
1599  word.
1600  This is easier than it seems:
1601 \layout LyX-Code
1602
1603 : numbers-game number-to-guess numbers-game-loop ;
1604 \layout Standard
1605
1606 Try it out! Simply invoke the numbers-game word in the interpreter.
1607  It should work flawlessly, assuming you tested each component of this design
1608  incrementally!
1609 \layout Subsection
1610
1611 The complete program
1612 \layout LyX-Code
1613
1614 ! Numbers game example
1615 \newline 
1616
1617 \layout LyX-Code
1618
1619 IN: numbers-game
1620 \layout LyX-Code
1621
1622 USE: parser
1623 \layout LyX-Code
1624
1625 USE: stdio
1626 \newline 
1627
1628 \newline 
1629 : read-number ( -- n ) read parse-number ;
1630 \newline 
1631
1632 \newline 
1633 : guess-banner
1634 \layout LyX-Code
1635
1636     
1637 \begin_inset Quotes eld
1638 \end_inset 
1639
1640 I'm thinking of a number between 0 and 100.
1641 \begin_inset Quotes erd
1642 \end_inset 
1643
1644  print ;
1645 \layout LyX-Code
1646
1647 : guess-prompt 
1648 \begin_inset Quotes eld
1649 \end_inset 
1650
1651 Enter your guess: 
1652 \begin_inset Quotes erd
1653 \end_inset 
1654
1655  write ;
1656 \layout LyX-Code
1657
1658 : too-high 
1659 \begin_inset Quotes eld
1660 \end_inset 
1661
1662 Too high
1663 \begin_inset Quotes erd
1664 \end_inset 
1665
1666  print ;
1667 \layout LyX-Code
1668
1669 : too-low 
1670 \begin_inset Quotes eld
1671 \end_inset 
1672
1673 Too low
1674 \begin_inset Quotes erd
1675 \end_inset 
1676
1677  print ;
1678 \layout LyX-Code
1679
1680 : correct 
1681 \begin_inset Quotes eld
1682 \end_inset 
1683
1684 Correct - you win!
1685 \begin_inset Quotes erd
1686 \end_inset 
1687
1688  print ;
1689 \newline 
1690
1691 \newline 
1692 : inexact-guess ( guess actual -- )
1693 \layout LyX-Code
1694
1695      > [ too-high ] [ too-low ] ifte ;
1696 \newline 
1697
1698 \newline 
1699 : judge-guess ( actual guess -- ? )
1700 \layout LyX-Code
1701
1702     2dup = [
1703 \layout LyX-Code
1704
1705         correct f
1706 \layout LyX-Code
1707
1708     ] [
1709 \layout LyX-Code
1710
1711         inexact-guess t
1712 \layout LyX-Code
1713
1714     ] ifte ;
1715 \newline 
1716
1717 \newline 
1718 : number-to-guess ( -- n ) 0 100 random-int ;
1719 \newline 
1720
1721 \newline 
1722 : numbers-game-loop ( actual -- )
1723 \layout LyX-Code
1724
1725     dup guess-prompt read-number judge-guess [
1726 \layout LyX-Code
1727
1728         numbers-game-loop
1729 \layout LyX-Code
1730
1731     ] [
1732 \layout LyX-Code
1733
1734         drop
1735 \layout LyX-Code
1736
1737     ] ifte ;
1738 \newline 
1739
1740 \newline 
1741 : numbers-game number-to-guess numbers-game-loop ;
1742 \layout LyX-Code
1743
1744 \layout Section
1745
1746 Lists
1747 \layout Standard
1748
1749 A list is composed of a set of pairs; each pair holds a list element, and
1750  a reference to the next pair.
1751  Lists have the following literal syntax:
1752 \layout LyX-Code
1753
1754
1755 \begin_inset Quotes eld
1756 \end_inset 
1757
1758 CEO
1759 \begin_inset Quotes erd
1760 \end_inset 
1761
1762  5 
1763 \begin_inset Quotes eld
1764 \end_inset 
1765
1766 CFO
1767 \begin_inset Quotes erd
1768 \end_inset 
1769
1770  -4 f ]
1771 \layout Standard
1772
1773 Before we continue, it is important to understand the role of data types
1774  in Factor.
1775  Lets make a distinction between two categories of data types:
1776 \layout Itemize
1777
1778 Representational type -- this refers to the form of the data in the interpreter.
1779  Representational types include integers, strings, and vectors.
1780  Representational types are checked at run time -- attempting to multiply
1781  two strings, for example, will yield an error.
1782 \layout Itemize
1783
1784 Intentional type -- this refers to the meaning of the data within the problem
1785  domain.
1786  This could be a length measured in inches, or a string naming a file, or
1787  a list of objects in a room in a game.
1788  It is up to the programmer to check intentional types -- Factor won't prevent
1789  you from adding two integers representing a distance and a time, even though
1790  the result is meaningless.
1791 \layout Subsection
1792
1793 Cons cells
1794 \layout Standard
1795
1796 It may surprise you that in Factor, 
1797 \emph on 
1798 lists are intentional types
1799 \emph default 
1800 .
1801  This means that they are not an inherent feature of the interpreter; rather,
1802  they are built from a simpler data type, the 
1803 \emph on 
1804 cons cell
1805 \emph default 
1806 .
1807 \layout Standard
1808
1809 A cons cell is an object that holds a reference to two other objects.
1810  The order of the two objects matters -- the first is called the 
1811 \emph on 
1812 car
1813 \emph default 
1814 , the second is called the 
1815 \emph on 
1816 cdr
1817 \emph default 
1818 .
1819 \layout Standard
1820
1821 All words relating to cons cells and lists are found in the 
1822 \family typewriter 
1823 lists
1824 \family default 
1825  vocabulary.
1826  The words 
1827 \family typewriter 
1828 cons
1829 \family default 
1830
1831 \family typewriter 
1832 car
1833 \family default 
1834  and 
1835 \family typewriter 
1836 cdr
1837 \family default 
1838
1839 \begin_inset Foot
1840 collapsed false
1841
1842 \layout Standard
1843
1844 These infamous names originate from the Lisp language.
1845  Originally, 
1846 \begin_inset Quotes eld
1847 \end_inset 
1848
1849 Lisp
1850 \begin_inset Quotes erd
1851 \end_inset 
1852
1853  stood for 
1854 \begin_inset Quotes eld
1855 \end_inset 
1856
1857 List Processing
1858 \begin_inset Quotes erd
1859 \end_inset 
1860
1861 .
1862 \end_inset 
1863
1864  construct and deconstruct cons cells:
1865 \layout LyX-Code
1866
1867 1 2 cons .
1868 \layout LyX-Code
1869
1870
1871 \emph on 
1872 [ 1 | 2 ]
1873 \layout LyX-Code
1874
1875 3 4 car .
1876 \layout LyX-Code
1877
1878
1879 \emph on 
1880 3
1881 \layout LyX-Code
1882
1883 5 6 cdr .
1884 \layout LyX-Code
1885
1886
1887 \emph on 
1888 6
1889 \layout Standard
1890
1891 The output of the first expression suggests a literal syntax for cons cells:
1892 \layout LyX-Code
1893
1894 [ 10 | 20 ] cdr .
1895 \layout LyX-Code
1896
1897
1898 \emph on 
1899 20
1900 \layout LyX-Code
1901
1902
1903 \begin_inset Quotes eld
1904 \end_inset 
1905
1906 first
1907 \begin_inset Quotes erd
1908 \end_inset 
1909
1910  | [ 
1911 \begin_inset Quotes eld
1912 \end_inset 
1913
1914 second
1915 \begin_inset Quotes erd
1916 \end_inset 
1917
1918  | f ] ] car .
1919 \layout LyX-Code
1920
1921
1922 \emph on 
1923
1924 \begin_inset Quotes eld
1925 \end_inset 
1926
1927 first
1928 \begin_inset Quotes erd
1929 \end_inset 
1930
1931
1932 \layout LyX-Code
1933
1934
1935 \begin_inset Quotes eld
1936 \end_inset 
1937
1938 first
1939 \begin_inset Quotes erd
1940 \end_inset 
1941
1942  | [ 
1943 \begin_inset Quotes eld
1944 \end_inset 
1945
1946 second
1947 \begin_inset Quotes erd
1948 \end_inset 
1949
1950  | f ] ] cdr car .
1951 \layout LyX-Code
1952
1953
1954 \emph on 
1955
1956 \begin_inset Quotes eld
1957 \end_inset 
1958
1959 second
1960 \begin_inset Quotes erd
1961 \end_inset 
1962
1963
1964 \layout Standard
1965
1966 The last two examples make it clear how nested cons cells represent a list.
1967  Since this 
1968 \begin_inset Quotes eld
1969 \end_inset 
1970
1971 nested cons cell
1972 \begin_inset Quotes erd
1973 \end_inset 
1974
1975  syntax is extremely cumbersome, the parser provides an easier way:
1976 \layout LyX-Code
1977
1978 [ 1 2 3 4 ] cdr cdr car .
1979 \layout LyX-Code
1980
1981
1982 \emph on 
1983 3
1984 \layout Standard
1985
1986
1987 \emph on 
1988 generalized list
1989 \emph default 
1990  is a set of cons cells linked by their cdr.
1991  A 
1992 \emph on 
1993 proper list
1994 \emph default 
1995 , or just list, is a generalized list with a cdr equal to f, the list is
1996  a proper list.
1997  Also, the object 
1998 \family typewriter 
1999 f
2000 \family default 
2001  is a proper list, and in fact it is equivalent to the empty list 
2002 \family typewriter 
2003 [ ]
2004 \family default 
2005 .
2006  An
2007 \emph on 
2008  improper list
2009 \emph default 
2010  is a generalized list that is not a proper list.
2011 \layout Standard
2012
2013 The 
2014 \family typewriter 
2015 list?
2016 \family default 
2017  word tests if the object at the top of the stack is a proper list:
2018 \layout LyX-Code
2019
2020
2021 \begin_inset Quotes eld
2022 \end_inset 
2023
2024 hello
2025 \begin_inset Quotes erd
2026 \end_inset 
2027
2028  list? .
2029 \layout LyX-Code
2030
2031
2032 \emph on 
2033 f
2034 \layout LyX-Code
2035
2036
2037 \begin_inset Quotes eld
2038 \end_inset 
2039
2040 first
2041 \begin_inset Quotes erd
2042 \end_inset 
2043
2044  
2045 \begin_inset Quotes eld
2046 \end_inset 
2047
2048 second
2049 \begin_inset Quotes erd
2050 \end_inset 
2051
2052  | 
2053 \begin_inset Quotes eld
2054 \end_inset 
2055
2056 third
2057 \begin_inset Quotes erd
2058 \end_inset 
2059
2060  ] list? .
2061 \layout LyX-Code
2062
2063
2064 \emph on 
2065 f
2066 \layout LyX-Code
2067
2068
2069 \begin_inset Quotes eld
2070 \end_inset 
2071
2072 first
2073 \begin_inset Quotes erd
2074 \end_inset 
2075
2076  
2077 \begin_inset Quotes eld
2078 \end_inset 
2079
2080 second
2081 \begin_inset Quotes erd
2082 \end_inset 
2083
2084  
2085 \begin_inset Quotes eld
2086 \end_inset 
2087
2088 third
2089 \begin_inset Quotes erd
2090 \end_inset 
2091
2092  ] list? .
2093 \layout LyX-Code
2094
2095
2096 \emph on 
2097 t
2098 \layout Subsection
2099
2100 Working with lists
2101 \layout Standard
2102
2103 Unless otherwise documented, list manipulation words expect proper lists
2104  as arguments.
2105  Given an improper list, they will either raise an error, or disregard the
2106  hanging cdr at the end of the list.
2107 \layout Standard
2108
2109 Also unless otherwise documented, list manipulation words return newly-created
2110  lists only.
2111  The original parameters are not modified.
2112  This may seem inefficient, however the absence of side effects makes code
2113  much easier to test and debug.
2114 \begin_inset Foot
2115 collapsed false
2116
2117 \layout Standard
2118
2119 Side effect-free code is the fundamental idea underlying functional programming
2120  languages.
2121  While Factor allows side effects and is not a functional programming language,
2122  for a lot of problems, coding in a functional style gives the most maintanable
2123  and readable results.
2124 \end_inset 
2125
2126  Where performance is important, a set of 
2127 \begin_inset Quotes eld
2128 \end_inset 
2129
2130 destructive
2131 \begin_inset Quotes erd
2132 \end_inset 
2133
2134  words is provided.
2135  They are documented in the next section.
2136 \layout Standard
2137
2138
2139 \family typewriter 
2140 nth ( index list -- obj )
2141 \family default 
2142  Look up an element specified by a zero-based index, by successively iterating
2143  down the cdr of the list:
2144 \layout LyX-Code
2145
2146 1 [ 
2147 \begin_inset Quotes eld
2148 \end_inset 
2149
2150 Hamster
2151 \begin_inset Quotes erd
2152 \end_inset 
2153
2154  
2155 \begin_inset Quotes eld
2156 \end_inset 
2157
2158 Bagpipe
2159 \begin_inset Quotes erd
2160 \end_inset 
2161
2162  
2163 \begin_inset Quotes eld
2164 \end_inset 
2165
2166 Beam
2167 \begin_inset Quotes erd
2168 \end_inset 
2169
2170  ] nth .
2171 \layout LyX-Code
2172
2173
2174 \emph on 
2175
2176 \begin_inset Quotes eld
2177 \end_inset 
2178
2179 Bagpipe
2180 \begin_inset Quotes erd
2181 \end_inset 
2182
2183
2184 \layout Standard
2185
2186 This word takes linear time proportional to the list index.
2187  If you need constant time lookups, use a vector instead.
2188 \layout Standard
2189
2190
2191 \family typewriter 
2192 length ( list -- n )
2193 \family default 
2194  Iterate down the cdr of the list until it reaches 
2195 \family typewriter 
2196 f
2197 \family default 
2198 , counting the number of elements in the list:
2199 \layout LyX-Code
2200
2201 [ [ 1 2 ] [ 3 4 ] 5 ] length .
2202 \layout LyX-Code
2203
2204
2205 \emph on 
2206 3
2207 \layout LyX-Code
2208
2209 [ [ [ 
2210 \begin_inset Quotes eld
2211 \end_inset 
2212
2213 Hey
2214 \begin_inset Quotes erd
2215 \end_inset 
2216
2217  ] 5 ] length .
2218 \layout LyX-Code
2219
2220
2221 \emph on 
2222 2
2223 \layout Standard
2224
2225
2226 \family typewriter 
2227 unit ( obj -- list )
2228 \family default 
2229  Make a list of one element:
2230 \layout LyX-Code
2231
2232
2233 \begin_inset Quotes eld
2234 \end_inset 
2235
2236 Unit 18
2237 \begin_inset Quotes erd
2238 \end_inset 
2239
2240  unit .
2241 \layout LyX-Code
2242
2243
2244 \emph on 
2245
2246 \begin_inset Quotes eld
2247 \end_inset 
2248
2249 Unit 18
2250 \begin_inset Quotes erd
2251 \end_inset 
2252
2253  ]
2254 \layout Standard
2255
2256
2257 \family typewriter 
2258 append ( list list -- list )
2259 \family default 
2260  Append the two lists at the top of the stack:
2261 \layout LyX-Code
2262
2263 [ 1 2 3 ] [ 4 5 6 ] append .
2264 \layout LyX-Code
2265
2266
2267 \emph on 
2268 [ 1 2 3 4 5 6 ]
2269 \layout LyX-Code
2270
2271 [ 1 2 3 ] dup [ 4 5 6 ] append .s
2272 \layout LyX-Code
2273
2274
2275 \emph on 
2276 { [ 1 2 3 ] [ 1 2 3 4 5 6 ] }
2277 \layout Standard
2278
2279 The first list is copied, and the cdr of its last cons cell is set to the
2280  second list.
2281  The second example above shows that the original parameter was not modified.
2282  Interestingly, if the second parameter is not a proper list, 
2283 \family typewriter 
2284 append
2285 \family default 
2286  returns an improper list:
2287 \layout LyX-Code
2288
2289 [ 1 2 3 ] 4 append .
2290 \layout LyX-Code
2291
2292
2293 \emph on 
2294 [ 1 2 3 | 4 ]
2295 \layout Standard
2296
2297
2298 \family typewriter 
2299 add ( list obj -- list )
2300 \family default 
2301  Create a new list consisting of the original list, and a new element added
2302  at the end:
2303 \layout LyX-Code
2304
2305 [ 1 2 3 ] 4 add .
2306 \layout LyX-Code
2307
2308
2309 \emph on 
2310 [ 1 2 3 4 ]
2311 \layout LyX-Code
2312
2313 1 [ 2 3 4 ] cons .
2314 \layout LyX-Code
2315
2316
2317 \emph on 
2318 [ 1 2 3 4 ]
2319 \layout Standard
2320
2321 While 
2322 \family typewriter 
2323 cons
2324 \family default 
2325  and 
2326 \family typewriter 
2327 add
2328 \family default 
2329  appear to have similar effects, they are quite different -- 
2330 \family typewriter 
2331 cons
2332 \family default 
2333  is a very cheap operation, while 
2334 \family typewriter 
2335 add
2336 \family default 
2337  has to copy the entire list first! If you need adds to the end to take
2338  a constant time, use a vector.
2339 \layout Standard
2340
2341
2342 \family typewriter 
2343 reverse ( list -- list )
2344 \family default 
2345  Push a new list which has the same elements as the original one, but in
2346  reverse order:
2347 \layout LyX-Code
2348
2349 [ 4 3 2 1 ] reverse .
2350 \layout LyX-Code
2351
2352
2353 \emph on 
2354 [ 1 2 3 4 ]
2355 \layout Standard
2356
2357
2358 \family typewriter 
2359 contains ( obj list -- list )
2360 \family roman 
2361  
2362 \family default 
2363 Look
2364 \family roman 
2365  for an occurrence of an object in a list.
2366  The remainder of the list starting from the first occurrence
2367 \family default 
2368  is returned.
2369  If the object does not occur in the list, f is returned:
2370 \layout LyX-Code
2371
2372 : lived-in? ( country -- ? )
2373 \layout LyX-Code
2374
2375     [ 
2376 \begin_inset Quotes eld
2377 \end_inset 
2378
2379 Canada
2380 \begin_inset Quotes erd
2381 \end_inset 
2382
2383  
2384 \begin_inset Quotes eld
2385 \end_inset 
2386
2387 New Zealand
2388 \begin_inset Quotes erd
2389 \end_inset 
2390
2391  
2392 \begin_inset Quotes eld
2393 \end_inset 
2394
2395 Australia
2396 \begin_inset Quotes erd
2397 \end_inset 
2398
2399  
2400 \begin_inset Quotes eld
2401 \end_inset 
2402
2403 Russia
2404 \begin_inset Quotes erd
2405 \end_inset 
2406
2407  ] contains ;
2408 \layout LyX-Code
2409
2410
2411 \begin_inset Quotes eld
2412 \end_inset 
2413
2414 Australia
2415 \begin_inset Quotes erd
2416 \end_inset 
2417
2418  lived-in? .
2419 \layout LyX-Code
2420
2421
2422 \emph on 
2423
2424 \begin_inset Quotes eld
2425 \end_inset 
2426
2427 Australia
2428 \begin_inset Quotes erd
2429 \end_inset 
2430
2431  
2432 \begin_inset Quotes eld
2433 \end_inset 
2434
2435 Russia
2436 \begin_inset Quotes erd
2437 \end_inset 
2438
2439  ]
2440 \layout LyX-Code
2441
2442
2443 \begin_inset Quotes eld
2444 \end_inset 
2445
2446 Pakistan
2447 \begin_inset Quotes erd
2448 \end_inset 
2449
2450  lived-in? .
2451 \layout LyX-Code
2452
2453
2454 \emph on 
2455 f
2456 \layout Standard
2457
2458 For now, assume 
2459 \begin_inset Quotes eld
2460 \end_inset 
2461
2462 occurs
2463 \begin_inset Quotes erd
2464 \end_inset 
2465
2466  means 
2467 \begin_inset Quotes eld
2468 \end_inset 
2469
2470 contains an object that looks like
2471 \begin_inset Quotes erd
2472 \end_inset 
2473
2474 .
2475  The issue of object equality is covered in the next chapter.
2476 \layout Standard
2477
2478
2479 \family typewriter 
2480 remove ( obj list -- list )
2481 \family default 
2482  Push a new list, with all occurrences of the object removed.
2483  All other elements are in the same order:
2484 \layout LyX-Code
2485
2486 : australia- 
2487 \begin_inset Quotes eld
2488 \end_inset 
2489
2490 Australia
2491 \begin_inset Quotes erd
2492 \end_inset 
2493
2494  swap remove ;
2495 \layout LyX-Code
2496
2497 [ "Canada" "New Zealand" "Australia" "Russia" ] australia- .
2498 \layout LyX-Code
2499
2500
2501 \emph on 
2502 [ "Canada" "New Zealand" "Russia" ]
2503 \layout Standard
2504
2505
2506 \family typewriter 
2507 remove-nth ( index list -- list )
2508 \family default 
2509  Push a new list, with an index removed:
2510 \layout LyX-Code
2511
2512 : australia- 
2513 \begin_inset Quotes eld
2514 \end_inset 
2515
2516 Australia
2517 \begin_inset Quotes erd
2518 \end_inset 
2519
2520  swap remove ;
2521 \layout LyX-Code
2522
2523 [ "Canada" "New Zealand" "Australia" "Russia" ] australia- .
2524 \layout LyX-Code
2525
2526
2527 \emph on 
2528 [ "Canada" "New Zealand" "Russia" ]
2529 \layout Standard
2530
2531 XXX: unique, set-nth -- talk about lists as stacks
2532 \layout Subsection
2533
2534 Association lists
2535 \layout Standard
2536
2537 An 
2538 \emph on 
2539 association list
2540 \emph default 
2541  is one where every element is a cons.
2542  The car of each cons is a name, the cdr is a value.
2543  The literal notation is suggestive:
2544 \layout LyX-Code
2545
2546 [
2547 \layout LyX-Code
2548
2549     [ 
2550 \begin_inset Quotes eld
2551 \end_inset 
2552
2553 Jill
2554 \begin_inset Quotes erd
2555 \end_inset 
2556
2557  | 
2558 \begin_inset Quotes eld
2559 \end_inset 
2560
2561 CEO
2562 \begin_inset Quotes erd
2563 \end_inset 
2564
2565  ]
2566 \layout LyX-Code
2567
2568     [ 
2569 \begin_inset Quotes eld
2570 \end_inset 
2571
2572 Jeff
2573 \begin_inset Quotes erd
2574 \end_inset 
2575
2576  | 
2577 \begin_inset Quotes eld
2578 \end_inset 
2579
2580 manager
2581 \begin_inset Quotes erd
2582 \end_inset 
2583
2584  ]
2585 \layout LyX-Code
2586
2587     [ 
2588 \begin_inset Quotes eld
2589 \end_inset 
2590
2591 James  | 
2592 \begin_inset Quotes eld
2593 \end_inset 
2594
2595 lowly web designer
2596 \begin_inset Quotes erd
2597 \end_inset 
2598
2599  ]
2600 \layout LyX-Code
2601
2602 ]
2603 \layout Standard
2604
2605
2606 \family typewriter 
2607 assoc? ( obj -- ? )
2608 \family default 
2609  returns 
2610 \family typewriter 
2611 t
2612 \family default 
2613  if the object is a list whose every element is a cons; otherwise it returns
2614  
2615 \family typewriter 
2616 f
2617 \family default 
2618 .
2619 \layout Standard
2620
2621
2622 \family typewriter 
2623 assoc ( name alist -- value )
2624 \family default 
2625  looks for a pair with this name in the list, and pushes the cdr of the
2626  pair.
2627  Pushes f if no name with this pair is present.
2628  Note that assoc cannot differentiate between a name that is not present
2629  at all, or a name with a value of 
2630 \family typewriter 
2631 f
2632 \family default 
2633 .
2634 \layout Standard
2635
2636
2637 \family typewriter 
2638 assoc* ( name alist -- [ name | value ] )
2639 \family default 
2640  looks for a pair with this name, and pushes the pair itself.
2641  Unlike 
2642 \family typewriter 
2643 assoc
2644 \family default 
2645
2646 \family typewriter 
2647 assoc*
2648 \family default 
2649  returns different values in the cases of a value set to 
2650 \family typewriter 
2651 f
2652 \family default 
2653 , or an undefined value.
2654 \layout Standard
2655
2656
2657 \family typewriter 
2658 set-assoc ( value name alist -- alist )
2659 \family default 
2660  removes any existing occurrence of a name from the list, and adds a new
2661  pair.
2662  This creates a new list, the original is unaffected.
2663 \layout Standard
2664
2665
2666 \family typewriter 
2667 acons ( value name alist -- alist )
2668 \family default 
2669  is slightly faster than 
2670 \family typewriter 
2671 set-assoc
2672 \family default 
2673  since it simply conses a new pair onto the list.
2674  However, if used repeatedly, the list will grow to contain a lot of 
2675 \begin_inset Quotes eld
2676 \end_inset 
2677
2678 shadowed
2679 \begin_inset Quotes erd
2680 \end_inset 
2681
2682  pairs.
2683 \layout Standard
2684
2685 Searching an association list incurs a linear time cost, so they should
2686  only be used for small mappings -- a typical use is a mapping of half a
2687  dozen entries or so, specified literally in source.
2688  Hashtables can achieve better performance with larger mappings.
2689 \layout Subsection
2690
2691 List combinators
2692 \layout Standard
2693
2694 In a traditional language such as C, every iteration or collection must
2695  be written out as a loop, with setting up and updating of idices, etc.
2696  Factor on the other hand relies on combinators and quotations to avoid
2697  duplicating these loop 
2698 \begin_inset Quotes eld
2699 \end_inset 
2700
2701 design patterns
2702 \begin_inset Quotes erd
2703 \end_inset 
2704
2705  throughout the code.
2706 \layout Standard
2707
2708 The simplest case is iterating through each element of a list, and printing
2709  it or otherwise consuming it from the stack.
2710 \layout Standard
2711
2712
2713 \family typewriter 
2714 each ( list quot -- )
2715 \family default 
2716  pushes each element of the list in turn, and executes the quotation.
2717  The list and quotation are not on the stack when the quotation is executed.
2718  This allows a powerful idiom where the quotation makes a copy of a value
2719  on the stack, and consumes it along with the list element.
2720  In fact, this idiom works with all well-designed combinators.
2721 \begin_inset Foot
2722 collapsed false
2723
2724 \layout Standard
2725
2726 Later, you will learn how to apply it when designing your own combinators.
2727 \end_inset 
2728
2729
2730 \layout Standard
2731
2732 The previously-mentioned 
2733 \family typewriter 
2734 reverse
2735 \family default 
2736  word is implemented using 
2737 \family typewriter 
2738 each
2739 \family default 
2740 :
2741 \layout LyX-Code
2742
2743 : reverse [ ] swap [ swons ] each ;
2744 \layout Standard
2745
2746 To understand how it works, consider that each element of the original list
2747  is consed onto the beginning of a new list, in turn.
2748  So the last element of the original list ends up at the beginning of the
2749  new list.
2750 \layout Standard
2751
2752
2753 \family typewriter 
2754 inject ( list quot -- list )
2755 \family default 
2756  is similar to 
2757 \family typewriter 
2758 each
2759 \family default 
2760 , except the return values of the quotation are collected into the new list.
2761  The quotation must leave one more element on the stack than was present
2762  before the quotation was called, otherwise the combinator will not function
2763  properly; so the quotation must have stack effect 
2764 \family typewriter 
2765 ( obj -- obj )
2766 \family default 
2767 .
2768 \layout Standard
2769
2770 For example, suppose we have a list where each element stores the quantity
2771  of a some nutrient in 100 grams of food; we would like to find out the
2772  total nutrients contained in 300 grams:
2773 \layout LyX-Code
2774
2775 : multiply-each ( n list -- list )
2776 \layout LyX-Code
2777
2778     [ dupd * ] inject nip ;
2779 \layout LyX-Code
2780
2781 3 [ 50 450 101 ] multiply-each .
2782 \layout LyX-Code
2783
2784
2785 \emph on 
2786 [ 180 1350 303 ]
2787 \layout Standard
2788
2789 Note the use of 
2790 \family typewriter 
2791 nip
2792 \family default 
2793  to discard the original parameter 
2794 \family typewriter 
2795 n
2796 \family default 
2797 .
2798 \layout Standard
2799
2800 In case there is no appropriate combinator, recursion can be used.
2801  Factor performs tail call optimization, so a word where the recursive call
2802  is the last thing done will not use an arbitrary amount of stack space.
2803 \layout Standard
2804
2805
2806 \family typewriter 
2807 subset ( list quot -- list )
2808 \family default 
2809  produces a new list containing some of the elements of the original list.
2810  Which elements to collect is determined by the quotation -- the quotation
2811  is called with each list element on the stack in turn, and those elements
2812  for which the quotation does not return 
2813 \family typewriter 
2814 f
2815 \family default 
2816  are added to the new list.
2817  The quotation must have stack effect 
2818 \family typewriter 
2819 ( obj -- ? )
2820 \family default 
2821 .
2822 \layout Standard
2823
2824 For example, lets construct a list of all numbers between 0 and 99 such
2825  that the sum of their digits is less than 10:
2826 \layout LyX-Code
2827
2828 : sum-of-digits ( n -- n ) 10 /mod + ;
2829 \layout LyX-Code
2830
2831 100 count [ sum-of-digits 10 < ] subset .
2832 \layout LyX-Code
2833
2834
2835 \emph on 
2836 [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 21
2837 \layout LyX-Code
2838
2839
2840 \emph on 
2841 22 23 24 25 26 27 30 31 32 33 34 35 36 40 41 42 43 44
2842 \layout LyX-Code
2843
2844
2845 \emph on 
2846 45 50 51 52 53 54 60 61 62 63 70 71 72 80 81 90 ] 
2847 \layout Standard
2848
2849
2850 \family typewriter 
2851 all? ( list quot -- ? )
2852 \family default 
2853  returns 
2854 \family typewriter 
2855 t
2856 \family default 
2857  if the quotation returns 
2858 \family typewriter 
2859 t
2860 \family default 
2861  for all elements of the list, otherwise it returns 
2862 \family typewriter 
2863 f
2864 \family default 
2865 .
2866  In other words, if 
2867 \family typewriter 
2868 all?
2869 \family default 
2870  returns 
2871 \family typewriter 
2872 t
2873 \family default 
2874 , then 
2875 \family typewriter 
2876 subset
2877 \family default 
2878  applied to the same list and quotation would return the entire list.
2879 \begin_inset Foot
2880 collapsed false
2881
2882 \layout Standard
2883
2884 Barring any side effects which modify the execution of the quotation.
2885  It is best to avoid side effects when using list combinators.
2886 \end_inset 
2887
2888
2889 \layout Standard
2890
2891 For example, the implementation of 
2892 \family typewriter 
2893 assoc?
2894 \family default 
2895  uses 
2896 \family typewriter 
2897 all?
2898 \family default 
2899 :
2900 \layout LyX-Code
2901
2902 : assoc? ( list -- ? )
2903 \layout LyX-Code
2904
2905     dup list? [ [ cons? ] all? ] [ drop f ] ifte ;
2906 \layout Subsection
2907
2908 List constructors
2909 \layout Standard
2910
2911 The list construction words minimize stack noise with a clever trick.
2912  They store a partial list in a variable, thus reducing the number of stack
2913  elements that have to be juggled.
2914 \layout Standard
2915
2916 The word 
2917 \family typewriter 
2918 [, ( -- )
2919 \family default 
2920  begins list construction.
2921 \layout Standard
2922
2923 The word 
2924 \family typewriter 
2925 , ( obj -- )
2926 \family default 
2927  appends an object to the partial list.
2928 \layout Standard
2929
2930 The word 
2931 \family typewriter 
2932 ,] ( -- list )
2933 \family default 
2934  pushes the complete list.
2935 \layout Standard
2936
2937 While variables haven't been described yet, keep in mind that a new scope
2938  is created between 
2939 \family typewriter 
2940 [,
2941 \family default 
2942  and 
2943 \family typewriter 
2944 ,]
2945 \family default 
2946 .
2947  This means that list constructions can be nested, as long as in the end,
2948  the number of 
2949 \family typewriter 
2950 [,
2951 \family default 
2952  and 
2953 \family typewriter 
2954 ,]
2955 \family default 
2956  balances out.
2957  There is no requirement that 
2958 \family typewriter 
2959 [,
2960 \family default 
2961  and 
2962 \family typewriter 
2963 ,]
2964 \family default 
2965  appear in the same word, however, debugging becomes prohibitively difficult
2966  when a list construction begins in one word and ends with another.
2967 \layout Standard
2968
2969 Here is an example of list construction using this technique:
2970 \layout LyX-Code
2971
2972 [, 1 10 [ 2 * dup , ] times drop ,] .
2973 \layout LyX-Code
2974
2975
2976 \emph on 
2977 [ 2 4 8 16 32 64 128 256 512 1024 ]
2978 \layout LyX-Code
2979
2980 \layout Subsection
2981
2982 Destructively modifying lists
2983 \layout Standard
2984
2985 All previously discussed list modification functions always returned newly-alloc
2986 ated lists.
2987  Destructive list manipulation functions on the other hand reuse the cons
2988  cells of their input lists, and hence avoid memory allocation.
2989 \layout Standard
2990
2991 Only ever destructively change lists you do not intend to reuse again.
2992  You should not rely on the side effects -- they are unpredictable.
2993  It is wrong to think that destructive words 
2994 \begin_inset Quotes eld
2995 \end_inset 
2996
2997 modify
2998 \begin_inset Quotes erd
2999 \end_inset 
3000
3001  the original list -- rather, think of them as returning a new list, just
3002  like the normal versions of the words, with the added caveat that the original
3003  list must not be used again.
3004 \layout Standard
3005
3006
3007 \family typewriter 
3008 nreverse ( list -- list )
3009 \family default 
3010  reverses a list without consing.
3011  In the following example, the return value reuses the cons cells of the
3012  original list, and the original list has been ruined by unpredictable side
3013  effects:
3014 \layout LyX-Code
3015
3016 [ 1 2 3 4 ] dup nreverse .s
3017 \layout LyX-Code
3018
3019
3020 \emph on 
3021 { [ 4 ] [ 4 3 2 1 ] }
3022 \layout Standard
3023
3024 Compare the second stack element (which is what remains of the original
3025  list) and the top stack element (the list returned by 
3026 \family typewriter 
3027 nreverse
3028 \family default 
3029 ).
3030 \layout Standard
3031
3032 The 
3033 \family typewriter 
3034 nreverse
3035 \family default 
3036  word is the most frequently used destructive list manipulator.
3037  The usual idiom is a loop where values are consed onto the beginning of
3038  a list in each iteration of a loop, then the list is reversed at the end.
3039  Since the original list is never used again, 
3040 \family typewriter 
3041 nreverse
3042 \family default 
3043  can safely be used here.
3044  XXX - example
3045 \layout Standard
3046
3047
3048 \family typewriter 
3049 nappend ( list list -- list )
3050 \family default 
3051  sets the cdr of the last cons cell in the first list to the second list,
3052  unless the first list is 
3053 \family typewriter 
3054 f
3055 \family default 
3056 , in which case it simply returns the second list.
3057  Again, the side effects on the first list are unpredictable -- if it is
3058  
3059 \family typewriter 
3060 f
3061 \family default 
3062 , it is unchanged, otherwise, it is equal to the return value:
3063 \layout LyX-Code
3064
3065 [ 1 2 ] [ 3 4 ] nappend .
3066 \layout LyX-Code
3067
3068
3069 \emph on 
3070 [ 1 2 3 4 ]
3071 \layout Standard
3072
3073 Note in the above examples, we use literal list parameters to nreverse and
3074  nappend.
3075  This is actually a very bad idea, since the same literal list may be used
3076  more than once! For example, lets make a colon definition:
3077 \layout LyX-Code
3078
3079 : very-bad-idea [ 1 2 3 4 ] nreverse ;
3080 \layout LyX-Code
3081
3082 very-bad-idea .
3083 \layout LyX-Code
3084
3085
3086 \emph on 
3087 [ 4 3 2 1 ]
3088 \layout LyX-Code
3089
3090 very-bad-idea .
3091 \layout LyX-Code
3092
3093
3094 \emph on 
3095 [ 4 ]
3096 \layout LyX-Code
3097
3098
3099 \begin_inset Quotes eld
3100 \end_inset 
3101
3102 very-bad-idea
3103 \begin_inset Quotes erd
3104 \end_inset 
3105
3106  see
3107 \layout LyX-Code
3108
3109
3110 \emph on 
3111 : very-bad-idea
3112 \layout LyX-Code
3113
3114
3115 \emph on 
3116     [ 4 ] nreverse ;
3117 \layout Standard
3118
3119 As you can see, the word definition itself was ruined!
3120 \layout Standard
3121
3122 Sometimes it is desirable make a copy of a list, so that the copy may be
3123  safely side-effected later.
3124 \layout Standard
3125
3126
3127 \family typewriter 
3128 clone-list ( list -- list )
3129 \family default 
3130  pushes a new list containing the exact same elements as the original.
3131  The elements themselves are not copied.
3132 \layout Standard
3133
3134 If you want to write your own destructive list manipulation words, you can
3135  use 
3136 \family typewriter 
3137 set-car ( value cons -- )
3138 \family default 
3139  and 
3140 \family typewriter 
3141 set-cdr ( value cons -- )
3142 \family default 
3143  to modify individual cons cells.
3144  Some words that are not destructive on their inputs nonetheless create
3145  intermediate lists which are operated on using these words.
3146  One example is 
3147 \family typewriter 
3148 clone-list
3149 \family default 
3150  itself.
3151 \layout Section
3152
3153 Vectors
3154 \layout Standard
3155
3156 A vector is a contiguous chunk of cells which hold references to arbitrary
3157  objects.
3158  Vectors have the following literal syntax:
3159 \layout LyX-Code
3160
3161 { f f f t t f t t -6 
3162 \begin_inset Quotes eld
3163 \end_inset 
3164
3165 Hey
3166 \begin_inset Quotes erd
3167 \end_inset 
3168
3169  }
3170 \layout Standard
3171
3172 Use of vector literals in source code is discouraged, since vector manipulation
3173  relies on side effects rather than return values, and it is very easy to
3174  mess up a literal embedded in a word definition.
3175 \layout Subsection
3176
3177 Vectors versus lists
3178 \layout Standard
3179
3180 Vectors are applicable for a different class of problems than lists.
3181  Compare the relative performance of common operations on vectors and lists:
3182 \layout Standard
3183
3184
3185 \begin_inset  Tabular
3186 <lyxtabular version="3" rows="4" columns="3">
3187 <features>
3188 <column alignment="center" valignment="top" leftline="true" width="0">
3189 <column alignment="center" valignment="top" leftline="true" width="0">
3190 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
3191 <row topline="true" bottomline="true">
3192 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3193 \begin_inset Text
3194
3195 \layout Standard
3196
3197 \end_inset 
3198 </cell>
3199 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3200 \begin_inset Text
3201
3202 \layout Standard
3203
3204 Lists
3205 \end_inset 
3206 </cell>
3207 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3208 \begin_inset Text
3209
3210 \layout Standard
3211
3212 Vectors
3213 \end_inset 
3214 </cell>
3215 </row>
3216 <row topline="true">
3217 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3218 \begin_inset Text
3219
3220 \layout Standard
3221
3222 Random access of an index
3223 \end_inset 
3224 </cell>
3225 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3226 \begin_inset Text
3227
3228 \layout Standard
3229
3230 linear time
3231 \end_inset 
3232 </cell>
3233 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3234 \begin_inset Text
3235
3236 \layout Standard
3237
3238 constant time
3239 \end_inset 
3240 </cell>
3241 </row>
3242 <row topline="true">
3243 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3244 \begin_inset Text
3245
3246 \layout Standard
3247
3248 Add new element at start
3249 \end_inset 
3250 </cell>
3251 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3252 \begin_inset Text
3253
3254 \layout Standard
3255
3256 constant time
3257 \end_inset 
3258 </cell>
3259 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3260 \begin_inset Text
3261
3262 \layout Standard
3263
3264 linear time
3265 \end_inset 
3266 </cell>
3267 </row>
3268 <row topline="true" bottomline="true">
3269 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3270 \begin_inset Text
3271
3272 \layout Standard
3273
3274 Add new element at end
3275 \end_inset 
3276 </cell>
3277 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
3278 \begin_inset Text
3279
3280 \layout Standard
3281
3282 linear time
3283 \end_inset 
3284 </cell>
3285 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
3286 \begin_inset Text
3287
3288 \layout Standard
3289
3290 constant time
3291 \end_inset 
3292 </cell>
3293 </row>
3294 </lyxtabular>
3295
3296 \end_inset 
3297
3298
3299 \layout Standard
3300
3301 When using vectors, you need to pass around a vector and an index -- when
3302  working with lists, often only a list head is passed around.
3303  For this reason, if you need a sequence for iteration only, a list is a
3304  better choice because the list vocabulary contains a rich collection of
3305  recursive words.
3306 \layout Standard
3307
3308 On the other hand, when you need to maintain your own 
3309 \begin_inset Quotes eld
3310 \end_inset 
3311
3312 stack
3313 \begin_inset Quotes erd
3314 \end_inset 
3315
3316 -like collection, a vector is the obvious choice, since most pushes and
3317  pops can then avoid allocating memory.
3318 \layout Standard
3319
3320 Vectors and lists can be converted back and forth using the 
3321 \family typewriter 
3322 vector>list
3323 \family default 
3324  word 
3325 \family typewriter 
3326 ( vector -- list )
3327 \family default 
3328  and the 
3329 \family typewriter 
3330 list>vector
3331 \family default 
3332  word 
3333 \family typewriter 
3334 ( list -- vector )
3335 \family default 
3336 .
3337 \layout Subsection
3338
3339 Vector manipulation
3340 \layout Standard
3341
3342
3343 \family typewriter 
3344 <vector> ( capacity -- vector )
3345 \family default 
3346  pushes a zero-length vector.
3347  Storing more elements than the initial capacity grows the vector.
3348 \layout Standard
3349
3350
3351 \family typewriter 
3352 vector-nth ( index vector -- obj )
3353 \family default 
3354  pushes the object stored at a zero-based index of a vector:
3355 \layout LyX-Code
3356
3357 0 { 
3358 \begin_inset Quotes eld
3359 \end_inset 
3360
3361 zero
3362 \begin_inset Quotes erd
3363 \end_inset 
3364
3365  
3366 \begin_inset Quotes eld
3367 \end_inset 
3368
3369 one
3370 \begin_inset Quotes erd
3371 \end_inset 
3372
3373  } vector-nth .
3374 \layout LyX-Code
3375
3376
3377 \emph on 
3378
3379 \begin_inset Quotes eld
3380 \end_inset 
3381
3382 zero
3383 \begin_inset Quotes erd
3384 \end_inset 
3385
3386
3387 \layout LyX-Code
3388
3389 2 { 1 2 } vector-nth .
3390 \layout LyX-Code
3391
3392
3393 \emph on 
3394 ERROR: Out of bounds
3395 \layout Standard
3396
3397
3398 \family typewriter 
3399 set-vector-nth ( obj index vector -- )
3400 \family default 
3401  stores a value into a vector:
3402 \begin_inset Foot
3403 collapsed false
3404
3405 \layout Standard
3406
3407 The words 
3408 \family typewriter 
3409 get
3410 \family default 
3411  and 
3412 \family typewriter 
3413 set
3414 \family default 
3415  used in this example will be formally introduced later.
3416 \end_inset 
3417
3418
3419 \layout LyX-Code
3420
3421
3422 \begin_inset Quotes eld
3423 \end_inset 
3424
3425 math
3426 \begin_inset Quotes erd
3427 \end_inset 
3428
3429  
3430 \begin_inset Quotes eld
3431 \end_inset 
3432
3433 CS
3434 \begin_inset Quotes erd
3435 \end_inset 
3436
3437  } 
3438 \begin_inset Quotes eld
3439 \end_inset 
3440
3441 v
3442 \begin_inset Quotes erd
3443 \end_inset 
3444
3445  set
3446 \layout LyX-Code
3447
3448
3449 \begin_inset Quotes eld
3450 \end_inset 
3451
3452 philosophy
3453 \begin_inset Quotes erd
3454 \end_inset 
3455
3456  
3457 \begin_inset Quotes eld
3458 \end_inset 
3459
3460 v
3461 \begin_inset Quotes erd
3462 \end_inset 
3463
3464  get set-vector-nth
3465 \layout LyX-Code
3466
3467
3468 \begin_inset Quotes eld
3469 \end_inset 
3470
3471 v
3472 \begin_inset Quotes erd
3473 \end_inset 
3474
3475  get .
3476 \layout LyX-Code
3477
3478
3479 \emph on 
3480
3481 \begin_inset Quotes eld
3482 \end_inset 
3483
3484 math
3485 \begin_inset Quotes erd
3486 \end_inset 
3487
3488  
3489 \begin_inset Quotes eld
3490 \end_inset 
3491
3492 philosophy
3493 \begin_inset Quotes erd
3494 \end_inset 
3495
3496  }
3497 \layout LyX-Code
3498
3499
3500 \begin_inset Quotes eld
3501 \end_inset 
3502
3503 CS
3504 \begin_inset Quotes erd
3505 \end_inset 
3506
3507  
3508 \begin_inset Quotes eld
3509 \end_inset 
3510
3511 v
3512 \begin_inset Quotes erd
3513 \end_inset 
3514
3515  get set-vector-nth
3516 \layout LyX-Code
3517
3518
3519 \begin_inset Quotes eld
3520 \end_inset 
3521
3522 v
3523 \begin_inset Quotes erd
3524 \end_inset 
3525
3526  get .
3527 \layout LyX-Code
3528
3529
3530 \emph on 
3531
3532 \begin_inset Quotes eld
3533 \end_inset 
3534
3535 math
3536 \begin_inset Quotes erd
3537 \end_inset 
3538
3539  
3540 \begin_inset Quotes eld
3541 \end_inset 
3542
3543 philosophy
3544 \begin_inset Quotes erd
3545 \end_inset 
3546
3547  f f 
3548 \begin_inset Quotes eld
3549 \end_inset 
3550
3551 CS
3552 \begin_inset Quotes erd
3553 \end_inset 
3554
3555  }
3556 \layout Standard
3557
3558
3559 \family typewriter 
3560 vector-length ( vector -- length )
3561 \family default 
3562  pushes the number of elements in a vector.
3563  As the previous two examples demonstrate, attempting to fetch beyond the
3564  end of the vector will raise an error, while storing beyond the end will
3565  grow the vector as necessary.
3566 \layout Standard
3567
3568
3569 \family typewriter 
3570 set-vector-length ( length vector -- )
3571 \family default 
3572  resizes a vector.
3573  If the new length is larger than the current length, the vector grows if
3574  necessary, and the new cells are filled with 
3575 \family typewriter 
3576 f
3577 \family default 
3578 .
3579 \layout Standard
3580
3581
3582 \family typewriter 
3583 vector-push ( obj vector -- )
3584 \family default 
3585  adds an object at the end of the vector.
3586  This increments the vector's length by one.
3587 \layout Standard
3588
3589
3590 \family typewriter 
3591 vector-pop ( vector -- obj )
3592 \family default 
3593  removes the object at the end of the vector and pushes it.
3594  This decrements the vector's length by one.
3595 \layout Subsection
3596
3597 Vector combinators
3598 \layout Standard
3599
3600 vector-each, vector-map
3601 \layout Section
3602
3603 Strings
3604 \layout Subsection
3605
3606 Strings are character vectors
3607 \layout Standard
3608
3609 str-nth, str-length, substring, ...
3610 \layout Subsection
3611
3612 String buffers are mutable
3613 \layout Standard
3614
3615 <sbuf>, sbuf-append, sbuf>str
3616 \layout Standard
3617
3618 Otherwise like a vector:
3619 \layout Standard
3620
3621 sbuf-nth, set-sbuf-nth, sbuf-length, set-sbuf-length
3622 \layout Subsection
3623
3624 String constructors
3625 \layout Standard
3626
3627 <% % %>
3628 \layout Subsection
3629
3630 Printing and reading strings
3631 \layout Standard
3632
3633 print, write, read, turning a string into a number
3634 \layout Section
3635
3636 PRACTICAL: Contractor timesheet
3637 \layout Standard
3638
3639 TODO operations:
3640 \layout Standard
3641
3642 - print a time difference as hours:minutes
3643 \layout Standard
3644
3645 - begin work
3646 \layout Standard
3647
3648 - end work & annotate
3649 \layout Standard
3650
3651 - print an invoice, takes hourly rate as a parameter.
3652  do simple formatted output, using 'spaces' and 'pad-string'.
3653 \layout Standard
3654
3655 use a vector to store [ annotation | time ] pairs, pass the vector in
3656 \layout Section
3657
3658 Organization
3659 \layout Subsection
3660
3661 Hashtables
3662 \layout Subsection
3663
3664 Namespaces
3665 \layout Subsection
3666
3667 The name stack
3668 \layout Subsection
3669
3670 The inspector
3671 \layout Section
3672
3673 PRACTICAL: Music player
3674 \layout Section
3675
3676 Deeper in the beast
3677 \layout Standard
3678
3679 Text -> objects - parser, objects -> text - unparser for atoms, prettyprinter
3680  for collections.
3681 \layout Standard
3682
3683 What really is a word -- primitive, parameter, property list.
3684 \layout Standard
3685
3686 Call stack how it works and >r/r>
3687 \layout Subsection
3688
3689 Parsing words
3690 \layout Standard
3691
3692 Lets take a closer look at Factor syntax.
3693  Consider a simple expression, and the result of evaluating it in the interactiv
3694 e interpreter:
3695 \layout LyX-Code
3696
3697 2 3 + .
3698 \layout LyX-Code
3699
3700
3701 \emph on 
3702 5
3703 \layout Standard
3704
3705 The interactive interpreter is basically an infinite loop.
3706  It reads a line of input from the terminal, parses this line to produce
3707  a 
3708 \emph on 
3709 quotation
3710 \emph default 
3711 , and executes the quotation.
3712 \layout Standard
3713
3714 In the parse step, the input text is tokenized into a sequence of white
3715  space-separated tokens.
3716  First, the interpreter checks if there is an existing word named by the
3717  token.
3718  If there is no such word, the interpreter instead treats the token as a
3719  number.
3720 \begin_inset Foot
3721 collapsed false
3722
3723 \layout Standard
3724
3725 Of course, Factor supports a full range of data types, including strings,
3726  lists and vectors.
3727  Their source representations are still built from numbers and words, however.
3728 \end_inset 
3729
3730
3731 \layout Standard
3732
3733 Once the expression has been entirely parsed, the interactive interpreter
3734  executes it.
3735 \layout Standard
3736
3737 This parse time/run time distinction is important, because words fall into
3738  two categories; 
3739 \begin_inset Quotes eld
3740 \end_inset 
3741
3742 parsing words
3743 \begin_inset Quotes erd
3744 \end_inset 
3745
3746  and 
3747 \begin_inset Quotes eld
3748 \end_inset 
3749
3750 running words
3751 \begin_inset Quotes erd
3752 \end_inset 
3753
3754 .
3755 \layout Standard
3756
3757 The parser constructs a parse tree from the input text.
3758  When the parser encounters a token representing a number or an ordinary
3759  word, the token is simply appended to the current parse tree node.
3760  A parsing word on the other hand is executed
3761 \emph on 
3762  
3763 \emph default 
3764 immediately after being tokenized.
3765  Since it executes in the context of the parser, it has access to the raw
3766  input text, the entire parse tree, and other parser structures.
3767 \layout Standard
3768
3769 Parsing words are also defined using colon definitions, except we add 
3770 \family typewriter 
3771 parsing
3772 \family default 
3773  after the terminating 
3774 \family typewriter 
3775 ;
3776 \family default 
3777 .
3778  Here are two examples of definitions for words 
3779 \family typewriter 
3780 foo
3781 \family default 
3782  and 
3783 \family typewriter 
3784 bar
3785 \family default 
3786 , both are identical except in the second example, 
3787 \family typewriter 
3788 foo
3789 \family default 
3790  is defined as a parsing word:
3791 \layout LyX-Code
3792
3793 ! Lets define 'foo' as a running word.
3794 \layout LyX-Code
3795
3796 : foo 
3797 \begin_inset Quotes eld
3798 \end_inset 
3799
3800 1) foo executed.
3801 \begin_inset Quotes erd
3802 \end_inset 
3803
3804  print ;
3805 \layout LyX-Code
3806
3807 : bar foo 
3808 \begin_inset Quotes eld
3809 \end_inset 
3810
3811 2) bar executed.
3812 \begin_inset Quotes erd
3813 \end_inset 
3814
3815  ;
3816 \layout LyX-Code
3817
3818 bar
3819 \layout LyX-Code
3820
3821
3822 \emph on 
3823 1) foo executed
3824 \layout LyX-Code
3825
3826
3827 \emph on 
3828 2) bar executed
3829 \layout LyX-Code
3830
3831 bar
3832 \layout LyX-Code
3833
3834
3835 \emph on 
3836 1) foo executed
3837 \layout LyX-Code
3838
3839
3840 \emph on 
3841 2) bar executed
3842 \layout LyX-Code
3843
3844 \layout LyX-Code
3845
3846 ! Now lets define 'foo' as a parsing word.
3847 \layout LyX-Code
3848
3849 : foo 
3850 \begin_inset Quotes eld
3851 \end_inset 
3852
3853 1) foo executed.
3854 \begin_inset Quotes erd
3855 \end_inset 
3856
3857  print ; parsing
3858 \layout LyX-Code
3859
3860 : bar foo 
3861 \begin_inset Quotes eld
3862 \end_inset 
3863
3864 2) bar executed.
3865 \begin_inset Quotes erd
3866 \end_inset 
3867
3868  ;
3869 \layout LyX-Code
3870
3871
3872 \emph on 
3873 1) foo executed
3874 \layout LyX-Code
3875
3876 bar
3877 \layout LyX-Code
3878
3879
3880 \emph on 
3881 2) bar executed
3882 \layout LyX-Code
3883
3884 bar
3885 \layout LyX-Code
3886
3887
3888 \emph on 
3889 2) bar executed
3890 \layout Standard
3891
3892 In fact, the word 
3893 \family typewriter 
3894
3895 \begin_inset Quotes eld
3896 \end_inset 
3897
3898  
3899 \family default 
3900 that denotes a string literal is a parsing word -- it reads characters from
3901  the input text until the next occurrence of 
3902 \family typewriter 
3903
3904 \begin_inset Quotes eld
3905 \end_inset 
3906
3907
3908 \family default 
3909 , and appends this string to the current node of the parse tree.
3910  Note that strings and words are different types of objects.
3911  Strings are covered in great detail later.
3912 \layout Section
3913
3914 PRACTICAL: Infix syntax
3915 \layout Section
3916
3917 Continuations
3918 \layout Standard
3919
3920 Generators, co-routines, multitasking, exception handling
3921 \layout Section
3922
3923 HTTP Server
3924 \layout Section
3925
3926 PRACTICAL: Some web app
3927 \the_end