Currently trying to understand the \"^\" operator in Elixir. From the website:
The pin operator ^ can be used when there is no interest in rebinding
Data in elixir is immutable, variables though are re-assignable. What can make elixir slightly confusing is the combined assignment and pattern matching that you are seeing.
When you use the equals sign with a variable reference on the left elixir will first pattern match the structure, and then perform an assignment. When you have just a sole variable reference on the left, it will match any structure and so will be assigned like so:
a = 1 # 'a' now equals 1
a = [1,2,3,4] # 'a' now equals [1,2,3,4]
a = %{:what => "ever"} # 'a' now equals %{:what => "ever"}
When you have a more complex structure on the left elixir will first pattern match the structures, then perform the assignment.
[1, a, 3] = [1,2,3]
# 'a' now equals 2 because the structures match
[1, a] = [1,2,3]
# **(MatchError)** because the structures are incongruent.
# 'a' still equals it's previous value
If you want to value match against the contents of a variable you can use the pin '^':
a = [1,2] # 'a' now equals [1,2]
%{:key => ^a} = %{:key => [1,2]} # pattern match successful, a still equals [1,2]
%{:key => ^a} = %{:key => [3,4]} # **(MatchError)**
This contrived example could also have been written with 'a' on the right hand side and without the pin:
%{:key => [1,2]} = %{:key => a}
Now say you wanted to assign a variable to part of a structure but only if part of that structure matched something stored in 'a', in elixir this is trivial:
a = %{:from => "greg"}
[message, ^a] = ["Hello", %{:from => "greg"}] # 'message' equals "Hello"
[message, ^a] = ["Hello", %{:from => "notgreg"}] # **(MatchError)**
In these simple examples the use of the pin and pattern matching isn't immediately super valuable, but as you learn more elixir and start pattern matching more and more it becomes part of the expressiveness that elixir affords.