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
Hi!
In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir?
Searched the docs for ip address and the web, no good results.
Thanks!
New
I would like to know what is the best IDE for elixir development?
New
lets say i have a sample like
a = 20; b = 10;
if (a > b) do
{:ok, "a"}
end
if (a < b) do
{:ok, b}
end
if (a == b) do
{:ok, "equa...
New
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
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
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Other popular topics
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
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
What is the idiomatic way of matching for not nil in Elixir?
E.g.,
First way:
defp halt_if_not_signed_in(conn, signed_in_account) when...
New
Hi,
I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
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









