about summary refs log blame commit diff stats
path: root/js/games/nluqo.github.io/~bh/ssch20/io
blob: c5e962306310852cffab031451cfae9870d18795 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
aerc(1)

# NAME

aerc - the world's best email client

# SYNOPSIS

_aerc_ [-v]

For a guided tutorial, use *:help tutorial* from aerc, or *man aerc-tutorial*
from your terminal.

# OPTIONS

*-v*
	Prints the installed version of aerc and exits.

# RUNTIME COMMANDS

To execute a command, press ':' to bring up the command interface. Commands may
also be bound to keys, see *aerc-config*(5) for details. In some contexts, such
as the terminal emulator, '<c-x>' is used to bring up the command interface.

Different commands work in different contexts, depending on the kind of tab you
have selected.

Aerc stores a history of commands, which can be cycled through in command mode.
Pressing the up key cycles backwards in history, while pressing down cycles
forwards.

## GLOBAL COMMANDS

These commands work in any context.

*cd* <directory>
	Changes aerc's current working directory.

*change-tab* [+|-]<tab name or index>
	Changes the focus to the tab with the given name. If a number is given,
	it's treated as an index. If + or - is specified, the number is interpreted
	as a delta from the selected tab.

*exec* <command...>
	Executes an arbitrary command in the background.

	*Note*: commands executed in this way are not executed with the shell.

*pwd*
	Displays aerc's current working directory in the status bar.

*set* <category>.<option> <value>
	Changes the value of a configuration paramter at runtime. The category is
	the name of the [heading] for the config option you wish to change, and the
	option is the name of the config option. For example, to change this option:

	\[ui]++
	index-format=before

	Use :set ui.index-format after.

*term* [command...]
	Opens a new terminal tab with a shell running in the current working
	directory, or the specified command.

*prev-tab* [n], *next-tab* [n]
	Cycles to the previous or next tab in the list, repeating n times
	(default: 1).

*prompt* <prompt> <command...>
	Displays the prompt on the status bar, waits for user input, then appends
	that input as the last argument to the command and executes it. The input is
	passed as one argument to the command, unless it is empty, in which case no
	extra argument is added.

*quit*
	Exits aerc.

## MESSAGE COMMANDS

These commands are valid in any context that has a selected message (e.g. the
message list, the message in the message viewer, etc).

*archive* <scheme>
	Moves the selected message to the archive. The available schemes are:

	*flat*: No special structure, all messages in the archive directory

	*year*: Messages are stored in folders per year

	*month*: Messages are stored in folders per year and subfolders per month

*copy* <target>
	Copies the selected message to the target folder.

*delete*
	Deletes the selected message.

*forward* [-A] [address...]
	Opens the composer to forward the selected message to another recipient.

	*-A*: Forward the message as an RFC 8022 attachment.

*move* <target>
	Moves the selected message to the target folder.

*pipe* [-bmp] <cmd>
	Downloads and pipes the selected message into the given shell command, and
	opens a new terminal tab to show the result. By default, the selected
	message part is used in the message viewer and the full message is used in
	the message list.

	*-b*: Run the command in the background instead of opening a terminal tab

	*-m*: Pipe the full message

	*-p*: Pipe just the selected message part, if applicable

*reply* [-aq]
	Opens the composer to reply to the selected message.

	*-a*: Reply all

	*-q*: Insert a quoted version of the selected message into the reply editor

*read*
	Marks the selected message as read.

	*-t*: Toggle the selected message between read and unread.

*unread*
	Marks the selected message as unread.

	*-t*: Toggle the selected message between read and unread.

*modify-labels* <[+-]label>...
	Modify message labels (e.g. notmuch tags). Labels prefixed with a '+' are
	added, those prefixed with a '-' removed. As a convenience, labels without
	either operand add the specified label.

	Example: `modify-labels +inbox -spam unread` adds the labels inbox and unread
	and removes spam

*unsubscribe*
	Attempt to automatically unsubscribe the user from the mailing list through
	use of the List-Unsubscribe header. If supported, aerc may open a compose
	window pre-filled with the unsubscribe information or open the unsubscribe
	URL in a web browser.

## MESSAGE LIST COMMANDS

*clear*
	Clears the current search or filter criteria.

*cf* <folder>
	Change the folder shown in the message list.

*compose* [-H] [<body>]
	Open the compose window to send a new email. The new email will be sent with
	the current account's outgoing transport configuration. For details on
	configuring outgoing mail delivery consult *aerc-config*(5).

	*-H* <header>
		Add the specified header to the message, e.g. 'compose -H "X-Custom: custom
		value"'

*filter* [options] <terms...>
	Similar to *search*, but filters the displayed messages to only the search
	results. See the documentation for *search* for more details.

*mkdir* <name>
	Creates a new folder for this account and changes to that folder.

*next* <n>[%], *prev* <n>[%]
	Selects the next (or previous) message in the message list. If specified as
	a percentage, the percentage is applied to the number of messages shown on
	screen and the cursor advances that far.

*next-folder* <n>, *prev-folder* <n>
	Cycles to the next (or previous) folder shown in the sidebar, repeated n
	times (default: 1).

*next-result*, *prev-result*
	Selects the next or previous search result.

*search*
	Searches the current folder.
	The search syntax is dependant on the underlying backend.
	Refer to *aerc-search*(1) for details

*select* <n>
	Selects the nth message in the message list (and scrolls it into view if
	necessary).

*sort* [[-r] <criterion>]...
	Sorts the message list by the given criteria. *-r* sorts the
	immediately following criterion in reverse order.

	Available criteria:

