Ark.Interface (ark v0.13.2)

Copy Markdown View Source

Defines protocols whose implementation lives as plain functions on the implementing struct's own module.

A regular Elixir protocol needs a separate defimpl block for every struct it supports. Ark.Interface removes that step: you declare the function signatures once with definterface/2, and a struct satisfies the protocol by defining functions of the same name on its module and opting in.

Minimal example

Declare the interface with the function heads it requires:

import Ark.Interface

definterface Movable do
  def move(t, dx, dy)
end

Implement it on a struct by defining the matching function and deriving the interface:

defmodule Point do
  @derive Movable
  defstruct [:x, :y]

  def move(%Point{x: x, y: y}, dx, dy) do
    %Point{x: x + dx, y: y + dy}
  end
end

Calling the interface dispatches to the struct module's own function:

Movable.move(%Point{x: 0, y: 0}, 2, 3)
# => %Point{x: 2, y: 5}

Wiring an implementation

A struct opts into an interface in one of two ways:

  • Add @derive TheInterface next to defstruct, and define a function for each interface signature on the same module (directly or with defdelegate).
  • Call Ark.Interface.auto_impl/1 inside the module body, which builds the same delegation without @derive.

Both make TheInterface.fun(struct, ...) call TheModule.fun(struct, ...). Passing a struct that has opted into neither raises, since the interface has no implementation to dispatch to.

Summary

Functions

Implements proto for the current struct module by delegating to its own functions.

Declares an interface: a protocol plus the machinery to implement it from a struct's own module.

Functions

auto_impl(proto)

(macro)

Implements proto for the current struct module by delegating to its own functions.

Call this inside a struct module as an alternative to @derive proto. For each function the interface declares, it generates an implementation that calls the function of the same name and arity defined on the current module.

defmodule Point do
  Ark.Interface.auto_impl(Movable)
  defstruct [:x, :y]

  def move(%Point{x: x, y: y}, dx, dy) do
    %Point{x: x + dx, y: y + dy}
  end
end

See Ark.Interface for the full picture, including the @derive form.

definterface(proto, list)

(macro)

Declares an interface: a protocol plus the machinery to implement it from a struct's own module.

proto is the protocol module to define. The do block holds one def head per interface function, written as a signature with no body, exactly as in defprotocol/2.

import Ark.Interface

definterface Movable do
  def move(t, dx, dy)
end

This defines the Movable protocol and lets any struct implement it by deriving it or by calling auto_impl/1. See Ark.Interface for how a struct is wired to an interface.