csadewa
For Comprehension: there's no assignment, only filters?
Hi all, recently i have been trying out for comprehension after reading Introducing `for let` and `for reduce` and realizing i am also have severly underutilized for. Just now i have spend quite sometime debugging code written with for only to realize there is the following: there’s no “only” binding operation, it always also get used with filters.
For example, consider following code:
data = [%{a: 1, b: 2}, %{a: 2}]
for datum <- data,
b = datum[:b],
b == nil do
datum
end
what would you expect the result be? [%{a: 2}] like i was? the actual result (on elixir 1.10.3) was []. b = datum[:b] is actually treated as filter, and elixir recognize nil and false as falsey value.
I think this is pretty strange behaviour, though maybe this is the implication on A comprehension is made of three parts: generators, filters, and collectables. from https://elixir-lang.org/getting-started/comprehensions.html ?
For context, even at the web tutorial we find following code, in which path = Path.join(dir, file) is treated as variable assignment.
dirs = ['/home/mikey', '/home/james']
for dir <- dirs,
file <- File.ls!(dir),
path = Path.join(dir, file),
File.regular?(path) do
File.stat!(path).size
end
and at Haskell, they have separation between declaration and filter, like in following
Most Liked
josevalim
I don’t think it is worth doing this change in general, because it can be nil in many cases and sometimes you want to discard nil values, but we probably need to add a note to the API documentation just in case.
josevalim
In such cases I also tend to do this:
for x <- list,
y <- [may_be_nil(x)],
do: y
So that is likely the approach I would go with if it can’t be done with a guard?
josevalim
In your case you could also do:
for datum when not is_map_key(datum, :b) <- data do
datum
end
Popular in Discussions
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
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









