-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuse.html
1990 lines (1585 loc) · 85 KB
/
use.html
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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"><!-- DO NOT EDIT THIS FILE-->
<!-- Edit the .tex version instead-->
<html>
<head>
<title>使用Chez Scheme</title>
<link href="csug.css" rel="stylesheet" type="text/css">
</head>
<body>
<a name="g5"></a>
<a name="./use:h0"></a>
<h1>Chapter 2. 使用Chez Scheme<a name="CHPTUSE"></a></h1>
<p>
<i>Chez Scheme</i>常使用交互界面来支持程序开发和调试,然而它也能用于创建没有交互元素的独立应用。
本章描述了<i>Chez Scheme</i>的各种典型用法,或者说更普遍地,如何充分利用该系统。
Sections <a href="./use.html#g6">2.1</a>, <a href="./use.html#g7">2.2</a>,
和 <a href="./use.html#g8">2.3</a>描述了如何以交互式的方式使用<i>Chez Scheme</i>。
Section <a href="./use.html#g9">2.4</a>讨论了如何在<i>Chez Scheme</i>中使用库和RNRS顶级程序。
Section <a href="./use.html#g10">2.5</a>涵盖了书写与运行Scheme脚本,包括编译脚本、编译RNRS顶级程序。
Section <a href="./use.html#g11">2.6</a>描述了如何构造和编译一个程序以求编译出最高效的代码。
Section <a href="./use.html#g12">2.7</a>描述了如何自定义启动过程,例如,改变或消除命令行选项、预加载Scheme或其他语言代码、或以其他程序子程序的方式运行<i>Chez Scheme</i>。
Section <a href="./use.html#g13">2.8</a>描述了如何使用<i>Petite Chez Scheme</i>建造<i>Chez Scheme</i>应用程序以获得运行时支持。
最后,Section <a href="./use.html#g14">2.9</a>涵盖了调用<i>Chez Scheme</i>时所能使用的命令行选项。
<p>
<h3><a name="g6"></a><a name="./use:h1"></a>Section 2.1. 与Chez Scheme交互<a name="SECTUSEINTERACTION"></a></h3>
<p>
最简单最高效的编写测试Scheme程序的方式之一是使用<tt>vi</tt>或<tt>emacs</tt>之类的文本编辑器来编写,然后在shell窗口中运行的<i>Chez Scheme</i>中交互式地测试它们。
当<i>Chez Scheme</i>以默认选项被安装好后,在shell的提示符后输入命令<tt>scheme</tt>以启动一个交互式Scheme会话。类似的,命令<tt>petite</tt>则是用于启动<i>Petite Chez Scheme</i>的交互式会话。
在输入这条命令后,你可以看到一段简短的后跟一个行首带着尖括号的新行的问候,就像这样:
<p>
<p><tt>Chez Scheme Version 9.4<br>
Copyright 1984-2016 Cisco Systems, Inc.
<br>
<br>
> </tt>
<p>你应该能看到,光标位于尖括号偏右一个空格的位置。
尖括号是系统的"REPL"的提示符,"REPL"是"Read Eval Print Loop"的缩写,意味读、求值、打印一个表达式,然后从头开始继续读、求值、打印的过程,就这么不断重复。
(在<i>Chez Scheme</i>中,REPL也叫做waiter。)
<p>
你可以输入一些Scheme表达式以回应提示符。
如果表达式正确,那么REPL会运行表达式,然后打印它的值。
以下是一些例子:
<p>
<p><tt>> 3<br>
3<br>
> (+ 3 4)<br>
7<br>
> (cons 'a '(b c d))<br>
(a b c d)</tt>
<p>The reader used by the REPL is more sophisticated than an ordinary
reader.
In fact, it's a full-blown "expression editor" ("expeditor" for short)
like a regular text editor but for just one expression at a time.
One thing you might soon notice is that the system automatically indents
the second and subsequent lines of an expression.
For example, let's say we want to define <tt>fact</tt>, a procedure that
implements the factorial function.
If we type <tt>(define fact</tt> followed by the enter key, the cursor
should be sitting under the first <tt>e</tt> in <tt>define</tt>, so that
if we then type <tt>(lambda (x)</tt>, we should see:
<p>
<p><tt>> (define fact<br>
(lambda (x)</tt>
<p>The expeditor also allows us to move around within the expression
(even across lines) and edit the expression to correct mistakes.
After typing:
<p>
<p><tt>> (define fact<br>
(lambda (x)<br>
(if (= n 0)<br>
0<br>
(* n (fact </tt>
<p>we might notice that the procedure's argument is named <tt>x</tt>
but we have been referencing it as <tt>n</tt>.
We can move back to the second line using the arrow keys,
remove the offending <tt>x</tt> with the backspace key, and
replace it with <tt>n</tt>.
<p>
<p><tt>> (define fact<br>
(lambda (n)<br>
(if (= n 0)<br>
0<br>
(* n (fact </tt>
<p>We can then return to the end of the expression with the arrow
keys and complete the definition.
<p>
<p><tt>> (define fact<br>
(lambda (n)<br>
(if (= n 0)<br>
0<br>
(* n (fact (- n 1))))))</tt>
<p>Now that we have a complete form with balanced parentheses,
if we hit enter with the cursor just after the final parenthesis,
the expeditor will send it on to the evaluator.
We'll know that it has accepted the definition when we get another
right-angle prompt.
<p>
Now we can test our definition by entering, say, <tt>(fact 6)</tt>
in response to the prompt:
<p>
<p><tt>> (fact 6)<br>
0</tt>
<p>The printed value isn't what we'd hoped for, since 6! is actually 720.
The problem, of course, is that the base-case return-value <tt>0</tt>
should have been <tt>1</tt>.
Fortunately, we don't have to retype the definition to correct the
mistake.
Instead, we can use the expeditor's history mechanism to retrieve the
earlier definition.
The up-arrow key moves backward through the history.
In this case, the first up-arrow retrieves <tt>(fact 6)</tt>, and
the second retrieves the <tt>fact</tt> definition.
<p>
As we move back through the history, the expression editor shows us
only the first line, so after two up arrows, this is all we see of
the definition:
<p>
<p><tt>> (define fact</tt>
<p>We can force the expeditor to show the entire expression by typing
<tt>^L</tt> (control <tt>L</tt>, i.e., the control and <tt>L</tt> keys
pressed together):
<p>
<p><tt>> (define fact<br>
(lambda (n)<br>
(if (= n 0)<br>
0<br>
(* n (fact (- n 1))))))</tt>
<p>Now we can move to the fourth line and change the <tt>0</tt> to a
<tt>1</tt>.
<p>
<p><tt>> (define fact<br>
(lambda (n)<br>
(if (= n 0)<br>
1<br>
(* n (fact (- n 1))))))</tt>
<p>We're now ready to enter the corrected definition.
If the cursor is on the fourth line and we hit enter, however, it will
just open up a new line between the old fourth and fifth lines.
This is useful in other circumstances, but not now.
Of course, we can work around this by using the arrow keys to move
to the end of the expression, but an easier way is to type
<tt>^J</tt>, which forces the expression to be entered immediately
no matter where the cursor is.
<p>
Finally, we can bring back <tt>(fact 6)</tt> with another two
hits of the up-arrow key and try it again:
<p>
<p><tt>> (fact 6)<br>
720</tt>
<p>To exit from the REPL and return back to the shell, we can type
<tt>^D</tt> or call the <tt>exit</tt> procedure.
<p>
The interaction described above uses just a few of the expeditor's
features.
The expeditor's remaining features are described in the following
section.
<p>
Running programs may be interrupted by typing the interrupt
character (typically <tt>^C</tt>).
In response, the
system enters a debug handler, which prompts for input with a
<tt>break></tt> prompt.
One of several commands may be issued to the break handler (followed by a
newline), including
<dl compact>
<dt>"e"<dd> or end-of-file to exit from the handler and continue,
<dt>"r"<dd> to stop execution and reset to the current café,
<dt>"a"<dd> to abort <i>Chez Scheme</i>,
<dt>"n"<dd> to enter a new café (see below),
<dt>"i"<dd> to inspect the current continuation,
<dt>"s"<dd> to display statistics about the interrupted program, and
<dt>"?"<dd> to display a list of these options.
</dl>
<p>
When an exception other than a warning occurs, the default exception
handler prints a message that describes the exception to the console
error port.
If a REPL is running, the exception handler then returns to the REPL,
where the programmer can call the <tt>debug</tt> procedure to start up the
debug handler, if desired.
The debug handler is similar to the break handler and allows the
programmer to inspect the continuation (control
stack) of the exception to help determine the cause of the problem.
If no REPL is running, as is the case for a script or top-level program
run via the <a name="./use:s0"></a><tt>--script</tt>
or <a name="./use:s1"></a><tt>--program</tt>
command-line options, the default exception handler exits from the script
or program after printing the message.
To allow scripts and top-level programs to be debugged,
the default exception handler can be forced via the
<a name="./use:s2"></a><tt>debug-on-exception</tt>
parameter or the
<a name="./use:s3"></a><tt>--debug-on-exception</tt> command-line option
to invoke <tt>debug</tt> directly.
<p>
Developing a large program entirely in the REPL is unmanageable, and we
usually even want to store smaller programs in a file for future use.
(The expeditor's history is saved across Scheme sessions, but there is a
limit on the number of items, so it is not a good idea to count on a
program remaining in the history indefinitely.)
Thus, a Scheme programmer typically creates a file containing Scheme
source code using a text editor, such as <tt>vi</tt>, and loads the file
into <i>Chez Scheme</i> to test them.
The conventional filename extension for <i>Chez Scheme</i> source files is
"<tt>.ss</tt>," but the file can have any extension or even no extension
at all.
A source file can be loaded during an interactive session by typing
<a name="./use:s4"></a><tt>(load "<i>path</i>")</tt>.
Files to be loaded can also be named on the command line when the
system is started.
Any form that can be typed interactively can be placed in a file to be loaded.
<p>
<i>Chez Scheme</i> compiles source forms as it sees them to machine
code before evaluating them, i.e., "just in time."
In order to speed loading of a large file or group of files, each file
can be compiled ahead of time via
<a name="./use:s5"></a><tt>compile-file</tt>, which puts the
compiled code into a separate object file.
For example, <tt>(compile-file "<i>path</i>")</tt> compiles
the forms in the file <tt><i>path</i></tt>.ss and places the
resulting object code in the file <tt><i>path</i></tt>.so.
Loading a pre-compiled file is essentially no different from
loading the source file, except that loading is faster since
compilation has already been done.
<p>
<a name="./use:s6"></a>When compiling a file or set of files, it is often more convenient to
use a shell command than to enter <i>Chez Scheme</i> interactively to perform
the compilation.
This is easily accomplished by "piping" in the command to compile
the file as shown below.
<p>
<p><tt>echo '(compile-file "<i>filename</i>")' | scheme -q</tt>
<p>The <tt>-q</tt> option suppresses the system's greeting messages for more
compact output, which is especially useful when compiling numerous
files.
The single-quote marks surrounding the <tt>compile-file</tt> call
should be left off for Windows shells.
<p>
When running in this "batch" mode, especially from within "make"
files, it is often desirable to force the default exception handler to exit
immediately to the shell with a nonzero exit status.
This may be accomplished by setting the
<a name="./use:s7"></a><tt>reset-handler</tt> to
<tt>abort</tt>.
<p>
<p><tt>echo '(reset-handler abort) (compile-file "<i>filename</i>")' | scheme -q</tt>
<p>One can also redefine the
<a name="./use:s8"></a><tt>base-exception-handler</tt>
(Section <a href="./system.html#g108">12.1</a>) to achieve a similar effect
while exercising more control over the format of the messages that
are produced.
<p>
<h3><a name="g7"></a><a name="./use:h2"></a>Section 2.2. Expression Editor<a name="SECTUSEEXPEDITOR"></a></h3>
<p>
When Chez Scheme is used interactively in a shell window, as described
above, or when <tt>new-cafe</tt> is invoked explicitly from a top-level
program or script run via <tt>--program</tt> or <tt>--script</tt>, the
waiter's "prompt and read" procedure employs an expression editor that
permits entry and editing of single- and multiple-line expressions,
automatically indents expressions as they are entered, supports
identifier completion outside string constants based on the identifiers defined
in the interactive environment, and supports filename completion within
string constants.
The expression editor also maintains a history of expressions typed during
and across sessions and supports tcsh-like history movement and search
commands.
Other editing commands include simple cursor movement via
arrow keys, deletion of characters via backspace and delete, and
movement, deletion, and other commands using mostly
emacs key bindings.
<p>
The expression editor does not run if the TERM environment variable is not
set (on Unix-based systems), if the standard input or output files have
been redirected, or if the <tt>--eedisable</tt> command-line option
(Section <a href="./use.html#g14">2.9</a>) has been used.
The history is saved across sessions, by default, in the file
".chezscheme_history" in the user's home directory.
The <tt>--eehistory</tt> command-line option
(Section <a href="./use.html#g14">2.9</a>) can be used to specify a different
location for the history file or to disable the saving and restoring of
the history file.
<p>
Keys for nearly all printing characters (letters, digits, and special
characters) are "self inserting" by default.
The open parenthesis, close parenthesis, open bracket, and close bracket
keys are self inserting as well, but also cause the editor to "flash"
to the matching delimiter, if any.
Furthermore, when a close parenthesis or close bracket is typed, it is
automatically corrected to match the corresponding open delimiter, if any.
<p>
Key bindings for other keys and key sequences initially recognized by
the expression editor are given below, organized into groups by function.
Some keys or key sequences serve more than one purpose depending upon
context.
For example, tab is used for identifier completion, filename completion,
and indentation.
Such bindings are shown in each applicable functional group.
<p>
Multiple-key sequences are displayed with hyphens between the keys of
the sequences, but these hyphens should not be entered.
When two or more key sequences perform the same operation, the sequences
are shown separated by commas.
<p>
Detailed descriptions of the editing commands are given in
Chapter <a href="./expeditor.html#g128">14</a>, which also describes parameters that allow
control over the expression editor, mechanisms for adding or changing key
bindings, and mechanisms for creating new commands.
<p>
<p>
<p> Newlines, acceptance, exiting, and redisplay:
<p><TABLE><TR><TD nowrap align="left">
enter, <tt>^M</tt> </TD><TD nowrap align="left"> accept balanced entry if used at end of entry;</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> else add a newline before the cursor and indent</TD></TR><TR><TD nowrap align="left">
<tt>^J</tt> </TD><TD nowrap align="left"> accept entry unconditionally</TD></TR><TR><TD nowrap align="left">
<tt>^O</tt> </TD><TD nowrap align="left"> insert newline after the cursor and indent</TD></TR><TR><TD nowrap align="left">
<tt>^D</tt> </TD><TD nowrap align="left"> exit from the waiter if entry is empty;</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> else delete character under cursor</TD></TR><TR><TD nowrap align="left">
<tt>^Z</tt> </TD><TD nowrap align="left"> suspend to shell if shell supports job control</TD></TR><TR><TD nowrap align="left">
<tt>^L</tt> </TD><TD nowrap align="left"> redisplay entry</TD></TR><TR><TD nowrap align="left">
<tt>^L</tt>-<tt>^L</tt> </TD><TD nowrap align="left"> clear screen and redisplay entry
</TD></TR></TABLE>
<p>
<p>
Basic movement and deletion:
<p><TABLE><TR><TD nowrap align="left">
leftarrow, <tt>^B</tt> </TD><TD nowrap align="left"> move cursor left</TD></TR><TR><TD nowrap align="left">
rightarrow, <tt>^F</tt> </TD><TD nowrap align="left"> move cursor right</TD></TR><TR><TD nowrap align="left">
uparrow, <tt>^P</tt> </TD><TD nowrap align="left"> move cursor up; from top of unmodified entry,</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> move to preceding history entry.</TD></TR><TR><TD nowrap align="left">
downarrow, <tt>^N</tt> </TD><TD nowrap align="left"> move cursor down; from bottom of unmodified entry,</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> move to next history entry</TD></TR><TR><TD nowrap align="left">
<tt>^D</tt> </TD><TD nowrap align="left"> delete character under cursor if entry not empty,</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> else exit from the waiter</TD></TR><TR><TD nowrap align="left">
backspace, <tt>^H</tt> </TD><TD nowrap align="left"> delete character before cursor</TD></TR><TR><TD nowrap align="left">
delete </TD><TD nowrap align="left"> delete character under cursor
</TD></TR></TABLE>
<p>
<p>
Line movement and deletion:
<p><TABLE><TR><TD nowrap align="left">
home, <tt>^A</tt> </TD><TD nowrap align="left"> move cursor to beginning of line</TD></TR><TR><TD nowrap align="left">
end, <tt>^E</tt> </TD><TD nowrap align="left"> move cursor to end of line</TD></TR><TR><TD nowrap align="left">
<tt>^K</tt>,
esc-k </TD><TD nowrap align="left"> delete to end of line or, if cursor is at the end</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> of a line, join with next line</TD></TR><TR><TD nowrap align="left">
<tt>^U</tt> </TD><TD nowrap align="left"> delete contents of current line
</TD></TR></TABLE>
<p>
<p>
When used on the first line of a multiline entry of which only the first line
is displayed, i.e., immediately after history movement, <tt>^U</tt> deletes the
contents of the entire entry, like <tt>^G</tt> (described below).
<p>
Expression movement and deletion:
<p><TABLE><TR><TD nowrap align="left">
esc-<tt>^F</tt> </TD><TD nowrap align="left"> move cursor to next expression</TD></TR><TR><TD nowrap align="left">
esc-<tt>^B</tt> </TD><TD nowrap align="left"> move cursor to preceding expression</TD></TR><TR><TD nowrap align="left">
esc-<tt>]</tt> </TD><TD nowrap align="left"> move cursor to matching delimiter</TD></TR><TR><TD nowrap align="left">
<tt>^]</tt> </TD><TD nowrap align="left"> flash cursor to matching delimiter</TD></TR><TR><TD nowrap align="left">
esc-<tt>^K</tt>,
esc-delete </TD><TD nowrap align="left"> delete next expression</TD></TR><TR><TD nowrap align="left">
esc-backspace,
esc-<tt>^H</tt> </TD><TD nowrap align="left"> delete preceding expression
</TD></TR></TABLE>
<p>
<p>
Entry movement and deletion:
<p><TABLE><TR><TD nowrap align="left">
esc-<tt><</tt> </TD><TD nowrap align="left"> move cursor to beginning of entry</TD></TR><TR><TD nowrap align="left">
esc-<tt>></tt> </TD><TD nowrap align="left"> move cursor to end of entry</TD></TR><TR><TD nowrap align="left">
<tt>^G</tt> </TD><TD nowrap align="left"> delete current entry contents</TD></TR><TR><TD nowrap align="left">
<tt>^C</tt> </TD><TD nowrap align="left"> delete current entry contents; reset to end of history
</TD></TR></TABLE>
<p>
<p>
Indentation:
<p><TABLE><TR><TD nowrap align="left">
tab </TD><TD nowrap align="left"> re-indent current line if identifier/filename prefix</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> not just entered; else insert completion</TD></TR><TR><TD nowrap align="left">
esc-tab </TD><TD nowrap align="left"> re-indent current line unconditionally</TD></TR><TR><TD nowrap align="left">
esc-<tt>q</tt>,
esc-<tt>Q</tt>,
esc-<tt>^Q</tt> </TD><TD nowrap align="left"> re-indent each line of entry
</TD></TR></TABLE>
<p>
<p>
Identifier/filename completion:
<p><TABLE><TR><TD nowrap align="left">
tab </TD><TD nowrap align="left"> insert completion if identifier/filename prefix just</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> entered; else re-indent current line</TD></TR><TR><TD nowrap align="left">
tab-tab </TD><TD nowrap align="left"> show possible identifier/filename completions at end</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> of identifier/filename just typed, else re-indent</TD></TR><TR><TD nowrap align="left">
<tt>^R</tt> </TD><TD nowrap align="left"> insert next identifier/filename completion
</TD></TR></TABLE>
<p>
<p>
Identifier completion is performed outside of a string constant, and filename
completion is performed within a string constant.
(In determining whether the cursor is within a string constant, the
expression editor looks only at the current line and so can be fooled
by string constants that span multiple lines.)
If at end of existing identifier or filename, i.e., not one just typed, the first tab
re-indents, the second tab inserts identifier completion, and the third
shows possible completions.
<p>
History movement:
<p><TABLE><TR><TD nowrap align="left">
uparrow, <tt>^P</tt> </TD><TD nowrap align="left"> move to preceding entry if at top of unmodified</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> entry; else move up within entry</TD></TR><TR><TD nowrap align="left">
downarrow, <tt>^N</tt> </TD><TD nowrap align="left"> move to next entry if at bottom of unmodified</TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="left"> entry; else move down within entry</TD></TR><TR><TD nowrap align="left">
esc-uparrow,
esc-<tt>^P</tt> </TD><TD nowrap align="left"> move to preceding entry from unmodified entry</TD></TR><TR><TD nowrap align="left">
esc-downarrow,
esc-<tt>^N</tt> </TD><TD nowrap align="left"> move to next entry from unmodified entry</TD></TR><TR><TD nowrap align="left">
esc-p </TD><TD nowrap align="left"> search backward through history for given prefix</TD></TR><TR><TD nowrap align="left">
esc-n </TD><TD nowrap align="left"> search forward through history for given prefix</TD></TR><TR><TD nowrap align="left">
esc-P </TD><TD nowrap align="left"> search backward through history for given string</TD></TR><TR><TD nowrap align="left">
esc-N </TD><TD nowrap align="left"> search forward through history for given string
</TD></TR></TABLE>
<p>
<p>
To search, enter a prefix or string followed by one of the search key
sequences.
Follow with additional search key sequences to search further backward or
forward in the history.
For example, enter "(define" followed by one or more esc-p key sequences
to search backward for entries that are definitions, or "(define"
followed by one or more esc-P key sequences for entries that contain
definitions.
<p>
Word and page movement:
<p><TABLE><TR><TD nowrap align="left">
esc-<tt>f</tt>,
esc-<tt>F</tt> </TD><TD nowrap align="left"> move cursor to end of next word</TD></TR><TR><TD nowrap align="left">
esc-<tt>b</tt>,
esc-<tt>B</tt> </TD><TD nowrap align="left"> move cursor to start of preceding word</TD></TR><TR><TD nowrap align="left">
<tt>^X</tt>-<tt>[</tt> </TD><TD nowrap align="left"> move cursor up one screen page</TD></TR><TR><TD nowrap align="left">
<tt>^X</tt>-<tt>]</tt> </TD><TD nowrap align="left"> move cursor down one screen page
</TD></TR></TABLE>
<p>
<p>
Inserting saved text:
<p><TABLE><TR><TD nowrap align="left">
<tt>^Y</tt> </TD><TD nowrap align="left"> insert most recently deleted text</TD></TR><TR><TD nowrap align="left">
<tt>^V</tt> </TD><TD nowrap align="left"> insert contents of window selection/paste buffer
</TD></TR></TABLE>
<p>
<p>
Mark operations:
<p><TABLE><TR><TD nowrap align="left">
<tt>^@</tt>,
<tt>^</tt>space,
<tt>^^</tt> </TD><TD nowrap align="left"> set mark to current cursor position</TD></TR><TR><TD nowrap align="left">
<tt>^X</tt>-<tt>^X</tt> </TD><TD nowrap align="left"> move cursor to mark, leave mark at old cursor position</TD></TR><TR><TD nowrap align="left">
<tt>^W</tt> </TD><TD nowrap align="left"> delete between current cursor position and mark
</TD></TR></TABLE>
<p>
<p>
Command repetition:
<p><TABLE><TR><TD nowrap align="left">
esc-<tt>^U</tt> </TD><TD nowrap align="left"> repeat next command four times</TD></TR><TR><TD nowrap align="left">
esc-<tt>^U</tt>-<i>n</i> </TD><TD nowrap align="left"> repeat next command <i>n</i> times
</TD></TR></TABLE>
<p>
<p>
<h3><a name="g8"></a><a name="./use:h3"></a>Section 2.3. The Interaction Environment<a name="SECTUSEINTERACTIONENVIRONMENT"></a></h3>
<p>
<a name="./use:s9"></a><a name="./use:s10"></a><a name="./use:s11"></a>In the language of the Revised<sup>6</sup> Report, code is structured into
libraries and "top-level programs."
The Revised<sup>6</sup> Report does not require an implementation to support
interactive use, and it does not specify how an interactive top level
should operate, leaving such details up to the implementation.
<p>
In <i>Chez Scheme</i>, when one enters definitions or expressions at the
prompt or loads them from a file, they operate on an
interaction environment, which is a mutable environment that initially
holds bindings only for built-in keywords and primitives.
It may be augmented by user-defined identifier bindings via top-level
definitions.
The interaction environment is also referred to as the top-level
environment, because it is at the top level for purposes of scoping.
Programs entered at the prompt or loaded from a file via <tt>load</tt>
should not be confused with RNRS top-level programs, which are
actually more similar to libraries in their behavior.
In particular, while the same identifier can be defined multiple times
in the interaction environment, to support incremental program
development, an identifier can be defined at most once in an RNRS
top-level program.
<p>
The default interaction environment used for any code that occurs outside
of an RNRS top-level program or library (including such code typed at
a prompt or loaded from a file) contains all of the bindings of the
<tt>(chezscheme)</tt> library (or <tt>scheme</tt> module, which exports the
same set of bindings).
This set contains a number of bindings that are not in the RNRS libraries.
It also contains a number of bindings that extend the RNRS counterparts in
some way and are thus not strictly compatible with the RNRS bindings for
the same identifiers.
To replace these with bindings strictly compatible with RNRS, simply
import the <tt>rnrs</tt> libraries into the interaction environment by
typing the following into the REPL or loading it from a file:
<p>
<p><tt>(import<br>
(rnrs)<br>
(rnrs eval)<br>
(rnrs mutable-pairs)<br>
(rnrs mutable-strings)<br>
(rnrs r5rs))</tt>
<p><a name="./use:s12"></a>To obtain an interaction environment that contains all <i>and only</i>
RNRS bindings, use the following.
<p>
<p><tt>(interaction-environment<br>
(copy-environment<br>
(environment<br>
'(rnrs)<br>
'(rnrs eval) <br>
'(rnrs mutable-pairs) <br>
'(rnrs mutable-strings) <br>
'(rnrs r5rs))<br>
#t))</tt>
<p>To be useful for most purposes, <tt>library</tt> and <tt>import</tt>
should probably also be included, from the <tt>(chezscheme)</tt> library.
<p>
<p><tt>(interaction-environment<br>
(copy-environment<br>
(environment<br>
'(rnrs)<br>
'(rnrs eval) <br>
'(rnrs mutable-pairs) <br>
'(rnrs mutable-strings) <br>
'(rnrs r5rs)<br>
'(only (chezscheme) library import))<br>
#t))</tt>
<p>It might also be useful to include <tt>debug</tt> in the set of
identifiers imported from <tt>(chezscheme)</tt> to allow the debugger to be
entered after an exception is raised.
<p>
Most of the identifiers bound in the default interaction environment that
are not strictly compatible with the Revised<sup>6</sup> Report are variables bound to
procedures with extended interfaces, i.e., optional arguments or extended
argument domains.
The others are keywords bound to transformers that extend the Revised<sup>6</sup>
Report syntax in some way.
This should not be a problem except for programs that count on
exceptions being raised in cases that coincide with the extensions.
For example, if a program passes the <tt>=</tt> procedure a single numeric
argument and expects an exception to be raised, it will fail in the
initial interaction environment because <tt>=</tt> returns <tt>#t</tt>
when passed a single numeric argument.
<p>
Within the default interaction environment and those created as described
above, variables that name built-in procedures are read-only, i.e.,
cannot be assigned, since they resolve to the read-only bindings exported
from the <tt>(chezscheme)</tt> library or some other library:
<p>
<p><tt>(set! cons +) <img src="math/csug/0.gif" alt="<graphic>"> <i>exception: cons is immutable</i></tt>
<p>Before assigning a variable bound to the name of a built-in
procedure, the programmer must first define the variable.
For example,
<p>
<p><tt>(define cons-count 0)<br>
(define original-cons cons)<br>
(define cons<br>
(lambda (x y)<br>
(set! cons-count (+ cons-count 1))<br>
(original-cons x y)))</tt>
<p>redefines <tt>cons</tt> to count the number of times it is called, and
<p>
<p><tt>(set! cons original-cons)</tt>
<p>assigns <tt>cons</tt> to its original value.
Once a variable has been defined in the interaction environment using
<tt>define</tt>, a subsequent definition of the same variable is equivalent
to a <tt>set!</tt>, so
<p>
<p><tt>(define cons original-cons)</tt>
<p>has the same effect as the <tt>set!</tt> above.
The expression
<p>
<p><tt>(import (only (chezscheme) cons))</tt>
<p>also binds <tt>cons</tt> to its original value.
It also returns it to its original read-only state.
<p>
The simpler redefinition
<p>
<p><tt>(define cons (let () (import scheme) cons))</tt>
<p>turns <tt>cons</tt> into a mutable variable with the same value as it
originally had.
Doing so, however, prevents the compiler from generating efficient code
for calls to <tt>cons</tt> or producing warning messages when
<tt>cons</tt> is passed the wrong number of arguments.
<p>
All identifiers not bound in the initial interaction environment and
not defined by the programmer are treated as "potentially bound" as
variables to facilitate the definition of mutually recursive
procedures.
For example, assuming that <tt>yin</tt> and <tt>yang</tt> have not
been defined,
<p>
<p><tt>(define yin (lambda () (- (yang) 1)))</tt>
<p>defines <tt>yin</tt> at top level as a variable to a procedure that calls
the value of the top-level variable <tt>yang</tt>, even though <tt>yang</tt>
has not yet been defined.
If this is followed by
<p>
<p><tt>(define yang (lambda () (+ (yin) 1)))</tt>
<p>the result is a mutually recursive pair of procedures that, when called,
will loop indefinitely or until the system runs out of space to hold the
recursion stack.
If <tt>yang</tt> must be defined as anything other than a variable, its
definition should precede the definition of <tt>yin</tt>, since the compiler
assumes <tt>yang</tt> is a variable in the absence of any indication to
the contrary when <tt>yang</tt> has not yet been defined.
<p>
<a name="./use:s13"></a>A subtle consequence of this useful quirk of the interaction environment is that
the procedure
<tt>free-identifier=?</tt> (Section <a href="http://scheme.com/tspl4/./syntax.html#g136">8.3</a> of <i>The Scheme Programming Language, 4th Edition</i>)
does not consider unbound library identifiers to be equivalent to (as yet)
undefined top-level identifiers, even if they have the
same name, because the latter are actually assumed to be valid variable bindings.
<p>
<p><tt>(library (A) (export a)<br>
(import (rnrs))<br>
(define-syntax a<br>
(lambda (x)<br>
(syntax-case x ()<br>
[(_ id) (free-identifier=? #'id #'undefined)]))))<br>
(let () (import (A)) (a undefined)) <img src="math/csug/0.gif" alt="<graphic>"> #f</tt>
<p><a name="./use:s14"></a>If it is necessary that they have the same binding, as in the case where
an identifier is used as an auxiliary keyword in a syntactic abstraction
exported from a library and used at top level, the library should define
and export a binding for the identifier.
<p>
<p><tt>(library (A) (export a aux-a)<br>
(import (rnrs) (only (chezscheme) syntax-error))<br>
(define-syntax aux-a<br>
(lambda (x)<br>
(syntax-error x "invalid context")))<br>
(define-syntax a<br>
(lambda (x)<br>
(syntax-case x (aux-a)<br>
[(_ aux-a) #''okay]<br>
[(_ _) #''oops]))))<br>
(let () (import (A)) (a aux-a)) <img src="math/csug/0.gif" alt="<graphic>"> okay<br>
(let () (import (only (A) a)) (a aux-a)) <img src="math/csug/0.gif" alt="<graphic>"> oops</tt>
<p>This issue does not arise when libraries are used entirely within other
libraries or within RNRS top-level programs, since the interaction
environment does not come into play.
<p>
<h3><a name="g9"></a><a name="./use:h4"></a>Section 2.4. Using Libraries and Top-Level Programs<a name="SECTUSELIBRARIES"></a></h3>
<p>
<a name="./use:s15"></a><a name="./use:s16"></a>An R6RS library can be defined directly in the REPL, loaded explicitly
from a file (using <tt>load</tt> or <tt>load-library</tt>), or loaded
implicitly from a file via <tt>import</tt>.
When defined directly in the REPL or loaded explicitly from a file, a
library form can be used to redefine an existing library, but
<tt>import</tt> never reloads a library once it has been defined.
<p>
A library to be loaded implicitly via <tt>import</tt>
must reside in a file whose name reflects the name of the library.
For example, if the library's name is <tt>(tools sorting)</tt>, the
base name of the file must be <tt>sorting</tt> with a valid extension, and
the file must be in a directory named <tt>tools</tt> which itself resides
in one of the directories searched by <tt>import</tt>.
The set of directories searched by <tt>import</tt> is determined by
the
<a name="./use:s17"></a><tt>library-directories</tt>
parameter, and the set of
extensions is determined by the
<a name="./use:s18"></a><tt>library-extensions</tt>
parameter.
<p>
The values of both parameters are lists of pairs of strings.
The first string in each <tt>library-directories</tt> pair identifies a
source-file base directory, and the second identifies the corresponding
object-file base directory.
Similarly, the first string in each <tt>library-extensions</tt> pair
identifies a source-file extension, and the second identifies the
corresponding object-file extension.
The full path of a library source or object file consists of the source or
object base followed by the components of the library name, separated by
slashes, with the library extension added on the end.
For example, for base <tt>/usr/lib/scheme</tt>, library name
<tt>(app lib1)</tt>, and extension <tt>.sls</tt>, the full path is
<tt>/usr/lib/scheme/app/lib1.sls</tt>.
So, if <tt>(library-directories)</tt> contains the pathnames
<tt>"/usr/lib/scheme/libraries"</tt> and <tt>"."</tt>, and
<tt>(library-extensions)</tt> contains the extensions <tt>.ss</tt>
and <tt>.sls</tt>, the path of the <tt>(tools sorting)</tt>
library must be one of the following.
<p>
<p><tt>/usr/lib/scheme/libraries/tools/sorting.ss<br>
/usr/lib/scheme/libraries/tools/sorting.sls<br>
./tools/sorting.ss<br>
./tools/sorting.sls</tt>
<p>When searching for a library, <tt>import</tt> first constructs a partial
name from the list of components in the library name, e.g., <tt>a/b</tt>
for library <tt>(a b)</tt>.
It then searches for the partial name in each pair
of base directories, in order, trying each of the source extensions then
each of the object extensions in turn before moving onto the next pair of
base directories.
If the partial name is an absolute pathname, e.g., <tt>~/.myappinit</tt>
for a library named <tt>(~/.myappinit)</tt>, only the specified absolute
path is searched, first with each source extension, then with each object
extension.
If the expander finds both a source file and its corresponding object
file, and the object file is not older than the source file, the
expander loads the object file.
If the object file does not exist, if the object file is older, or
if after loading the object file, the expander determines it was
built using a library or include file that has changed, the source
file is loaded or compiled, depending on the value of the parameter
<a name="./use:s19"></a><tt>compile-imported-libraries</tt>.
If <tt>compile-imported-libraries</tt>
is set to <tt>#t</tt>, the expander
compiles the library via the value of the <tt>compile-library-handler</tt>
parameter, which by default calls <tt>compile-library</tt> (which is described below).
Otherwise, the expander loads the source file.
(Loading the source file actually causes the code to be compiled,
assuming the default value of <tt>current-eval</tt>, but the compiled
code is not saved to an object file.)
An exception is raised during this process if a
source or object file exists but is not readable or if an object
file cannot be created.
<p>
<a name="./use:s20"></a><a name="./use:s21"></a>The search process used by the expander when processing an <tt>import</tt>
for a library that has not yet been loaded can be monitored by
setting the parameter <tt>import-notify</tt> to <tt>#t</tt>.
This parameter can be set from the command line via the
<tt>--import-notify</tt> command-line option.
<p>
Whenever the expander determines it must compile a library to a file or
load one from source, it adds the directory in which the file resides to
the front of the
<a name="./use:s22"></a><tt>source-directories</tt>
list while compiling or loading the library.
This allows a library to include files stored in or relative to its
own directory.
<p>
When <tt>import</tt> compiles a library as described above, it does not
also load the compiled library, because this would cause portions of
library to be reevaluated.
Because of this, run-time expressions in the file outside of a
<tt>library</tt> form will not be evaluated.
If such expressions are present and should be evaluated, the library
should be compiled ahead of time or loaded explicitly.
<p>
<a name="./use:s23"></a><a name="./use:s24"></a>A file containing a library may be compiled with <tt>compile-file</tt>
or <tt>compile-library</tt>.
The only difference between the two is that the latter treats the source
file as if it were prefixed by an implicit <tt>#!r6rs</tt>, which
disables <i>Chez Scheme</i> lexical extensions unless an explicit
<tt>#!chezscheme</tt> marker appears in the file.
Any libraries upon which the library depends must be compiled first.
If one of the libraries imported by the library is subsequently
recompiled (say because it was modified), the importing library must also
be recompiled.
Compilation and recompilation of imported libraries must be done
explicitly by default but is done automatically when the parameter
<tt>compile-imported-libraries</tt> is set to <tt>#t</tt> before
compiling the importing library.
<p>
As with <tt>compile-file</tt>, <tt>compile-library</tt> can be used
in "batch" mode via a shell command:
<p>
<p><tt>echo '(compile-library "<i>filename</i>")' | scheme -q</tt>
<p>with single-quote marks surrounding the <tt>compile-library</tt> call
omitted for Windows shells.
<p>
An RNRS top-level-program usually resides in a file, but one can also
enter one directly into the REPL using the <tt>top-level-program</tt>
forms, e.g.:
<p>
<p><tt>(top-level-program<br>
(import (rnrs))<br>
(display "What's up?\n"))</tt>
<p>A top-level program stored in a file does not have the <tt>top-level-program</tt>
wrapper, so the same top-level program in a file is just:
<p>
<p><tt>(import (rnrs))<br>