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

arcanemachine
https://nitter.net/josevalim/status/1744395345872683471 https://twitter.com/josevalim/status/1744395345872683471
New
marciol
Please, let me know if this kind of discussion already took place in another topic . Hi all, how do you consider if is better to build ...
New
crispinb
On reading dhh’s latest The One Person Framework it strikes me that Phoenix with LiveView is already pretty much this. However, never hav...
New
AstonJ
Are there any Elixir or Erlang libraries that help with this? I’ve been thinking how streaming services like twitch have exploded recentl...
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
hazardfn
I suppose this question is effectively hackney vs. ibrowse but we are at a point in our project where we have to make a choice between th...
New
Qqwy
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...
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
AstonJ
Can you believe the first professionally published Elixir book was published just 8 years ago? Since then I think we’ve seen more books f...
New
fireproofsocks
This is more of a general question, but I’m wondering how other people in the community think about the pattern matching in function sign...
New

Other popular topics Top

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
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
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 29703 241
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
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 Postgres...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52774 488
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

We're in Beta

About us Mission Statement