Oliver
One common problem we face in constructing lists is that there is (AFAIK) no support for conditionally inserting members into list declarations.
You can’t write:
allow_even? = false
[
1,
if allow_even? do 2 end,
3
]
because the result would be [1, nil, 3], though syntactically a lot of code would be easier and more readable for us if you could do that.
What if returning a very specific value, like :ignore_list_member would lead to a list being constructed like this:
[1, :ignore_list_member, 3] ==> [1, 3]
Functions could return specifically this value if there’s nothing to insert.
def foo(x), do: if rem(x, 2) != 0 do x else :ignore_list_member end
[
foo(1),
foo(2),
foo(3)
]
===> [1, 3]
Right now we typically do something like piping a whole list like this:
allow_even? = false
[
1,
if allow_even? do 2 end,
3
]
|> Enum.reject(&is_nil/1)
which is fine, but I wonder if this could be solved more conveniently and generic without the need to walk the list a second time after constructing it - just once when it’s “constructed” with the declarative syntax.
If it’s not possible with small effort, I still thank you for reading this. ![]()
Trending in Proposals: Ideas
Other Trending 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
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex











Showing Posts 1 to 10- Show Best Posts
- Show All Posts (oldest first)
- Show All Posts (newest first)
LostKobrakai
Ages ago I did look into mimicing dart lists, which do have an add item conditionally synta as well as spreading loops onto the list:
linusdm
I was thinking about this language feature too. As @LostKobrakai mentioned, this is a core feature in Dart. It’s documented here: Collections.
I came across a very nice podcast, where Robert Nystrom explains how this works in Dart, and why they choose to make it part of the language (tldr; because it’s handy to build collections like this, in a context where you’re building UI’s declaratively).
LV side-steps this problem with class lists by ignoring falsey values in these lists. I’m not sure the pull towards this feature is just as strong in Elixir, as it was in Dart. Afaik this can’t be emulated with macros, or something similar, but must be a core language feature.
I’m curious if there were previous discussions about this feature, and if there was consensus in the past about it.
LostKobrakai
After I posted a macro implementing those features
It cannot be done without extra syntax, though elixir won’t be able to do so either. It only has a but more flexibility around new syntax over macros.
Oliver
That’s an interesting proposal, but looking at the implementation it requires list concatenation underneath if I understand it right.
That would make it very similar to what we’re currently doing:
which could also handle if constructs
I was kind of hoping that the declarative syntax could be done in such a way at language level that it can avoid paying for concatenation in that way. (Unless ++ concatenation is very efficient. I always resorted to [ x | xs ] syntax where possible assuming ++ comes at a higher cost.)
linusdm
Haha, I see where I messed up. I mean without wrapping the list as a whole
I was thinking of a solution that doesn’t require a certain context to be set up. Maybe only a marcro inside a list.
linusdm
Since this is about list literals, I wouldn’t worry too much about performance.
D4no0
What is the problem of using macro proposed by @LostKobrakai ?
I’m not a fan of this becoming a language feature, as it involves a lot of mental overload vs not having to write 2 more lines of code.
benwilson512
If the value is conditionally there then there is no avoiding paying for concatenation. Lists are linked lists, they’re built from back to front. If part of the back is different depending on a runtime value then you have to pay a runtime cost to deal with it.
gregvaughn
You can use the filter of a for comprehension
or you could use
Enum.flat_mapbut then you’re creating intermediate listsdimitarvp
On the very rare occasion I’ve done this I just used a list of lists (where the conditional adding of a thing added a non-empty list, and if the condition was
falsethen it simply added an empty list) and then just doList.flattenat the end.I understand the appeal of having such a language construct but it’s IMO too niche.