On Thu, Jun 29, 2023 at 2:51 AM Paul Schoenfelder < paulschoenfel...@fastmail.com> wrote:
> For reasons explained in Austin's reply > <https://groups.google.com/g/elixir-lang-core/c/P6VprVlRd6k/m/ijxO7HdpAgAJ>, > a "barewords" implementation is not viable in Elixir, because of the > prevalence of both atom and string key types. > > IMO, discussing the nuance of if a barewords representation should prefer > atoms or keys is what has been continually holding this feature up for a > decade, and that's what this proposal tries to move past. > > I don't agree that the rationale given by Austin is sufficient to reject a > barewords-only implementation of field punning in Elixir. It is not at all > clear to me why supporting string keys is critical to the feature, and I > especially don't find the argument that people will ignore all of the > plentiful advice about avoiding atom table exhaustion just so they can use > field punning (e.g. switching to `Jason.parse(.., keys: atoms)`) > compelling, at all. There will always be people who find a way to do dumb > things in their code, but languages (thankfully) don't base their designs > on the premise that most of their users are idiots, and I don't see why it > would be any different here. > Prior to Symbol garbage collection, people had to be told repeatedly not to use symbol keys for JSON parsing in Ruby so that they would get to use the "cleaner" `foo[:bar]` syntax rather than `foo['bar']` or `foo["bar"]`. This *did* inspire the Ruby core team to figure out how to identify *temporary* symbols (created during runtime) as opposed to *permanent* symbols (created during code parsing) so that temporary symbols could be garbage collected, so languages *can* adapt to many of their users being idiots by reducing some sharp edges. Atom exhaustion is a particularly sharp edge to Elixir that would require convincing at the BEAM level…and I’m less certain that would pass muster. If there are other benefits that could be obtained by identifying and garbage collecting temporary atoms, then it could be added to the BEAM and eventually Elixir would be able to have bareword map deconstruction. As Chris suggested, and I completely agree, it’s the pattern matching at the edges — not just Phoenix. I deal with a lot of JSON and CSV parsing, and we almost always try to push those into maps which eventually get transformed into structs. Bareword map deconstruction working with string keys would increase the readability of some of those transformations (but not enough that I think that this is a make-or-break feature for Elixir). Other people want to use bareword map deconstruction working with atom keys only on maps that they have full control over. Almost everyone agrees that bareword struct deconstruction would be easily accomplished and understood, but that there are some sharp edges where — because structs *are* maps — confusion would enter again (e.g., `%{struct | key}` would need to be specified as `%Struct{struct | key}` if we disallow deconstruction / field punning on maps). I've seen this debate come up over and over since the very first time it > was brought up on this list, and there is a good reason why it keeps dying > on the vine. The justification for field punning is weak to begin with, > largely sugar that benefits the code author rather than the reader, and > syntax sugar must carry its own weight in the language, and the only chance > of that here is by building on the foundations laid by other languages > which have it. Doing so means readers are much more likely to recognize the > syntax for what it is, it adds no new sigils/operators, and it is narrowly > scoped yet still convenient in many common scenarios. If anything, the > desire to make this work for string keys is what keeps killing this > feature, not the other way around. > Having used object deconstruction heavily in JavaScript / Typescript, I disagree that it primarily benefits the code author. It really does help the readability of the code in general, at least for those languages. I’m less convinced that it would be of great benefit in Elixir except for accidental misspellings (e.g., `%{catalog: catelog}` type errors; the field punning here would benefit both writer and reader by reducing accidental errors like this). I think that your assertion that it is the desire for string keys killing this proposal is incorrect — I have seen complaints about excess similarity to tuple declaration raised in each discussion, too (misreading `%{ok, reason}` as `{ok, reason}`). I think that if the Elixir community wants bareword field punning, then it should be limited to things which have *fields*: structs (and maybe sugar could be built for Erlang record support). IMO, maps don’t have fields, they have keys with values. Once the rules around struct field punning could be worked around, then this could be introduced and the discussion could be laid to rest. As far as I can tell, neither Ocaml nor Haskell support it for maps, and Typescript will scream about it for string records (e.g., `Record<string, any>` or `type foo = { [key: string]: any }` or `object`) because it can’t do any validation of the value under the key. Otherwise, I think we’re going to need to accept that such destructuring would need some sort of syntax added. -a IMO, it would be too magic to do something like `%{"foo", 'bar', :baz} = %{"foo" => 1, 'bar' => 2, :baz => 3}; {foo, bar, baz} #=> {1, 2, 3}`, but it *would* allow for atom, string, and charlist keys being deconstructed without much excess verbosity. On Thu, Jun 29, 2023, at 12:40 AM, Christopher Keele wrote: > > > This proposal mentions OCaml, Haskell and JS as prior works of art for > > this type of feature. I think a key thing to point out is that in those > > languages, they did not need to add additional syntax in order to > > support this. > > This is true, and the discomfort extends to Ruby as well. > > For reasons explained in Austin's reply > <https://groups.google.com/g/elixir-lang-core/c/P6VprVlRd6k/m/ijxO7HdpAgAJ>, > a "barewords" implementation is not viable in Elixir, because of the > prevalence of both atom and string key types. > > IMO, discussing the nuance of if a barewords representation should prefer > atoms or keys is what has been continually holding this feature up for a > decade, and that's what this proposal tries to move past. > > Perhaps in an ideal Elixir 2.0 future if we get garbage collection of > atoms like Ruby, Phoenix can move over to parsing params with atom-based > key pairs, we can drop the operator and atom/string differentiation, and > move the entire syntax over to barewords. Worth calling out that this > proposal (with a new operator, not the capture operator) could remain > backwards-compatible with the proposed syntax if we moved into an > atom-oriented Phoenix params parsing Elixir 2.0 future. > > As Elixir 2.0 may never get released, famously, this is the only clear > path I see forward for our production applications today to get field > punning, that skirts issues with prior art. > On Wednesday, June 28, 2023 at 11:27:48 PM UTC-5 me wrote: > > This proposal mentions OCaml, Haskell and JS as prior works of art for > this type of feature. I think a key thing to point out is that in those > languages, they did not need to add additional syntax in order to > support this. > > In OCaml, the syntax goes from > > { foo = foo; bar = bar } > > to > > { foo; bar } > > Haskell starts with > > C { foo = foo, bar = bar } > > and turns into > > C { foo, bar } > > And lastly, Javascript uses > > { foo: foo, bar: bar } > > which can be used as > > { foo, bar } > > Note the lack of additional syntax surrounding these features. > > > {foo, bar, baz} = {1, 2, 3} > > > > %{$:foo, "fizz" => "buzz", $"bar", fizz: :buzz} > > # => %{:fizz => :buzz, :foo => 1, "bar" => 2, "fizz" => "buzz"} > > If I were coming from one of the above languages (or any other language > that supports this feature), I would not look at this syntax and say > "This is field punning". I would have no intuition what is going on. > > Speaking as someone that has a decent amount of Elixir experience, > $"bar" looks like it should be closer in functionality to :"bar" than > field punning. Or maybe even similar to using ? to find the codepoint of > a single character. Something to keep in mind, Erlang actually uses $ > for the same purpose that Elixir uses ?. I'm not saying Elixir couldn't > use the same token/operator for a different purpose, I just think it is > something that should be considered. > > Justin > > > -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to elixir-lang-core+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/aee0f98a-9b9b-4ff0-9a48-08d4e31df8c5n%40googlegroups.com > <https://groups.google.com/d/msgid/elixir-lang-core/aee0f98a-9b9b-4ff0-9a48-08d4e31df8c5n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > > > -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to elixir-lang-core+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/72586965-c3ee-42c0-b7d3-7e863ace2706%40app.fastmail.com > <https://groups.google.com/d/msgid/elixir-lang-core/72586965-c3ee-42c0-b7d3-7e863ace2706%40app.fastmail.com?utm_medium=email&utm_source=footer> > . > -- Austin Ziegler • halosta...@gmail.com • aus...@halostatue.ca http://www.halostatue.ca/ • http://twitter.com/halostatue -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAJ4ekQtbTnTrXNX2STuE2WENtS_V6LSuq1Ne9cFK6tiMO2DMww%40mail.gmail.com.