Any suggestions on how I can speed up my workflow in Elixir?

I often use h or i in the console…

eg

iex> h Task.async

def async(fun)                                 

    @spec async((() -> any())) :: t()

Starts a task that must be awaited on.

This function spawns a process that is linked to and monitored by the caller
process. A Task struct is returned containing the relevant information.

Read the Task module documentation for more info on general usage of async/1
and async/3.

See also async/3.


                           def async(mod, fun, args)                            

    @spec async(module(), atom(), [term()]) :: t()

Starts a task that must be awaited on.

A Task struct is returned containing the relevant information. Developers must
eventually call Task.await/2 or Task.yield/2 followed by Task.shutdown/2 on the
returned task.

Read the Task module documentation for more info on general usage of async/1
and async/3.

## Linking

This function spawns a process that is linked to and monitored by the caller
process. The linking part is important because it aborts the task if the parent
process dies. It also guarantees the code before async/await has the same
properties after you add the async call. For example, imagine you have this:

    x = heavy_fun()
    y = some_fun()
    x + y

Now you want to make the heavy_fun() async:

    x = Task.async(&heavy_fun/0)
    y = some_fun()
    Task.await(x) + y

As before, if heavy_fun/0 fails, the whole computation will fail, including the
parent process. If you don't want the task to fail then you must change the
heavy_fun/0 code in the same way you would achieve it if you didn't have the
async call. For example, to either return {:ok, val} | :error results or, in
more extreme cases, by using try/rescue. In other words, an asynchronous task
should be thought of as an extension of a process rather than a mechanism to
isolate it from all errors.

If you don't want to link the caller to the task, then you must use a
supervised task with Task.Supervisor and call Task.Supervisor.async_nolink/2.

In any case, avoid any of the following:

  • Setting :trap_exit to true - trapping exits should be used only in
    special circumstances as it would make your process immune to not only
    exits from the task but from any other processes.
    Moreover, even when trapping exits, calling await will still exit if the
    task has terminated without sending its result back.

  • Unlinking the task process started with async/await. If you unlink the
    processes and the task does not belong to any supervisor, you may leave
    dangling tasks in case the parent dies.

## Message format

The reply sent by the task will be in the format {ref, result}, where ref is
the monitor reference held by the task struct and result is the return value of
the task function.

I also use a lot of tab completion, it gives me the list of module’s functions directly from the console.

Another tip is I start a phoenix server with

$ iex -S mix phx.server

I can update code, recompile from the console and have it reload in my browser (in case of Phoenix) without ever restarting my server.

8 Likes