fireproofsocks
Functional equivalent of OO parent/child code sharing
This is more of a philosophical question hoping for some best-practices or practical suggestions to help write better code.
I’m working with behaviours and callbacks and it provides a sensible way to organize code into different implementations, e.g. modules that implement vendor-specific business rules.
Sometimes I want multiple implementations to refer to a shared function because it does something onerous or complicated. This makes sense from an OO perspective where you have an abstract base class and then children classes: the children classes can call methods on the parent classes, so they don’t have to re-write code.
In a functional language, however, I feel like it is a potential smell when the implementation calls shared functions. I would prefer that the implementations are NOT dependent on anything else: it would be cleaner if those modules were completely isolated.
What are ways to share/reuse functions that perform complex tasks?
- Option 1: each implementation lists a dependency
- Option 2: each implementation returns a more complex result and then the dispatching module can interpret the results and perform the more complex operations there.
- Others?
Most Liked
dgmcguire
Sometimes I want multiple implementations to refer to a shared function because it does something onerous or complicated.
Simply calling that function to do work in the context of each module you want to use it would satisfy the need for re-use. Are you asking how you should organize shared functions? Because I’m also interested in how people choose to organize shared functions.
Personally I’m fine just having a Utils module or similar that encapsulates the often reused functions. Often reused functions to me implies a generic function and as such it seems fine to organize generic functions under a generic namespace.
imetallica
You can have an behaviour with a “standard” implementation, much in the same line on how GenServer, Behaviour, GenStage, works.
As an example: elixir/lib/elixir/lib/gen_server.ex at main · elixir-lang/elixir · GitHub
imetallica
You may want something like this:
defmodule Shared.OrderHandling do
@callback do_something(foo, bar)
defmacro __using__(opts) do
quote location: :keep, bind_quoted: [opts: opts] do
@behaviour Shared.OrderHandling
def do_something(foo, bar), do: ... your default implementation here
def complex_operation, do: ... your implementation here ...
def i_can_also_override(bar), do: ... your implementation ...
defoverridable i_can_also_override: 1, do_something: 2
end
end
end
Then in your AppOne application:
defmodule AppOne.VendorOne do
use Shared.OrderHandling
# Now you can override the implementation of i_can_also_override and do_something
def do_something(foo, bar), do: ...
end
Same for VendorTwo.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








