Proposal: Add field puns/map shorthand to Elixir

proposal
on-topic-only-please

#42

I was trying to not require people who voted no, to not have to vote again. That’s why I wrote this in both places:

There may be people who don’t come back to this thread that didn’t want this feature and I felt like it would be unfair for their vote to not get counted just because there’s a different poll. However, I’m open to suggestions about how it could be done better.

EDIT: Sorry, I think I might have misread you to mean there should be a “I don’t want this”, but perhaps you meant a “I don’t want just structs”. I’ll add that option. Thanks.


#43

I can see the value in using something like this in function heads etc.

Maybe this? Since & is already being used for function capture syntax and function arguments e.g. fun = &(&1 + 1), maybe just replace the % map/struct prefix with & or &% something like this:

&{a, b, c} = %{:a => 1, "b" => 2, "c" => 3}
# or
&%{a, b, c} = %{:a => 1, "b" => 2, "c" => 3}

As long as the assignment matches an atom or string key, it’s assigned.

&{a, c} = %Struct{a: 1, b: 2, c: 3}

&{a, c, x} = %{:a => 1, "b" => 2, "c" => 3}
** (MatchError) no match of right hand side value: %{:a => 1, "b" => 2, "c" => 3}
...

I agree that function heads could be shortened:

def index(&{account_id, filters, lists, etc}) do
  ...
# or
def index(&%{account_id, filters, lists, etc}) do
  ...

Edit: The example with x above to be a no match error instead of x = nil

Just a thought :slight_smile:


#44

6 posts were split to a new topic: How to reduce bias in surveys and ideas on garnering community feedback


#46

This would potentially be very slow. It would first need to check for the atom key of the same name, and if that doesn’t exist, it would check for the string key with that name (or string then atom). So you are effectively slowing down your map calls by up to 100% just to type a couple less characters?

I think your proposal of using & would be overloading that character too much. Right now it is meant for functions, and in seeing your proposed syntax, I would think it had something to do with functions.


#49

Longer construct doesn’t mean harder to read as it has a certain rhythm. Adding a flag to distinguish between data types while map keys can be both atom and string can have opposite effect and bring more confusion.

this is is probably the best option so far as it distinguish key types on the individual basis.


#50

I don’t like the idea of diverging structs from maps any further since the general message is “structs are just maps”.

This. Can we look at some code that made you write this proposal, because I’m not sure where it’s coming from. The proposal is not solving any of my problems, so I’m just in the “no” mode.


#51

I, personally, don’t want field punning in Elixir at all and I wish the survey options stayed as they were before. Yes, function heads can get big, but thanks to the simplicity of Elixir syntax they are always easily readable. New syntax means more complexity and more unnecessary mental overhead when reading code. Erlang is simpler, and Elixir added some syntax complexity to allow more succinct code, and thanks to macros it is extensible. So you can add field punning with macros through a package.

All the libraries, in my opinion, suffer from not looking like a map. This makes it harder to understand what is going on.

To me, this is an advantage, and does not make it harder to understand when you get used to it. And this way (with support through package) you’re not forcing everyone to learn the new syntax. Because to me, on a first glance, %{x, y}a looks more like a tuple or a list, or a one key-value pair, not a two key-value pair data structure, because I see only 2 times one thing (not two, as in a key and a value). So I’d have to get used to it. Again, unnecessarily.

m([foo, bar]) = my_map

This looks perfectly fine and usable for me, if you’re into that kind of thing and want to use field punning in your project.


#52

Thanks to everyone who participated! I wanted to wait long enough to give people a chance to voice there opinions. There’s been a pretty consistent 2-1 in favor of not adding this to the language, which tells me the community support isn’t behind this feature. I don’t believe I will be able to convince anyone beyond what I’ve already said.

I’ve changed my position to, "this should not be added to the language."

I do believe there are short-comings and trade-offs to the third-party packages, but they are still good software. So, people do have a choice even if it’s not the most optimal. I think effort for field puns should be directed at making those better, which may mean proposals to the Elixir language to allow third-party packages to closer implement what’s desired without the short-comings and trade-offs.

Finally, if you think you’ve got a more convincing argument than I’ve made to add field puns to the language in some form, don’t let me discourage you from trying.

Thanks again for the discussion!


#53

That’s a very interesting approach :+1: :+1: :+1:


