Sanjibukai

Sanjibukai

About variables scope

Hello everybody,

I just noticed something that I admit I should have been notice way more earlier TBH..
Variables are scoped in ifs, conds, cases (and I bet it’s applicable to any block).

An example with a simplified snippet:

def doing_something do
  a = 1
  ...
  if some_true_condition do
    a = 2
    ...
  end
  IO.inspect(a)  # > Still 1 even if some_true_condition is true
end

Now I’m even surprised of how I didn’t got any bugs so far related to this behavior I wasn’t aware.
Maybe I’ve embraced FP well more than I think (so i’m glad).

But until now I didn’t come across (or maybe I didn’t notice) any resource explaining this behavior.
And it’s a really important behavior!

I searched on hexdocs.pm and looked on almost all the guides pages on elixir-lang and this is the only result I found, a changelog for version 1.3 where the following is stated:

Elixir will now warn if constructs like if , case and friends assign to a variable that is accessed in an outer scope.

And contrary to that there isn’t any warning anymore (on v1.10 btw).

I thought replacing the if construct by assigning from the whole block like so:

a =
  if some_true_condition do
    ...
    2
  end

But in this case we are still changing the value with nil if some_true_condition is actually false instead of doing nothing.

If you happen to have to do something equivalent (changing a value in a block) how do you handle it?
Also if you have any more information about this behavior, I’m interested to learn more.

Thank you!

Most Liked

lud

lud

Remember that you are not changing the value of a. What you are really doing is creating a new variable with the same name (and deleting the old variable).

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

What you’re proving is precisely that rebinding isn’t mutability. The function closes over the value of x. That value isn’t changed when you rebind x. If it changed in the function then x is in fact not immutable. Javascript does not have immutability, so it behaves the way you observe. Closures in immutable languages behave the way you observed in Elixir.

al2o3cr

al2o3cr

FWIW, I find myself using this with Ecto.Multi when operations should only be done sometimes:

multi =
  Ecto.Multi.new()
  |> Ecto.Multi.insert(:a, some_changeset)
  |> Ecto.Multi.update(:b, some_other_changeset)

multi =
  if control_variable do
    Ecto.Multi.insert(multi, :c, optional_changeset)
  else
    multi
  end

Last Post!

LostKobrakai

LostKobrakai

cond do
  to_date_time(string) = datatime -> datetime
  to_date(string) = date ->  to_date_time("#{string}T00:00:00+03:00")
  String.contains?(string, "+") -> to_date_time(String.replace(string, "+", "T00:00:00.000+"))
  true -> string
end

Where Next?

Popular in Discussions Top

AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31695 143
New
ben-pr-p
In general I’ve been sticking to this community style guide GitHub - christopheradams/elixir_style_guide: A community driven style guide ...
New
rower687
Hi all, I’ve been reading a lot about the “let it crash” term and how supervising processes and the whole messaging passing make an elixi...
New
chulkilee
Here are the list of HTTP client libraries/wrappers, and some thoughts on HTTP client in general. I’d like to hear from others how they w...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
crispinb
On reading dhh’s latest The One Person Framework it strikes me that Phoenix with LiveView is already pretty much this. However, never hav...
New

Other popular topics Top

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
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
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
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement