Oliver

Oliver

Allowing an ignored member in list construction?

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. :slightly_smiling_face:

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Yes, but this happens rather a lot and is very well optimized. Eg an Enum.map is a 2x walk because you have to build up the result backwards and then reverse it (or use a body recursive stack, but that’s still functionally a 2x walk since you have to pop the stack).

If you have literally just one optional item btw you can:

if optional_thing do
  [a, optional_thing, b]
else
  [a, b]
end

If you are trying to construct a list that has many different items that may optional interspersed amongst items that are not, I don’t see how the compiler is supposed to do constant optimization. Definitionally you aren’t constructing a constant, you’re constructing a value who’s length varies by a bunch of different values.

Overall I think this discussion of costs is probably misplaced. Are we talking about lists that are literally a handful of items long? If so we’re in hyper optimization land and the code that performs best will rely heavily on exactly what you’re trying to do.

al2o3cr

al2o3cr

At a minimum, I think this would need some alternative syntax because this is already valid Elixir:

[
  :foo,
  if x.something? do :bar end,
  :baz
]

This is distinctly different from Dart, where the regular if is a statement with no value so putting it inside an expression would otherwise be meaningless.

That syntax would also cause headaches for referential transparency, since this should be “the same” code as the above:

extra_var = if x.something? do :bar end

[
  :foo,
  extra_var,
  :baz
]

IMO the better approach is to use a domain-appropriate “empty” element and clean it up if needed. Cleanup may not even be strictly necessary - for instance, if you’re producing a big iolist value with optional parts then [] is a perfectly fine “skip this and go to the next element” marker.

dimitarvp

dimitarvp

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 false then it simply added an empty list) and then just do List.flatten at the end.

I understand the appeal of having such a language construct but it’s IMO too niche.

Where Next?

Popular in Proposals: Ideas Top

mythicalprogrammer
Hello, since the 1.8rc0 was out, DaisyUI was noted to have the benefit of light and dark mode. From the elixir subreddit, it seem a few ...
New
andypearson
Hey all, I have been working on some performance improvements for the Phoenix application I work on. As part of this, through trial and...
New
cevado
IEx is a very powerfull shell and it would be awesome to have all this power integrated inside a code editor. Clojure enables something l...
New
engineeringdept
In 2026 double submit/session tokens are no longer necessary to prevent against CSRF attacks. Instead, we can use the Sec-Fetch-Site head...
New
ffloyd
The Problem Currently, if I define a struct in the following way: defmodule MyStruct do # Both x and y will have the FIXED values unti...
New
aglassman
Problem The cancel_async function is easily overlooked. Since the results of “outdated” tasks are ignored, it’s easy for developers to a...
New
pierrelegall
Problem Currently, List.first/2 and List.last/2 return a default value (or nil) when the list is empty. However, there are cases where an...
New
mortenlund
Hi! Suggest to add the ability to do use the components socket as input into Phoenix.LiveView.send_update/3 function to make it easier t...
New
Redbaritone
In the current Auth code, the email must change to be valid. This may be true for the two situations the author has in mind: Registering ...
New
dvartic
Would there be interest to implement a link/1 that gives to option to operate on other events? So I implemented a simple link/1 function...
New

Other popular topics Top

malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
RisingFromAshes
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
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement