calmm-js / partial.lenses

Partial lenses is a comprehensive, high-performance optics library for JavaScript
MIT License
915 stars 36 forks source link

error in setIndex when index is 0 #117

Closed victor-carvalho closed 7 years ago

victor-carvalho commented 7 years ago

I was testing karet and when doing something like this I got an error on mapElems:

const Todo = ({ todo }) => (
  <div>
    <span>{todo}</span>
    <button onClick={() => todo.remove()}></button>
  </div>
)

const Todos = ({ todos = U.atom([]) }) => (
  <div>
    {U.seq(todos, U.mapElems((e,i) => <Todo key={i}  todo={e} />))}
  </div>
)

When I try to remove the last element remaining I got an error on mapElems because setIndex returned undefined.

I can fix it by substituting U.atom([]) by U.view(L.define([]), U.atom([])).

Is setIndex intendend to return undefined in this case?

polytypic commented 7 years ago

Yes, this behaviour, namely that removal of the last element of an array triggers removal of the array itself, is by design as mentioned in the documentation of L.index. Partial lenses are designed to support "propagating removal". For example:

L.remove([0, 0, 0, 0], [[[[1]]]])
// undefined

Operations on both objects and array like objects behave similarly. For example:

L.remove([0, "x", 0], [{x: [1]}])
// undefined

In cases where certain objects or array like objects must not be removed, one needs to explicitly make it so by using e.g. L.define([]). For example:

L.remove([0, 0, L.define([]), 0, 0], [[[[1]]]])
// [[[]]]

And also:

L.remove([0, L.define({}), "x", 0], [{x: [1]}])
// [{}]

Conversely, partial lenses also support "optimistic queries and updates". For example:

L.get([0, "x", 0], undefined)
// undefined (no errors)

And also:

L.set([0, "x", 0], 1, undefined)
// [{x: [1]}]

Note that there is also a Gitter channel for discussing lenses (and other libraries in the Calmm org).

victor-carvalho commented 7 years ago

Thanks for the info! Great work in this library, I was looking for something like this for my project.

polytypic commented 7 years ago

No problem. :)

Feel free to ask questions here or in the Gitter channel whenever something is unclear.