bartblast

bartblast

Creator of Hologram

Keyword inside tuple shorthand syntax {a: 1, b: 2}

This could resolve to {[a: 1, b: 2]}. Was it ever considered to allow such syntax? Notice this: {:abc, a: 1, b: 2} and this: my_fun(:abc, a: 1, b: 2) work as I described. As I understand, the compiler is able to figure out that the second part is a keyword list.

I can see that it is similar to %{a: 1, b: 2}, and it may be misleading for people coming from Ruby (hash syntax).

Context: I’m working on Hologram’s template engine. If the shorthand syntax worked for tuples as well, it would simplify a few things since Hologram uses tuples for interpolation and prop syntax, e.g.

<MyComponent my_prop={:my_value} />

or

<button $click={:do_something, a: 1, b: 2}>Click me</button>

or shorthand class attribute syntax:

<div class={button: true, "button-active": false}></div>

This issue can be handled by the template parser, but I feel that it may be beneficial to support it in the Elixir compiler.

First 10 of 16 Posts Switch mode

al2o3cr

al2o3cr

My supported-only-by-vibes take is that when a user writes {a: 1, b: 2} they are far more likely to be typoing either a map literal (missing %) or a kwlist literal (wrong kind of bracket). :man_shrugging:

gregvaughn

gregvaughn

I’m rather confused. Tuples do not support key/value pairs, so I don’t have a picture of what you want. Perhaps you want property lists, which are used more in Erlang than Elixir?

Eiji

Eiji

@gregvaughn Yes, it’s indeed confusing - the syntax, see:

iex> {:do_something, a: 1, b: 2}
{:do_something, [a: 1, b: 2]}
iex> {a: 1, b: 2}
** (SyntaxError) invalid syntax found on iex:2:1:
    error: unexpected keyword list inside tuple. Did you mean to write a map (using %{...}) or a list (using [...]) instead? Syntax error after: '{'
    │
  2 │ {a: 1, b: 2}
    │ ^
    │
    └─ iex:2:1
    (iex 1.17.0-rc.1) lib/iex/evaluator.ex:295: IEx.Evaluator.parse_eval_inspect/4
    (iex 1.17.0-rc.1) lib/iex/evaluator.ex:187: IEx.Evaluator.loop/1
    (iex 1.17.0-rc.1) lib/iex/evaluator.ex:32: IEx.Evaluator.init/5
    (stdlib 6.0) proc_lib.erl:329: :proc_lib.init_p_do_apply/3

How about something like this?
<div {:class, button: true, "button-active": false}></div>

Eiji

Eiji

It’s more rather about consistency. As mentioned this is supported in other cases, so I think same i.e. it should be supported in tuples.

sodapopcan

sodapopcan

I can get on board with the consistency argument but I think the desire for this would be realllllly niche. I’ve had the exact thought as @bartblast were I was thinking it would be nice shorthand for this to work in HEEx, but that is literally the only time. I think it’s more beneficial not introduce the ambiguity of %{a: :b} vs {a: :b} for a niche purpose.

LostKobrakai

LostKobrakai

Looking at Syntax reference — Elixir v1.20.2 I’m wondering if the syntax sugar in tuples should rather be removed. The atom shorthand within […] and %{…} works the same, but is considered a feature available for both those types and is not available for tuples.

The syntax sugar for skipping square brackets is documented to apply for the last parameter of calls. Creating a tuple is not a call. The closest comparison to the creation of a tuple would be the creation of a binary <<…>>.

Eiji

Eiji

Oh, in that case I can partially agree. However we need to keep in mind that 2-element tuples are considered literals, see:

iex> quote do
...> {:a}
...> end
{:{}, [], [:a]}
iex> quote do
...> {:a, :b}
...> end
{:a, :b}
iex> quote do
...> {:a, :b, :c}
...> end
{:{}, [], [:a, :b, :c]}
iex> quote do
...> {:a, :b, :c, :d}
...> end
{:{}, [], [:a, :b, :c, :d]}

If we go this way we should discuss if it could be allowed only for 2-element tuples. However such behaviour may be found as confusing. I guess that Elixir core team decided to make it work tuples like that because there is no real need for a list as the only element of tuple - instead we could simply use a list. So as always we end up with same thing: such stuff are related only to template engines. If all above is correct I guess this behaviour would not be changed. :thinking:

LostKobrakai

LostKobrakai

I’m not sure this matters. Optional square brackets are a syntax feature, which doesn’t affect AST. At least outside of the optional metadata for the formatter, which might care.

iex(1)> quote do: call(:a, test: 1, test: 2)
{:call, [], [:a, [test: 1, test: 2]]}
iex(2)> quote do: call(:a, [test: 1, test: 2])
{:call, [], [:a, [test: 1, test: 2]]}
slouchpie

slouchpie

My objection is that if

{a: 1, b: 2}

is the same as

{[a: 1, b: 2]}

then why not also

{[a: 1], [b: 2]}

The role of the comma becomes far too ambiguous.

P.S. I don’t even like the “invisible brackets” implicit in my_fun(arg_1, opt_a: 1, opt_b: 3). I prefer an excess of clarity to an excess of magic.

sodapopcan

sodapopcan

Which, the a: :b syntax?

Looking at this sort of drives home too: outside of OP’s situation, why would you ever want to wrap a single keyword list in a tuple? One-element tuples aren’t encouraged in Elixir (and rightly so, AFAIC) and this syntax would push against that.

Where Next?

Trending in Proposals: Ideas Top

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
akoutmos
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New

We're in Beta

About us Mission Statement