Qqwy

Qqwy

TypeCheck Core Team

The issue with the static access operator (the dot)

I would like to spark a discussion about the static access operator: ..
For whom does not know: it is used in Elixir to access fields of a struct or map, where you want to be sure (/are sure) that a given (atom) key exists.

It is arguably more easy to write out foo.bar instead of foo[:bar] or binding it in a pattern-match, but I have found that relying on . too quickly/often is a recipe for tightly-coupled code, in my opinion.

Namely, changing the internals of a %Foo{} struct becomes impossible when you (or, even worse, users of your library) rely on being able to type foo.bar. If you want to be able to change the internals of a data structure, you should instead have written a function like Foo.bar(foo). Besides being more explicit (and also slightly longer to type), this allows you to alter the way bar is obtained from within the structure at a later time.

I have run into this issue multiple times now while developing libraries, so I want to ask you all about your opinion about this subject: Do you rely on using . a lot? Do you agree that . should be used with care? Are there alternatives? How to you mitigate this issue? Or is it, in your opinion, not an (important) issue at all?

Most Liked

ericmj

ericmj

Elixir Core Team

Typespecs to the rescue. Declare your types as opaque and users should know they shouldn’t depend on the structure. If they use dialyzer they will even get errors when matching on the structure or using the dot field access.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

I’m a bit confused, what is “direct field access” here, foo.bar ? If that’s what you mean it isn’t really a function call, IIRC it translates to basically:

case foo do
  %{bar: val} -> val
  _ -> apply(foo, :bar, []) # or an error handling clause, can't recall
end

foo[:bar] However is a function call Access.get which you can see easily from quoting it:

iex(1)> quote do: foo[:bar]
{{:., [], [Access, :get]}, [], [{:foo, [], Elixir}, :bar]}

I don’t believe any fancy inlining happens there.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

But this isn’t the case. Nothing at all happens at compile time to ensure that the key does or does not exist in the map, nor even that foo is a map.

Where Next?

Popular in Discussions Top

Other popular topics Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39247 209
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement