cevado

cevado

Any reason for the different semantics with records in Elixir?

So I was experimenting with records in elixir and I found it very odd the different behaviour between using records in erlang.

defmodule R do
  require Record
  Record.defrecord :some, [:a, :b, :c]
end

R.some({:some, 1}, :a)

This would return 1 instead of returning a error of bad record.
while in erlang:

1> rd(some, {a, b, c}).
some
2> B = {some, 1}.
{some,1}
3> B#some.a.
** exception error: {badrecord,{some,1}}

Most Liked

rkallos

rkallos

Unlike in your Elixir example, in your Erlang example, you aren’t actually creating a #some record.

This should work instead:

1> rd(some, {a, b, c}).
some
2> B = #some{a = 1}.
#some{a = 1,b = undefined,c = undefined}
3> B#some.a.
1

The reason the Elixir example works is definitely interesting. It winds up calling :erlang.element(2, {:some, 1}), which only works for the :a field. If you try to get :b or :c, it should raise an exception about the index being out of range.

I suspect the core misunderstanding might be that {:some, 1} is not a valid ‘some’ record. The tuple representation of #some{a=1} is {some, 1, undefined, undefined}.

rkallos

rkallos

both examples do the same.

The intent of the examples is the same, but <record_name>/2 uses :erlang.element/2 to fetch a field. The Elixir example works on the {:some, 1} input, while the Erlang one doesn’t, because it first checks that the input is a ‘tagged tuple’ with the appropriate arity (in this case; 4).

this is exactly what i’m reporting… the elixir version doesn’t identify it as a bad record at all.

Right!

I guess we could conclude that the reason why the semantics are different in Elixir is because the private function Record.get/4 uses the :erlang.element/2 BIF. This avoids checking that the input is a tuple of the correct arity, and that the ‘tag’ element of the tuple matches the record tag. The result of this is that <record_name>/2 will work for tuples that aren’t necessarily records.

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
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
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

Other popular topics Top

ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 44139 214
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

We're in Beta

About us Mission Statement