forked from matthiasl/Erlang-FAQ
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathproblems.xml
executable file
·538 lines (441 loc) · 14.3 KB
/
problems.xml
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
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<title>Troubleshooting, Problems and 'Gotchas'</title>
<prepared>Matthias Lang</prepared>
<docno></docno>
<date>2007-09-12</date>
<rev>1.0</rev>
<file>problems.xml</file>
</header>
<p>
This section looks at problems which trip up many beginners,
starting with some minor syntactic irritations. If you
bump into something confusing which isn't listed here,
try posting a question to the <seealso marker="mailing-lists">
mailing lists</seealso>.
</p>
<section><title>Why can't I write a = 3 (badmatch)?</title>
<p>
In Erlang, all variables must start with a capital letter,
so you can write <c>A = 3.</c> but not
<c>a = 3.</c> In the latter case Erlang
complains that this is a "bad match".
</p><p>
In the second version, the 'a' is an atom while 3 is a number.
'a' cannot be <em>pattern matched</em> with 3. The use of
capital letters for variables comes from Prolog.
</p><p>
If the terms <em>atom</em> and <em>pattern match </em> are new to you,
have a read of the first chapter or two of the
<url href="http://www.erlang.org/doc.html"> Erlang book</url>.
(<em>Very</em> roughly, an atom corresponds to
an enum in C and pattern matching in this case is like an
<c>assert</c> statement.
</p></section>
<section><title>Why can't I change the value of a variable?</title>
<p>
Erlang only lets you assign a variable once in a function.
Some simple examples of when you bump into this are:
</p>
<pre>
1> A = 3.
3
2> A = 4.
** exited: {{badmatch,4},[{erl_eval,expr,3}]} **
3> A = A + 4.
** exited: {{badmatch,7},[{erl_eval,expr,3}]} **
</pre>
<p>
The usual "workaround" is to use a new variable:
</p>
<pre>
4> B = A + 4.
7
</pre>
<p>
(This behaviour is called "single assignment", and it's
considered to be a feature, not a bug. Most functional
languages, including ML and Haskell, also behave this way.
Among other things, It's nice being able to rely on a
certain variable always having the same value.)
</p>
</section>
<section><title>Why do lists of numbers get printed incorrectly?</title>
<p>
Sometimes the shell (or a program) prints a list of
number in an unexpected way, for instance:
</p>
<pre>
1> [65, 66, 67].
"ABC"
</pre>
<p>
This happens because Erlang represents strings as lists of
integers, so if you ask the shell to print a list of
integers, the shell takes a guess as to whether you want
to see it as a list of numbers or as a string. The shell bases
its guess on checking whether or not the list contains all
printable characters, so you can force a string to be unprintable:
</p>
<pre>
5> [0, 65, 66, 67].
[0,65,66,67]
</pre>
<p>
A similar problem occurs with <c>io:fwrite()</c>,
but in that case you can take direct control by specifying the
appropriate formatting character. "~s" always prints the
argument as a string, "~w" always prints it as a list.
</p>
</section>
<section><title> Why can't I call arbitrary functions in a guard?</title>
<p>
If that was allowed, there would be no guarantee that guards
were side-effect free.
</p><p>
Also, it is convenient to be able to program as though guards do not
consume any significant amount of execution time. There's
a list of BIFs which can be called from within guards in
the Erlang book and the standard Erlang spec, some examples
are <c>size(), length(), integer(), record()</c>.
</p><p>
The "problem" often crops up when using <c>if</c>:
</p>
<code>
issue_warning() ->
if (os:type() == {win32, windows}) -> %% illegal guard
ok = io:fwrite("you are using windows\\n");
true ->
ok = io:fwrite("no problem\\n")
end.
</code>
<p>
The solution is usually to use <c>case</c>
instead. Case is used much more frequently than
<c>if</c> in most Erlang programs:
</p>
<code>
issue_warning() ->
case os:type() of
{win32, windows} -> ok = io:fwrite("you are using windows\\n");
_ -> ok = io:fwrite("no problem\\n")
end.
</code>
</section>
<section><title> Why can't I use "or" in a guard?</title>
<p>
You can. Since R6A, several guards separated with semicolons
perform a logical 'or', for example:
</p>
<code>
f(N) when (N - 1) > 3; atom(N) -> yes;
f(N) -> no.
</code>
<p>
will return <c>yes</c> for
<c>f(5)</c> as well as
<c>f(blork)</c>. Similarly, the comma is
used for logical and:
</p>
<code>
g(N) when integer(N), N > 5 -> yes;
g(N) -> no.
</code>
<p>
Beware! The semicolon operator
doesn't mean exactly the same thing as 'or', for instance
<c>f(hello)</c> returns <c>yes </c>, whereas evaluating
<c>f(hello - 1) > 3 or atom(hello)</c>
returns a <c>badarith</c> error.
The first example, f(), is <em>defined</em>
as having the same effect as writing:
</p>
<code>
f(N) when (N - 1) > 3 -> yes;
f(N) when atom(N) -> yes;
f(N) -> no.
</code>
</section>
<section><title> Why does 'catch' give me a syntax error?</title>
<p>
It seems natural enough to write
</p>
<code>
2> A = catch 1/0.
** 2: syntax error before: 'catch' **
</code>
<p>
But the parsing rules for Erlang are a bit unexpected here,
catch binds less tightly than you might expect it to.
To make it parse the way you really want:
</p>
<code>
3> A = (catch 1/0).
{'EXIT',{badarith,[{erl_eval,eval_op,3},
{erl_eval,expr,3},
{erl_eval,exprs,4},
{shell,eval_loop,2}]}}
</code>
</section>
<section><title> What is a sticky directory?</title>
<p>
This typically crops up when playing with examples from the
old (last century) Erlang book, for instance:
</p>
<code>
1> c(sets.erl).
{error,sticky_directory}
</code>
<p>
The problem is that there already is a standard library module
called 'sets'. The Erlang runtime system is protecting
you.
</p><p>
The easiest solution is to rename your module, e.g. to
<c>mysets.erl</c>. It is also possible to
'un-stick' the directory containing the library module.
</p></section>
<section><title>Why won't my distributed Erlang nodes communicate?</title><p>
For Erlang nodes to be able to communicate, you need
</p>
<list>
<item><p>A working tcp network between the nodes.
On unix systems you can check this by using telnet,
though a working telnet doesn't guarantee that
enough of your network is working, e.g. DNS problems
throw a spanner in Erlang's distribution mechanisms.
</p></item>
<item><p>The nodes to use the same node naming scheme
(you cannot have a system where some nodes use fully
qualified names and others use short names).
</p></item>
<item><p>The nodes must agree to use the same
"magic security cookie".
</p></item>
</list>
<p>
Here's an example of how to create two nodes on different machines
called <em>martell</em> and <em>grolsch</em>
and verify that they're connected. On one machine:
</p>
<code>
~ >rlogin martell
Last login: Sat Feb 5 20:40:52 from super
~ >erl -sname first_node
Eshell V4.9.1.1 (abort with ^G)
(first_node@martell)1> erlang:set_cookie(first_node, nocookie).
true
</code>
<p>
And on the other
</p>
<code>
~ >rlogin grolsch
Last login: Thu Feb 3 10:54:20 from :0
~ >erl -sname second_node
Eshell V4.9.1.1 (abort with ^G)
(second_node@grolsch)1> erlang:set_cookie(second_node, nocookie).
true
(second_node@grolsch)2> net:ping(first_node@martell).
pong
(second_node@grolsch)3> rpc:call(first_node@martell, os, type, []).
{unix,sunos}
</code>
<p>
The <c>pong</c> tells us that the
connection works, the result
of <c>net:ping()</c> is <c>pang </c> when the connection isn't working.
The <c>rpc:call()</c> command illustrates
executing a command on the other node.
</p>
<warning>
<p>Cookies are a password for Erlang nodes. The example above
sets the password to "nocookie", which removes almost
all security. Anyone on your network can use your Erlang node
for anything, including deleting all of your files. </p>
</warning>
</section>
<section><title>When distribution won't work</title>
<p>
One simple reason why distribution won't work is if you're
combining different versions of Erlang.
At the time of writing (R13B), the OTP group's strategy is to
maintain backwards compatibility with the two previous major
versions of Erlang/OTP, i.e. R13B works with all R13B minor
releases as well as with R12B and R11B.
</p><p>
Beyond that, you need to start digging. Erlang nodes communicate
by connecting to the <c>epmd</c> daemon.
The daemon is started
automatically the first time you start a distributed node. For
debugging, it's useful to kill it by running <c>epmd -kill
</c>) and
then restart it with the debugging flag. You can find
<c>epmd</c> in the same directory as the erlang binary:
</p>
<code>
~ >/otp/releases/otp_beam_sunos5_r6b/erts-4.9.1/bin/epmd -d -d
epmd: Sat Feb 5 21:04:39 2000: epmd running - daemon = 0
epmd: Sat Feb 5 21:04:39 2000: try to initiate listening port 4369
epmd: Sat Feb 5 21:04:39 2000: starting
epmd: Sat Feb 5 21:04:39 2000: entering the main select() loop
</code>
<p>
When you start a distributed node on the same system, you
should see a message in the <c>epmd</c> window:
</p>
<code>
epmd: Sat Feb 5 21:07:33 2000: registering 'first_node:1', port 53566
</code>
<p>
Similarly, when you use <c>net:ping</c> from a
node on another
system, you should see some messages go by. If nothing seems
to be happening on <c>epmd</c>,
it's useful to scan for
packets on the ethernet to see if the information is really
getting out on the net. On unix systems you can do this with
tcpdump:
</p>
<code>
# /usr/local/sbin/tcpdump port 4369
tcpdump: listening on le0
21:10:17.349286 grolsch.37558 > martell.4369: S 747683789:747683789(0)
</code>
</section>
<section><title>Avoiding DNS</title><p>
One fairly common obstacle to getting distribution to work is
a broken DNS setup. One way to avoid that, or test for it, is
to start distributed Erlang with IP addresses instead of hostnames,
e.g. on one machine or window:
</p>
<code>
~ >erl -name [email protected]
Erlang (BEAM) emulator version 5.5.5 [source] [64-bit]
Eshell V5.5.5 (abort with ^G)
([email protected])1> erlang:set_cookie('[email protected]', nocookie).
true
([email protected])2> net:ping('[email protected]').
pong
</code>
<p>
and in the other:
</p>
<code>
~ >erl -name [email protected]
Erlang (BEAM) emulator version 5.5.5 [source] [64-bit] [async-threads:0]
Eshell V5.5.5 (abort with ^G)
([email protected])1> erlang:set_cookie('[email protected]', nocookie).
</code>
</section>
<section><title>
Why does my application die every second time I load new code into it?
</title><p>
Erlang's code replacement system is based around there being
(up to) two copies of the code loaded at any time, these
are called "old" and "new". When you load new code, the
current version becomes "old" and the "old" code is thrown
away. Any processes still running "old" code are killed.
</p><p>
You can check if there is any old code for a particular
module still running:
</p>
<code>
Eshell V4.9.1 (abort with ^G)
1> l(erl).
{module,erl}
2> code:soft_purge(erl).
false
</code>
<p>
In this case old code is still running. You can also check
if a particular process is running old code, by using
<c>erlang:check_process_code(Pid, Module)</c>.
</p></section>
<section><title>Why can't I open devices (e.g. a serial port) like normal files?
</title><p>
Short answer: because the erlang runtime system was not
designed to do that.
The Erlang runtime system's internal file access system,
efile, must avoid blocking, otherwise the whole Erlang
system will block. This is not a good thing in a soft
real-time system.
When accessing regular files, it's generally a reasonable
assumption that operations will not block. Devices, on the
other hand, are quite likely to block. Some devices, such
as serial ports, may block indefinitely.
There are several possible ways to solve this. The Erlang
runtime system could be altered, or an external port program
could be used to access the device.
Two mailing list discussions about the topic can be found
<url href="http://erlang.org/pipermail/erlang-questions/2004-January/011351.html">here</url> and
<url
href="http://erlang.org/pipermail/erlang-questions/2000-March/001050.html">
here</url>.
</p>
</section>
<section><title>
Why doesn't the stack backtrace show the right functions for
this code:
</title>
<code>
-module(erl).
-export([a/0]).
a() -> b().
b() -> c().
c() -> 3 = 4. %% will cause badmatch
</code>
<p>
The stack backtrace only shows function c(), rather
than a(), b() and c(). This is because of last-call-optimisation;
the compiler knows it does not need to generate a stack frame
for a() or b() because the last thing it did was call another
function, hence the stack frame does not appear in the stack backtrace.
</p></section>
<section><title>What do I do if I get an error when compiling Open Source Erlang?
</title><p>
Consider using a binary release (Debian GNU/Linux includes them in the
woody and potato releases, windows binaries are on the
<url href="http://www.erlang.org/download.html">
download page </url>).
</p><p>
Ask for help on the mailing list, providing as many details
as you can, including
</p>
<list>
<item><p> your system details (OS, OS version, compiler version)
</p></item>
<item><p> the error messages you get
</p></item>
<item><p> any errors you got when you ran <c>configure
</c> </p></item>
</list>
</section>
<section><title>Why do errors in the shell kill other processes?</title>
<p>
Because the other processes are linked to the shell process.
</p><p>
Each time an error occurs in the erlang shell, the shell
process exits and a new one is started:
</p>
<pre><![CDATA[
1> self().
<0.23.0>
2> x - y.
** exited: {badarith,[{erl_eval,eval_op,3},
{erl_eval,exprs,4},
{shell,eval_loop,2}]} **
3> self().
<0.40.0>
]]></pre>
<p>
Thus all processes linked to <0.23.0> will receive exit
signals. Unless they trap exits, they will exit too. One
way to avoid this is avoid linking "background" processes
to shell processes, for instance by using <c>spawn</c>
instead of <c>spawn_link</c>.
</p>
</section>
</chapter>