ExCompatible
ExCompatible strives to make your Elixir code compatible with as many Elixir versions as possible, while reducing the number of compiler warnings.
See http://hexdocs.pm/ex_compatible/ for documentation, https://github.com/kafkaex/ex_compatible/ for code.
Have you ever wanted to use String.to_charlist/1, but then your code no longer
compiles on Elixir 1.1? You switch to using String.to_char_list/1 instead,
but now your compiler spits out annoying warnings on Elixir 1.5. What should
you do?
ExCompatible can inspect your Elixir version, and by using the safe macro, it
will always inject the most appropriate version of a defition so your compiler
stays happy.
Note: This project is still under heavy construction. Please check the to-do list further down, and we love contributors!
Usage
To add ExCompatible to your Elixir application, change the deps definition
in your mix.exs file:
defp deps do
[
{:ex_compatible, "~> 0.1"}
]
end
Then you will need to import the safe/1 macro inside any modules in which
you would like to use it. For example:
defmodule MyModule do
import ExCompatible, only: [safe: 1]
def my_def do
IO.puts safe(String.to_char_list("Hello world!"))
safe do
Enum.partition([5, 4, 3, 2], fn(x) -> rem(x, 2) == 0 end)
end
end
endPerformance
ExCompatible is implemented using macros, which always inject the most appropriate version of a given definition directly into the AST. This happens at compile time, so at runtime there should be zero performance impact by using ExCompatible.
To-do
There are lots of different types of deprecations, ranging from simple renames, to spec changes, complete removal, or splits into multiple functions. The goal is to be able to handle all of these different types, and to do that we'll need a checklist.
Elixir 1.6 Deprecations
Enum.partition/2Keyword.replace/3Macro.unescape_tokens/1andMacro.unescape_tokens/2Module.add_doc/6Map.replace/3Range.range?/1
Elixir 1.5 Deprecations
Atom.to_char_list/1Enum.filter_map/3Float.to_char_list/1GenEventmoduleInteger.to_char_list/1andInteger.to_char_list/2Kernel.to_char_list/1List.Chars.to_char_list/1Stream.filter_map/3String.ljust/3andString.rjust/3String.strip/1andString.strip/2String.lstrip/1andString.rstrip/1String.lstrip/2andString.rstrip/2String.to_char_list/1()to meannil:as_char_listsvalue int:Inspect.Opts.t/0type:char_listskey int:Inspect.Opts.t/0typechar_list/0type@compile {:parse_transform, _}inModule-
EEx:
<%=in middle and end expressions
Elixir 1.4 Deprecations
Access.key/1BehaviourmoduleEnum.uniq/2Float.to_char_list/2Float.to_string/2HashDictmoduleHashSetmoduleSetmoduleStream.uniq/2IEx.Helpers.import_file/2Mix.Utils.camelize/1Mix.Utils.underscore/1- Variable used as function call
-
Anonymous functions with no expression after
->
Elixir 1.3 Deprecations
DictmoduleKeyword.size/1Map.size/1SetbehaviourString.valid_character?/1Task.find/2:append_firstoption inKernel.defdelegate/2/roption inRegex\x{X*}inside strings/sigils/charlists-
Map or dictionary as second argument in
Enum.group_by/3 -
Non-map as second argument in
URI.decode_query/2
Elixir 1.2 Deprecations
Dictbehaviour
Elixir 1.1 Deprecations
Accessprotocolas: true \| falseinalias/2andrequire/2?\xHEX