Oops, this is the correct `~/.iex.exs`. The idea is I want to use 
Mix.install when using `iex` but _not_ (as it will fail) when using `iex -S 
mix`.

if :mix not in Enum.map(Application.started_applications(), &elem(&1, 0)) do
  Mix.install([
    :decimal,
    :jason,
    :nimble_csv,
    {:requests, github: "wojtekmach/requests"}
  ])
end

czwartek, 21 stycznia 2021 o 12:18:45 UTC+1 [email protected] napisał(a):

> A minor addition: I'd like to add a shortcut so you can write 
> `Mix.install([:decimal])` instead of  `Mix.install([{:decimal, ">= 
> 0.0.0"}])`.
>
> > The only downside of this approach compared to global dependencies is 
> that each IEx session is a blank session - but that can be streamlined in 
> the future.
>
> Agreed. I didn't mention this in the proposal but here's a trick I've been 
> using:
>
> # ~/.iex.exs
> unless Code.ensure_loaded?(Mix) do
>   Mix.install([
>     :decimal,
>     :jason,
>     :nimble_csv,
>     {:requests, github: "wojtekmach/requests"}
>   ])
> end
>
> This means however that when you start a session, you won't be able to 
> call `Mix.install` again. In those cases I'd `iex --dot-iex ""` to ignore 
> my global config.
>
>
> czwartek, 21 stycznia 2021 o 12:05:18 UTC+1 José Valim napisał(a):
>
>> I have discussed this with Wojtek and I am in favor of this proposal.
>>
>> Elixir was designed to support scripting but I constantly hear that the 
>> lack of some quality of life features, such as trapping exits, limited IO 
>> handling, lack of support for dependencies, etc make it so even advanced 
>> Elixir developers don't end-up using Elixir for regular single-file scripts.
>>
>> I have never been a fan of global dependencies. Between global 
>> dependencies (not easily reproducible and with implicit dependencies) and 
>> Mix projects (fully reproducible with explicit dependencies), this sounds 
>> like a reasonable compromise (explicit dependencies reproducible within 
>> requirements). The only downside of this approach compared to global 
>> dependencies is that each IEx session is a blank session - but that can be 
>> streamlined in the future.
>>
>> Note the goal here is not to replace escripts either. Escripts have the 
>> full-backing of a project, with dependencies, multiple source files and 
>> tests. If it is anything beyond experimentation or more than a couple dozen 
>> lines, then you do want a complete project.
>>
>> TL;DR: +1
>>
>> On Thu, Jan 21, 2021 at 11:40 AM [email protected] <
>> [email protected]> wrote:
>>
>>> 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 [email protected].
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/elixir-lang-core/ed320491-005c-4414-b1a9-5ca0e540bd3dn%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/elixir-lang-core/ed320491-005c-4414-b1a9-5ca0e540bd3dn%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/8c51fd5f-01ff-4ac6-9b17-9e048745c1cfn%40googlegroups.com.

Reply via email to