axelson

axelson

Scenic Core Team

Weird/incorrect output from a with statement

This is a question that originated on the Elixir Slack from David Billskog and I have made only minor changes to the module.

Given this module:

defmodule Dummy do
  def execute(x) do
    with var_a <- get_a(x),
         var_b <- get_b(x) do
      IO.inspect(var_a, label: "a")
      IO.inspect(var_b, label: "b")
      IO.inspect({var_a, var_b})

      if var_a != var_b do
        IO.inspect(var_a, label: "a")
        IO.inspect(var_b, label: "b")
        IO.inspect({var_a, var_b})
      end
    end
  end
  defp get_a(x) do
    IO.puts("get a")
    if Enum.any?(x, & &1 == "A"), do: 3, else: 2
    |> IO.inspect(label: "returning a")
  end
  defp get_b(x) do
    IO.puts("get b")
    if Enum.any?(x, & &1 == "B"), do: 2, else: 1
    #|> IO.inspect(label: "returning b")
  end
end

Dummy.execute(["A", "B"])

I get this unexpected output:

$ elixir sample.exs
get a
get b
a: 3
b: 2
{3, 2}
a: 3
b: 1
{3, 1}

Does anyone understand what is happening here? I don’t expect for the value of b to change within the if statement, and I do expect the returning a inspect to be printed. Tested on elixir 1.11.2-otp-23 and erlang 23.0.2.

Marked As Solved

josevalim

josevalim

Creator of Elixir

Thanks for the isolated case. I was able to convert it to Erlang:

-module(dummy).

-compile([no_auto_import]).

-export([execute/1]).

execute(_x@1) ->
    _a@1 = get_a(_x@1),
    _b@1 = get_b(_x@1),
    erlang:display(_b@1),
    case _a@1 /= _b@1 of
        false ->
            nil;
        true ->
            erlang:display(_b@1),
            ok
    end.

get_a(_x@1) ->
    case _x@1 == <<"A">> of
        false ->
            2;
        true ->
            3
    end.

get_b(_x@1) ->
    case _x@1 == <<"A">> of
        false ->
            1;
        true ->
            2
    end.


And I see the same issue. I will open up a bug report.

Done: https://bugs.erlang.org/browse/ERL-1440

Also Liked

blackode

blackode

We can check how the code was developed by using quote do

quote do
  if Enum.any?(x, & &1 == "A"), do: 3, else: 2
  |> IO.inspect(label: "returning a")
end
|> Macro.to_string()
|> IO.puts()

That results to

if(Enum.any?(x, &(&1 == "A"))) do
  3
else
  2 |> IO.inspect(label: "returning a")
end

Which is always true in this case. So, it won’t enter into else

axelson

axelson

Scenic Core Team

I’m still seeing the issue with elixir 1.11.2-otp-23 and erlang 23.1.5

al2o3cr

al2o3cr

Can confirm - Axelson’s example works fine on my machine (OTP23.1 / Elixir 1.11.2) and this one fails.

A colleague tried @LostKobrakai’s example on 22.2.6 / 1.11.1 and it printed 2 three times, as expected…

Where Next?

Popular in Questions Top

WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29603 241
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43757 214
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
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
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36352 110
New
shijith.k
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

We're in Beta

About us Mission Statement