Erlang creates good stack traces when something goes wrong, it is useful when the programmer wants to understand why it went wrong. However, with higher-order functions, the stack trace mechanism seems short. For example, compare the two examples below (I added the generated stack traces to the code comments).
I read about the difficulties of creating stack traces for lazy evaluation (like in Haskell) before. But since Erlang is rated strictly, I expected a better result here.
My question is: what makes higher-order functions an issue for the mechanism that Erlang uses to create a stack trace? And are there any other well-known technologies that will give the best result?
1 -module(test).
2 -export([f/1,a/1]).
3
4 % Auxilary function to print stack trace (by throwing an exception).
5
6 s(X) when X < 0 -> 0.
7
8 % Example 1: Stack trace in presence of a higher order function.
9 %
10 % > test:f(1).
11 % ** exception error: no function clause matching test:s(1) (test.erl, line 6)
12 % in function test:g/2 (test.erl, line 15)
13
14 f(X) -> h(fun g/2,X).
15 g(X,Y) -> s(X) - Y.
16 h(I,X) -> I(X,3).
17
18 % Example 2: Stack trace for chain of 1st order function applications.
19 %
20 % > test:a(1).
21 % ** exception error: no function clause matching test:s(1) (test.erl, line 6)
22 % in function test:c/1 (test.erl, line 28)
23 % in call from test:b/1 (test.erl, line 27)
24 % in call from test:a/1 (test.erl, line 26)
25
26 a(X) -> b(X) + 1.
27 b(X) -> c(X) + 2.
28 c(X) -> s(X) + 3.
source
share