6 ms·
The syntax to update records doesn't seem particularly nice: e{lbl = val} Though this has been a part of haskell for a while it seems: > Note: e{lbl = va
by pbiggar 6y ago
The syntax to update records doesn't seem particularly nice:
e{lbl = val}
Though this has been a part of haskell for a while it seems:
> Note: e{lbl = val} is the syntax of a standard H98 record update
FSharp, OCaml and Elm have not got great solution here either:
{ e with lbl = value } // ocaml/fsharp
{ e | lbl = value }
Do any functional languages have anything as nice as:
e.lbl = value
- frou_dh 6y agoTo me those ML syntax look very in keeping with the fact that it's an immutable update. Don't mind them at all.
- tome 6y agoAs frou_dh hints, the updates are not done in place, so it would have to be something like new_e = e.lbl = value at which point "nice" is not how I would describe it.
- garethrowlands 6y agoLens has this: e & lbl .~ value It's not an in-place update like `e.lbl = value`.
- srtjstjsj 6y agoThat doesn't solve GP's problem of "not looking exactly like C++/Java/Python"
- pbiggar 6y agoMy goal isn't to look _exactly_ like C++/etc, but rather to have a fairly natural duality between read and write. You can read with: a.b.c.d but a write is: let a = {a with b = { a.b with c = { a.b.c with d = 5 } } } } which is much much more verbose than the OO/imperative: a.b.c.d = 5
- kqr 6y agoYeah, lenses let you do a & b.c.d .~ 5 To construct a new version of `a` where those nested fields have the new value 5. Or for an in-place update in a context where that is allowed, a.b.c.d .= 5 The lens concept is incredibly nice.
- bionhoward 6y agojax has nice e2 = e.at[lbl].set(value) syntax, and Ramda has e2 = assoc(lbl, value, e) which is curried and data-last, so you can keep that setter around for future instances of e. Usually not too bad to translate Ramda into your language of choice, and a valuable exercise. I did it with Python and it helped a TON Once JS gets immutables, web devs will have more tools for FP, and we can look forward to that expanding the community of functional programmers a lot: (https://www.infoworld.com/article/3569118/ecma-proposal-would-bring-records-and-tuples-to-javascript.html https://www.infoworld.com/article/3569118/ecma-proposal-woul...) Python’s lack of an immutable map is annoying but there are nice pip packages for it
- sullyj3 6y agoThe `e.lbl = value` syntax suggests mutation to me, which would be misleading.
- pbiggar 6y agoTrue, and so there might be a need for something like: e = e.lbl <- value (I didn't reuse the '=' because two '=' like that looks weird. The main thing I want to address is that a.b.c.d is so much work to write to.
- grantjpowell 6y agoElixir has a few forms of updating a struct (or map) %{existing_map_or_struct | some_key_1: :some_val, some_key_2: :some_val} Then there is also `put_in/2`, `put_in/3`, `update_in/2`, `update_in/3`, these are nice because they work in pipelines some_val |> put_in([:foo, :bar, :baz], 3) some_val |> update_in([:foo, :bar, :baz], fn x -> x + 1 end) The macro forms are cool too put_in(foo.bar.baz, 2) update_in(foo[:some]["nested"][:path], & &1 + 1) The cool thing about the `/2` forms of `put_in` and `update_in` is that they are macros they rewrite the ast to return the entire object, and not just the changed value. iex(1)> foo = %{bar: %{baz: 2}} %{bar: %{baz: 2}} iex(2)> update_in(foo.bar.baz, & &1 + 1) %{bar: %{baz: 3}} There's even more powerful macros like `get_and_update_in` which can use "selectors" to extend their functionality (https://hexdocs.pm/elixir/master/Kernel.html#get_and_update_in/2 https://hexdocs.pm/elixir/master/Kernel.html#get_and_update_...) https://hexdocs.pm/elixir/master/Kernel.html#put_in/2 https://hexdocs.pm/elixir/master/Kernel.html#put_in/2 https://hexdocs.pm/elixir/master/Kernel.html#put_in/3 https://hexdocs.pm/elixir/master/Kernel.html#put_in/3 https://hexdocs.pm/elixir/master/Kernel.html#update_in/2 https://hexdocs.pm/elixir/master/Kernel.html#update_in/2 https://hexdocs.pm/elixir/master/Kernel.html#update_in/3 https://hexdocs.pm/elixir/master/Kernel.html#update_in/3
- brmgb 6y agoOcaml distinguishes between "e.lbl <- value" which is a mutation of e and "{e with lbl = value}" which creates a modified copy.
- pbiggar 6y agoTo clarify, the thing I want is to make it nice and simple to create a new record with a nested field updated. It's easy to read a.b.c.d, but updating that field painful: let a = {a with b = { a.b with c = { a.b.c with d = 5 } } } }
- PhineasRex 6y agoThe update syntax is actually more of a `.copy` method, than a property update since it returns a new object. It's actually quite nice in that respect since it's easy to update multiple fields: e{lbl = val, lbl2 = val2}