{"id":18000133,"url":"https://github.com/kzemek/es6_maps","last_synced_at":"2025-04-05T18:09:45.927Z","repository":{"id":229317490,"uuid":"776427671","full_name":"kzemek/es6_maps","owner":"kzemek","description":"ES6-like shorthand syntax for Elixir maps: `%{foo, bar} = map; IO.puts(foo)`","archived":false,"fork":false,"pushed_at":"2024-10-25T19:30:02.000Z","size":43,"stargazers_count":60,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-10-30T00:34:11.669Z","etag":null,"topics":["elixir","es6","hex","map","shorthand","syntax"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kzemek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-23T13:33:43.000Z","updated_at":"2024-10-25T19:30:06.000Z","dependencies_parsed_at":"2024-04-30T19:38:33.426Z","dependency_job_id":"24cd3d69-42a0-44db-87f7-a74fef20a938","html_url":"https://github.com/kzemek/es6_maps","commit_stats":null,"previous_names":["kzemek/es6_maps"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kzemek%2Fes6_maps","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kzemek%2Fes6_maps/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kzemek%2Fes6_maps/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kzemek%2Fes6_maps/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kzemek","download_url":"https://codeload.github.com/kzemek/es6_maps/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247378149,"owners_count":20929297,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","es6","hex","map","shorthand","syntax"],"created_at":"2024-10-29T23:09:46.120Z","updated_at":"2025-04-05T18:09:45.894Z","avatar_url":"https://github.com/kzemek.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# es6_maps\n\n[![CI](https://github.com/kzemek/es6_maps/actions/workflows/elixir.yml/badge.svg)](https://github.com/kzemek/es6_maps/actions/workflows/elixir.yml)\n[![Module Version](https://img.shields.io/hexpm/v/es6_maps.svg)](https://hex.pm/packages/es6_maps)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/es6_maps/)\n[![License](https://img.shields.io/hexpm/l/es6_maps.svg)](https://github.com/kzemek/es6_maps/blob/master/LICENSE)\n\nEnables ES6-like shorthand usage of Elixir maps.\n\n### Why?\n\nWhen writing code that heavily utilizes structures and passes complex objects through multiple layers, it's common to frequently use map literals.\nThis often results in repetitive code patterns such as `ctx = %{variable: variable, user: user, ...}` or `%{variable: variable, user: user, ...} = ctx`.\n\nI believe that introducing a shorthand form of object creation to Elixir enhances the language's ergonomics and is a natural extension of its existing map literals syntax.\nThis feature will be immediately familiar to JavaScript and Rust developers, and similar shorthands are present in other languages such as Go.\n\n### Is there any runtime overhead?\n\nNo; the shorthand map keys compile down to exactly the same bytecode as the \"vanilla-style\" maps.\n\n## Installation\n\nThe package can be installed by adding `es6_maps` to your list of dependencies and compilers in `mix.exs`:\n\n```elixir\n# mix.exs\n\ndef project do\n  [\n    compilers: [:es6_maps | Mix.compilers()],\n    deps: deps()\n  ]\nend\n\ndef deps do\n  [\n    {:es6_maps, \"~\u003e 0.2.2\", runtime: false}\n  ]\nend\n```\n\n## Usage\n\n### Creating maps\n\n```elixir\niex\u003e {hello, foo, bar} = {\"world\", 1, 2}\niex\u003e %{hello, foo, bar: bar}\n%{hello: \"world\", foo: 1, bar: 2}\n```\n\n### Destructuring maps\n\n```elixir\niex\u003e %{hello, foo} = %{hello: \"world\", foo: 1, bar: 2}\niex\u003e hello\n\"world\"\niex\u003e foo\n1\n```\n\n### Updating maps\n\n```elixir\niex\u003e map = %{hello: \"world\", foo: 1, bar: 2}\niex\u003e foo = :baz\niex\u003e %{map | foo, bar: :bong}\n%{hello: \"world\", foo: :baz, bar: :bong}\n```\n\n### Structs\n\nAll of the above work for structs as well:\n\n```elixir\ndefmodule MyStruct do\n  defstruct [:hello, :foo, :bar]\nend\n\niex\u003e {foo, bar} = {1, 2}\niex\u003e %MyStruct{foo, bar, hello: \"world\"}\n%MyStruct{foo: 1, bar: 2, hello: \"world\"}\n\niex\u003e struct = %MyStruct{foo: 1, bar: 2}\niex\u003e hello = \"world\"\niex\u003e %MyStruct{struct | hello}\n%MyStruct{foo: 1, bar: 2, hello: \"world\"}\n\niex\u003e %MyStruct{hello} = %MyStruct{hello: \"world\", foo: 1}\niex\u003e hello\n\"world\"\n```\n\n## Converting existing code to use ES6-style maps\n\n`es6_maps` includes a formatting plugin that will convert your existing map and struct literals into the shorthand style.\nAdd the plugin to `.formatter.exs`, then call `mix format` to reformat your code:\n\n```elixir\n# .formatter.exs\n[\n  plugins: [Es6Maps.Formatter],\n  inputs: [\"{mix,.formatter}.exs\", \"{config,lib,test}/**/*.{ex,exs}\"]\n]\n```\n\nThe plugin manipulates the AST, not raw strings, so it's precise and will only change your code by:\n\n1. changing map keys into the shorthand form;\n2. reordering map keys so the shorthand form comes first;\n3. formatting the results like `mix format` would.\n\n### Reverting to the vanilla-style maps\n\nThe formatting plugin can also be used to revert all of the ES6-style map shorthand uses back to the \"vanilla\" style.\nSet the `es6_maps: [map_style: :vanilla]` option in `.formatter.exs`, then call `mix format` to reformat your code:\n\n```elixir\n# .formatter.exs\n[\n  plugins: [Es6Maps.Formatter],\n  inputs: [\"{mix,.formatter}.exs\", \"{config,lib,test}/**/*.{ex,exs}\"],\n  es6_maps: [map_style: :vanilla]\n]\n```\n\n### Formatting pragmas\n\nThe plugin supports pragmas in the comments to control the formatting.\nThe pragma must be in the form `# es6_maps: [map_style: :es6]` and can be placed anywhere in the file.\nThe `map_style` option can be set to `:es6` to convert to shorthand form or `:vanilla` to revert to the vanilla-style maps.\nThe pragma takes effect only on the line following the comment.\n\nFor example in the code below, the first map will be formatted to the shorthand form, while the second map will be left as is:\n\n```elixir\n  %{foo, bar: 1} = var\n  # es6_maps: [map_style: :vanilla]\n  %{hello: hello, foo: foo, bar: 1} = var\n```\n\n`es6_maps: [map_style: :vanilla]` option in `.formatter.exs` can be combined with `# es6_maps: [map_style: :es6]` comment pragmas.\n\n## How does it work?\n\n`es6_maps` replaces in runtime the Elixir compiler's `elixir_map` module.\nThe module's `expand_map/4` function is wrapped with a function that replaces map keys `%{k}` as if they were `%{k: k}`.\nAfter `es6_maps` runs as one of the Mix compilers, the Elixir compiler will use the replaced functions to compile the rest of the code.\n\n\u003e [!IMPORTANT]\n\u003e By the nature of this solution it's tightly coupled to the internal Elixir implementation.\n\u003e The current version of `es6_maps` should work for Elixir 1.15, 1.16, 1.17 and the upcoming 1.18 version, but may break in the future.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkzemek%2Fes6_maps","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkzemek%2Fes6_maps","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkzemek%2Fes6_maps/lists"}