#55

Can I ask why this thread was pinned? Usually, when I see pinned threads they are either forum announcements or official Elixir business. As far as I’ve seen, this was just a proposal that you wrote on your own accord. Am I missing something? I’m wondering what prompted this proposal to be pinned. If most people had voted in favor of field punning was the Elixir core team going to implement it or something?

Apologies if this is off-topic, but pinned threads might give users the wrong impression that this was going to be an official addition to the language depending on the poll results (which as far as I know was not the case).


#56

Yes, it’s just a proposal I wrote on my own.

I added the polls because I wanted to understand people position without requiring them to post something. The voting would have probably played a factor into whether the core team would accept the feature. I don’t think it would be any indication that the core team would agree to add it to the language or implement it. I would have likely implement it myself had it gotten the level of support necessary (including core approval). However, it didn’t even get to the level where I would be comfortable asking the core team.

I don’t have the ability to pin and didn’t ask for it (though, I appreciate it). I suspect it was pinned because it was a proposal and if it isn’t pinned, it can easily get swallowed by other posts limiting the amount of feedback it can get.

This wasn’t posted in the categories that the core team posts in here on the forum, which would ideally be the indication that it’s not from the core team. But, perhaps there’s something that could be done better in the future to help distinguish. However, I think any proposal that appears to have favor in the community will serve as indication that the core team should at least consider it. In that sense, it does matter that you voice your opinion on proposals by non-core members.


#57

Thank you for putting in the effort, and keeping a cool and level-headed approach. One thing that’s certain is that anyone can be wrong about anything. Maybe in the future, the Elixir team will look more kindly on simple field punning syntax–maybe if and when Elixir is used at the kind of scale where its lack is a real pain point.


#58

Hi Joe, the thread was pinned by José. I’m guessing for a number of reasons:

  • Proposals around the same topic have cropped up many times
  • @blatyo’s proposal was well thought out and comprehensive and a good example of how a proposal should be composed
  • It also contained details of previous related proposals with a good summary of them
  • José was interested in how the discussion would unfold on the forum (as mentioned in another post, we’ve been discussing how best to accommodate proposals on the forum)

Re pinned threads that are by members who are not part of the forum or core teams, in future we’ll do our best to post a note to mention why they’re pinned (unless the reason is obvious) :slight_smile:


#59

Ah that makes more sense! I didn’t see anything about who pinned it. But if Jose pinned it then it makes total sense about why he and the other core team members would be interested in the discussion and overall opinion of the users. I absolutely agree that the proposal was very well thought out and a good summary of the issue for the Elixir community.

Thanks for the explanation! I agree it would be useful in the future to know why threads are pinned if it isn’t something obvious like a language release or forum announcement.

Cheers :slight_smile:


#60

I am a big advocate of this. But I think we should only allow punning for atom keys. This makes the syntax less awkward with the extra letter after the map definition, and in my experience punning is most valuable when destructuring existing data types.

Usually you only have string keys when processing user input or so, and for that situation it’s not a big deal to have some repetition. However for internal code that uses structs, or maps with atom keys, it will make the code a lot more concise and more readable. I agree you have to get used to the syntax, but if you are used to it, it’s really a lot more readable in my opinion.

I think this doesn’t make elixir less accessible, because a huge portion of the people already know (and like) how to use this from JavaScript. I do think anyone who writes JavaScript a lot, really really likes this, and the benefit might not be obvious to people who are not familiar with it (I had to get use to it when I learned ES6). But trust me, this is a great language feature, and it will make the code more elegant and readable.

I also would really like to have the object spread operator in Elixir, for manipulating maps, but that is a discussion for another.day :slight_smile:


#61

By the way for another language that took these features to a functional language environment. ReasonML, implemented the punning syntax for OCaml.


#62

The major difference is that ReasonML has a distinct syntax for tuples and maps whereas in Elixir it would just be a matter of %.


#63

Uh… OCaml itself not only has punning but also a simplified matching with guards as well. ReasonML did not add that feature, it’s built in to OCaml.


#64

Well, it’s arguable that the difference between %{} and {} and {} and () is smaller. I actually think the %{} syntax is quite dinstinct from {}.


#65

Ah thought it was syntax sugar coming from ReasonML, actually I have never had time to dive into OCaml or ReasonML yet!