jakub-zawislak

jakub-zawislak

Protocols and pattern matching?

I’m trying to write two independent libraries with the same API. I thought I would achieve it with Protocols. I have already reviewed implementations of Phoenix.HTML.FormData for Plug.Conn and for Ecto.Changeset.

One of my library epxects a simple struct as argument, and the other one an Ecto’s schema. I know how to distinguish those in a pattern matching. The problem is, the defimpl ..., for: ... expects a module as :for parameter, not the pattern.

Is there any way to solve this problem using Protocols?

The only idea I have is to wrap those arguments with another modules like this: %MyLib.Struct{data: struct}, %MyLib.Schema{data: schema}. Then to write implementation of my protocol for MyLib.Struct and MyLib.Schema. But it wouldn’t be programmer-friendly :smile:

Most Liked

marcelotto

marcelotto

Protocols can’t be dispatched by pattern matching in a native way like Qqwy already mentioned, but ProtocolEx seems to get this to work.

OvermindDL1

OvermindDL1

Perfectly suited for that.

Fairly stable now, and if you use the suggested names (I have some names that only exist for backwards compatibility that ‘could’ potentially be removed in the future, but probably will not, and it would be a major version bump anyway).

It goes for more power than Elixir traditionally prefers because it is easier to break things than the stock protocol if you do things wrong (though I have a lot of checks and newer/documented styles of doing things that handle much of those issues now).

Hah, really? This is NOT an example of good code internally. It started purely as an experiment of How easy would it be to do something like this... and it indeed up being something I actually ‘use’ and I just never refactored it (refactoring would be done in a backwards compatible way though). ^.^;

OvermindDL1

OvermindDL1

Ah this is an old thread. ^.^

But yep, that was the purpose of why I made ProtocolEx, and I had a few ideas to get some extra speed out of it like being able to @inline definitions or defmacro implementations into the protocol and such, as well as inline case-by-case default implementations, all of which is implemented, and it can run circles around the stock Protocol in speed and capabilities at this point while entirely replacing its feature set with just a couple extra tokens overall. :slight_smile:

Qqwy

Qqwy

TypeCheck Core Team

Protocols are in fact a wrapper around Behaviours, that reduce a little boilerplate, but will only work if your input is a struct (or one of Elixir’s built-in datatypes). Dispatching a protocol based on a pattern-match is not possible.

Instead, I’d advise you to just write a behaviour for this.

samphilipd

samphilipd

If one of your implementations has to deal with arbitrary structs then defimpl can’t help you I think. If it’s one particular type of struct then it should be fine.

I tried to demystify protocols a bit and explain the difference between those and behaviours in my post here.

Could you post here the details of the other struct you’re trying to match on? I think you can use protocols for this.

Where Next?

Popular in Questions Top

New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
kostonstyle
Hi all I want to have a unix time, from the current time plus 1 hour. DateTime.now + 1 hour How to get it in elixir? Thanks
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
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
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
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement