shinhããã®ã³ã¡ã³ãããã®ãµã¤ãã«åå¿ãããã®ã¯åãã¦ãããããªãã®ã§åæºãã¦ãã¾ã(ã¢ã¯ã»ã¹è§£æãã¦ããªãã®ã§ãä»ã«ãã£ããããããªãã)ãèªãã§ããã¦ãããã¨ããããã¾ãã
åã åã®ã¨ã³ããªã§fact/1ãsum/3ãä½ã£ãã¨ãã弿°ã1ã¤å¤ããã(Accumlator)ä¸è«ã颿°ãä½ã£ãã®ã¯ãææã®éãæ«å°¾åå¸°ã®æé©åãããããã§ããããæ¬å½ã«ããã£ã¦ãã®ãããï¼ã¨ãããããã¡ãã¡ãããªãã¨ãããªãã¦ãå®ã¯ãã¾ããã¨ãã£ã¦ããããªãã®ãããï¼ã¨ããçåãåºã¦ããã®ã§ãæå ã®ç°å¢ã§å®é¨ãã¦ã¿ã¾ããã
æé©åãçºçãã¦ãããã¨ãã©ããã£ã¦ç¢ºãããã°ããã®ãã¨èãã¦ã¿ãã®ã§ãããä¾å¤åãã¦ã¹ã¿ãã¯ãã¬ã¼ã¹ãè¦ãã®ãæã£ã¨ãæ©ãããªã¨æãã¾ãããæ«å°¾å帰ãæé©åã§ã¸ã£ã³ãã«ç½®ãæãã£ã¦ããã°ãã¹ã¿ãã¯ãã¬ã¼ã¹ã«ã¯å帰å¼ã³åºãã®çè·¡ãè¦ããªãã¯ãã§ãã
ãããªæãã§ä¾å¤ããã£ããããããã«ãã¦ãä¸çªæ·±ãã¨ããã§
ã¿ãããªã®ãå¼ã¶ããã«ããã°ã¹ã¿ãã¯ãã¬ã¼ã¹ãè¦ããã¨ãã§ããããªã¨æããæ©é試ãã¦ã¿ãã®ã§ããããã¾ãè³ããçµæã«ã¯ãªãã¾ããã§ããã
æ«å°¾å帰çã¨ããã§ãªãçãæºåãã¦...
ã¹ã¿ãã¯ãã¬ã¼ã¹ã¯ã{Module, Function, Arity(ã¾ãã¯Arg)}ã®ãªã¹ãã帰ã£ã¦ãããã§ããã鿫尾å帰çè¦ã¦ã2ã¤ããç©ã¾ãã¦ããªãããã«è¦ãã¾ããããããªé¢æ°ä½ã£ã¦è©¦ãã¦ã¿ãã®ã§ãããã©ããåä¸ã®M:F/Aã¯éç´ããã¦ãã¾ã£ã¦ããããã«è¦ãã¾ã...
ããã¥ã¡ã³ãããããã調ã¹ãã試ãããããã¨ãããerlang:process_display(pid(), backtrace) ã¨ããã®ã使ãã¨ããã¨ããçµæã«ãªããã¨ãåããã¾ããã
show_backtrace/0 ãä¸è¨ã®ããã«ç½®ãæãã¦...
å¼åºãã¦ã¿ãã¨ããä¸è¨ã®ãããªçµæã«ãªãã¾ããã
確ãã«fact_notailã®æ¹ã¯å¼åºãããåæ°åã¹ã¿ãã¯ã«ç©ã¾ãã¦ããããã§ãã
ãããã試ãã¦ã¿ãã¨ãããå帰ã§ãªãã¦ãæ«å°¾å¼åºãã§ããã°ã¸ã£ã³ãã«ç½®ãæãã£ã¦ããããã§ãä¾ãã°ä»¥ä¸ã®ãããªã³ã¼ãã§ahya/0ãå¼åºãã¨ãã¹ã¿ãã¯ãã¬ã¼ã¹ã«ã¯ahya6ããåºã¦ããªãç¶æ ã§ãã
ãããªãããªã®ããªãã¨æã£ã¦ãããã°ã©ãã³ã°Erlangããèªã¿ãªããã¦ã¿ããã p364(第1ç)ã«ãErlangã§ã¯æ«å°¾å¼ã³åºãæé©åãè¡ã£ã¦ãããã¨æè¨ããã¦ãã¾ããããã®å¾ããæªå±±ããã®æ¥è¨ã§ãæ«å°¾å¼åºãã®ãã£ã¨è峿·±ãä¾ãè¦ã¤ãããã¨ãã§ãã¾ããã
åã åã®ã¨ã³ããªã§fact/1ãsum/3ãä½ã£ãã¨ãã弿°ã1ã¤å¤ããã(Accumlator)ä¸è«ã颿°ãä½ã£ãã®ã¯ãææã®éãæ«å°¾åå¸°ã®æé©åãããããã§ããããæ¬å½ã«ããã£ã¦ãã®ãããï¼ã¨ãããããã¡ãã¡ãããªãã¨ãããªãã¦ãå®ã¯ãã¾ããã¨ãã£ã¦ããããªãã®ãããï¼ã¨ããçåãåºã¦ããã®ã§ãæå ã®ç°å¢ã§å®é¨ãã¦ã¿ã¾ããã
æé©åãçºçãã¦ãããã¨ãã©ããã£ã¦ç¢ºãããã°ããã®ãã¨èãã¦ã¿ãã®ã§ãããä¾å¤åãã¦ã¹ã¿ãã¯ãã¬ã¼ã¹ãè¦ãã®ãæã£ã¨ãæ©ãããªã¨æãã¾ãããæ«å°¾å帰ãæé©åã§ã¸ã£ã³ãã«ç½®ãæãã£ã¦ããã°ãã¹ã¿ãã¯ãã¬ã¼ã¹ã«ã¯å帰å¼ã³åºãã®çè·¡ãè¦ããªãã¯ãã§ãã
call(F) -> try erlang:apply(?MODULE, F, [5]) %% F(5)ãå¼åºã catch Class:Reason -> io:format("~p:~p ~p~n", [Class, Reason, erlang:get_stacktrace()]) end.
ãããªæãã§ä¾å¤ããã£ããããããã«ãã¦ãä¸çªæ·±ãã¨ããã§
show_backtrace() -> 1 = 0. %% badmatch
ã¿ãããªã®ãå¼ã¶ããã«ããã°ã¹ã¿ãã¯ãã¬ã¼ã¹ãè¦ããã¨ãã§ããããªã¨æããæ©é試ãã¦ã¿ãã®ã§ããããã¾ãè³ããçµæã«ã¯ãªãã¾ããã§ããã
fact_tail(N) -> fact_tail(N, 1). fact_tail(N, Result) when N =:= 0 orelse N =:= 1 -> show_backtrace(), Result; fact_tail(N, Result) when N > 0 -> fact_tail(N - 1, Result * N). fact_notail(N) when N =:= 0 orelse N =:= 1 -> show_backtrace(), 1; fact_notail(N) when N > 0 -> N * fact_notail(N - 1).
æ«å°¾å帰çã¨ããã§ãªãçãæºåãã¦...
2> tailrecursion:call(fact_tail). error:{badmatch,0} [{tailrecursion,show_backtrace,0}, {tailrecursion,fact_tail,2}, {tailrecursion,call,1}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_exprs,6}, {shell,eval_loop,3}] ok 3> tailrecursion:call(fact_notail). error:{badmatch,0} [{tailrecursion,show_backtrace,0}, {tailrecursion,fact_notail,1}, {tailrecursion,fact_notail,1}, {tailrecursion,call,1}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_exprs,6}, {shell,eval_loop,3}] ok
ã¹ã¿ãã¯ãã¬ã¼ã¹ã¯ã{Module, Function, Arity(ã¾ãã¯Arg)}ã®ãªã¹ãã帰ã£ã¦ãããã§ããã鿫尾å帰çè¦ã¦ã2ã¤ããç©ã¾ãã¦ããªãããã«è¦ãã¾ããããããªé¢æ°ä½ã£ã¦è©¦ãã¦ã¿ãã®ã§ãããã©ããåä¸ã®M:F/Aã¯éç´ããã¦ãã¾ã£ã¦ããããã«è¦ãã¾ã...
ããã¥ã¡ã³ãããããã調ã¹ãã試ãããããã¨ãããerlang:process_display(pid(), backtrace) ã¨ããã®ã使ãã¨ããã¨ããçµæã«ãªããã¨ãåããã¾ããã
show_backtrace/0 ãä¸è¨ã®ããã«ç½®ãæãã¦...
show_backtrace() -> io:format("~p~n", [erlang:process_display(self(), backtrace)]).
å¼åºãã¦ã¿ãã¨ããä¸è¨ã®ãããªçµæã«ãªãã¾ããã
8> tailrecursion:call(fact_tail). Program counter: 0x01201380 (shell:eval_loop/3 + 44) CP: 0x00000000 (invalid) 0x00e114d4 Return addr 0x015c2edc (tailrecursion:fact_tail/2 + 52) 0x00e114d8 Return addr 0x015c2db4 (tailrecursion:call/1 + 60) y(0) 120 0x00e114e0 Return addr 0x01222b60 (erl_eval:do_apply/5 + 1268) y(0) [] y(1) Catch 0x015c2dc4 (tailrecursion:call/1 + 76) (ä¸ç¥) 0x00e11540 Return addr 0x00a51b64 (<terminate process normally>) y(0) 8204 y(1) <0.25.0> true 120 9> tailrecursion:call(fact_notail). Program counter: 0x01201380 (shell:eval_loop/3 + 44) CP: 0x00000000 (invalid) 0x00e08874 Return addr 0x015c2f70 (tailrecursion:fact_notail/1 + 44) 0x00e08878 Return addr 0x015c2fc0 (tailrecursion:fact_notail/1 + 124) 0x00e0887c Return addr 0x015c2fc0 (tailrecursion:fact_notail/1 + 124) y(0) 2 0x00e08884 Return addr 0x015c2fc0 (tailrecursion:fact_notail/1 + 124) y(0) 3 0x00e0888c Return addr 0x015c2fc0 (tailrecursion:fact_notail/1 + 124) y(0) 4 0x00e08894 Return addr 0x015c2db4 (tailrecursion:call/1 + 60) y(0) 5 0x00e0889c Return addr 0x01222b60 (erl_eval:do_apply/5 + 1268) y(0) [] y(1) Catch 0x015c2dc4 (tailrecursion:call/1 + 76) (ä¸ç¥) 0x00e088fc Return addr 0x00a51b64 (<terminate process normally>) y(0) 8204 y(1) <0.25.0> true 120
確ãã«fact_notailã®æ¹ã¯å¼åºãããåæ°åã¹ã¿ãã¯ã«ç©ã¾ãã¦ããããã§ãã
ãããã試ãã¦ã¿ãã¨ãããå帰ã§ãªãã¦ãæ«å°¾å¼åºãã§ããã°ã¸ã£ã³ãã«ç½®ãæãã£ã¦ããããã§ãä¾ãã°ä»¥ä¸ã®ãããªã³ã¼ãã§ahya/0ãå¼åºãã¨ãã¹ã¿ãã¯ãã¬ã¼ã¹ã«ã¯ahya6ããåºã¦ããªãç¶æ ã§ãã
ahya() -> ahya1(). ahya1() -> ahya2(). ahya2() -> ahya3(). ahya3() -> ahya4(). ahya4() -> ahya5(). ahya5() -> ahya6(). ahya6() -> show_backtrace(), 0.
ãããªãããªã®ããªãã¨æã£ã¦ãããã°ã©ãã³ã°Erlangããèªã¿ãªããã¦ã¿ããã p364(第1ç)ã«ãErlangã§ã¯æ«å°¾å¼ã³åºãæé©åãè¡ã£ã¦ãããã¨æè¨ããã¦ãã¾ããããã®å¾ããæªå±±ããã®æ¥è¨ã§ãæ«å°¾å¼åºãã®ãã£ã¨è峿·±ãä¾ãè¦ã¤ãããã¨ãã§ãã¾ããã