Today, the only way to use dependencies in Elixir is by first adding them to the current Mix project or installing them as archives. This makes Elixir less than ideal for simple tasks where you'd usually use a scripting language, e.g. download a JSON file, parse it, extract some data. This is also adding pressure for a more "batteries-included" approach in the stdlib to make these simple tasks more convenient to accomplish and require neither creating a Mix project nor installing dependencies.
I'd like to propose adding a `Mix.install` function that will download, compile, and load given dependencies into the VM. Here's how we could use it from an IEx session: $ iex iex> Decimal.new(42) ** (UndefinedFunctionError) function Decimal.new/1 is undefined (module Decimal is not available) Decimal.new(42) iex> Mix.install([{:decimal, "~> 2.0"}]) :ok iex> Decimal.new(42) #Decimal<42> Or from a script: $ cat run.exs Mix.install([ {:decimal, "~> 2.0"}, {:jason, "~> 1.0"} ]) IO.puts Jason.encode!(Decimal.new(42)) $ elixir run.exs "42" You need to call `Mix.install` in your VM and explicitly list all your dependencies. And if you start a new VM, you'd have to call `Mix.install` again. Under the hood, the `Mix.install` starts Mix and creates a temporary Mix project to install and load the dependencies and unloads the temporary project when it's done. For simplicity, the initial implementation allows you to only call this function outside of a Mix project and you can only call it once in a given VM. The temporary project is preserved across runs so if you start another VM and call `Mix.install` with the same set of dependencies, they'll be loaded right away without needing to download or compile them. Each set of dependencies will have it's own temporary directory, roughly: `/tmp/mix_installs/<md5_of_deps>`. The location and the layout of the temporary project is considered an implementation detail that users shouldn't depend on. The fact that the resulting `mix.lock` file is hidden from the users presents challenges around reproducibility and updating deps. If you pin your deps to specific versions, a call to `Mix.install` will give consistent results, however if you use version requirements like `~> 1.0`, it may give different results depending on what the deps resolve to at at given time. Similarly, if there's a new version of a package that satisfies a given version requirement, `Mix.install` won't automatically install it as it already cached the dependency. For this, you'll be able to pass a `force: true` flag to bypass the cache and install & compile from scratch for a given set of dependencies. This will also help if your install somehow got into an inconsistent state. ### Reproducibility Another way of quickly installing and using dependencies is via workspaces, you'd install and automatically load dependencies within a given workspace. That brings questions about reproducibility. Imagine you write a piece of Elixir code that uses dependencies and share it with people, how reproducible is it? - using Mix project, the dependencies are fully reproducible given the Mix project maintains a `mix.lock` file - using `Mix.install`, the dependencies are reproducible within the specified version requirements - using global state like workspaces, the dependencies are not reproducible. If you ask a user to run your script, you need to tell them what dependencies they need to install Between global dependencies having very weak reproducibility and Mix projects being fully reproducible, `Mix.install` is a compromise where you can reasonably reproduce things within a list of requirements. ### Further reading Thanks to https://hex.pm/packages/teex authors for exploring some of these ideas! Also see https://github.com/wojtekmach/playground for an earlier proof-of-concept and https://github.com/elixir-lang/elixir/compare/master...wojtekmach:wm-mix-install for a work-in-progress implementation. -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/ed320491-005c-4414-b1a9-5ca0e540bd3dn%40googlegroups.com.