Adzz

Adzz

Solving the Expression Problem with Elixir

Hello,

I have been thinking about how Elixir might help us solve the expression problem. There are some really good articles on how clojure does it with protocols, so I thought I’d give it a go:

https://tech.nested.com/solving-the-expression-problem-with-elixir-916bb9b5dd74

The solution I came to is very un-idiomatic elixir. I’d be interested in hearing how others would approach the problem!

Most Liked Responses

OvermindDL1

OvermindDL1

Not heard of it referred to as the ‘Expression Problem’, but that is a good example as to why both pure functional and OOP are very bad at solving it, protocols are not really better than OOP here, what would work best is multiple polymorphic dispatch (rehashing a bit of the article to set up context here), like CLOS (Lisps’s OOP system) supports, where you can dynamically dispatch on more than one argument, which is easily solved via pattern matching in Elixir (but requires horrible dispatch trees and such for OOP). Here’s an example (typed in post so probably errors somewhere) using my ProtocolEx library (which builds matchers at compile-time, think of it as a significantly more powerful version of the built-in Protocols):

import ProtocolEx
defprotocol_ex Overlap, as: shapes do
  def overlap?(shape, other_shape), do: overlap?({shape, other_shape})
  def overlap?(shapes)
end


defimpl_ex SquareRect, {%schemal{}, %schemar{}} when schemal in [Square, Rect] and schemar in [Square, Rect], for: Overlaps do
  def overlap?({%Square{}, %Square{}}), do: :test_if_squares_overlap
  def overlap?({%Rect{}, %Rect{}}), do: :test_if_rects_overlap
  def overlap?({%Rect{}, %Square{}}), do: :test_if_rect_overlaps_square
  def overlap?({%Square{}, %Rect{}}), do: :test_if_square_overlaps_rect
end

defimpl_ex CircleRect, {%schemal{}, %schemar{}} when schemal in [Circle, Rect] and schemar in [Circle, Rect], for: Overlaps do
  def overlap?({%Circle{}, %Circle{}}), do: :test_if_circles_overlap
  def overlap?({%Rect{}, %Circle{}}), do: :test_if_rect_overlaps_circle
  def overlap?({%Circle{}, %Rect{}}), do: :test_if_circle_overlaps_rect
end

Or whatever, there’s many ways of doing it, and you can split each case of overlap into it’s own module, or put them all together, or define defaults, or control ordering, or let dependencies of this add in their own things for their own types, or use tagged tuples instead of structs, or whatever. :slight_smile:

Shikada

Shikada

I’m not sure if you watched this talk already, but it’s very relevant to what you’re doing.

Adzz

Adzz

No I haven’t, it looks good. I understand protocols well already though. Just interested to hear other’s thoughts

Where Next?

Popular in Discussions Top

Qqwy
Looking at the stacks that existing large companies have used, WhatsApp internally uses Mnesia to store the messages, while Discord uses ...
New
MarioFlach
Hello, I want to share a project I’ve been working on for a while: https://github.com/almightycouch/gitgud Background Some time ago I ...
New
chuck
Let me start by stating an assumption: Phoenix is a great approach to building REST APIs. There are many reasons for this, but I will ass...
New
nburkley
AWS re:Invent is on at the moment with some interesting announcements. One new feature in particular is the Lambda Runtime API for AWS La...
New
AstonJ
I’ve just started the Phoenix part of the utterly brilliant online course by @pragdave. On generating the Phoenix app he uses the --no-ec...
New
IVR
Hi all, I’ve seen a number of related threads in the past, but I’d still be very curious to hear an up-to-date opinion on this topic. I...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
RudManusachi
What configs will make sense to put to runtime.exs? – A bit of how I configure apps: I have generic configs in config/config.exs, dev...
New
Owens
Hello all, I am developing a new mobile app with Flutter frontend and Phoenix backend. The mobile app has real-time task management and c...
New

Other popular topics Top

AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31142 143
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New

We're in Beta

About us Mission Statement