It is probably a path at least worth exploring. It may address the issue, without changes to the language, in a way it also feels natural without impacting code readability.
On Thu, Jun 29, 2023 at 10:59 Christopher Keele <christheke...@gmail.com> wrote: > > Another idea is to improve Elixir LS itself to suggest the variable name > itself after ":". So if I type "%{foo:", it immediately suggests " foo". > So, once again, easy to write, easy to read. > > I think this is part of the popularity of the opinion that some such > syntax should only work for structs: with Elixir LS today, starting to type > a `key:` in a struct/map literal does indeed suggest from the list of known > struct keys. I don't see this being impossible in LS tooling today, but > also don't know much about what is possible with the language server > protocol today. :) > On Thursday, June 29, 2023 at 2:54:28 AM UTC-5 José Valim wrote: > >> There is another idea here, which is to fix this at the tooling level. >> >> For example, we could write %{foo, bar} and have the formatter >> automatically expand it to: %{foo: foo, bar: bar}. So you get the concise >> syntax when writing, the clear syntax when reading. Since most editors >> format on save nowadays, it can be beneficial. Executing code with the >> shortcut syntax will print a warning saying you must format the source file >> before. >> >> Another idea is to improve Elixir LS itself to suggest the variable name >> itself after ":". So if I type "%{foo:", it immediately suggests " foo". >> So, once again, easy to write, easy to read. >> >> On Thu, Jun 29, 2023 at 9:49 AM Christopher Keele <christ...@gmail.com> >> wrote: >> >>> > As a counter point: Ruby has added this feature as {foo:, bar:}, >>> which would have a direct translation to Elixir. Source: >>> https://bugs.ruby-lang.org/issues/14579 >>> >>> As a Rubyist who came to Elixir in the early days for personal projects >>> before that Ruby syntax was implemented, and has only been professionally >>> an engineering team manager of python, JS, and TS applications since: I >>> like the explicitness of Ruby's notation here, but still really hate it how >>> it reads and syntax highlights. :`) >>> >>> That is just a personal opinion though, out of context of the utility of >>> this proposal. However, I believe that incarnation for Elixir has been >>> proposed before, and I am just searching for alternatives that would still >>> enable field punning sooner rather than later. >>> >>> > You are doing great. You defend your proposal and ideas. :) >>> >>> Thank you! It is not easy to defend a language syntax proposal I do not >>> personally adore the syntax of; but I imagine that's what many people felt >>> like for Ruby's equivalent, with {foo:, bar:} (as I did at the time). I >>> earnestly believe that this idea could mitigate pain points with Elixir >>> adoption while reasonably contending with ES6 barewords syntax we are not >>> yet able to adopt. However, I would not be heartbroken if we agreed that >>> waiting for Elixir 2.0 and/or atom garbage collection was the right play >>> here. >>> >>> On Thursday, June 29, 2023 at 2:33:22 AM UTC-5 José Valim wrote: >>> >>>> > I would argue that if we want to support only atoms, but make it >>>> clear that the syntax only applies to atoms, before an Elixir 2.0, we must >>>> leverage atom literals in the feature. The addition of a new operator (or, >>>> overloading of the capture operator in previous incarnations of this >>>> proposal) is the only way to accomplish this today. >>>> >>>> As a counter point: Ruby has added this feature as {foo:, bar:}, which >>>> would have a direct translation to Elixir. Source: >>>> https://bugs.ruby-lang.org/issues/14579 >>>> >>>> > Apologies if it feels like I am trying to torpedo other solutions, >>>> that is not my intent at all. >>>> >>>> You are doing great. You defend your proposal and ideas. :) >>>> >>>> On Thu, Jun 29, 2023 at 9:29 AM Christopher Keele <christ...@gmail.com> >>>> wrote: >>>> >>>>> Honestly, I do not adore the syntax of the proposed solution, in >>>>> either capture or $ operator incarnation. I would also prefer >>>>> barewords. >>>>> >>>>> *Re: Paul's note:* >>>>> >>>>> > It is not at all clear to me why supporting string keys is critical >>>>> to the feature >>>>> >>>>> 100%, Phoenix params parsing support. This is the major obvious >>>>> use-case for full-stack devs today of this proposal. If garbage collection >>>>> of atoms is implemented in erlang, we could deprecate the proposed syntax >>>>> readily. >>>>> >>>>> Most of my personal Elixir development does not use Phoenix, so I do >>>>> empathize with the sentiment and prefer atoms/barewords, but have tried to >>>>> accommodate the outcry for this feature in this proposal, contending with >>>>> popularity of JS's barewords implementation, concerning fullstack Phoenix >>>>> development on >>>>> >>>>> > the Elixir forum (1 >>>>> <https://elixirforum.com/t/proposal-add-field-puns-map-shorthand-to-elixir/15452> >>>>> , 2 >>>>> <https://elixirforum.com/t/shorthand-for-passing-variables-by-name/30583> >>>>> , 3 >>>>> <https://elixirforum.com/t/if-you-could-change-one-thing-in-elixir-language-what-you-would-change/19902/17> >>>>> , 4 >>>>> <https://elixirforum.com/t/has-map-shorthand-syntax-in-other-languages-caused-you-any-problems/15403> >>>>> , 5 >>>>> <https://elixirforum.com/t/es6-ish-property-value-shorthands-for-maps/1524> >>>>> , 6 >>>>> <https://elixirforum.com/t/struct-creation-pattern-matching-short-hand/7544> >>>>> ) >>>>> >>>>> *Re: José's note:* >>>>> >>>>> > I agree with Paul that we don't need to support both strings and >>>>> atoms, but it must be clear that it applies to either strings or atoms. >>>>> >>>>> I would also prefer only supporting atoms, or even as a compromise >>>>> with string confusion, only structs. Previous proposals have flighted this >>>>> before, and have not succeeded. >>>>> >>>>> I would argue that if we want to support only atoms, but make it clear >>>>> that the syntax only applies to atoms, before an Elixir 2.0, we must >>>>> leverage atom literals in the feature. The addition of a new operator (or, >>>>> overloading of the capture operator in previous incarnations of this >>>>> proposal) is the only way to accomplish this today. >>>>> >>>>> If we really wanted to drive this home, we could only support atom >>>>> literals in the proposal, and drop the support for strings; however, I >>>>> don't see a way to resolve this tension today without employing atom >>>>> literals in the feature's syntax. >>>>> >>>>> *Re: Paul's note:* >>>>> >>>>> > I really don't want this thread to devolve into argument like many >>>>> of the others on this topic, but making statements like "a barewords >>>>> implementation is not viable in Elixir" is not doing any favors. It is >>>>> factually untrue, and the premise of the statement is based entirely on an >>>>> opinion. If this thread is going to have any hope of making progress, >>>>> broad >>>>> assertions of that nature better be backed up with a lot of objective >>>>> data. >>>>> >>>>> I wish there were a data-driven way to approach language design. The >>>>> only tool I know of is flighting proposals with working prototypes. >>>>> >>>>> > Make the case why *extra* syntax is better than the more limited >>>>> barewords-only implementation, for example, by enabling support for string >>>>> keys, by offering a syntax construct that can be used in more places, etc. >>>>> It isn't necessary for your proposal to torpedo other solutions in order >>>>> to >>>>> succeed, and has a better chance of doing so if you don't. >>>>> >>>>> This proposal makes a case for this syntax being better than a more >>>>> limited barewords-only implementation. Specifically, it enables support >>>>> for >>>>> string keys, and offers a syntax construct that can be used in more places >>>>> (as a specific example, error = "rate limit exceeded"; $:error # >>>>> return error tuple. Apologies if it feels like I am trying to torpedo >>>>> other solutions, that is not my intent at all. >>>>> On Thursday, June 29, 2023 at 2:02:04 AM UTC-5 José Valim wrote: >>>>> >>>>>> Hi Chris Keele, thank you for the excellent proposal. I just want to >>>>>> add that I agree with Paul that we don't need to support both strings and >>>>>> atoms, but it must be clear that it applies to either strings or atoms >>>>>> (if >>>>>> it supports only one of them) and the reason for that is because >>>>>> otherwise >>>>>> it will add to the string vs atom confusion that already exists in the >>>>>> language. Someone would easily write def show(conn, %{id}) and be >>>>>> surprised >>>>>> why it doesn't match. >>>>>> >>>>>> A couple additional thoughts to the thread: >>>>>> >>>>>> * : in JS and = in Haskell/OCaml are operators. : in Elixir is not an >>>>>> operator >>>>>> >>>>>> * &:foo/$:foo as a shortcut for {:foo, foo} is interesting but note >>>>>> that "foo: foo" already work as a shortcut in select places - so we would >>>>>> introduce more ways of doing something similar >>>>>> >>>>>> * Elixir and Ruby shares a lot syntax wise, it may be worth >>>>>> revisiting what they do and which points arose in their >>>>>> discussions/implementations >>>>>> >>>>>> On Thu, Jun 29, 2023 at 8:51 AM Paul Schoenfelder < >>>>>> paulscho...@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. >>>>>>> >>>>>>> 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. >>>>>>> >>>>>>> I really don't want this thread to devolve into argument like many >>>>>>> of the others on this topic, but making statements like "a barewords >>>>>>> implementation is not viable in Elixir" is not doing any favors. It is >>>>>>> factually untrue, and the premise of the statement is based entirely on >>>>>>> an >>>>>>> opinion. If this thread is going to have any hope of making progress, >>>>>>> broad >>>>>>> assertions of that nature better be backed up with a lot of objective >>>>>>> data. >>>>>>> Make the case why *extra* syntax is better than the more limited >>>>>>> barewords-only implementation, for example, by enabling support for >>>>>>> string >>>>>>> keys, by offering a syntax construct that can be used in more places, >>>>>>> etc. >>>>>>> It isn't necessary for your proposal to torpedo other solutions in >>>>>>> order to >>>>>>> succeed, and has a better chance of doing so if you don't. >>>>>>> >>>>>>> Paul >>>>>>> >>>>>>> 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-co...@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-co...@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> >>>>>>> . >>>>>>> >>>>>> -- >>>>> 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-co...@googlegroups.com. >>>>> >>>> To view this discussion on the web visit >>>>> https://groups.google.com/d/msgid/elixir-lang-core/7134e702-f9b2-44ad-bf33-3b8a633862d7n%40googlegroups.com >>>>> <https://groups.google.com/d/msgid/elixir-lang-core/7134e702-f9b2-44ad-bf33-3b8a633862d7n%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-co...@googlegroups.com. >>> >> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/elixir-lang-core/d265a338-e815-4e6b-a541-e61e2ec89611n%40googlegroups.com >>> <https://groups.google.com/d/msgid/elixir-lang-core/d265a338-e815-4e6b-a541-e61e2ec89611n%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/a281c514-67e6-41e1-a4f4-4f8d5572948fn%40googlegroups.com > <https://groups.google.com/d/msgid/elixir-lang-core/a281c514-67e6-41e1-a4f4-4f8d5572948fn%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/CAGnRm4K%2BNAzyumpomg2nAhvZ3PYUkvQTiB2-1UecLozf82toBA%40mail.gmail.com.