-
Notifications
You must be signed in to change notification settings - Fork 15
/
scmman
executable file
·3972 lines (2987 loc) · 142 KB
/
scmman
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
#!/bin/sh
# \
exec wish "$0" "$@"
#!/usr/local/bin/wish -f
#:set ts=100
set efont -sony-fixed-medium-r-normal--16-120-100-100-c-80-iso8859-1
wm title . "R4RS On-line Document"
set menu_path {}
set menu_number {}
proc inc_menu_number {} {
global menu_number
set menu_number [expr $menu_number + 1]
}
proc new_menu { path title } {
global menu_path menu_number efont kfont
set menu_path $path.m
set menu_number 0
menubutton $path -text $title \
-menu $menu_path \
-font $efont
menu $menu_path \
-font $efont
}
proc new_cascade { path title } {
global menu_path menu_number efont kfont
set menu_path $path
set menu_number 0
menubutton $path -text $title \
-menu $menu_path \
-font $efont
}
proc add_cascade { label } {
global menu_path menu_number efont kfont
$menu_path add cascade \
-label $label \
-menu $menu_path.$menu_number \
-font $efont
menu $menu_path.$menu_number \
-font $efont
inc_menu_number
}
proc add_command { label command } {
global menu_path efont kfont
$menu_path add command \
-label $label \
-font $efont \
-command $command
}
proc add_jump { label lineno } {
global menu_path efont kfont
$menu_path add command \
-label $label \
-font $efont \
-command ".text yview $lineno.0"
}
#--------------------------------------------------------
# The code below creates the main, window consisting of a
# menu bar and of portion of R4RS.
#--------------------------------------------------------
frame .menu -relief raised \
-borderwidth 1
pack .menu -side top \
-fill x
#--------------------------------------------------------
# Index over R4RS Sections
#--------------------------------------------------------
new_menu .menu.sect "R4RS Sections"
add_cascade "1. Overview of Scheme"
add_cascade "2. Lexical conventions"
add_cascade "3. Basic concepts"
add_cascade "4. Expressions"
add_cascade "5. Program structure"
add_cascade "6. Standard procedures"
add_cascade "7. Formal syntax and semantics"
set menu_path .menu.sect.m.0
add_jump "1. Overview of Scheme" 1
add_jump "1.1. Semantics" 3
add_jump "1.2. Syntax" 73
add_jump "1.3. Notation and terminology" 89
add_jump "1.3.1. Essential and non-essential features" 92
add_jump "1.3.2. Error situations and unspecified behavior" 106
add_jump "1.3.3. Entry format" 142
add_jump "1.3.4. Evaluation examples" 214
add_jump "1.3.5. Naming conventions" 229
set menu_path .menu.sect.m.1
add_jump "2. Lexical conventions" 248
add_jump "2.1. Identifiers" 260
add_jump "2.2. Whitespace and comments" 314
add_jump "2.3. Other notations" 340
set menu_path .menu.sect.m.2
add_jump "3. Basic concepts" 390
add_jump "3.1. Variables and regions" 393
add_jump "3.2. True and false" 430
add_jump "3.3. External representations" 442
add_jump "3.4. Disjointness of types" 490
add_jump "3.5. Storage model" 503
set menu_path .menu.sect.m.3
add_jump "4. Expressions" 538
add_jump "4.1. Primitive expression types" 552
add_jump "4.1.1. Variable references" 555
add_jump "4.1.2. Literal expressions" 569
add_jump "4.1.3. Procedure calls" 611
add_jump "4.1.4. Lambda expressions" 650
add_jump "4.1.5. Conditionals" 713
add_jump "4.1.6. Assignments" 736
add_jump "4.2. Derived expression types" 752
add_jump "4.2.1. Conditionals" 759
add_jump "4.2.2. Binding constructs" 863
add_jump "4.2.3. Sequencing" 959
add_jump "4.2.4. Iteration" 981
add_jump "4.2.5. Delayed evaluation" 1059
add_jump "4.2.6. Quasiquotation" 1074
set menu_path .menu.sect.m.4
add_jump "5. Program structure" 1135
add_jump "5.1. Programs" 1138
add_jump "5.2. Definitions" 1159
add_jump "5.2.1. Top level definitions" 1196
add_jump "5.2.2. Internal definitions" 1225
set menu_path .menu.sect.m.5
add_jump "6. Standard procedures" 1256
add_jump "6.1. Booleans" 1268
add_jump "6.2. Equivalence predicates" 1323
add_jump "6.3. Pairs and lists" 1541
add_jump "6.4. Symbols" 1847
add_jump "6.5. Numbers" 1946
add_jump "6.5.1. Numerical types" 1968
add_jump "6.5.2. Exactness" 2007
add_jump "6.5.3. Implementation restrictions" 2041
add_jump "6.5.4. Syntax of numerical constants" 2129
add_jump "6.5.5. Numerical operations" 2170
add_jump "6.5.6. Numerical input and output" 2546
add_jump "6.6. Characters" 2619
add_jump "6.7. Strings" 2746
add_jump "6.8. Vectors" 2897
add_jump "6.9. Control features" 3003
add_jump "6.10. Input and output" 3272
add_jump "6.10.1. Ports" 3275
add_jump "6.10.2. Input" 3363
add_jump "6.10.3. Output" 3445
add_jump "6.10.4. System interface" 3495
set menu_path .menu.sect.m.6
add_jump "7. Formal syntax and semantics" 3531
#--------------------------------------------------------
# Index over Syntax
#--------------------------------------------------------
new_menu .menu.sytx "Syntax"
add_jump "<constant>" 574
add_jump "<variable>" 558
add_jump "'<datum>" 573
add_jump "`<template>" 1078
add_jump "(<operator> <operand_1> ...)" 614
add_jump "and" 832
add_jump "begin" 962
add_jump "case" 799
add_jump "cond" 762
add_jump "delay" 1062
add_jump "do" 983
add_jump "if" 716
add_jump "lambda" 653
add_jump "let (1/2)" 876
add_jump "let (2/2)" 1032
add_jump "let*" 902
add_jump "letrec" 921
add_jump "or" 847
add_jump "quasiquote" 1077
add_jump "quote" 572
add_jump "set!" 739
new_menu .menu.proc_ab {[A-B]}
add_jump "abs" 2313
add_jump "acos" 2447
add_jump "angle" 2506
add_jump "append" 1745
add_jump "apply" 3024
add_jump "asin" 2446
add_jump "assoc" 1819
add_jump "assq" 1817
add_jump "assv" 1818
add_jump "atan" 2448
add_jump "boolean?" 1314
new_menu .menu.proc_c {[C]}
add_jump "car" 1654
add_jump "cdr" 1665
add_jump "c(a|d)+r" 1692
add_jump "call-with-current-continuation" 3186
add_jump "call-with-input-file" 3283
add_jump "call-with-output-file" 3284
add_jump "ceiling" 2390
add_jump "char=?" 2657
add_jump "char<?" 2658
add_jump "char>?" 2659
add_jump "char<=?" 2660
add_jump "char>=?" 2661
add_jump "char?" 2652
add_jump "char-alphabetic?" 2699
add_jump "char-ci=?" 2686
add_jump "char-ci<?" 2687
add_jump "char-ci>?" 2688
add_jump "char-ci<=?" 2689
add_jump "char-ci>=?" 2690
add_jump "char-downcase" 2738
add_jump "char->integer" 2715
add_jump "char-lower-case?" 2703
add_jump "char-numeric?" 2700
add_jump "char-ready?" 3425
add_jump "char-upcase" 2737
add_jump "char-upper-case?" 2702
add_jump "char-whitespace?" 2701
add_jump "close-input-port" 3354
add_jump "close-output-port" 3355
add_jump "complex?" 2185
add_jump "cons" 1641
add_jump "cos" 2444
add_jump "current-input-port" 3315
add_jump "current-output-port" 3316
new_menu .menu.proc_df {[D-F]}
add_jump "denominator" 2376
add_jump "display" 3459
add_jump "eof-object?" 3417
add_jump "eq?" 1480
add_jump "equal?" 1521
add_jump "eqv?" 1334
add_jump "even?" 2258
add_jump "exact?" 2224
add_jump "exact->inexact" 2526
add_jump "exp" 2441
add_jump "expt" 2492
add_jump "floor" 2389
add_jump "force" 3084
add_jump "for-each" 3069
new_menu .menu.proc_gl {[G-L]}
add_jump "gcd" 2361
add_jump "imag-part" 2504
add_jump "inexact?" 2225
add_jump "inexact->exact" 2527
add_jump "input-port?" 3308
add_jump "integer?" 2188
add_jump "integer->char" 2716
add_jump "lcm" 2362
add_jump "length" 1736
add_jump "list?" 1714
add_jump "list" 1728
add_jump "list-ref" 1785
add_jump "list->string" 2877
add_jump "list-tail" 1773
add_jump "list->vector" 2984
add_jump "load" 3502
add_jump "log" 2442
new_menu .menu.proc_mn {[M-N]}
add_jump "magnitude" 2505
add_jump "make-polar" 2502
add_jump "make-rectangular" 2501
add_jump "make-string" 2788
add_jump "make-vector (1/2)" 186
add_jump "make-vector (2/2)" 2934
add_jump "map" 3043
add_jump "max" 2264
add_jump "member" 1798
add_jump "memq" 1796
add_jump "memv" 1797
add_jump "min" 2265
add_jump "modulo" 2322
add_jump "negative?" 2256
add_jump "newline" 3477
add_jump "not" 1301
add_jump "null?" 1709
add_jump "number?" 2184
add_jump "number->string" 2549
add_jump "numerator" 2375
new_menu .menu.proc_or {[O-R]}
add_jump "odd?" 2257
add_jump "open-input-file" 3338
add_jump "open-output-file" 3345
add_jump "output-port?" 3309
add_jump "pair?" 1631
add_jump "peek-char" 3399
add_jump "positive?" 2255
add_jump "procedure?" 3010
add_jump "quotient" 2320
add_jump "rational?" 2187
add_jump "rationalize" 2423
add_jump "read" 3366
add_jump "read-char" 3389
add_jump "real?" 2186
add_jump "real-part" 2503
add_jump "remainder" 2321
add_jump "reverse" 1763
add_jump "round" 2392
new_menu .menu.proc_s {[S]}
add_jump "set-car!" 1675
add_jump "set-cdr!" 1686
add_jump "sin" 2443
add_jump "sqrt" 2485
add_jump "string" 2796
add_jump "string?" 2783
add_jump "string=?" 2826
add_jump "string<?" 2836
add_jump "string>?" 2837
add_jump "string<=?" 2838
add_jump "string>=?" 2839
add_jump "string-append" 2870
add_jump "string-ci=?" 2827
add_jump "string-ci<?" 2840
add_jump "string-ci>?" 2841
add_jump "string-ci<=?" 2842
add_jump "string-ci>=?" 2843
add_jump "string-copy" 2886
add_jump "string-fill!" 2891
add_jump "string-length" 2801
add_jump "string->list" 2876
add_jump "string->number" 2588
add_jump "string-ref" 2806
add_jump "string-set!" 2812
add_jump "string->symbol" 1919
add_jump "substring" 2858
add_jump "symbol?" 1882
add_jump "symbol->string" 1894
new_menu .menu.proc_tz {[T-Z]}
add_jump "tan" 2445
add_jump "transcript-off" 3518
add_jump "transcript-on" 3517
add_jump "truncate" 2391
add_jump "vector?" 2928
add_jump "vector" 2941
add_jump "vector-fill!" 2997
add_jump "vector-length" 2949
add_jump "vector->list" 2983
add_jump "vector-ref (1/2)" 180
add_jump "vector-ref (2/2)" 2954
add_jump "vector-set!" 2968
add_jump "with-input-from-file" 3321
add_jump "with-output-to-file" 3322
add_jump "write" 3448
add_jump "write-char" 3486
add_jump "zero?" 2254
new_menu .menu.other "Others"
add_jump "<" 2233
add_jump ">" 2234
add_jump "<=" 2235
add_jump ">=" 2236
add_jump "+" 2282
add_jump "*" 2283
add_jump "-" 2294
add_jump "/" 2297
add_jump "=" 2232
new_menu .menu.misc "Miscellaneous"
add_command "Quit" {destroy .}
pack .menu.sect .menu.sytx .menu.proc_ab .menu.proc_c .menu.proc_df .menu.proc_gl .menu.proc_mn .menu.proc_or .menu.proc_s .menu.proc_tz .menu.other .menu.misc -side left
tk_menuBar .menu .menu.sect .menu.sytx .menu.proc_ab .menu.proc_c .menu.proc_df .menu.proc_gl .menu.proc_mn .menu.proc_or .menu.proc_s .menu.proc_tz .menu.other .menu.misc -side left
text .text -font $efont \
-width 70 \
-height 30 \
-relief raised \
-bd 2 \
-yscrollcommand ".scroll set" \
-setgrid true
scrollbar .scroll -relief flat \
-command ".text yview"
pack .scroll -side right -fill y
pack .text -expand yes \
-fill both
.text insert 0.0 {\
1. Overview of Scheme
1.1. Semantics
This section gives an overview of Scheme's semantics. A detailed
informal semantics is the subject of chapters 3 through 6. For
reference purposes, section 7.2 provides a formal semantics of
Scheme.
Following Algol, Scheme is a statically scoped programming
language. Each use of a variable is associated with a lexically
apparent binding of that variable.
Scheme has latent as opposed to manifest types. Types are
associated with values (also called objects) rather than with
variables. (Some authors refer to languages with latent types as
weakly typed or dynamically typed languages.) Other languages
with latent types are APL, Snobol, and other dialects of Lisp.
Languages with manifest types (sometimes referred to as strongly
typed or statically typed languages) include Algol 60, Pascal,
and C.
All objects created in the course of a Scheme computation,
including procedures and continuations, have unlimited extent.
No Scheme object is ever destroyed. The reason that
implementations of Scheme do not (usually!) run out of storage
is that they are permitted to reclaim the storage occupied by an
object if they can prove that the object cannot possibly matter
to any future computation. Other languages in which most objects
have unlimited extent include APL and other Lisp dialects.
Implementations of Scheme are required to be properly
tail-recursive. This allows the execution of an iterative
computation in constant space, even if the iterative computation
is described by a syntactically recursive procedure. Thus with a
tail-recursive implementation, iteration can be expressed using
the ordinary procedure-call mechanics, so that special iteration
constructs are useful only as syntactic sugar.
Scheme procedures are objects in their own right. Procedures can
be created dynamically, stored in data structures, returned as
results of procedures, and so on. Other languages with these
properties include Common Lisp and ML.
One distinguishing feature of Scheme is that continuations,
which in most other languages only operate behind the scenes,
also have ``first-class'' status. Continuations are useful for
implementing a wide variety of advanced control constructs,
including non-local exits, backtracking, and coroutines. See
section 6.9.
Arguments to Scheme procedures are always passed by value, which
means that the actual argument expressions are evaluated before
the procedure gains control, whether the procedure needs the
result of the evaluation or not. ML, C, and APL are three other
languages that always pass arguments by value. This is distinct
from the lazy-evaluation semantics of Haskell, or the
call-by-name semantics of Algol 60, where an argument expression
is not evaluated unless its value is needed by the procedure.
Scheme's model of arithmetic is designed to remain as
independent as possible of the particular ways in which numbers
are represented within a computer. In Scheme, every integer is a
rational number, every rational is a real, and every real is a
complex number. Thus the distinction between integer and real
arithmetic, so important to many programming languages, does not
appear in Scheme. In its place is a distinction between exact
arithmetic, which corresponds to the mathematical ideal, and
inexact arithmetic on approximations. As in Common Lisp, exact
arithmetic is not limited to integers.
1.2. Syntax
Scheme, like most dialects of Lisp, employs a fully
parenthesized prefix notation for programs and (other) data; the
grammar of Scheme generates a sublanguage of the language used
for data. An important consequence of this simple, uniform
representation is the susceptibility of Scheme programs and data
to uniform treatment by other Scheme programs.
The read procedure performs syntactic as well as lexical
decomposition of the data it reads. The read procedure parses
its input as data (section 7.1.2), not as program.
The formal syntax of Scheme is described in section 7.1.
1.3. Notation and terminology
1.3.1. Essential and non-essential features
It is required that every implementation of Scheme support
features that are marked as being essential. Features not
explicitly marked as essential are not essential.
Implementations are free to omit non-essential features of
Scheme or to add extensions, provided the extensions are not in
conflict with the language reported here. In particular,
implementations must support portable code by providing a
syntactic mode that preempts no lexical conventions of this
report and reserves no identifiers other than those listed as
syntactic keywords in section 2.1.
1.3.2. Error situations and unspecified behavior
When speaking of an error situation, this report uses the phrase
``an error is signalled'' to indicate that implementations must
detect and report the error. If such wording does not appear in
the discussion of an error, then implementations are not
required to detect or report the error, though they are
encouraged to do so. An error situation that implementations are
not required to detect is usually referred to simply as ``an
error.''
For example, it is an error for a procedure to be passed an
argument that the procedure is not explicitly specified to
handle, even though such domain errors are seldom mentioned in
this report. Implementations may extend a procedure's domain of
definition to include such arguments.
This report uses the phrase ``may report a violation of an
implementation restriction'' to indicate circumstances under
which an implementation is permitted to report that it is unable
to continue execution of a correct program because of some
restriction imposed by the implementation. Implementation
restrictions are of course discouraged, but implementations are
encouraged to report violations of implementation restrictions.
For example, an implementation may report a violation of an
implementation restriction if it does not have enough storage to
run a program.
If the value of an expression is said to be ``unspecified,''
then the expression must evaluate to some object without
signalling an error, but the value depends on the
implementation; this report explicitly does not say what value
should be returned.
1.3.3. Entry format
Chapters 4 and 6 are organized into entries. Each entry
describes one language feature or a group of related features,
where a feature is either a syntactic construct or a built-in
procedure. An entry begins with one or more header lines of the
form
template essential category
if the feature is an essential feature, or simply
template category
if the feature is not an essential feature.
If category is ``syntax'', the entry describes an expression
type, and the header line gives the syntax of the expression
type. Components of expressions are designated by syntactic
variables, which are written using angle brackets, for example,
<expression>, <variable>. Syntactic variables should be
understood to denote segments of program text; for example,
<expression> stands for any string of characters which is a
syntactically valid expression. The notation
<thing_1> ...
indicates zero or more occurrences of a <thing>, and
<thing_1> <thing_2> ...
indicates one or more occurrences of a <thing>.
If category is ``procedure'', then the entry describes a
procedure, and the header line gives a template for a call to
the procedure. Argument names in the template are italicized.
Thus the header line
(vector-ref vector k) essential procedure
indicates that the essential built-in procedure vector-ref takes
two arguments, a vector vector and an exact non-negative integer
k (see below). The header lines
(make-vector k) essential procedure
(make-vector k fill) procedure
indicate that in all implementations, the make-vector procedure
must be defined to take one argument, and some implementations
will extend it to take two arguments.
It is an error for an operation to be presented with an argument
that it is not specified to handle. For succinctness, we follow
the convention that if an argument name is also the name of a
type listed in section 3.4, then that argument must be of the
named type. For example, the header line for vector-ref given
above dictates that the first argument to vector-ref must be a
vector. The following naming conventions also imply type
restrictions:
obj any object
list, list_1, ... list_j, ... list (see section 6.3)
z, z_1, ... z_j, ... complex number
x, x_1, ... x_j, ... real number
y, y_1, ... y_j, ... real number
q, q_1, ... q_j, ... rational number
n, n_1, ... n_j, ... integer
k, k_1, ... k_j, ... exact non-negative integer
1.3.4. Evaluation examples
The symbol ``==>'' used in program examples should be read
``evaluates to.'' For example,
(* 5 8) ==> 40
means that the expression (* 5 8) evaluates to the object 40.
Or, more precisely: the expression given by the sequence of
characters ``(* 5 8)'' evaluates, in the initial environment, to
an object that may be represented externally by the sequence of
characters ``40''. See section 3.3 for a discussion of external
representations of objects.
1.3.5. Naming conventions
By convention, the names of procedures that always return a
boolean value usually end in ``?''. Such procedures are called
predicates.
By convention, the names of procedures that store values into
previously allocated locations (see section 3.5) usually end in
``!''. Such procedures are called mutation procedures. By
convention, the value returned by a mutation procedure is
unspecified.
By convention, ``->'' appears within the names of procedures
that take an object of one type and return an analogous object
of another type. For example, list->vector takes a list and
returns a vector whose elements are the same as those of the
list.
2. Lexical conventions
This section gives an informal account of some of the lexical
conventions used in writing Scheme programs. For a formal syntax
of Scheme, see section 7.1.
Upper and lower case forms of a letter are never distinguished
except within character and string constants. For example, Foo
is the same identifier as FOO, and #x1AB is the same number as
#X1ab.
2.1. Identifiers
Most identifiers allowed by other programming languages are also
acceptable to Scheme. The precise rules for forming identifiers
vary among implementations of Scheme, but in all implementations
a sequence of letters, digits, and ``extended alphabetic
characters'' that begins with a character that cannot begin a
number is an identifier. In addition, +, -, and ... are
identifiers. Here are some examples of identifiers:
lambda q
list->vector soup
+ V17a
<=? a34kTMNs
the-word-recursion-has-many-meanings
Extended alphabetic characters may be used within identifiers as
if they were letters. The following are extended alphabetic
characters:
+ - . * / < = > ! ? : $ % _ & ~ ^
See section 7.1.1 for a formal syntax of identifiers.
Identifiers have several uses within Scheme programs:
Certain identifiers are reserved for use as syntactic keywords
(see below).
Any identifier that is not a syntactic keyword may be used as a
variable (see section 3.1).
When an identifier appears as a literal or within a literal
(see section 4.1.2), it is being used to denote a symbol (see
section 6.4).
The following identifiers are syntactic keywords, and should not
be used as variables:
=> do or
and else quasiquote
begin if quote
case lambda set!
cond let unquote
define let* unquote-splicing
delay letrec
Some implementations allow all identifiers, including syntactic
keywords, to be used as variables. This is a compatible
extension to the language, but ambiguities in the language
result when the restriction is relaxed, and the ways in which
these ambiguities are resolved vary between implementations.
2.2. Whitespace and comments
Whitespace characters are spaces and newlines. (Implementations
typically provide additional whitespace characters such as tab
or page break.) Whitespace is used for improved readability and
as necessary to separate tokens from each other, a token being
an indivisible lexical unit such as an identifier or number, but
is otherwise insignificant. Whitespace may occur between any
two tokens, but not within a token. Whitespace may also occur
inside a string, where it is significant.
A semicolon (;) indicates the start of a comment. The comment
continues to the end of the line on which the semicolon appears.
Comments are invisible to Scheme, but the end of the line is
visible as whitespace. This prevents a comment from appearing in
the middle of an identifier or number.
;;; The FACT procedure computes the factorial
;;; of a non-negative integer.
(define fact
(lambda (n)
(if (= n 0)
1 ;Base case: return 1
(* n (fact (- n 1))))))
2.3. Other notations
For a description of the notations used for numbers, see section
6.5.
. + - These are used in numbers, and may also occur anywhere in
an identifier except as the first character. A delimited plus or
minus sign by itself is also an identifier. A delimited period
(not occurring within a number or identifier) is used in the
notation for pairs (section 6.3), and to indicate a
rest-parameter in a formal parameter list (section 4.1.4). A
delimited sequence of three successive periods is also an
identifier.
( ) Parentheses are used for grouping and to notate lists
(section 6.3).
' The single quote character is used to indicate literal data
(section 4.1.2).
` The backquote character is used to indicate almost-constant
data (section 4.2.6).
, ,@ The character comma and the sequence comma at-sign are used
in conjunction with backquote (section 4.2.6).
" The double quote character is used to delimit strings (section
6.7).
\ Backslash is used in the syntax for character constants
(section 6.6) and as an escape character within string constants
(section 6.7).
[ ] { } Left and right square brackets and curly braces are
reserved for possible future extensions to the language.
# Sharp sign is used for a variety of purposes depending on the
character that immediately follows it:
#t #f These are the boolean constants (section 6.1).
#\ This introduces a character constant (section 6.6).
#( This introduces a vector constant (section 6.8). Vector
constants are terminated by ) .
#e #i #b #o #d #x These are used in the notation for numbers
(section 6.5.4).
3. Basic concepts
3.1. Variables and regions
Any identifier that is not a syntactic keyword (see section 2.1)
may be used as a variable. A variable may name a location where
a value can be stored. A variable that does so is said to be
bound to the location. The set of all visible bindings in effect
at some point in a program is known as the environment in effect
at that point. The value stored in the location to which a
variable is bound is called the variable's value. By abuse of
terminology, the variable is sometimes said to name the value or
to be bound to the value. This is not quite accurate, but
confusion rarely results from this practice.
Certain expression types are used to create new locations and to
bind variables to those locations. The most fundamental of these
binding constructs is the lambda expression, because all other
binding constructs can be explained in terms of lambda
expressions. The other binding constructs are let, let*, letrec,
and do expressions (see sections 4.1.4, 4.2.2, and 4.2.4).
Like Algol and Pascal, and unlike most other dialects of Lisp
except for Common Lisp, Scheme is a statically scoped language
with block structure. To each place where a variable is bound in
a program there corresponds a region of the program text within
which the binding is effective. The region is determined by the
particular binding construct that establishes the binding; if
the binding is established by a lambda expression, for example,
then its region is the entire lambda expression. Every reference
to or assignment of a variable refers to the binding of the
variable that established the innermost of the regions
containing the use. If there is no binding of the variable whose
region contains the use, then the use refers to the binding for
the variable in the top level environment, if any (section 6);
if there is no binding for the identifier, it is said to be
unbound.
3.2. True and false
Any Scheme value can be used as a boolean value for the purpose
of a conditional test. As explained in section 6.1, all values
count as true in such a test except for #f. This report uses the
word ``true'' to refer to any Scheme value that counts as true,
and the word ``false'' to refer to #f.
Note: In some implementations the empty list also counts as
false instead of true.
3.3. External representations
An important concept in Scheme (and Lisp) is that of the
external representation of an object as a sequence of
characters. For example, an external representation of the
integer 28 is the sequence of characters ``28'', and an external
representation of a list consisting of the integers 8 and 13 is
the sequence of characters ``(8 13)''.
The external representation of an object is not necessarily
unique. The integer 28 also has representations ``#e28.000'' and
``#x1c'', and the list in the previous paragraph also has the
representations ``( 08 13 )'' and ``(8 . (13 . ()))'' (see
section 6.3).
Many objects have standard external representations, but some,
such as procedures, do not have standard representations
(although particular implementations may define representations
for them).
An external representation may be written in a program to obtain
the corresponding object (see quote, section 4.1.2).
External representations can also be used for input and output.
The procedure read (section 6.10.2) parses external
representations, and the procedure write (section 6.10.3)
generates them. Together, they provide an elegant and powerful
input/output facility.
Note that the sequence of characters ``(+ 2 6)'' is not an
external representation of the integer 8, even though it is an
expression evaluating to the integer 8; rather, it is an
external representation of a three-element list, the elements of
which are the symbol + and the integers 2 and 6. Scheme's syntax
has the property that any sequence of characters that is an
expression is also the external representation of some object.
This can lead to confusion, since it may not be obvious out of
context whether a given sequence of characters is intended to
denote data or program, but it is also a source of power, since
it facilitates writing programs such as interpreters and
compilers that treat programs as data (or vice versa).
The syntax of external representations of various kinds of
objects accompanies the description of the primitives for
manipulating the objects in the appropriate sections of chapter
6.
3.4. Disjointness of types
No object satisfies more than one of the following predicates:
boolean? pair?
symbol? number?
char? string?
vector? procedure?
These predicates define the types boolean, pair, symbol, number,
char (or character), string, vector, and procedure.
3.5. Storage model
Variables and objects such as pairs, vectors, and strings
implicitly denote locations or sequences of locations. A string,
for example, denotes as many locations as there are characters
in the string. (These locations need not correspond to a full
machine word.) A new value may be stored into one of these
locations using the string-set! procedure, but the string
continues to denote the same locations as before.
An object fetched from a location, by a variable reference or by
a procedure such as car, vector-ref, or string-ref, is
equivalent in the sense of eqv? (section 6.2) to the object last
stored in the location before the fetch.
Every location is marked to show whether it is in use. No
variable or object ever refers to a location that is not in use.
Whenever this report speaks of storage being allocated for a
variable or object, what is meant is that an appropriate number
of locations are chosen from the set of locations that are not
in use, and the chosen locations are marked to indicate that
they are now in use before the variable or object is made to
denote them.
In many systems it is desirable for constants (i.e. the values
of literal expressions) to reside in read-only-memory. To
express this, it is convenient to imagine that every object that
denotes locations is associated with a flag telling whether that
object is mutable or immutable. The constants and the strings
returned by symbol->string are then the immutable objects, while
all objects created by the other procedures listed in this
report are mutable. It is an error to attempt to store a new
value into a location that is denoted by an immutable object.
4. Expressions
A Scheme expression is a construct that returns a value, such as
a variable reference, literal, procedure call, or conditional.
Expression types are categorized as primitive or derived.
Primitive expression types include variables and procedure
calls. Derived expression types are not semantically primitive,
but can instead be explained in terms of the primitive
constructs as in section 7.3. They are redundant in the strict
sense of the word, but they capture common patterns of usage,
and are therefore provided as convenient abbreviations.
4.1. Primitive expression types
4.1.1. Variable references
<variable> essential syntax
An expression consisting of a variable (section 3.1) is a
variable reference. The value of the variable reference is the
value stored in the location to which the variable is bound. It
is an error to reference an unbound variable.
(define x 28)