To update the considerations of this proposal if we adopt a new tagged variable literal operator <https://groups.google.com/g/elixir-lang-core/c/P6VprVlRd6k/m/017oS_xmAgAJ> ($) instead:
*Pro: solves existing pain points* *Pro: works with existing code* The newly proposed operator results in a compile-time-error on older versions of Elixir. All compiling Elixir code today will continue to compile as before. *Cons: does not work well with existing tooling* A new operator would require dedicated formatter support and updates to downstream syntax highlighters. *Cons: does not minimize surface area of the language* A new operator is more new syntax to learn; although one could readily argue that this is worth not making the capture operator a more complicated syntax to learn. *Pros: does not overload the capture operator* *Open Question: charlists* A dedicated operator resolves the previous AST parsing ambiguity compared to using the capture operator. I have implemented charlist tagged variable literal support <https://github.com/elixir-lang/elixir/commit/9176180799e1ba11348034c4aa3aa1bf37f11e87> to my new-operator prototype branch <https://github.com/elixir-lang/elixir/compare/main...christhekeele:elixir:tagged-variable-literals>. This would complicate parsing of non-literal expressions like field access <https://groups.google.com/g/elixir-lang-core/c/P6VprVlRd6k/m/WyqlwZ1iAgAJ> in the future nice-to-have feature-set more difficult, but still much more tractable than re-appropriating the capture operator. On Thursday, June 29, 2023 at 12:16:23 AM UTC-5 Christopher Keele wrote: > > 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. > > Indeed, the main argument against a "bare" usage of tagged variable > literals (like foo = 1; {:foo, baz} = $:foo; bar #=> 1) is that we could > not roll back this syntax without 2.0 breaking-changes to only support > barewords where applications really want them: within list/map literals > only. > > On Wednesday, June 28, 2023 at 11:40:39 PM UTC-5 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/75b0c90a-e08f-4ca6-8c01-95b9a79e4814n%40googlegroups.com.