Specifically, we expanded an undefined variable foo to a function call foo(), warned about the expansion, then reported a compile-time error about the missing function, instead.
On Wednesday, June 28, 2023 at 11:13:18 PM UTC-5 Christopher Keele wrote: > The above is how we dealt with undefined variable references until > recently (I think 1.15?): warn about the problematic expansion, error on > the expanded syntax. > > On Wednesday, June 28, 2023 at 11:05:00 PM UTC-5 Christopher Keele wrote: > >> An alternative would be to prepend compiler issues with a depiction of >> the how the sugar expands. Something like: >> >> %{$:foo, "fizz" => "buzz", $"bar", fizz: :buzz, $:baz} >> # !> warning: expanding %{$:foo, "fizz" => "buzz", $"bar", fizz: :buzz, $ >> :baz} into a syntactically invalid construct: >> # !> %{:foo => foo, "fizz" => "buzz", "bar" => bar, fizz: :buzz, :baz => >> baz} >> # !> iex:12:47 >> # !> # !> ** (SyntaxError) invalid syntax found on iex:12:47: >> # !> ┌─ error: iex:12:47 >> # !> 12 │ %{:foo => foo, "fizz" => "buzz", "bar" => bar, fizz: :buzz, >> :baz => baz} >> # !> │ ^ >> # !> │ >> # !> unexpected expression after keyword list. Keyword lists must >> always come last in lists and maps. >> # !> >> # !> Syntax error after: ',' >> >> On Wednesday, June 28, 2023 at 10:56:13 PM UTC-5 Christopher Keele wrote: >> >>> %{$:foo, "fizz" => "buzz", $"bar", fizz: :buzz, $:baz} >>> >>> Personally, my preference would be to disallow this usage, but perhaps >>> with an even more instructive compiler error message. >>> >>> In fact, I think that we could leverage most existing errors/warnings >>> today, as long as things like the compiler error reporter desugar this >>> feature before reporting, to make it clearer upon error what is actually >>> going on in a variety of circumstances. This would give us something more >>> like: >>> >>> %{$:foo, "fizz" => "buzz", $"bar", fizz: :buzz, $:baz} # !> ** >>> (SyntaxError) invalid syntax found on iex:12:47: >>> # !> ┌─ error: iex:12:47 >>> # !> │ >>> # !> 12 │ %{:foo => foo, "fizz" => "buzz", "bar" => bar, fizz: :buzz, >>> :baz => baz} >>> # !> │ ^ >>> # !> │ >>> # !> unexpected expression after keyword list. Keyword lists must >>> always come last in lists and maps. >>> # !> >>> # !> Syntax error after: ',' >>> On Wednesday, June 28, 2023 at 10:44:44 PM UTC-5 Christopher Keele wrote: >>> >>>> Posted that last reply early. continued: >>>> >>>> Part of the elegance in of making $:foo and &"bar" expand to a valid >>>> pair, right before Map expansion handles pairs as {:%{}, [], [... >>>> pairs]}, is that it *could* easily allow us to support mixing tagged >>>> variable captures anywhere in the existing syntax constructs: This is not >>>> true of my prototype today, though, it would need more work based on how >>>> we >>>> decide to handle it: >>>> >>>> {foo, bar, baz} = {1, 2, 3} >>>> >>>> %{$:foo, "fizz" => "buzz", $"bar", fizz: :buzz} >>>> # => %{:fizz => :buzz, :foo => 1, "bar" => 2, "fizz" => "buzz"} >>>> >>>> %{$:foo, "fizz" => "buzz", $"bar", fizz: :buzz, $:baz} # !> ** >>>> (SyntaxError) invalid syntax found on iex:12:47: >>>> # !> ┌─ error: iex:12:47 >>>> # !> │ >>>> # !> 12 │ %{$:foo, "fizz" => "buzz", $"bar", fizz: :buzz, $:baz} >>>> # !> │ ^ >>>> # !> │ >>>> # !> unexpected expression after keyword list. Keyword lists must >>>> always come last in lists and maps. Therefore, this is not allowed: >>>> # !> >>>> # !> [some: :value, :another] >>>> # !> %{some: :value, another => value} >>>> # !> >>>> # !> Instead, reorder it to be the last entry: >>>> # !> >>>> # !> [:another, some: :value] >>>> # !> %{another => value, some: :value} >>>> # !> >>>> # !> Syntax error after: ',' >>>> >>>> >>>> >>>> On Wednesday, June 28, 2023 at 10:32:20 PM UTC-5 Christopher Keele >>>> wrote: >>>> >>>>> > Alternatively, the `$` symbol could be used at the beginning of the >>>>> data structure to indicate that it is performing capture destructuring >>>>> (e.g., `$%{key1:, key2:}` or `$%{"key1", "key2"}`, but then it starts >>>>> feeling a little more line-noisy. >>>>> >>>>> I agree that'd be noisy. Also, it might make mixing tagged variable >>>>> literals, literal => pairs, and trailing keyword pairs even more >>>>> confusing. >>>>> >>>>> Consider today that we support: >>>>> %{"fizz" => "buzz", foo: :bar} >>>>> # => %{:foo => :bar, "fizz" => "buzz"} >>>>> >>>>> But do not support: >>>>> %{foo: :bar, "fizz" => "buzz"} >>>>> # !> ** (SyntaxError) invalid syntax found on iex:5:12: >>>>> # !> ┌─ error: iex:5:12 >>>>> # !> │ >>>>> # !> 5 │ %{foo: :bar, "fizz" => "buzz"} >>>>> # !> │ ^ >>>>> # !> │ >>>>> # !> unexpected expression after keyword list. Keyword lists must >>>>> always come last in lists and maps. Therefore, this is not allowed: >>>>> # !> >>>>> # !> [some: :value, :another] >>>>> # !> %{some: :value, another => value} >>>>> # !> >>>>> # !> Instead, reorder it to be the last entry: >>>>> # !> >>>>> # !> [:another, some: :value] >>>>> # !> %{another => value, some: :value} >>>>> # !> >>>>> # !> Syntax error after: ',' >>>>> >>>>> Supporting $%{key1:, key2:} or $%{"key1", "key2"} obfuscates this >>>>> situation even further. >>>>> On Wednesday, June 28, 2023 at 10:16:10 PM UTC-5 halos...@gmail.com >>>>> wrote: >>>>> >>>>>> On Wed, Jun 28, 2023 at 8:41 PM Paul Schoenfelder < >>>>>> paulscho...@fastmail.com> wrote: >>>>>> >>>>>>> I have an almost visceral reaction to the use of capture syntax for >>>>>>> this though, and I don’t believe any of the languages you mentioned >>>>>>> that >>>>>>> support field punning do so in this fashion. They all use a similar >>>>>>> intuitive syntax where the variable matches the field name, and they >>>>>>> don’t >>>>>>> make any effort to support string keys. >>>>>>> >>>>>> >>>>>> JavaScript *only* supports string keys. Ruby’s pattern matching >>>>>> which can lead to field punning only supports symbol keys, but since >>>>>> ~2.2 >>>>>> Ruby can garbage collect symbols, making it *somewhat* less >>>>>> dangerous to do `JSON.parse!(data, keys: :symbol)` than it was >>>>>> previously. >>>>>> >>>>>> As far as I know, the BEAM does not do any atom garbage collection, >>>>>> and supporting *only* symbols will lead to a greater chance of atom >>>>>> exhaustion because a non-flagged mechanism here that only works on atom >>>>>> keys will lead to `Jason.parse(data, keys: :atom)` (and not >>>>>> `Jason.parse(data, keys: :atom!)`). I do not think that any >>>>>> destructuring >>>>>> syntax which works on maps with symbol keys but not string keys will be >>>>>> acceptable, although if it is constrained to *only* work on structs, >>>>>> then >>>>>> it does not matter (as that is the same restriction that it appears that >>>>>> OCaml and Haskell have). >>>>>> >>>>>> I think that either `&:key` / `&"key"` or `$:key` / `$"key"` will >>>>>> work very nicely for this feature, although it would be nice to have >>>>>> `&key:` or `$key:` work the same as the former version. Alternatively, >>>>>> the >>>>>> `$` symbol could be used at the beginning of the data structure to >>>>>> indicate >>>>>> that it is performing capture destructuring (e.g., `$%{key1:, key2:}` or >>>>>> `$%{"key1", "key2"}`, but then it starts feeling a little more >>>>>> line-noisy. >>>>>> >>>>>> I think that the proposal here — either using `&` or `$` — is >>>>>> entirely workable and IMO extends the concept nicely. >>>>>> >>>>>> -a >>>>>> >>>>>> On Wed, Jun 28, 2023, at 7:56 PM, Christopher Keele wrote: >>>>>>> >>>>>>> This is a formalization of my concept here >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/oFbaOT7rTeU/m/BWF24zoAAgAJ>, >>>>>>> >>>>>>> as a first-class proposal for explicit discussion/feedback, since I now >>>>>>> have a working prototype >>>>>>> <https://github.com/elixir-lang/elixir/compare/main...christhekeele:elixir:tagged-variable-capture> >>>>>>> . >>>>>>> >>>>>>> *Goal* >>>>>>> >>>>>>> The aim of this proposal is to support a commonly-requested feature: >>>>>>> *short-hand >>>>>>> construction and pattern matching of key/value pairs of associative >>>>>>> data >>>>>>> structures, based on variable names* in the current scope. >>>>>>> >>>>>>> *Context* >>>>>>> >>>>>>> Similar shorthand syntax sugar exists in many programming languages >>>>>>> today, known variously as: >>>>>>> >>>>>>> - Field Punning <https://dev.realworldocaml.org/records.html> — >>>>>>> OCaml >>>>>>> - Record Puns >>>>>>> >>>>>>> <https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/record_puns.html> >>>>>>> >>>>>>> — Haskell >>>>>>> - Object Property Value Shorthand >>>>>>> >>>>>>> <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#property_definitions> >>>>>>> >>>>>>> — ES6 Javascript >>>>>>> >>>>>>> This feature has been in discussion for a decade, on this mailing >>>>>>> list (1 >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/4w9eOeLvt-8/m/WOkoPSMm6kEJ>, >>>>>>> >>>>>>> 2 >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/NoUo2gqQR3I/m/WTpArTGMKSIJ>, >>>>>>> >>>>>>> 3 >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/3XrVXEVSixc/m/NHU2M4QFAQAJ>, >>>>>>> >>>>>>> 4 >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/OvSQkvXxsmk/m/bKKHbBxiCwAJ>, >>>>>>> >>>>>>> 5 >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/XxnrGgZsyVc/m/1W-d_XAlBgAJ> >>>>>>> , 6 <https://groups.google.com/g/elixir-lang-core/c/oFbaOT7rTeU>) >>>>>>> and 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>), >>>>>>> >>>>>>> and has motivated many libraries (1 >>>>>>> <https://github.com/whatyouhide/short_maps>, 2 >>>>>>> <https://github.com/meyercm/shorter_maps>, 3 >>>>>>> <https://hex.pm/packages/shorthand>, 4 >>>>>>> <https://hex.pm/packages/synex>). These narrow margins cannot fit >>>>>>> the full history of possibilities, proposals, and problems with this >>>>>>> feature, and I will not attempt to summarize them all. For context, I >>>>>>> suggest reading this mailing list proposal >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/XxnrGgZsyVc/m/1W-d_XAlBgAJ> >>>>>>> >>>>>>> and this community discussion >>>>>>> <https://elixirforum.com/t/proposal-add-field-puns-map-shorthand-to-elixir/15452> >>>>>>> in >>>>>>> particular. >>>>>>> >>>>>>> However, in summary, this particular proposal tries to solve a >>>>>>> couple of past sticking points: >>>>>>> >>>>>>> 1. Atom vs String >>>>>>> >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/NoUo2gqQR3I/m/IpZQHbZk4xEJ> >>>>>>> >>>>>>> key support >>>>>>> 2. Visual clarity >>>>>>> >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/XxnrGgZsyVc/m/NBkAVto0BAAJ> >>>>>>> >>>>>>> that atom/string matching is occurring >>>>>>> 3. Limitations of string-based sigil parsing >>>>>>> >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/XxnrGgZsyVc/m/TiZw6xM3BAAJ> >>>>>>> 4. Easy confusion >>>>>>> >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/XxnrGgZsyVc/m/WRhXxHDfBAAJ> >>>>>>> >>>>>>> with tuples >>>>>>> >>>>>>> I have a working fork of Elixir here >>>>>>> <https://github.com/christhekeele/elixir/tree/tagged-variable-capture> >>>>>>> where this proposed syntax can be experimented with. Be warned, it is >>>>>>> buggy. >>>>>>> >>>>>>> *Proposal: Tagged Variable Captures* >>>>>>> >>>>>>> I propose we overload the unary capture operator (*&*) to accept >>>>>>> compile-time atoms and strings as arguments, for example *&:foo* and >>>>>>> *&"bar"*. This would *expand at compile time* into *a tagged tuple >>>>>>> with the atom/string and a variable reference*. For now, I am >>>>>>> calling this a *"tagged-variable capture"* to differentiate it >>>>>>> from a function capture. >>>>>>> >>>>>>> For the purposes of this proposal, assume: >>>>>>> >>>>>>> {foo, bar} = {1, 2} >>>>>>> >>>>>>> Additionally, >>>>>>> >>>>>>> - Lines beginning with *# == * indicate what the compiler >>>>>>> expands an expression to. >>>>>>> - Lines beginning with *# => * represent the result of >>>>>>> evaluating that expression. >>>>>>> - Lines beginning with *# !> * represent an exception. >>>>>>> >>>>>>> *Bare Captures* >>>>>>> >>>>>>> I'm not sure if we should support *bare* tagged-variable capture, >>>>>>> but it is illustrative for this proposal, so I left it in my prototype. >>>>>>> It >>>>>>> would look like: >>>>>>> >>>>>>> &:foo >>>>>>> *# == **{:foo, foo}* >>>>>>> *# => *{:foo, 1} >>>>>>> &"foo" >>>>>>> *# == **{"foo", foo}* >>>>>>> *# => *{"foo", 1} >>>>>>> >>>>>>> If bare usage is supported, this expansion would work as expected in >>>>>>> match and guard contexts as well, since it expands before variable >>>>>>> references are resolved: >>>>>>> >>>>>>> {:foo, baz} = &:foo >>>>>>> *# == {:foo, baz} = {:foo, foo}* >>>>>>> *# => *{:foo, 1} >>>>>>> baz >>>>>>> *# => *1 >>>>>>> >>>>>>> *List Captures* >>>>>>> >>>>>>> Since capture expressions are allowed in lists, this can be used to >>>>>>> construct Keyword lists from the local variable scope elegantly: >>>>>>> >>>>>>> list = [&:foo, &:bar] >>>>>>> *# == **list = [{:foo, foo}, {:bar, bar}]* >>>>>>> *# => *[foo: 1, bar: 2] >>>>>>> >>>>>>> This would work with other list operators like *|*: >>>>>>> >>>>>>> baz = 3 >>>>>>> list = [&:baz | list] >>>>>>> *# == **list = [**{:baz, baz} **| **list**]* >>>>>>> *# => *[baz: 3, foo: 1, bar: 2] >>>>>>> >>>>>>> And list destructuring: >>>>>>> >>>>>>> {foo, bar, baz} = {nil, nil, nil} >>>>>>> [&:baz, &:foo, &:bar] = list >>>>>>> *# == [{:baz, baz}, {:foo, foo}, {:bar, bar}] = list* >>>>>>> *# => *[baz: 3, foo: 1, bar: 2] >>>>>>> {foo, bar, baz} >>>>>>> *# => *{1, 2, 3} >>>>>>> >>>>>>> *Map Captures* >>>>>>> >>>>>>> With a small change to the parser, >>>>>>> <https://github.com/elixir-lang/elixir/commit/0a4f5376c0f9b4db7d71514d05df6b8b6abc96a9> >>>>>>> >>>>>>> we can allow this expression inside map literals. Because this >>>>>>> expression >>>>>>> individually gets expanded into a tagged-tuple before the map >>>>>>> associations >>>>>>> list as a whole are processed, it allow this syntax to work in all >>>>>>> existing >>>>>>> map/struct constructs, like map construction: >>>>>>> >>>>>>> map = %{&:foo, &"bar"} >>>>>>> *# == %{:foo => foo, "bar" => bar}* >>>>>>> *# => *%{:foo => 1, "bar" => 2} >>>>>>> >>>>>>> Map updates: >>>>>>> >>>>>>> foo = 3 >>>>>>> map = %{map | &:foo} >>>>>>> *# == %{map | :foo => foo}* >>>>>>> *# => *%{:foo => 3, "bar" => 2} >>>>>>> >>>>>>> And map destructuring: >>>>>>> >>>>>>> {foo, bar} = {nil, nil} >>>>>>> %{&:foo, &"bar"} = map >>>>>>> *# == %{:foo => foo, "bar" => bar} = map* >>>>>>> *# => *%{:foo => 3, "bar" => 2} >>>>>>> {foo, bar} >>>>>>> *# => *{3, 2} >>>>>>> >>>>>>> *Considerations* >>>>>>> >>>>>>> Though just based on an errant thought >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/oFbaOT7rTeU/m/BWF24zoAAgAJ> >>>>>>> >>>>>>> that popped into my head yesterday, I'm unreasonably pleased with how >>>>>>> well >>>>>>> this works and reads in practice. I will present my thoughts here, >>>>>>> though >>>>>>> again I encourage you to grab my branch >>>>>>> <https://github.com/christhekeele/elixir/tree/tagged-variable-capture>, >>>>>>> compile it from source >>>>>>> <https://github.com/christhekeele/elixir/tree/tagged-variable-capture#compiling-from-source>, >>>>>>> and >>>>>>> play with it yourself! >>>>>>> >>>>>>> *Pro: solves existing pain points* >>>>>>> >>>>>>> As mentioned, this solves flaws previous proposals suffer from: >>>>>>> >>>>>>> 1. Atom vs String >>>>>>> >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/NoUo2gqQR3I/m/IpZQHbZk4xEJ> >>>>>>> key >>>>>>> support >>>>>>> This supports both. >>>>>>> 2. Visual clarity >>>>>>> >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/XxnrGgZsyVc/m/NBkAVto0BAAJ> >>>>>>> that >>>>>>> atom/string matching is occurring >>>>>>> This leverages the appropriate literal in question within the >>>>>>> syntax sugar. >>>>>>> 3. Limitations of string-based sigil parsing >>>>>>> >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/XxnrGgZsyVc/m/TiZw6xM3BAAJ> >>>>>>> This is compiler-expansion-native. >>>>>>> 4. Easy confusion >>>>>>> >>>>>>> <https://groups.google.com/g/elixir-lang-core/c/XxnrGgZsyVc/m/WRhXxHDfBAAJ> >>>>>>> with >>>>>>> tuples >>>>>>> %{&:foo, &"bar"} is very different from {foo, bar}, instead of >>>>>>> 1-character different. >>>>>>> >>>>>>> Additionally, it solves my main complaint with historical proposals: >>>>>>> syntax to combine a variable identifier with a literal must either >>>>>>> obscure >>>>>>> that we are building an identifier, or obscure the key/string typing of >>>>>>> the >>>>>>> literal. >>>>>>> >>>>>>> I'm proposing overloading the capture operator rather than >>>>>>> introducing a new operator because the capture operator already has a >>>>>>> semantic association with messing with variable scope, via the nested >>>>>>> integer-based positional function argument syntax (ex *& &1*). >>>>>>> >>>>>>> By using the capture operator we indicate that we are messing with >>>>>>> an identifier in scope, but via a literal atom/string we want to >>>>>>> associate >>>>>>> with, to get the best of both worlds. >>>>>>> >>>>>>> *Pro: works with existing code* >>>>>>> >>>>>>> The capture today operator has well-defined compile-time-error >>>>>>> semantics if you try to pass it an atom or a string. All compiling >>>>>>> Elixir >>>>>>> code today will continue to compile as before. >>>>>>> >>>>>>> *Pro: works with existing tooling* >>>>>>> >>>>>>> By overloading an existing operator, this approach works seamlessly >>>>>>> for me with the syntax highlighters I have tried it with so far, and >>>>>>> reasonable with the formatter. >>>>>>> >>>>>>> In my experimentation I've found that the formatter wants to rewrite >>>>>>> *&:baz >>>>>>> *to *(&:baz)* pretty often. That's good, because there are several >>>>>>> edge cases in my prototype where not doing so causes it to behave >>>>>>> strangely; I'm sure it's resolving ambiguities that would occur in >>>>>>> function >>>>>>> captures that impact my proposal in ways I have yet fully anticipated. >>>>>>> >>>>>>> *Pros: minimizes surface area of the language* >>>>>>> >>>>>>> By overriding the capture operator instead of introducing a new >>>>>>> operator or sigil, we are able to keep the surface area of this feature >>>>>>> slim. >>>>>>> >>>>>>> *Cons: overloads the capture operator* >>>>>>> >>>>>>> Of course, much of the virtues of this proposal comes from >>>>>>> overloading the capture operator. But it is an already semantically >>>>>>> fraught >>>>>>> syntactic sugar construct that causes confusion to newcomers, and this >>>>>>> would place more strain on it. >>>>>>> >>>>>>> We would need to augment it with more than the meager error message >>>>>>> modification >>>>>>> <https://github.com/elixir-lang/elixir/commit/3d83d21ada860d03cece8c6f90dbcf7bf9e737ec#diff-92b98063d1e86837fae15261896c265ab502b8d556141aaf1c34e67a3ef3717cL199-R207> >>>>>>> in >>>>>>> my prototype, as well as documentation and anticipate a new wave of >>>>>>> questions from the community upon release. >>>>>>> >>>>>>> This inelegance really shows when considering embedding a tagged >>>>>>> variable capture inside an anonymous function capture, ex *& &1 = >>>>>>> &:foo*. In my prototype I've chosen to allow this rather than error >>>>>>> on "nested captures not allowed" (would probably become: "nested >>>>>>> *function* captures not allowed"), but I'm not sure I found all the >>>>>>> edge-cases of mixing them in all possible constructions. >>>>>>> >>>>>>> Additionally, since my proposal now allows the capture operator as >>>>>>> an associative element inside map literal parsing, that would change >>>>>>> the >>>>>>> syntax error reported by providing a function capture as an associative >>>>>>> element to be generated during expansion rather than during parsing. I >>>>>>> am >>>>>>> not fluent enough in leex to have have updated the parser to preserve >>>>>>> the >>>>>>> exact old error, but serendipitously what it reports in my prototype >>>>>>> today >>>>>>> is pretty good regardless, but I prefer the old behaviour: >>>>>>> >>>>>>> Old: >>>>>>> %{& &1} >>>>>>> *# !> **** (SyntaxError) syntax error before '}'* >>>>>>> *# !> * | >>>>>>> *# !> * 1 | %{& &1} >>>>>>> *# !> * | ^ >>>>>>> New: >>>>>>> %{& &1} >>>>>>> *# => error: expected key-value pairs in a map, got: & &1* >>>>>>> *# => ** (CompileError) cannot compile code (errors have been >>>>>>> logged)* >>>>>>> >>>>>>> *Cons: here there be dragons I cannot see* >>>>>>> >>>>>>> I'm quite sure a full implementation would require a lot more >>>>>>> knowledge of the compiler than I am able to provide. For example, >>>>>>> *&:foo >>>>>>> = &:foo *raises an exception where *(&:foo) = &:foo* behaves as >>>>>>> expected. I also find the variable/context/binding environment >>>>>>> implementation in the erlang part of the compiler during expansion to >>>>>>> be >>>>>>> impenetrable, and I'm sure my prototype fails on edge cases there. >>>>>>> >>>>>>> *Open Question: the pin operator* >>>>>>> >>>>>>> As this feature constructs a variable ref for you, it is not clear >>>>>>> if/how we should support attempts to pin the generated variable to >>>>>>> avoid >>>>>>> new bindings. In my prototype, I have tried to support the pin operator >>>>>>> via >>>>>>> the *&^:atom *syntax, though I'm pretty sure it's super buggy on >>>>>>> bare out-of-data-structure cases and I only got it far enough to work >>>>>>> in >>>>>>> function heads for basic function head map pattern matching. >>>>>>> >>>>>>> *Open Question: charlists* >>>>>>> >>>>>>> I did not add support for charlist tagged variable captures in my >>>>>>> prototype, as it would be more involved to differentiate a capture of >>>>>>> list >>>>>>> mean to become a tagged tuple from a list representing the AST of a >>>>>>> function capture. I would not lose a lot of sleep over this. >>>>>>> >>>>>>> *Open Question: allowed contexts* >>>>>>> >>>>>>> Would we even want to allow this syntax construct outside of map >>>>>>> literals? Or list literals? >>>>>>> >>>>>>> I can certainly see people abusing the >>>>>>> bare-outside-of-associative-datastructure syntax to make some neigh >>>>>>> impenetrable code where it's really unclear where assignment and >>>>>>> pattern >>>>>>> matching is occuring, and relatedly this is where I see a lot of odd >>>>>>> edge-case behaviour in my prototype. I allowed it to speed up the >>>>>>> implementation, but it merits more discussion. >>>>>>> >>>>>>> On the other hand, this does seem like an... interesting use-case: >>>>>>> >>>>>>> error = "rate limit exceeded" >>>>>>> &:error *# return error tuple* >>>>>>> >>>>>>> *Thanks for reading! What do you think?* >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> 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/ad7e0313-4207-4cb7-a5f3-d824735830abn%40googlegroups.com >>>>>>> >>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/ad7e0313-4207-4cb7-a5f3-d824735830abn%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/4ee25f02-f27e-47a8-b4b5-b8520c1c9b05%40app.fastmail.com >>>>>>> >>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/4ee25f02-f27e-47a8-b4b5-b8520c1c9b05%40app.fastmail.com?utm_medium=email&utm_source=footer> >>>>>>> . >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Austin Ziegler • halos...@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/c1b0a9e7-cdc4-44ec-b824-261f5ad3b131n%40googlegroups.com.