mint-lang / mint

:leaves: A refreshing programming language for the front-end web.
https://mint-lang.com
BSD 3-Clause "New" or "Revised" License
4.06k stars 141 forks source link

Can't encode Maps with record keys, nor Tuples #513

Open ryanprior opened 2 years ago

ryanprior commented 2 years ago

You can encode a record, and you can encode a map, but you can't encode a map with record keys. You also can't encode Tuples, which seemed to me like it would be the best workaround.

Here's a sandbox illustrating the issue: https://sandbox.mint-lang.com/sandboxes/Cvi4ReudJVxywQ

Workarounds

I tried to work around this by first transforming the map using Map.entries. This didn't work for me because Tuple types also can't be encoded.

What did work was ultimately to write my own inline JS like so:

json =
  data
  |> Map.entries
  |> Array.map((data : Tuple(Room, String)) { `{room: {id: #{data[0].id}, name: #{data[0].name}}, when: #{data[1]}}` })
  |> Object.Encode.array
  |> Json.stringify
gdotdesign commented 2 years ago

We can do automatic tuple decoding / encoding, no problem :muscle:

Supporting Map with any keys is more problematic, we have two options here:

  1. Map(a, b) would be encoded as [[a, b]] which is basically its internal representation but with the keys and values encoded. This would be a breaking change because now they are encoded as objects {a: b}.
  2. We would do as in the first option but encode / decode Map(String, a) as before so no breaking change since we only allowed String keys before, but this would mean different behavior with String keys and the rest.

I'm wondering what you folks think :bulb: :thinking:

ryanprior commented 2 years ago

I'd like encode on a Map(a, b) to give a normal JS object if a is String, otherwise a JS Map. This would not work with Mint's Json.stringify but it could work for other serialization modules that could handle maps with non-string keys, such as if we introduce an EDN module.