defmodule Foo do
def bar(x)
when is_map(x) or
is_tuple(x) or
is_pid(x) or
is_port(x) or
is_reference(x) or
is_function(x) or
(is_bitstring(x) and not is_binary(x)) do
IO.puts("one: #{x}")
end
def bar(x) do
IO.puts("two: #{x}")
end
end
Foo.bar("hello")
If I run this with OTP-21.1 and OTP-22 I get different results.
iex script.exs
Erlang/OTP 22 [erts-10.4] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
one: hello
Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
iex script.exs
Erlang/OTP 21 [erts-10.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
two: hello
Interactive Elixir (1.8.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
I have no clue why.
I am using asdf, maybe I do something wrong when I am changing the versions.
defmodule Foo do
def bar(x) when is_bitstring(x) and not is_binary(x) do
IO.puts("one: #{x}")
end
def bar(x) do
IO.puts("two: #{x}")
end
end
Foo.bar("hello")
x = "hello"
guard = is_bitstring(x) and not is_binary(x)
IO.inspect(guard, label: :guard)
and get this
Erlang/OTP 21 [erts-10.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
two: hello
guard: false
Interactive Elixir (1.8.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
Erlang/OTP 22 [erts-10.4] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
one: hello
guard: false
Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
As I have seen both time the unexpected result of one: hello with a local test on elixir 1.8.1 and 1.8.2, both OTP-22, I’m now trying to reproduce something similar on pure erlang.
This seems most likely. You need to be using an Elixir that was compiled with the same version of OTP that you are using at runtime. That means switching between elixir 1.8.1-otp22 and elixir 1.8.1 as you switch OTP. Is that what you are doing? You are definitely getting the wrong result on OTP 22.
This is not true. An elixir compiled on OTP 20 can work well on an OTP 21 or 22 and usually should not create any unwanted effects besides not using features that are available on the current platform.
$> asdf current elixir
1.8.2-otp-22 (set by /Users/kruse/.tool-versions)
$> asdf current erlang
22.0 (set by /Users/kruse/.tool-versions)
# change version
$> asdf local elixir 1.8.1
$> asdf local erlang 21.1
It is a bug in an optimization pass in the new compiler in OTP 22. I am not sure what I was thinking when I wrote that code, and we didn’t catch it in our internal tests.