This repository was archived by the owner on Nov 6, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathch13
264 lines (167 loc) · 8.69 KB
/
ch13
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
Introduction to Gofer 13. LAYOUT
13. LAYOUT
13.1 Comments
-------------
Comments provide an informal but useful way of annotating a program
with a description of its purpose, structure and development.
Following the definition of Haskell, two styles of comment are
supported by Gofer:
o A one line comment begins with the two characters "--" and is
terminated at the end of the same line. Note that an operator
symbol cannot begin with "--" as this will be treated as the
beginning of a comment. It is however possible to use the two
characters "--" at any other position within an operator symbol.
Thus a line such as:
(xs ++ ys) -- xs
includes a comment and will actually be treated as if the line had
been written:
(xs ++ ys)
Whereas the line:
xs >--> ys >--> zs
does not contain any comments (although it will cause an error
unless ">-->" has been defined using an appropriate infixl or
infixr declaration).
o A nested comment begins with the characters "{-", ends with the
characters "-}" and may span any number of lines. [N.B. the
initial "{-" string cannot overlap with the terminating "-}"
string so that the shortest possible nested comment is "{--}", and
not "{-}"]. An unterminated nested comment will be treated as an
error.
As the name suggests, comments of this kind may be nested so that
"{- {- ... -} ... {- ... -} -}" is treated as a single comment.
This makes nested comments particularly convenient for enclosing
parts of a program which may already contain other nested
comments.
Both kinds of comment may be used in expressions entered directly into
the Gofer system, or more usually, in files of definitions loaded into
Gofer. The two styles of comment may be mixed within the same
expression or program, remembering that the string "--" has no special
significance within a nested comment and that the strings "{-" and "-}"
have no special significance in a single line comment. Thus:
[ 2, -- {- [ 2, {-
3, -- -} -- -} 3,
4 ] 4 ]
are both equivalent to the list expression [2,3,4].
57
Introduction to Gofer 13.2 The layout rule
13.2 The layout rule
--------------------
In a tradition dating back at least a quarter of a century to Landin's
ISWIM family of languages, most Gofer programs use indentation to
indicate the structure of a program. For example, in a definition such
as:
f x y = g (x + w)
where g u = u + v
where v = u * u
w = 2 + y
it is clear from the layout that the definition of w is intended to be
local to f rather than to g. Another example where layout plays an
important role is in distinguishing the two definitions:
example x y z = a + b example x y z = a + b
where a = f x y where a = f x
b = g z y b = g z
There are three situations in Gofer where indentation is typically used
to determine the structure of a program:
o At the top-level of a file of definitions.
o In a group of local declarations following either of the keywords
"let" or "where".
o In a group of alternatives in a case expression, following the
keyword "of".
In each case, Gofer actually expects to find a list of items enclosed
between braces `{' and `}' with individual items separated from one
another by semicolons `;'. However, if the leading brace is not found
then Gofer uses the layout rule described below to arrange for `{', `}'
and `;' tokens to be inserted into the input stream automatically
according to the indentation of each line.
In this way, the first example above will in fact be treated as if the
user had entered:
f x y = g (x + w)
where {g u = u + v
where {v = u * u
}; w = 2 + y
}
or, equivalently, just:
f x y = g (x + w) where {g u = u + v where {v = u * u}; w = 2 + y}
where the additional punctuation using the `{', `}' and `;' characters
makes the intended grouping clear, regardless of indentation.
58
Introduction to Gofer 13.2 The layout rule
The layout rule used in Gofer is the same as that of Haskell, and can
be described as follows:
o An opening brace `{' is inserted in front of the first token at
the beginning of a file or following one of the keywords "where",
"let" or "of", unless that token is itself an opening brace.
o A `;' token is inserted in front of the first token in any
subsequent line with exactly the same indentation as the token in
front of which the opening brace was inserted.
o The layout rule ends and a `}' token is inserted in front of the
first token in a subsequent line whose indentation is strictly
less than that of the token in front of which the opening brace
was inserted.
o A closing brace `}' will also be inserted at any point where an
otherwise unexpected token is encountered. This part of the rule
makes it possible to use expressions such as:
let a = fact 12 in a+a
without needing to use the layout characters explicitly as in:
let {a = fact 12} in a+a.
o Lines containing only whitespace (blanks and tabs) and comments do
not affect the use of the layout rule.
o For the purposes of determining the indentation of each line in a
file, tab stops are assumed to be placed every 8 characters, with
the leftmost tab stop in column 9. Each tab character inserts one
or more spaces as necessary to move to the next tab stop.
o The indentation of the end of file token is zero.
The following (rather contrived) program, is based on an example in the
Haskell report [5], and provides an extended example of the use of the
layout rule. A file containing the following definitions:
data Stack a = Empty
| MkStack a (Stack a)
push :: a -> Stack a -> Stack a
push x s = MkStack x s
size :: Stack a -> Int
size s = length (stkToList s) where
stkToList Empty = []
stkToList (MkStack x s) = x:xs where xs = stkToList s
pop :: Stack a -> (a, Stack a)
pop (MkStack x s) = (x, case s of r -> i r where i x = x)
top :: Stack a -> a
top (MkStack x s) = x
59
Introduction to Gofer 13.2 The layout rule
will be treated by Gofer as if it has been written:
{data Stack a = Empty
| MkStack a (Stack a)
;push :: a -> Stack a -> Stack a
;push x s = MkStack x s
;size :: Stack a -> Int
;size s = length (stkToList s) where
{stkToList Empty = []
;stkToList (MkStack x s) = x:xs where {xs = stkToList s
}};pop :: Stack a -> (a, Stack a)
;pop (MkStack x s) = (x, case s of {r -> i r where {i x = x}})
;top :: Stack a -> a
;top (MkStack x s) = x
}
Note that some of the more sophisticated forms of expression cannot be
written on a single line (and hence entered directly into the Gofer
system) without explicit use of the layout characters `{', `}' and `;':
? len [1..10] where len [] = 0; len (x:xs) = 1 + len xs
10
(81 reductions, 108 cells)
? f True where f x = case x of True->n where {n=not x}; False->True
False
(4 reductions, 11 cells)
?
One situation in which the layout rule can cause problems is with
top-level definitions. For example, the two lines:
f x = 1 + x
g y = 1 - y
will be treated as a single line "f x = 1 + x g y = 1 - y", which will
cause a syntax error. This kind of problem becomes rather more
difficult to spot if the two definitions are not on subsequent lines,
particularly if they are separated by several lines of comments. For
this reason, it is usually a good idea to ensure that all of the
top-level definitions in a file start in the same column (the first
column is usually the most convenient). COBOL and Fortran programmers
are not likely to find this problem too distressing :-)
60