daanturo
How to invoke a tail-call loop expression like Clojure's loop?
Without defining a function, is there an equivalent of Clojure’s loop or Scheme’s named let where I can run a tail-call loop expression while accumulating multiple values?
There’s Enum.reduce, but the number of iterations may not known in advance, and carrying multiple accumulated values with reduce is clunky.
Thank you in advance.
Edit: provided my concrete usage in reply.
Most Liked
Eiji
Often there are multiple ways to solve one problem. You need to give an example of what you want to do including example input, output and what you tried so far, before anybody would give you a satisfying solution.
dimitarvp
Your Elixir code looks good to me, what’s your issue with it?
One thing I’d change is make it more obvious what part of a tuple you’re getting at the end e.g. not use elem but the then construct – just to make it little more readable.
But other than that the code looks good IMO.
Eiji
Having 2-element Tuple as acc is not a shame. Many reduce-based solutions written by senior developers are using it. Your code is really good enough. ![]()
However there is other way to write same code. You can use a simple pattern matching solution, for example:
defmodule Example do
# function header with default arguments
def sample(files, bookmarks \\ "", counter \\ 1)
# when done return only bookmarks string
def sample([], bookmarks, _counter), do: bookmarks
# tail recursion
def sample([file | files], acc_bookmarks, acc_counter) do
# your logic goes here, for example
{file_bookmarks, file_counter} = process_file(file)
# recursively call this for rest files with updated bookmarks and counter
sample(files, acc_bookmarks <> file_bookmarks, acc_counter + file_counter)
end
end
Personally I like separating accumulation and process logic, as in example above, which makes the code more clear.
Popular in Questions
Other popular topics
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









