lud
Wrapping a tail recursive function with try/catch
Hi,
I’m pretty sure it is the case but I found conflicting informations online.
Can you confirm that the tail call optimization will take place for a function when only the first call is wrapped in a try/catch?
For instance this module:
defmodule T do
def top do
until(1_000_000_000)
catch
e -> {:got, e}
end
defp until(n, n) do
throw(:hello)
end
defp until(n, x) do
until(n, x + 1)
end
defp until(n) do
until(n, 0)
end
end
IO.inspect(T.top())
As you can see, the first call to until is wrapped in a try/catch but afterwards, there are no more wrapping blocks around the recursion. So TCO should be there, right?
I’m pretty sure this example would blow up if that were not the case anyway ![]()
Other case, with this code:
defmodule T do
def top do
until(1_000)
catch
e -> {:got, e}
end
defp until(n, m) when m >= n do
throw(:hello)
end
defp until(n, x) do
add =
try do
some_other_fun()
catch
_ -> 1
end
until(n, x + add)
end
defp until(n) do
until(n, 0)
end
defp some_other_fun do
case Enum.random(1..2) do
1 -> throw(:nope)
2 -> 2
end
end
end
The try/catch around some_other_fun does not wrap the tail call, so TCO is still there right?
Thanks!
Marked As Solved
noelHan
defmodule T do
def top do
until(1_000_000_000)
catch
e -> {:got, e}
end
defp until(n, n) do
IO.inspect(Process.info(self(), :current_stacktrace))
throw(:hello)
end
defp until(n, x) do
until(n, x + 1)
end
defp until(n) do
until(n, 0)
end
end
IO.inspect(T.top())
I add one line to your code and get a result below
{:current_stacktrace,
[
{Process, :info, 2, [file: 'lib/process.ex', line: 773]},
{T, :until, 2, [file: 'iex', line: 12]},
{T, :top, 0, [file: 'iex', line: 6]},
{:elixir, :"-eval_external_handler/1-fun-2-", 4,
[file: 'src/elixir.erl', line: 309]},
{:erl_eval, :do_apply, 7, [file: 'erl_eval.erl', line: 748]},
{:erl_eval, :expr_list, 7, [file: 'erl_eval.erl', line: 961]},
{:erl_eval, :expr, 6, [file: 'erl_eval.erl', line: 454]},
{:elixir, :eval_forms, 4, [file: 'src/elixir.erl', line: 294]}
]}
{:got, :hello}
It looks like TCO is take place. You can try this with your second one
0
Also Liked
lud
Last Post!
lud
Popular in Questions
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
Lets say I have map like this fetching from my database
%{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
Hello everybody,
usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
Hello all!
I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
After calling mix ecto.create I get this error:
17:00:32.162 [error] GenServer #PID<0.412.0> terminating
** (Postgrex.Error) FATAL...
New
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]
15:22:35.803 [error] gen_event {lager_file_backend...
New
Other popular topics
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum.
...
New
Hello!
Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible.
total = 10
while total != 0
...
New
Phoenix 1.4.0 released
Phoenix 1.4 is out! This release ships with exciting new features, most notably
with HTTP2 support, improved deve...
New
Hello everyone,
Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









