Pattern matching on Erlang type (e.g. :queue.queue())

Hi,

Is there a way to pattern match on an Erlang type, e.g. :queue.queue() ?

I tried multiple things like

iex(5)> case :queue.new() do x when :queue.is_queue(x) -> IO.put("yes")
...(5)> _ -> nil
...(5)> end
** (CompileError) iex:5: cannot invoke remote function :queue.is_queue/1 inside guard

Cheers,

François

EDIT: Leaving this here for posterity’s sake but, this is a bad idea, don’t do it.

:queue.is_queue/1 itself is basically just a couple guards. You could mirror it’s definition in Elixir.

2 Likes

But :queue.queue/1 is opaque, one should not rely on its internal representation. It could change from a pair to something else with every release of Erlang.

Therefore: don’t use a guard or pattern match, but use :queue.is_queue/1 to do a check in your functions body.

4 Likes

@NobbZ you’re absolutely right. Sorry about the bad advice, thanks for the correction!

Too bad there doesn’t exist any standard way to import erlang guards…

Will look into rearchitecturing my functions, but pattern matching would be more elegant in some areas.

It’s just an ordinary function, you weren’t able to use it in a guard in Erlang as well.

1 Like

You can use Erlang guards just fine. The problem is that is_queue is not a guard. It’s a function. In Elixir it could be implemented as a guard using defguard, but not in Erlang, which doesn’t support the definition of custom guards.

You could define your own guard (in Elixir, not in Erlang) but you shouldn’t because the way queues are implemented is an implementation detail.

2 Likes