Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 396 lines (354 sloc) 13.541 kb
b6c6468 Miek Gieben use ubercool underbraces
authored
1 \epi{I'm always delighted by the light touch and stillness of
2 early programming languages. Not much text; a lot gets
3 done. Old programs read like quiet conversations
4 between a well-spoken research worker and a well-
5 studied mechanical colleague, not as a debate with a
6 compiler. Who'd have guessed sophistication bought
1f704ac Miek Gieben sorta fix small caps
authored
7 such noise?}{\textsc{RICHARD P. GABRIEL}}
b6c6468 Miek Gieben use ubercool underbraces
authored
8
9 \noindent{}Functions are the basic building blocks in Go programs; all interesting
6e05a3d Miek Gieben more stuff for the better
authored
10 stuff happens in them. A function is declared as follows:
80c31b4 Miek Gieben added explanation for functions
authored
11 \input{fig/function.tex}
12 \showremarks
12c8a6c Miek Gieben small tweaks
authored
13 Here are a two examples, the left is a function without a return value,
14 the one on the right is a simple function that returns its input.
1338834 Miek Gieben put the function next to each other
authored
15
16 \begin{minipage}{.5\textwidth}
b9c8efb Miek Gieben add piece for defer
authored
17 \begin{lstlisting}
18 func subroutine(in int) {
19 return
20 }
21 \end{lstlisting}
1338834 Miek Gieben put the function next to each other
authored
22 \end{minipage}
23 \begin{minipage}{.5\textwidth}
b9c8efb Miek Gieben add piece for defer
authored
24 \begin{lstlisting}
25 func identity(in int) int {
26 return in
27 }
28 \end{lstlisting}
1338834 Miek Gieben put the function next to each other
authored
29 \end{minipage}
30
df075f6 Miek Gieben First 3 chaps done
authored
31 Functions can be declared in any order you wish, the compiler scans the
32 entire file before execution. So function prototyping is a thing of the
33 past in Go.
02e7dab Miek Gieben Lots of (small) changes by JC
authored
34 Go disallows nested functions.
8439630 Miek Gieben more
authored
35 You can however
0cc6318 Miek Gieben add method/function call. Fix references
authored
36 work around this by using anonymous functions, see section
58804c1 Miek Gieben titleref
authored
37 "\titleref{sec:functions as values}" on page \pageref{sec:functions as values}
0cc6318 Miek Gieben add method/function call. Fix references
authored
38 in this chapter.
17a1170 Miek Gieben add scope figure
authored
39
f9dde2f Miek Gieben move the average function to the correct place
authored
40 Recursive functions just work as in other languages:
41 \begin{lstlisting}[caption=Recursive function]
42 func rec(i int) {
43 if i == 10 {
44 return
45 }
46 rec(i+1)
47 fmt.Printf("%d ", i)
48 }
49 \end{lstlisting}
50 This prints \texttt{9 8 7 6 5 4 3 2 1 0}.
51
17a1170 Miek Gieben add scope figure
authored
52 \section{Scope}
df075f6 Miek Gieben First 3 chaps done
authored
53 Variables declared outside any functions are \first{global}{scope!local} in Go, those
54 defined in functions are \first{local}{scope!local} to those functions. If names overlap --- a
b9c8efb Miek Gieben add piece for defer
authored
55 local variable is declared with the same name as a global one --- the
02e7dab Miek Gieben Lots of (small) changes by JC
authored
56 local variable hides the global one when the current function is
eb3f994 Miek Gieben need todo scope3
authored
57 executed.
02e7dab Miek Gieben Lots of (small) changes by JC
authored
58
17a1170 Miek Gieben add scope figure
authored
59 \begin{minipage}{.5\textwidth}
60 \input{fig/scope1.tex}
61 \hfill
9670ad2 Miek Gieben more stuff and better
authored
62 \vfill
17a1170 Miek Gieben add scope figure
authored
63 \end{minipage}
609a702 Miek Gieben Make it work with a5paper
authored
64 \hfill
17a1170 Miek Gieben add scope figure
authored
65 \begin{minipage}{.5\textwidth}
66 \input{fig/scope2.tex}
67 \hfill
9670ad2 Miek Gieben more stuff and better
authored
68 \vfill
17a1170 Miek Gieben add scope figure
authored
69 \end{minipage}
70
9670ad2 Miek Gieben more stuff and better
authored
71 In listing \ref{src:scope1} we introduce a local variable \var{a}
02e7dab Miek Gieben Lots of (small) changes by JC
authored
72 in the function \func{q()}.
9670ad2 Miek Gieben more stuff and better
authored
73 This local \var{a} is only visible in \func{q()}. That is
74 why the code will print: \texttt{656}.
75 In listing \ref{src:scope2} no new variables are introduced, there
76 is only a global \var{a}.
df075f6 Miek Gieben First 3 chaps done
authored
77 Assigning a new value to will be globally visible. This code will
9670ad2 Miek Gieben more stuff and better
authored
78 print: \texttt{655}
79
eb3f994 Miek Gieben need todo scope3
authored
80 In the following example we call \func{g()} from \func{f()}:
df075f6 Miek Gieben First 3 chaps done
authored
81
66920e2 Miek Gieben drop the dots at the end of the captions
authored
82 \lstinputlisting[caption=Scope when calling functions from functions]{src/scope3.go}
df075f6 Miek Gieben First 3 chaps done
authored
83
d8e9406 Miek Gieben another review of chapter 3
authored
84 The printout will be: \texttt{565}. A \emph{local} variable is \emph{only}
02e7dab Miek Gieben Lots of (small) changes by JC
authored
85 valid when we are executing the function in which it is defined.
df075f6 Miek Gieben First 3 chaps done
authored
86 %%Finally, one can create a \first{"function literal"}{function literal} in which you essentially
87 %%define a function inside another
88 %%function, i.e. a \first{nested function}{nested function}.
89 %%The following figure should clarify why it prints: \texttt{565757}.
90 %%\input{fig/scope3.tex}
eb3f994 Miek Gieben need todo scope3
authored
91
80c31b4 Miek Gieben added explanation for functions
authored
92 \section{Multiple return values}
93 \label{sec:multiple return}
21f65e7 Miek Gieben added stuff
authored
94 One of Go's unusual features is that functions and methods can return multiple
02e7dab Miek Gieben Lots of (small) changes by JC
authored
95 values (Python can do this too). This can be used to improve on a couple of
96 clumsy idioms in C programs:
eb3f994 Miek Gieben need todo scope3
authored
97 in-band error returns (such as -1 for \texttt{EOF}) and modifying an argument.
d8e9406 Miek Gieben another review of chapter 3
authored
98 In Go, \lstinline{Write} returns a count and an
21f65e7 Miek Gieben added stuff
authored
99 error: "Yes, you wrote some bytes but not all of them because you filled the
100 device". The signature of \lstinline{*File.Write} in package
101 \package{os} is:
102 \begin{lstlisting}
103 func (file *File) Write(b []byte) (n int, err Error)
104 \end{lstlisting}
105 and as the documentation says, it returns the number of bytes written and a
8966fda Miek Gieben more proof reading fixes
authored
106 non-\lstinline{nil} \var{Error} when \lstinline{n != len(b)}. This is a common
eb3f994 Miek Gieben need todo scope3
authored
107 style in Go.
21f65e7 Miek Gieben added stuff
authored
108
109 A similar approach obviates the need to pass a pointer to a return value to
110 simulate a reference parameter. Here's a simple-minded function to grab a
111 number from a position in a byte array, returning the number and the next
112 position.
113 \begin{lstlisting}
114 func nextInt(b []byte, i int) (int, int) {
115 x := 0
0cc6318 Miek Gieben add method/function call. Fix references
authored
116 // Naively assume everything is a number
117 for ; i < len(b); i++ {
21f65e7 Miek Gieben added stuff
authored
118 x = x*10 + int(b[i])-'0'
119 }
120 return x, i
121 }
122 \end{lstlisting}
123 You could use it to scan the numbers in an input array a like this:
124 \begin{lstlisting}
0cc6318 Miek Gieben add method/function call. Fix references
authored
125 a := []byte{'1', '2', '3', '4'}
126 var x int
127 for i := 0; i < len(a); { |\coderemark{No \texttt{i++}}|
128 x, i = nextInt(a, i)
129 println(x)
130 }
21f65e7 Miek Gieben added stuff
authored
131 \end{lstlisting}
02e7dab Miek Gieben Lots of (small) changes by JC
authored
132 Without having tuples as a native type, multiple return values is the next
eb3f994 Miek Gieben need todo scope3
authored
133 best thing to have. You can return precisely what you want without
134 overloading the domain space with special values to signal errors.
b9c8efb Miek Gieben add piece for defer
authored
135
136 \section{Named result parameters}
aa4f15b Miek Gieben add more stuff about defer
authored
137 \label{sec:named result parameters}
df075f6 Miek Gieben First 3 chaps done
authored
138 The return or result parameters of a Go function can be given names and used
21f65e7 Miek Gieben added stuff
authored
139 as regular variables, just like the incoming parameters. When named, they are
140 initialized to the zero values for their types when the function begins; if the
ebf32e8 Miek Gieben multiple tweaks
authored
141 function executes a \key{return} statement with no arguments, the current values of
eb3f994 Miek Gieben need todo scope3
authored
142 the result parameters are used as the returned values. Using this
c80be2c Miek Gieben Use letters for footnotes
authored
143 features enables you (again) to do more with less code \footnote{This is
ae22103 Miek Gieben style changes
authored
144 a motto of Go; "Do \emph{more} with \emph{less} code".}.
21f65e7 Miek Gieben added stuff
authored
145
ebf32e8 Miek Gieben multiple tweaks
authored
146 The names are not mandatory but they can make code shorter and clearer:
147 \emph{they are documentation}.
148 If we name the results of \lstinline{nextInt} it becomes obvious which
149 returned \type{int} is which.
21f65e7 Miek Gieben added stuff
authored
150
151 \begin{lstlisting}
f08ef0b Miek Gieben more automatic code checking
authored
152 func nextInt(b []byte, pos int) (value, nextPos int) { /* ... */ }
21f65e7 Miek Gieben added stuff
authored
153 \end{lstlisting}
154 Because named results are initialized and tied to an unadorned
155 \key{return},
156 they can simplify as well as clarify. Here's a version of
157 \lstinline{io.ReadFull} that uses them well:
158
159 \begin{lstlisting}
160 func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
161 for len(buf) > 0 && err == nil {
162 var nr int
163 nr, err = r.Read(buf)
164 n += nr
165 buf = buf[nr:len(buf)]
166 }
167 return
168 }
169 \end{lstlisting}
164f7a7 Miek Gieben start new repo
authored
170 In the following example we declare a simple function which calculates
df075f6 Miek Gieben First 3 chaps done
authored
171 \gomarginpar{Some text in this section comes from \cite{go_intro}.} % layout
164f7a7 Miek Gieben start new repo
authored
172 the factorial value of a value \var{x}.
173 \begin{lstlisting}
6e05a3d Miek Gieben more stuff for the better
authored
174 func Factorial(x int) int { |\coderemark{\texttt{func Factorial(x int) (int)} is also OK}|
164f7a7 Miek Gieben start new repo
authored
175 if x == 0 {
820c9bc Miek Gieben first batch of comments, checked in
authored
176 return 1
164f7a7 Miek Gieben start new repo
authored
177 } else {
820c9bc Miek Gieben first batch of comments, checked in
authored
178 return x * Factorial(x - 1)
164f7a7 Miek Gieben start new repo
authored
179 }
180 }
181 \end{lstlisting}
eb3f994 Miek Gieben need todo scope3
authored
182 So you could also write factorial as:
164f7a7 Miek Gieben start new repo
authored
183 \begin{lstlisting}
184 func Factorial(x int) (result int) {
185 if x == 0 {
820c9bc Miek Gieben first batch of comments, checked in
authored
186 result = 1
164f7a7 Miek Gieben start new repo
authored
187 } else {
820c9bc Miek Gieben first batch of comments, checked in
authored
188 result = x * Factorial(x - 1)
164f7a7 Miek Gieben start new repo
authored
189 }
820c9bc Miek Gieben first batch of comments, checked in
authored
190 return
164f7a7 Miek Gieben start new repo
authored
191 }
192 \end{lstlisting}
02e7dab Miek Gieben Lots of (small) changes by JC
authored
193 When we use named result values, the code is shorter and
194 easier to read.
195 You can also write a function with multiple return values:
164f7a7 Miek Gieben start new repo
authored
196 \begin{lstlisting}
197 func fib(n) (val int, pos int) {
198 if n == 0 {
820c9bc Miek Gieben first batch of comments, checked in
authored
199 val = 1
200 pos = 0
164f7a7 Miek Gieben start new repo
authored
201 } else if n == 1 {
820c9bc Miek Gieben first batch of comments, checked in
authored
202 val = 1
203 pos = 1
164f7a7 Miek Gieben start new repo
authored
204 } else {
820c9bc Miek Gieben first batch of comments, checked in
authored
205 v1, _ := fib(n-1)
f3af4be Miek Gieben Again a batch of fixes from Filip
authored
206 v2, _ := fib(n-2)
820c9bc Miek Gieben first batch of comments, checked in
authored
207 val = v1 + v2
208 pos = n
164f7a7 Miek Gieben start new repo
authored
209 }
820c9bc Miek Gieben first batch of comments, checked in
authored
210 return
164f7a7 Miek Gieben start new repo
authored
211 }
212 \end{lstlisting}
213
b9c8efb Miek Gieben add piece for defer
authored
214 \section{Deferred code}
215 Suppose you have a function in which you open a file and perform various
216 writes and reads on it. In such a function there are often spots where
eb3f994 Miek Gieben need todo scope3
authored
217 you want to return early. If you do that, you will need to close the file
b9c8efb Miek Gieben add piece for defer
authored
218 descriptor you are working on. This often leads to the following code:
5a25657 Miek Gieben Now style stuff in captions
authored
219 \begin{lstlisting}[caption=Without defer]
f08ef0b Miek Gieben more automatic code checking
authored
220 func ReadWrite() bool {
eb3f994 Miek Gieben need todo scope3
authored
221 file.Open("file")
b9c8efb Miek Gieben add piece for defer
authored
222 // Do you thing
223 if failureX {
820c9bc Miek Gieben first batch of comments, checked in
authored
224 file.Close()
b9c8efb Miek Gieben add piece for defer
authored
225 return false
226 }
227
228 if failureY {
820c9bc Miek Gieben first batch of comments, checked in
authored
229 file.Close()
b9c8efb Miek Gieben add piece for defer
authored
230 return false
231 }
820c9bc Miek Gieben first batch of comments, checked in
authored
232 file.Close()
b9c8efb Miek Gieben add piece for defer
authored
233 return true
234 }
235 \end{lstlisting}
d8e9406 Miek Gieben another review of chapter 3
authored
236 Here a lot of code is repeated. To overcome this Go has the
df075f6 Miek Gieben First 3 chaps done
authored
237 \first{\key{defer}}{keyword!defer} statement. After
8e6fa40 Miek Gieben Filip Zaludek fix
authored
238 \key{defer} you specify a function which is called just \emph{before} a
239 return from the function is executed.
b9c8efb Miek Gieben add piece for defer
authored
240
02e7dab Miek Gieben Lots of (small) changes by JC
authored
241 The code above could be rewritten as follows. This makes the
aa4f15b Miek Gieben add more stuff about defer
authored
242 function more readable, shorter and puts the \func{Close} right next
243 to the \func{Open}.
5a25657 Miek Gieben Now style stuff in captions
authored
244 \begin{lstlisting}[caption=With defer]
f08ef0b Miek Gieben more automatic code checking
authored
245 func ReadWrite() bool {
eb3f994 Miek Gieben need todo scope3
authored
246 file.Open("file")
f08ef0b Miek Gieben more automatic code checking
authored
247 defer file.Close() |\coderemark{\func{file.Close()} \emph{is} the function}|
b9c8efb Miek Gieben add piece for defer
authored
248 // Do you thing
249 if failureX {
f08ef0b Miek Gieben more automatic code checking
authored
250 return false |\coderemark{\func{Close()} is now done automatically}|
b9c8efb Miek Gieben add piece for defer
authored
251 }
252 if failureY {
f08ef0b Miek Gieben more automatic code checking
authored
253 return false |\coderemark{And here too}|
b9c8efb Miek Gieben add piece for defer
authored
254 }
255 return true
256 }
257 \end{lstlisting}
278d4d4 Miek Gieben spell check
authored
258 You can put multiple functions on the "deferred list"\index{deferred list}, like this
eb3f994 Miek Gieben need todo scope3
authored
259 example from \cite{effective_go}:
18eade9 Miek Gieben more
authored
260 \begin{lstlisting}
261 for i := 0; i < 5; i++ {
262 defer fmt.Printf("%d ", i)
263 }
264 \end{lstlisting}
265 Deferred functions are executed in LIFO order, so the above code
aa4f15b Miek Gieben add more stuff about defer
authored
266 prints: \lstinline{4 3 2 1 0}.
267
268 With \func{defer} you can even change return values, provided that
df075f6 Miek Gieben First 3 chaps done
authored
269 you are using named result parameters and a function
eb27712 Miek Gieben remove another bunch of todos
authored
270 literal\index{function!literal}\footnote{A function literal
271 is sometimes called a \index{closure} closure.}, i.e:
66920e2 Miek Gieben drop the dots at the end of the captions
authored
272 \begin{lstlisting}[caption=Function literal]
aa4f15b Miek Gieben add more stuff about defer
authored
273 defer func() {
f08ef0b Miek Gieben more automatic code checking
authored
274 /* ... */
d44ae4d Miek Gieben more changes
authored
275 }() |\coderemark{() is needed here}|
aa4f15b Miek Gieben add more stuff about defer
authored
276 \end{lstlisting}
bcdbb27 Miek Gieben Add parameters to the function.
authored
277 Or this example which makes it easier to understand why and where
278 you need the braces:
279 \begin{lstlisting}[caption=Function literal with parameters]
280 defer func(x int) {
281 /* ... */
282 }(5) |\coderemark{Give the input variable \var{x} the value 5}|
283 \end{lstlisting}
d44ae4d Miek Gieben more changes
authored
284 In that (unnamed) function you can access any named return
02e7dab Miek Gieben Lots of (small) changes by JC
authored
285 parameter:
5a25657 Miek Gieben Now style stuff in captions
authored
286 \begin{lstlisting}[caption=Access return values within defer]
f08ef0b Miek Gieben more automatic code checking
authored
287 func f() (ret int) { |\coderemark{\var{ret} is initialized with zero}|
aa4f15b Miek Gieben add more stuff about defer
authored
288 defer func() {
a537d58 Miek Gieben small fixes
authored
289 ret++ |\coderemark{Increment \var{ret} with 1}|
aa4f15b Miek Gieben add more stuff about defer
authored
290 }()
df075f6 Miek Gieben First 3 chaps done
authored
291 return 0 |\coderemark{1 \emph{not} 0 will be returned!}|
aa4f15b Miek Gieben add more stuff about defer
authored
292 }
293 \end{lstlisting}
294
b9c8efb Miek Gieben add piece for defer
authored
295 \section{Variadic parameters}
7b95cc0 Miek Gieben more more more
authored
296 \todo{Extend this section a bit. How to call another function with
d8e9406 Miek Gieben another review of chapter 3
authored
297 a variadic argument (propagation) (MG).}
b9c8efb Miek Gieben add piece for defer
authored
298 Functions that take variadic parameters are functions that have a
02e7dab Miek Gieben Lots of (small) changes by JC
authored
299 variable number of parameters. To do this, you first
300 need to declare your function to take variadic arguments:
d05e417 Miek Gieben remove stuff
authored
301 \begin{lstlisting}
f800954 Miek Gieben more on variadac args
authored
302 func myfunc(arg ... int) {}
303 \end{lstlisting}
304 The \lstinline{arg ... int} instructs Go to see this as a function that
02e7dab Miek Gieben Lots of (small) changes by JC
authored
305 takes a variable number of arguments. Note that these arguments all
f800954 Miek Gieben more on variadac args
authored
306 have the type \type{int}. Inside your function's body the variable
d02c2fa Miek Gieben fix prural of types (ints, strings) dont make the first part bold
authored
307 \var{arg} is a slice of ints:
f800954 Miek Gieben more on variadac args
authored
308 \begin{lstlisting}
309 for _, n := range arg {
310 fmt.Printf("And the number is: %d\n", n)
311 }
312 \end{lstlisting}
5dd602f Miek Gieben more
authored
313
c29f528 Miek Gieben Spell check
authored
314 If you don't specify the type of the variadic argument it defaults to the
7add098 Miek Gieben fix references n stuff
authored
315 empty interface \var{interface\{\}} (see chapter
316 \ref{chap:interfaces}").
21f65e7 Miek Gieben added stuff
authored
317
cd19815 Miek Gieben add anonymous functions
authored
318 \section{Functions as values}
319 \label{sec:functions as values}
df075f6 Miek Gieben First 3 chaps done
authored
320 \index{function!as values}
321 \index{function!literals}
02e7dab Miek Gieben Lots of (small) changes by JC
authored
322 As with almost everything in Go, functions are also \emph{just} values.
323 They can be assigned to variables as follows:
d8e9406 Miek Gieben another review of chapter 3
authored
324 \lstinputlisting[label=src:anonfunc,caption=Anonymous function,linerange={3,}]{src/anon-func.go}
02e7dab Miek Gieben Lots of (small) changes by JC
authored
325 If we use \lstinline{fmt.Printf("%T\n", a)} to print the type of
326 \var{a}, it prints \func{func()}.
cd19815 Miek Gieben add anonymous functions
authored
327
fc00628 Miek Gieben functions as values expanded
authored
328 Functions--as--values may also be used in other places, like in maps.
df075f6 Miek Gieben First 3 chaps done
authored
329 Here we convert from integers to functions:
17f2abb Miek Gieben lots of updates
authored
330 \begin{lstlisting}[caption=Functions as values in maps]
02e7dab Miek Gieben Lots of (small) changes by JC
authored
331 var xs = map[int]func() int{
332 1: func() int { return 10 },
333 2: func() int { return 20 },
f08ef0b Miek Gieben more automatic code checking
authored
334 3: func() int { return 30 }, |\coderemark{Mandatory ,}|
335 /* ... */
336 }
fc00628 Miek Gieben functions as values expanded
authored
337 \end{lstlisting}
a84fec3 Miek Gieben add higher order Map function
authored
338 Or you can write a function that takes a function as its parameter, for
8966fda Miek Gieben more proof reading fixes
authored
339 example a \func{Map} function that works on \type{int} slices. This is
340 left as an exercise for the reader, see exercise Q\ref{ex:map function}
341 on page \pageref{ex:map function}.
fc00628 Miek Gieben functions as values expanded
authored
342
16121c9 Miek Gieben Add more
authored
343 \section{Callbacks and closures}
344 \label{sec:callbacks}
345
346
74f9941 Miek Gieben start work on panic/recover
authored
347 \section{Panic and recovering}
ccd7f2b Miek Gieben more typos fixed
authored
348 \label{sec:panic}
832d3d4 Miek Gieben more on panic and recover
authored
349 Go does not have a exception mechanism, like that in Java for instance: you can not throw exceptions.
350 Instead it using a panic-and-recover mechanism. It is worth remembering that you should use this as
351 a last resort, your code will not look, or be, better if it is littered with panics. It's a powerful tool:
352 use it wisely. So, how do you use it.
353
354 The following description was taken from \cite{go_blog_panic}:
355 \begin{description}
356 \item[Panic]{is a built-in function that stops the ordinary flow of control and begins panicking. When the function
357 \func{F} calls \key{panic},
358 execution of \func{F} stops, any deferred functions in \func{F} are executed normally, and
359 then \func{F} returns to its caller. To the caller, \func{F} then
360 behaves like a call to \key{panic}. The process continues up the stack until all functions in the current
361 goroutine have returned, at which point the program crashes.
362
363 Panics can be initiated by invoking \func{panic} directly. They can also be caused by \emph{runtime errors}, such
364 as out-of-bounds array accesses.}
365
366 \item[Recover]{is a built-in function that regains control of a panicking goroutine. Recover is \emph{only} useful inside
40195c3 Miek Gieben emph the right word
authored
367 \emph{deferred} functions.
832d3d4 Miek Gieben more on panic and recover
authored
368
369 During normal execution, a call to \func{recover} will return \type{nil} and have no other effect.
370 If the current goroutine is panicking, a call
371 to \func{recover} will capture the value given to \func{panic} and resume normal execution.}
372 \end{description}
74f9941 Miek Gieben start work on panic/recover
authored
373
1480620 Miek Gieben add more stuff
authored
374 \section{Exercises}
8144196 Miek Gieben more stuff moved around
authored
375 \input{ex-functions/ex-average.tex}
376
02e7dab Miek Gieben Lots of (small) changes by JC
authored
377 \input{ex-functions/ex-order.tex}
378
3134bde Miek Gieben More comments from JC. This time for chapter 04
authored
379 \input{ex-functions/ex-scope.tex}
380
ab3a85f Miek Gieben added figure and exercises
authored
381 \input{ex-functions/ex-stack.tex}
382
81e1b36 Miek Gieben tweaks and making it better
authored
383 \input{ex-functions/ex-vararg.tex}
384
7fcac65 Miek Gieben Move around the fibonaci exercise and add one in channels chapter
authored
385 \input{ex-functions/ex-fib.tex}
386
691d301 Miek Gieben put map exercise in the function chapter
authored
387 \input{ex-functions/ex-map.tex}
388
8144196 Miek Gieben more stuff moved around
authored
389 \input{ex-functions/ex-minmax.tex}
390
1730bc1 Miek Gieben move bubblesort to functions
authored
391 \input{ex-functions/ex-bubblesort.tex}
392
ab3a85f Miek Gieben added figure and exercises
authored
393 \cleardoublepage
394 \section{Answers}
395 \shipoutAnswer
Something went wrong with that request. Please try again.