[[ *Criterion*
:- *Description*
|  arrival
:- Date and time of the messages arrival
|  cc
:- Addresses in the "cc" field
|  date
:- Date and time of the message
|  from
:- Addresses in the "from" field
|  read
:- Presence of the read flag
|  size
:- Size of the message
|  subject
:- Subject of the message
|  to
:- Addresses in the "to" field

*view*
	Opens the message viewer to display the selected message.

## MESSAGE VIEW COMMANDS

*close*
	Closes the message viewer.

*next* <n>[%], *prev* <n>[%]
	Selects the next (or previous) message in the message list. If specified as
	a percentage, the percentage is applied to the number of messages shown on
	screen and the cursor advances that far.

*next-part*, *prev-part*
	Cycles between message parts being shown. The list of message parts is shown
	at the bottom of the message viewer.

*open*
	Saves the current message part in a temporary file and opens it
	with the system handler.

*save* [-p] <path>
	Saves the current message part to the given path.

	If no path is given but general.default-save-path is set, the
	file will be saved there.

	*-p*: Make any directories in the path that do not exist

## MESSAGE COMPOSE COMMANDS

*abort*
	Close the composor without sending, discarding the message in progress.

*attach* <path>
	Attaches the file at the given path to the email.

*detach* [path]
	Detaches the file with the given path from the composed email. If no path is
	specified, detaches the first attachment instead.

*cc* [addresses], *bcc* [addresses]
	Sets the Cc or Bcc header to the given addresses. If an editor for the header
	is not currently visible in the compose window, a new one will be added.

*edit*
	(Re-) opens your text editor to edit the message in progress.

*next-field*, *prev-field*
	Cycles between input fields in the compose window.

*save* [-p] <path>
	Saves the selected message part to the specified path. If -p is selected,
	aerc will create any missing directories in the specified path. If the path
	specified is a directory or ends in /, aerc will use the attachment filename
	if available or a generated name if not.

*send*
	Sends the message using this accounts default outgoing transport
	configuration. For details on configuring outgoing mail delivery consult
	*aerc-config*(5).

*toggle-headers*
	Toggles the visibility of the message headers.

## TERMINAL COMMANDS

*close*
	Closes the terminal.

# LOGGING

Aerc does not log by default, but collecting log output can be useful for
troubleshooting and reporting issues. Redirecting stdout when invoking aerc will
write log messages to that file:

	$ aerc > log

# SEE ALSO

*aerc-config*(5) *aerc-imap*(5) *aerc-smtp*(5) *aerc-maildir*(5)
*aerc-sendmail*(5) *aerc-tutorial*(7)

# AUTHORS

Maintained by Drew DeVault <sir@cmpwn.com>, who is assisted by other open
source contributors. For more information about aerc development, see
https://git.sr.ht/~sircmpwn/aerc.
d='n744' href='#n744'>744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































                                                                               
\input bkmacs
\pagetag{\typing}
\photo{}{\pspicture{4in}{io}{io}{}\vfill}
\chapter{Input and Output}
\chaptag{\io}


In the tic-tac-toe project in Chapter \ttt, we didn't write a complete game
program.  We wrote a {\it function\/} that took a board position and {\tt x}
or {\tt o} as arguments, returning the next move.  We noted at the time that
a complete game program would also need to carry on a {\it conversation\/}
with the user.  Instead of computing and returning one single value, a
\bkidx{conversational}{program} must carry out a sequence of events in time,
reading information from the \idx{keyboard} and displaying other information
on the \idx{screen}.

Before we complete the tic-tac-toe project, we'll start by
exploring Scheme's mechanisms for \bkidx{interactive}{programming}.

\backskipsubhd{Printing}{5}
\justidx{printing}

Up until now, we've never told Scheme to print anything.  The programs we've
written have computed values and returned them; we've relied on the
\idx{read-eval-print loop} to print these values.\footnt{The only
exception is that we've used {\tt trace}, which prints messages about
the progress of a computation.}

But let's say we want to write a program to print out all of the words to
``99 Bottles of Beer on the Wall.'' We could implement a function to produce a
humongous {\it list\/} of the lines of the song, like this:

{\prgex%
(define (bottles n)
  (if (= n 0)
      '()
      (append (verse n)
	      (bottles (- n 1)))))
}

{\medskipamount=4pt\prgexskipamount=9pt\prgexbaselineamount=10pt
{\prgex%
(define (verse n)
  (list (cons n '(bottles of beer on the wall))
	(cons n '(bottles of beer))
	'(if one of those bottles should happen to fall)
	(cons (- n 1) '(bottles of beer on the wall))
	'()))

> (bottles 3)
((3 BOTTLES OF BEER ON THE WALL)
 (3 BOTTLES OF BEER)
 (IF ONE OF THOSE BOTTLES SHOULD HAPPEN TO FALL)
 (2 BOTTLES OF BEER ON THE WALL)
 ()
 (2 BOTTLES OF BEER ON THE WALL)
 (2 BOTTLES OF BEER)
 (IF ONE OF THOSE BOTTLES SHOULD HAPPEN TO FALL)
 (1 BOTTLES OF BEER ON THE WALL)
 ()
 (1 BOTTLES OF BEER ON THE WALL)
 (1 BOTTLES OF BEER)
 (IF ONE OF THOSE BOTTLES SHOULD HAPPEN TO FALL)
 (0 BOTTLES OF BEER ON THE WALL)
 ())
}

\noindent The problem is that we don't want a list.  All we
want is to print out the lines of the song; storing them in a data structure
is unnecessary and inefficient.  Also, some versions of Scheme would print
the above list like this:

{\prgex%
((3 BOTTLES OF BEER ON THE WALL) (3 BOTTLES OF BEER) (IF ONE OF
 THOSE BOTTLES SHOULD HAPPEN TO FALL) (2 BOTTLES OF BEER ON THE
 WALL) () (2 BOTTLES OF BEER ON THE WALL) (2 BOTTLES OF BEER) (IF
 ONE OF THOSE BOTTLES SHOULD HAPPEN TO FALL) (1 BOTTLES OF BEER ON
 THE WALL) () (1 BOTTLES OF BEER ON THE WALL) (1 BOTTLES OF BEER)
 (IF ONE OF THOSE BOTTLES SHOULD HAPPEN TO FALL) (0 BOTTLES OF BEER
 ON THE WALL) ())
}

\noindent or even all on one line.  We can't rely on Scheme's mechanism for
printing lists if we want to be sure of a particular arrangement on the
screen.

Instead we'll write a program to {\it print\/} a verse, rather
than return it in a list:
\justtt{show}

{\prgex%
(define (\ufun{bottles} n)
  (if (= n 0)
      'burp
      (begin (verse n)
	     (bottles (- n 1)))))

(define (\ufun{verse} n)
  (show (cons n '(bottles of beer on the wall)))
  (show (cons n '(bottles of beer)))
  (show '(if one of those bottles should happen to fall))
  (show (cons (- n 1) '(bottles of beer on the wall)))
  (show '()))

> (bottles 3)
(3 BOTTLES OF BEER ON THE WALL)
(3 BOTTLES OF BEER)
(IF ONE OF THOSE BOTTLES SHOULD HAPPEN TO FALL)
(2 BOTTLES OF BEER ON THE WALL)
()
(2 BOTTLES OF BEER ON THE WALL)
(2 BOTTLES OF BEER)
(IF ONE OF THOSE BOTTLES SHOULD HAPPEN TO FALL)
(1 BOTTLES OF BEER ON THE WALL)
()
(1 BOTTLES OF BEER ON THE WALL)
(1 BOTTLES OF BEER)
(IF ONE OF THOSE BOTTLES SHOULD HAPPEN TO FALL)
(0 BOTTLES OF BEER ON THE WALL)
()
BURP
}

} % skip kludges

\noindent Notice that Scheme doesn't print an outer set of parentheses.
Each line was printed separately; there isn't one big list containing all of
them.\footnt{We know that it's still not as beautiful as can be, because of
the capital letters and parentheses, but we'll get to that later.}

Why was ``burp''\ printed at the end?  Just because we're printing things
explicitly doesn't mean that the read-eval-print loop stops functioning.  We
typed the expression {\tt (bottles~3)}.  In the course of evaluating that
expression, Scheme printed several lines for us.  But the {\it value\/} of
the expression was the word {\tt burp}, because that's what {\tt bottles}
returned.

\subhd{Side Effects and Sequencing}

How does our program work?  There are two new ideas here:\ {\it
\bkidx{side}{effect}s\/} and {\it sequencing.}

Until now, whenever we've invoked a procedure, our only goal has been to get
a return value.  The procedures we've used compute and return a value, and do
nothing else.  {\tt Show} is different.  Although every Scheme procedure
returns a value, the Scheme language standard doesn't specify what
value the printing procedures should return.\footnt{Suppose {\tt show}
returns {\tt \#f} in your version of Scheme.  Then you might see

{\prgex%
> (show 7)
7
#F
}

\noindent But since the return value is unspecified, we try to write
programs in such a way that we never use {\tt show}'s return value as the
return value from our procedures.  That's why we return values like {\tt
burp}.} Instead, we are interested in their side effects.  In other words,
we invoke {\tt show} because we want it to {\it do\/} something, namely,
print its argument on the screen.

What exactly do we mean by ``side effect''?  The kinds of procedures that
we've used before this chapter can compute values, invoke helper procedures,
provide arguments to the helper procedures, and return a value.  There may be
a lot of activity going on within the procedure, but the procedure
affects the world outside of itself only by returning a value that some
other procedure might use.  {\tt Show} affects the world outside of itself
by putting something on the screen.  After {\tt show} has finished its
work, someone who looks at the screen can tell that {\tt show} was
used.\footnt{The term {\it side\/} effect is based on the idea that a
procedure may have a useful return value as its main purpose and may also
have an effect ``on the side.'' It's a misnomer to talk about the
side effect of {\tt show}, since the effect is its main purpose.  But nobody
ever says ``side return value''!}

{\medskipamount=4pt\prgexskipamount=9pt\prgexbaselineamount=10pt
\def\psate{\prgexskipamount=8pt}

Here's an example to illustrate the difference between values and effects:

{\prgex%
(define (\ufun{effect} x)
  (show x)
  'done)

(define (\ufun{value} x)
  x)

> (effect '(oh! darling))
(OH! DARLING)
DONE

> (value '(oh! darling))
(OH! DARLING)

> (bf (effect '(oh! darling)))
(OH! DARLING)
ONE\psate

> (bf (value '(oh! darling)))
(DARLING)

> (define (\ufun{lots-of-effect} x)
    (effect x)
    (effect x)
    (effect x))

> (define (\ufun{lots-of-value} x)
    (value x)
    (value x)
    (value x))

> (lots-of-effect '(oh! darling))
(OH! DARLING)
(OH! DARLING)
(OH! DARLING)
DONE

> (lots-of-value '(oh! darling))
(OH! DARLING)
}

} % skip kludge

This example also demonstrates the second new idea,
\idx{sequencing}:  Each of {\tt effect}, {\tt lots-of-effect},
and {\tt lots-of-value} contains more than one expression in
its body.  When you invoke such a procedure, Scheme evaluates all
the expressions in the body, in order, and returns the value of the
last one.\footnt{In Chapter \defining, we said that the body of a
procedure was always one single expression.  We lied.  But as long
as you don't use any procedures with side effects, it doesn't do you
any good to evaluate more than one expression in a body.} This also
works in the body of a {\tt let}, which is really the body of a
procedure, and in each clause of a {\ttidx cond}.\footnt{For example:

{\zfprgex%
> (cond ((< 4 0)
	 (show '(how interesting))
	 (show '(4 is less than zero?))
	 #f)
	((> 4 0)
	 (show '(more reasonable))
	 (show '(4 really is more than zero))
	 'value)
	(else
	 (show '(you mean 4=0?))
	 #f))
(MORE REASONABLE)
(4 REALLY IS MORE THAN ZERO)
VALUE}}

When we invoked {\tt lots-of-value}, Scheme invoked {\tt value} three times;
it discarded the values returned by the first two invocations, and returned
the value from the third invocation.  Similarly, when we invoked {\tt
lots-of-effect}, Scheme invoked {\tt effect} three times and returned the
value from the third invocation.  But each invocation of {\tt effect} caused
its argument to be printed by invoking {\tt show}.

\subhd{The \ttpmb{Begin} Special Form}
\pagetag{\beg}

The {\tt lots-of-effect} procedure accomplished sequencing by having more
than one expression in its body.  This works fine if the sequence of events
that you want to perform is the entire body of a procedure.  But in {\tt
bottles} we wanted to include a sequence as one of the alternatives in an
{\tt if} construction.  We couldn't just say

{\prgex%
(define (bottles n)                          ;; wrong
  (if (= n 0)
      '()
      (verse n)
      (bottles (- n 1))))
}

\noindent because {\tt if} must have exactly three arguments.  Otherwise,
how would {\tt if} know whether we meant {\tt (verse~n)} to be the second
expression in the true case, or the first expression in the false case?

Instead, to turn the sequence of expressions into a single expression, we
use the \bkidx{special}{form} \ttidx{begin}.  It takes any number of
arguments, evaluates them from left to right, and returns the value of the
last one.

{\prgex%
(define bottles n)
  (if (= n 0)
      'burp
      (begin (verse n)
	     (bottles (- n 1)))))
}

\noindent (One way to think about sequences in procedure bodies is that
every procedure body has an invisible {\tt begin} surrounding it.)

\subhd{This Isn't Functional Programming}

Sequencing and side effects are radical departures from the idea of
\bkidx{functional}{programming}.  In fact, we'd like to reserve the name {\it
function\/} for something that computes and returns one value, with no side
effects.  ``Procedure'' is the general term for the thing that {\tt lambda}
returns---an embodiment of an algorithm.  If the algorithm is the kind that
computes and returns a single value without side effects, then we say that
the procedure implements a function.\footnt{Sometimes people sloppily
say that the procedure {\it is\/} a function.  In fact, you may hear people
be {\it really\/} sloppy and call a non-functional procedure a function!}

There is a certain kind of sequencing even in functional programming.  If
you say

{\prgex%
(* (+ 3 4) (- 92 15))
}

\noindent it's clear that the addition has to happen before the
multiplication, because the result of the addition provides one of the
arguments to the multiplication.  What's new in the sequential programming
style is the {\it emphasis\/} on sequence, and the fact that the expressions
in the sequence are {\it independent\/} instead of contributing values to
each other.  In this multiplication problem, for example, we don't care
whether the addition happens before or after the subtraction.  If the
addition and subtraction were in a sequence, we'd be using them for
independent purposes:

{\prgex%
(begin
 (show (+ 3 4))
 (show (- 92 15)))
}

\noindent This is what we mean by being independent.  Neither expression
helps in computing the other.  And the order matters because we can see
the order in which the results are printed.

\subhd{Not Moving to the Next Line}

Each invocation of {\tt show} prints a separate line.  What if we
want a program that prints several things on the same line, like this:

{\prgex%
> (begin (show-addition 3 4)
	 (show-addition 6 8)
	 'done)
3+4=7
6+8=14
DONE
}

\noindent We use \ttidx{display}, which doesn't move to the next line after
printing its argument:

{\prgex%
(define (\ufun{show-addition} x y)
  (display x)
  (display '+)
  (display y)
  (display '=)
  (show (+ x y)))
}

\noindent (The last one is a {\tt show} because we {\it do\/} want to start
a new line after it.)

What if you just want to print a blank line?  You use \ttidx{newline}:

{\prgex%
(define (verse n)
  (show (cons n '(bottles of beer on the wall)))
  (show (cons n '(bottles of beer)))
  (show '(if one of those bottles should happen to fall))
  (show (cons (- n 1) '(bottles of beer on the wall)))
  (newline))                                 ; replaces (show '())
}

In fact, {\tt show} isn't an official Scheme primitive; we wrote it
in terms of {\tt display} and {\tt newline}.

\subhd{Strings}

Throughout the book we've occasionally used strings, that is, words enclosed in
double-quote marks so that Scheme will permit the use of punctuation or other
unusual characters.  Strings also preserve the case of letters, so they can
be used to beautify our song even more.  Since {\it any\/} character can be
in a \idx{string}, including spaces, the easiest thing to do in this case is
to treat all the letters, spaces, and punctuation characters of each line of
the song as one long word.  (If we wanted to be able to compute functions of
the individual words in each line, that wouldn't be such a good idea.)

{\prgex%
(define (\ufun{verse} n)
  (display n)
  (show " bottles of beer on the wall,")
  (display n)
  (show " bottles of beer.")
  (show "If one of those bottles should happen to fall,")
  (display (- n 1))
  (show " bottles of beer on the wall.")
  (newline))
}

{\medskipamount=4pt\prgexskipamount=8pt\prgexbaselineamount=10pt
{\prgex%
> (verse 6)
6 bottles of beer on the wall,
6 bottles of beer.
If one of those bottles should happen to fall,
5 bottles of beer on the wall.

#F                               ; or whatever is returned by (newline)
}

% \def\vb{\vispc\penalty 0{}}
% \def\vb{\_}
\def\vb{\ }
\noindent It's strange to think of ``{\tt\vb bottles\vb of\vb
beer\vb on\vb the\vb wall,}'' as a single word.  But the rule is that
anything inside double quotes counts as a single word.  It doesn't have to
be an English word.

\backskipsubhd{A Higher-Order Procedure for Sequencing}{8}

Sometimes we want to print each element of a list separately:

{\prgex%
(define (\ufun{show-list} lst)
  (if (null? lst)
      'done
      (begin (show (car lst))
	     (show-list (cdr lst)))))

> (show-list '((dig a pony) (doctor robert) (for you blue)))
(DIG A PONY)
(DOCTOR ROBERT)
(FOR YOU BLUE)
DONE
}

Like other patterns of computation involving lists, this one can be
abstracted into a higher-order procedure.  (We can't call it a
``higher-order function'' because this one is for computations with side
effects.)  The procedure {\tt \ttidx{for-each}} is part of standard Scheme:

{\prgex%
> (for-each show '((mean mr mustard) (no reply) (tell me why)))
(MEAN MR MUSTARD)
(NO REPLY)
(TELL ME WHY)
}

\noindent The value returned by {\tt for-each} is unspecified.

Why couldn't we just use {\tt map} for this purpose?  There are two reasons.
One is just an efficiency issue:  {\tt Map} constructs a list containing the
values returned by each of its sub-computations; in this example, it would
be a list of three instances of the unspecified value returned by {\tt
show}. But we aren't going to use that list for anything, so there's no
point in constructing it.  The second reason is more serious.  In functional
programming, the order of evaluation of subexpressions is unspecified.  For
example, when we evaluate the expression

{\prgex%
(- (+ 4 5) (* 6 7))
}

\noindent we don't know whether the addition or the multiplication happens
first.  Similarly, the order in which {\tt map} computes the results for
each element is unspecified.  That's okay as long as the ultimately returned
list of results is in the right order.  But when we are using side effects,
we {\it do\/} care about the order of evaluation.  In this case, we want
to make sure that the elements of the argument list are printed from left to
right.  {\tt For-each} guarantees this ordering.

\backskipsubhd{Tic-Tac-Toe Revisited}{8}

We're working up toward playing a game of tic-tac-toe against the computer.
But as a first step, let's have the computer play against itself.  What we
already have is {\tt ttt}, a {\it strategy\/} function:\ one that takes a
board position as argument (and also a letter {\tt x} or {\tt o}) and
returns the chosen next move.  In order to play a game of tic-tac-toe, we
need two players; to make it more interesting, each should have its own
strategy.  So we'll write another one, quickly, that just moves in the first
empty square it sees:

{\prgex%
(define (\ufun{stupid-ttt} position letter)
  (location '_ position))

(define (\ufun{location} letter word)
  (if (equal? letter (first word))
      1
      (+ 1 (location letter (bf word)))))
}

Now we can write a program that takes two strategies as arguments and
actually plays a game between them.

{\prgex%
(define (\ufun{play-ttt} x-strat o-strat)
  (play-ttt-helper x-strat o-strat '_________ 'x))

(define (\ufun{play-ttt-helper} x-strat o-strat position whose-turn)
  (cond ((already-won? position (opponent whose-turn))
	 (list (opponent whose-turn) 'wins!))
	((tie-game? position) '(tie game))
	(else (let ((square (if (equal? whose-turn 'x)
				(x-strat position 'x)
				(o-strat position 'o))))
		(play-ttt-helper x-strat
				 o-strat
				 (add-move square whose-turn position)
				 (opponent whose-turn))))))
}
} % skip kludge

\noindent We use a helper procedure because we need to keep track of two
pieces of information besides the strategy procedures:\ the current board
position and whose turn it is ({\tt x} or {\tt o}).  The helper procedure
is invoked recursively for each move.  First it checks whether the game
is already over (won or tied).\footnt{You wrote the procedures {\tt
already-won?}\ and {\tt tie-game?}\ in Exercises \tttwon\ and \ttttied:

{\prgex%
(define (\ufun{already-won?} position who)
  (member? (word who who who)  (find-triples position)))

(define (\ufun{tie-game?} position)
  (not (member? '_ position)))
}}
If not, the helper procedure invokes the current player's strategy procedure,
which returns the square number for the next move.  For the recursive call,
the arguments are the same two strategies, the new position after the move,
and the letter for the other player.

We still need {\tt add-move}, the procedure that takes a square and an old
position as arguments and returns the new position.

{\prgex%
(define (\ufun{add-move} square letter position)
  (if (= square 1)
      (word letter (bf position))
      (word (first position)
	    (add-move (- square 1) letter (bf position)))))

> (play-ttt ttt stupid-ttt)
(X WINS!)

> (play-ttt stupid-ttt ttt)
(O WINS!)
}

\subhd{Accepting User Input}

The work we did in the last section was purely functional.  We didn't print
anything (except the ultimate return value, as always) and we didn't
have to read information from a human player, because there wasn't one.

You might expect that the structure of an {\it interactive\/} game program
would be very different, with a top-level procedure full of sequential
operations.  But the fact is that we hardly have to change anything to turn
this into an interactive game.  All we need is a new ``strategy'' procedure
that asks the user where to move, instead of computing a move based on
built-in rules.

{\prgex%
(define (\ufun{ask-user} position letter)
  (print-position position)
  (display letter)
  (display "'s move: ")
  (read))

(define (print-position position)            ;; first version
  (show position))
}

\noindent (Ultimately we're going to want a beautiful two-dimensional
display of the current position, but we don't want to get distracted by that
just now.  That's why we've written a trivial temporary version.)

{\prgex%
> (play-ttt ttt ask-user)
____X____
O'S MOVE: \pmb{1}
O___XX___
O'S MOVE: \pmb{4}
O__OXXX__
O'S MOVE: \pmb{3}
OXOOXXX__
O'S MOVE: \pmb{8}
(TIE GAME)
}

\noindent What the user typed is just the single digits shown in boldface at
the ends of the lines.

What's new here is that we invoke the procedure \ttidx{read}.  It waits for
you to type a Scheme expression, and returns that expression.  Don't
be confused:  {\tt Read} does {\it not\/} evaluate what you type.  It
returns exactly the same expression that you type:

{\prgex%
(define (\ufun{echo})
  (display "What? ")
  (let ((expr (read)))
    (if (equal? expr 'stop)
	'okay
	(begin
	 (show expr)
	 (echo)))))
}

{\medskipamount=2pt\prgexskipamount=7.5pt\prgexbaselineamount=10pt
{\prgex%
> (echo)
What? \pmb{hello}
HELLO
What? \pmb{(+ 2 3)}
(+ 2 3)
What? \pmb{(first (glass onion))}
(FIRST (GLASS ONION))
What? \pmb{stop}
OKAY
}

\backskipsubhd{Aesthetic Board Display}{9}

Here's our beautiful position printer:

{%\setbox2=\hbox{{\ninett +}}\catcode`+=\active\def+{\lower1pt\copy2}

{\prgex%
(define (\ufun{print-position} position)
  (print-row (subword position 1 3))
  (show "-+-+-")
  (print-row (subword position 4 6))
  (show "-+-+-")
  (print-row (subword position 7 9))
  (newline))

(define (\ufun{print-row} row)
  (maybe-display (first row))
  (display "|")
  (maybe-display (first (bf row)))
  (display "|")
  (maybe-display (last row))
  (newline))

(define (\ufun{maybe-display} letter)
  (if (not (equal? letter '_))
      (display letter)
      (display " ")))

(define (\ufun{subword} wd start end)
  ((repeated bf (- start 1))
   ((repeated bl (- (count wd) end))
    wd)))\pgfoot
\nobreak}
\nobreak\vfootnt{Alternate version:
\def\fpskip{\vskip 5pt\relax}
{\prgex\fprgexbaselineamount=9.5pt%
(define (subword wd start end)
  (cond ((> start 1) (subword (bf wd) (- start 1) (- end 1)))
	((< end (count wd)) (subword (bl wd) start end))
	(else wd)))
}

\noindent You can take your choice, depending on which you think is easier,
recursion or higher-order functions.
}
} % skip kludge

Here's how it works:

{\prgex%
> (print-position '_x_oo__xx)
 |X| 
-+-+-
O|O| 
-+-+-
 |X|X
}
} %%%%%%%%% active + kludge %%%%%%%%%%%%%

\subhd{Reading and Writing Normal Text}

The {\tt read} procedure works fine as long as what you type looks like a
Lisp program.  That is, it reads one expression at a time.  In the
tic-tac-toe program the user types a single number, which is a Scheme
expression, so {\tt read} works fine.  But what if we want to read more than
one word?

{\prgex%
(define (music-critic)                       ;; first version
  (show "What's your favorite Beatles song?")
  (let ((song (read)))
    (show (se "I like" song "too."))))

> (music-critic)
What's your favorite Beatles song?
\pmb{She Loves You}
(I like SHE too.)
}

\noindent If the user had typed the song title in parentheses, then it would
have been a single Scheme expression and {\tt read} would have accepted it.
But we don't want the users of our program to have to be typing parentheses
all the time.

Scheme also lets you read one character at a time.  This allows you to read
any text, with no constraints on its format.  The disadvantage is that you
find yourself putting a lot of effort into minor details.  We've provided a
procedure {\tt \ttidx{read-line}} that reads one line of input and returns a
sentence.  The words in that sentence will contain any punctuation
characters that appear on the line, including parentheses, which are not
interpreted as sublist delimiters by {\tt read-line}.  {\tt Read-line} also
preserves the case of letters.

{\prgex%
(define (music-critic)                       ;; second version
  (read-line)   ; See explanation on next page.
  (show "What's your favorite Beatles song?")
  (let ((song (read-line)))
    (show (se "I like" song "too."))))

> (music-critic)
What's your favorite Beatles song?
\pmb{She Loves You}
(I like She Loves You too.)
}

\noindent Why do we call {\tt read-line} and ignore its result at the
beginning of {\tt music-critic}?  It has to do with the interaction between
{\tt read-line} and {\tt read}.  {\tt Read} treats what you type as a
sequence of Scheme expressions; each invocation of {\tt read} reads one of
them.  {\tt Read} pays no attention to formatting details, such as several
consecutive spaces or line breaks.  If, for example, you type several
expressions on the same line, it will take several invocations of {\tt read}
to read them all.

By contrast, {\tt read-line} treats what you type as a sequence of lines,
reading one line per invocation, so it does pay attention to line breaks.

Either of these ways to read input is sensible in itself, but if you mix
the two, by invoking {\tt read} sometimes and {\tt read-line} sometimes in
the same program, the results can be confusing.  Suppose you type a line
containing an expression and your program invokes {\tt read} to read it.
Since there might have been another expression on the line, {\tt read}
doesn't advance to the next line until you ask for the next
expression.  So if you now invoke {\tt read-line}, thinking that it will
read another line from the keyboard, it will instead return an empty list,
because what it sees is an empty line---what's left after {\tt read} uses up
the expression you typed.

You may be thinking, ``But {\tt music-critic} doesn't call {\tt read}!''
That's true, but Scheme itself used {\tt read} to read the expression that
you used to invoke {\tt music-critic}.  So the first invocation of {\tt
read-line} is needed to skip over the spurious empty line.

Our solution works only if {\tt music-critic} is invoked directly at a
Scheme prompt.  If {\tt music-critic} were a subprocedure of some larger
program that has already called {\tt read-line} before calling {\tt
music-critic}, the extra {\tt read-line} in {\tt music-critic} would really
read and ignore a useful line of text.

If you write a procedure using {\tt read-line} that will sometimes be called
directly and sometimes be used as a subprocedure, you can't include an extra
{\tt read-line} call in it.  Instead, when you call your procedure directly
from the Scheme prompt, you must say

{\prgex%
> (begin (read-line) (my-procedure))
}

Another technical detail about {\tt read-line} is that since
it preserves the capitalization of words, its result may
include strings, which will be shown in quotation marks if you return the
value rather than {\tt show}ing it:

{\prgex%
(define (music-critic-return)
  (read-line)
  (show "What's your favorite Beatles song?")
  (let ((song (read-line)))
    (se "I like" song "too.")))

> (music-critic-return)
What's your favorite Beatles song?
\pmb{She Loves You}
("I like" "She" "Loves" "You" "too.")
}

We have also provided {\tt \ttidx{show-line},} which takes a sentence
as argument.  It prints the sentence without surrounding parentheses,
followed by a newline.  (Actually, it takes any list as argument; it prints
all the parentheses except for the outer ones.)

{\prgex%
(define (\ufun{music-critic})
  (read-line)
  (show "What's your favorite Beatles song?")
  (let ((song (read-line)))
    (show-line (se "I like" song "too."))))

> (music-critic)
What's your favorite Beatles song?
\pmb{She Loves You}
I like She Loves You too.
}

The difference between {\tt show} and {\tt show-line} isn't
crucial.  It's just a matter of a pair of parentheses.  The point is that
{\tt read-line} and {\tt show-line} go together.  {\tt Read-line} reads a
bunch of disconnected words and combines them into a sentence.  {\tt
Show-line} takes a sentence and prints it as if it were a bunch of
disconnected words.  Later, when we read and write files in Chapter
\files, this ability to print in the same form in which we read will be
important.

\subhd{Formatted Text}

We've been concentrating on the use of sequential programming with explicit
\pagetag{\spformat}
printing instructions for the sake of conversational programs.  Another
common application of sequential printing is to display tabular information,
such as columns of numbers.  The difficulty is to get the numbers to line up
so that corresponding digits are in the same position, even when the numbers
have very widely separated values.  The
\ttidx{align} function can be used to convert a number to a printable word
with a fixed number of positions before and after the decimal point:

{\prgex%
(define (square-root-table nums)
  (if (null? nums)
      'done
      (begin (display (align (car nums) 7 1))
	     (show (align (sqrt (car nums)) 10 5))
	     (square-root-table (cdr nums)))))

> (square-root-table '(7 8 9 10 20 98 99 100 101 1234 56789))
    7.0   2.64575
    8.0   2.82843
    9.0   3.00000
   10.0   3.16228
   20.0   4.47214
   98.0   9.89949
   99.0   9.94987
  100.0  10.00000
  101.0  10.04988
 1234.0  35.12834
56789.0 238.30443
DONE
}

\noindent {\tt Align} takes three arguments.  The first is the value to be
displayed.  The second is the width of the column in which it will be
displayed; the returned value will be a word with that many characters in it.
The third argument is the number of digits that should be displayed to the
right of the decimal point.  (If this number is zero, then no decimal point
will be displayed.)  The width must be great enough to include all the
digits, as well as the decimal point and minus sign, if any.

As the program example above indicates, {\tt align} does not print
anything.  It's a function that returns a value suitable for printing with
{\tt display} or {\tt show}.

What if the number is too big to fit in the available space?

{\prgex%
> (align 12345679 4 0)
"123+"
}

\noindent {\tt Align} returns a word containing the first few digits,
as many as fit, ending with a plus sign to indicate that part of the value
is missing.

{\tt Align} can also be used to include non-numeric text in columns.  If
the first argument is not a number, then only two arguments are needed; the
second is the column width.  In this case {\tt align} returns a word with
extra spaces at the right, if necessary, so that the argument word will
appear at the left in its column:

{\prgex%
(define (\ufun{name-table} names)
  (if (null? names)
      'done
      (begin (display (align (cadar names) 11))
	     (show (caar names))
	     (name-table (cdr names)))))

> (name-table '((john lennon) (paul mccartney)
		(george harrison) (ringo starr)))
LENNON     JOHN
MCCARTNEY  PAUL
HARRISON   GEORGE
STARR      RINGO
DONE
}

\noindent As with numbers, if a non-numeric word won't fit in the allowed
space, {\tt align} returns a partial word ending with a plus sign.

This {\tt align} function is not part of standard Scheme.  Most programming
languages, including some versions of Scheme, offer much more elaborate
formatting capabilities with many alternate ways to represent both numbers
and general text.  Our version is a minimal capability to show the flavor
and to meet the needs of projects in this book.

\subhd{Sequential Programming and Order of Evaluation}

Our expanded tic-tac-toe program includes both functional and sequential
parts.  The program computes its strategy functionally but uses sequences
of commands to control the {\it \bkidx{user}{interface}\/} by alternately
printing information to the screen and reading information from the keyboard.

By adding sequential programming to our toolkit, we've increased our ability
to write interactive programs.  But there is a cost that goes along with
this benefit:  We now have to pay more attention to the order of events than
we did in purely functional programs.

The obvious concern about order of events is that sequences of {\tt show}
expressions must come in the order in which we want them to appear, and {\tt
read} expressions must fit into the sequence properly so that the user is
asked for the right information at the right time.

But there is another, less obvious issue about order of events.  When the
evaluation of expressions can have side effects in addition to returning
values, the order of evaluation of argument subexpressions becomes important.
Here's an example to show what we mean.  Suppose we type the expression

{\prgex%
(list (+ 3 4) (- 10 2))
}

\noindent The answer, of course, is {\tt (7~8)}.  It doesn't matter whether
Scheme computes the seven first (left to right) or the eight first (right to
left).  But here's a similar example in which it {\it does\/} matter:

{\prgex%
(define (\ufun{show-and-return} x)
  (show x)
  x)

> (list (show-and-return (+ 3 4)) (show-and-return (- 10 2)))
8
7
(7 8)
}

\noindent The value that's ultimately returned, in this example, is the same
as before.  But the two numeric values that go into the list are also
printed separately, so we can see which is computed first.  (We've shown
the case of right-to-left computation; your Scheme might be different.)

Suppose you want to make sure that the seven prints first, regardless of
which order your Scheme uses.  You could do this:

{\prgex%
> (let ((left (show-and-return (+ 3 4))))
    (list left (show-and-return (- 10 2))))
7
8
(7 8)
}

\noindent The expression in the body of a {\tt let} can't be evaluated until
the {\tt let} variables (such as {\tt left}) have had their values computed.

It's hard to imagine a practical use for the artificial {\tt
show-and-return} procedure, but a similar situation arises whenever we use
{\tt read}.  Suppose we want to write a procedure to ask a person for his or
her full name, returning a two-element list containing the first and last
name.  A natural mistake to make would be to write this procedure:

{\prgex%
(define (ask-for-name)                       ;; wrong
  (show "Please type your first name, then your last name:")
  (list (read) (read)))

> (ask-for-name)
Please type your first name, then your last name:
\pmb{John
Lennon}
(LENNON JOHN)
}

\noindent What went wrong?  We happen to be using a version of Scheme that
evaluates argument subexpressions from right to left.  Therefore, the word
{\tt John} was read by the rightmost call to {\tt read}, which provided the
second argument to {\tt list}.  The best solution is to use {\tt let} as we
did above:

{\prgex%
(define (\ufun{ask-for-name})
  (show "Please type your first name, then your last name:")
  (let ((first-name (read)))
    (list first-name (read))))
}

Even this example looks artificially simple, because of the two invocations
of {\tt read} that are visibly right next to each other in the erroneous
version.  But look at {\tt play-ttt-helper}.  The word {\tt read} doesn't
appear in its body at all.  But when we invoke it using {\tt ask-user} as
the strategy procedure for {\tt x}, the expression

{\prgex%
(x-strat position 'x)
}

\noindent hides an invocation of {\tt read}.  The structure of {\tt
play-ttt-helper} includes a {\tt let} that controls the timing of that {\tt
read}.  (As it turns out, in this particular case we could have gotten away
with writing the program without {\tt let}.  The hidden invocation of {\tt
read} is the only subexpression with a side effect, so there aren't two
effects that might get out of order.  But we had to think carefully about
the program to be sure of that.)

\subhd{Pitfalls}

\pit It's easy to get confused about what is printed explicitly by your
\justidx{printing}
program and what is printed by Scheme's read-eval-print loop.  Until now,
{\it all\/} printing was of the second kind.  Here's an example that doesn't
do anything very interesting but will help make the point clear:

{\prgex%
(define (name)
  (display "MATT ")
  'wright)

> (name)
MATT WRIGHT
}

\noindent At first glance it looks as if putting the word ``Matt'' inside a
call to {\tt display} is unnecessary.  After all, the word {\tt wright} is
printed even without using {\tt display}.  But watch this:

{\prgex%
> (bf (name))
MATT RIGHT
}

\noindent Every time you invoke {\tt name}, whether or not as the entire
expression used at a Scheme prompt, the word {\tt MATT} is printed.  But
the word {\tt wright} is {\it returned,\/} and may or may not be printed
depending on the context in which {\tt name} is invoked.

\pit A sequence of expressions returns the value of the {\it last\/}
expression.  If that isn't what you want, you must remember the value you
want to return using {\tt let}:

{\prgex%
(let ((result (compute-this-first)))
  (begin
   (compute-this-second)
   (compute-this-third)
   result))
}

\pit Don't forget that the first call to {\tt read-line}, or any call to
{\tt read-line} after a call to {\tt read}, will probably read the empty
line that {\tt read} left behind.

\pit Sometimes you want to use what the user typed more than once in your
program.  But don't forget that {\tt read} has an effect as well as a return
value.  Don't try to read the same expression twice:

{\prgex%
(define (ask-question question)              ;; wrong
  (show question)
  (cond ((equal? (read) 'yes) #t)
	((equal? (read) 'no) #f)
	(else (show "Please answer yes or no.")
	      (ask-question question))))
}

\noindent If the answer is {\tt yes}, this procedure will work fine.  But if
not, the second invocation of {\tt read} will read a second expression, not
test the same expression again as intended.  To avoid this problem, invoke
{\tt read} only once for each expression you want to read, and use {\tt let}
to remember the result:

{\prgex%
(define (\ufun{ask-question} question)
  (show question)
  (let ((answer (read)))
    (cond ((equal? answer 'yes) #t)
	  ((equal? answer 'no) #f)
	  (else (show "Please answer yes or no.")
		(ask-question question)))))
}

\esubhd{Boring Exercises}

{\exercise
What happens when we evaluate the following expression?  What is printed,
and what is the return value?  Try to figure it out in your head before you
try it on the computer.

{\prgex%
(cond ((= 2 3) (show '(lady madonna)) '(i call your name))
      ((< 2 3) (show '(the night before)) '(hello little girl))
      (else '(p.s. i love you)))
}}

\solution
{\tt (THE NIGHT BEFORE)} is printed.

{\tt (HELLO LITTLE GIRL)} is returned.

@

{\exercise
What does {\tt newline} return in your version of Scheme?
}

{\exercise
Define {\tt show} in terms of {\tt newline} and {\tt display}.
}

\solution
{\prgex%
(define (show stuff)
  (display stuff)
  (newline))
}
@

\esubhd{Real Exercises}

{\exercise
Write a program that carries on a conversation like the following example.
What the user types is in boldface.

{\prgex%
> \pmb{(\ufun{converse})}
Hello, I'm the computer.  What's your name? \pmb{Brian Harvey}
Hi, Brian.  How are you? \pmb{I'm fine.}
Glad to hear it.
}}

\solution

Here's a boring version that's glad to hear anything about how you're
doing.  Naturally you could make it do a lot more if you were so inclined.

{\prgex%
(define (converse)
  (read-line)
  (display "Hello, I'm the computer.  What's your name? ")
  (let ((name (read-line)))
    (display (word "Hi, " (first name) ".  How are you? "))
    (read-line)
    (show "Glad to hear it.")))
}
@

{\exercise
Our {\tt name-table} procedure uses a fixed width for the column containing
the last names of the people in the argument list.  Suppose that instead of
liking British-invasion music you are into late romantic Russian composers:

{\prgex%
> (name-table '((piotr tchaikovsky) (nicolay rimsky-korsakov)
		(sergei rachmaninov) (modest musorgsky)))
}

\noindent Alternatively, perhaps you like jazz:

{\prgex%
> (name-table '((bill evans) (paul motian) (scott lefaro)))
}

\noindent Modify {\tt name-table} so that it figures out the longest last
name in its argument list, adds two for spaces, and uses that number as the
width of the first column.
}

\solution
{\prgex%
(define (name-table names)
  (if (null? names)
      'done
      (nt-help names
	       (+ 2 (reduce max (map (lambda (nm) (count (last nm)))
				     names))))))

(define (nt-help names width)
  (if (null? names)
      'done
      (begin (display (align (cadar names) width))
	     (show (caar names))
	     (nt-help (cdr names) width))))
}

The {\tt null?} test in {\tt name-table} is needed only for the case
in which the user gives an empty argument; the {\tt null?} test that
serves as the base case for the recursion is the one in {\tt nt-help}.

@

{\exercise
The procedure {\tt ask-user} isn't robust.  What happens if you type
something that isn't a number, or isn't between 1 and 9?  Modify it to check
that what the user types is a number between 1 and 9.  If not, it should
print a message and ask the user to try again.
}

\solution
The changed parts of the procedure are shown here in boldface.

{\prgex%
(define (ask-user position letter)
  (print-position position)
  (display letter)
  (display "'s move: ")
  \pmb{(let ((answer (read)))}
    \pmb{(if (and (integer? answer) (>= answer 1) (<= answer 9))}
	\pmb{answer}
	\pmb{(begin (show "That's not a move, silly!")}
	       \pmb{(ask-user position letter)))))}
}
@

{\exercise
Another problem with {\tt ask-user} is that it allows a user to request a
square that isn't free.  If the user does this, what happens?  Fix {\tt
ask-user} to ensure that this can't happen.
}

\solution
If the user asks for a square that's already taken, the square will
be reassigned to the user.  The following solution assumes that the
previous exercise is also included.
The changed parts of the procedure are shown here in boldface.


{\prgex%
(define (ask-user position letter)
  (print-position position)
  (display letter)
  (display "'s move: ")
  (let ((answer (read)))
    \pmb{(cond ((not} (and (integer? answer) (>= answer 1) (<= answer 9)))
	   (show "That's not a move, silly!")
	   (ask-user position letter))
	  \pmb{((not (equal? '_ (item answer position)))}
	   \pmb{(show "That square is occupied.")}
	   \pmb{(ask-user position letter))}
	  \pmb{(else} answer))))
}
@

{\exercise
At the end of the game, if the computer wins or ties, you never find out
which square it chose for its final move.  Modify the program to correct
this.  (Notice that this exercise requires you to make {\tt play-ttt-helper}
non-functional.)
}

\solution
The changed parts of the procedure are shown here in boldface.

{\prgex%
(define (play-ttt-helper x-strat o-strat position whose-turn)
  (cond ((already-won? position (opponent whose-turn))
	 \pmb{(print-position position)}
	 (list (opponent whose-turn) 'wins!))
	((tie-game? position)
	 \pmb{(print-position position)}
	 '(tie game))
	(else (let ((square (if (equal? whose-turn 'x)
				(x-strat position 'x)
				(o-strat position 'o))))
		(play-ttt-helper x-strat
				 o-strat
				 (add-move square whose-turn position)
				 (opponent whose-turn))))))
}
@

{\exercise
The way we invoke the game program isn't very user-friendly.  Write a
procedure {\tt game} that asks you whether you wish to play {\tt x} or {\tt
o}, then starts a game.  (By definition, {\tt x} plays first.)  Then write a
procedure {\tt games} that allows you to keep playing repeatedly.  It
can ask ``do you want to play again?''\ after each game.  (Make sure that
the outcome of each game is still reported, and that the user can choose
whether to play {\tt x} or {\tt o} before each game.)
}

\solution
{\prgex%
(define (game)
  (display "Do you want to play X or O? ")
  (let ((letter (read)))
    (cond ((equal? letter 'x)
	   (play-ttt ask-user ttt))
	  ((equal? letter 'o)
	   (play-ttt ttt ask-user))
	  (else (show "Please type X or O!")
		(game)))))

(define (games)
  (show (game))
  (display "Do you want to play again (Y or N)? ")
  (if (another?)
      (games)
      "Thank you for playing, have a day."))

(define (another?)
  (let ((letter (read)))
    (cond ((equal? letter 'y) #t)
	  ((equal? letter 'n) #f)
	  (else (show "C'mon, Y or N!")
		(another?)))))
}

{\tt Game} and {\tt games} both ask a question, and both include a
check for invalid answers.  But {\tt game} is able to repeat the
question itself, if the answer was invalid, whereas {\tt games}
uses a helper procedure {\tt another?} to ask the question.  The
reason for this difference is that {\tt games} plays a game before
asking its question, whereas the question is the first thing in
{\tt game}.  If {\tt games} were written as a single procedure,
an invalid answer would result in playing another game before
asking again.

@

\bye