New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of Zipper
should be private
#10
Comments
@joneshf has some great thoughts on this. See twitter thread https://twitter.com/st58/status/785507064910983169. |
Basically, what I'm afraid of exposing is the fact that 'before' is reversed. This is something a user might miss when constructing a 'Zipper' themselves. |
Other than that I think a parameterized type 'Zipper b c a' is great idea :) |
I will happily take the opposite position: Opaque Let's discuss! 😄 |
This is a great argument for a hidden implementation. This is a concern today, but the future concern is even greater. Suppose you initially implemented it without reversing, because you weren't aware that optimization existed. (I know I wasn't, the first time I heard of zippers.) So you release the library, then later find out about the optimization, and release an update to the library which starts doing reversing. In a world where In the At this point the way to cause the least user pain is probably to abandon the current library, publish a fork called tl;dr Given the choice between "should I add unreliable support for hypothetical use cases" or "should I make this exact API as reliable as possible long-term," I think the latter is best. 🙂 |
@rtfeldman @wernerdegroot arg, sorry I didn't mean |
still, has the same concern with the reversed |
You can run into the same problem with zipperMap : (a -> b) -> List.Zipper.Zipper a -> List.Zipper.Zipper b
zipperMap transform zipList =
List.Zipper.Zipper
(List.foldl (\elem list -> transform elem :: list) [] (List.Zipper.before zipList))
-- ^==^ we expect before to be reversed here
(transform (List.Zipper.current zipList))
(List.map transform (List.Zipper.after zipList)) and by making it private, we make it harder for the user to implement such a function. |
|
But you can access the relevant values (before, current, after) through the accessors, right? Only these can offer the guarantee that elements are in the same order as in the original list, making the reversal of 'before' an implementation detail. |
@stoeffel Shouldn't |
It's already in work by @wernerdegroot. But it's just an example for a use-case a user had. There could be other use-cases. |
true. But when we construct again with |
@scottcorgan see #9 |
This will always be true though. There are infinitely many possible use cases, so it is necessarily impossible to anticipate them all. The question is where to draw the line. As library authors, eventually we must say one of two things:
Essentially the former optimizes for the short-term and the latter optimizes for the long-term. In the short-term, the more you expose, the more quickly someone can unblock themselves. This is true. The alternative would be that they would file an issue or create a fork, both of which would take more time. In the long-term, the less you expose, the better experience you can provide for everyone, including people whose use cases were not initially anticipated. If someone raises a use case that you did not anticipate at first, you can update the library to do a good job supporting that use case. You can also continue supporting it well for future releases, whereas you cannot help them if they resort to exposed-but-not-officially-supported APIs. The long-term maintenance burden has been shifted to the user. Overall, I think Elm library authors should optimize for the long-term user experience, which means defaulting to exposing less. Even as someone who tends toward unusual use cases, as a library user I've been much happier with that experience (in, say, Elm's core libraries) than I have with other systems that were quicker to expose things. 😄 |
I use a simpler implementation for my use case (maintaining a selection over a list where an element always has focus). https://gist.github.com/artisonian/102b278ef1f6ed9fe851c448689dc2e9 |
True!
Having more contributions is great and @wernerdegroot was always really responsive in the past ❤️ I'm open to give this a try. |
|
I'd rather see the implementation of
Zipper
private.Tests should be in terms of the
List
that theZipper
produces, instead of in terms of (what I feel is) an implementation detail.This way we could change the way the
Zipper
works internally, without breaking the interface.The text was updated successfully, but these errors were encountered: