Skip to content
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

is Parinfer an 85% solution? (if so, minimize the 15% problems w/ reversibility) #111

Open
shaunlebron opened this issue Apr 6, 2016 · 2 comments

Comments

@shaunlebron
Copy link
Collaborator

from Jonathan Blow's talk on designing a simple language:

I think I would like to look for 85% solutions-- versus what languages usually do which is "100%" (sarcasm quotes) solutions.

A "100%" solution is when you try to provide a mechanism that a programmer can use everywhere, or should use everywhere that handles all their problems. And usually it doesn't handle all the problems that well, and so you start hacking in little special cases... The problem is that's how you get complexity...

Whereas, if you do an 85% solution, it means more like, "well, we provided this facility for programmers and it doesn't really apply to everything you could ever do, but it really helps you in 85% of cases. So let's stop there and let's not add other complexity to make it apply to 100% of cases. Let's just say you can't do those cases. We'll just give you an error message if you trying doing them.

In some sense, a language designer might feel like a failure for not handling that other 15%, but actually they're a winner because they gave you the most simple thing that covers the widest base of cases. I want to look for this kind of the thing in cases where it's been ignored until now...

If we design a language, our job is to not overreach.

Comparing this to Parinfer, it is good for ~85% of cases, but can be detrimental in ~15% of cases (that is, not just a soft fail, but a hard one). In the context of a compiler, runtime error messages are an acceptable compromise to suspend and communicate failure. We currently do not do that in Parinfer. Rather we silently fail, perform a quick fix that may not be what the user wanted, and then continue as if nothing happened.

To first fix this, I believe we should define failure as transforming the code in a non-reversible way. That is, deleting the character that you inserted, or re-inserting the character you deleted-- both should return the code as you saw it before the edit. Limiting the types of fixes to be strictly reversible may allow us to form a compromise between predictability and smoothness of experience. That is, we don't want to be disrupting the user with potentially frequent errors, but we also don't want to be breaking their code in a surprising way for the sake of not emitting an error. The middle ground might be achieved by choosing only auto-corrections which respect reversibility.

Some examples of Indent Mode's problems in the 15% cases, in order of decreasing severity due to reversibility:

Problem Reversible?
1 inserting/deleting open-parens which have uninferred close-parens: https://github.com/shaunlebron/parinfer/issues/102. NO
2 pressing enter right before a non-inferred close-paren: https://github.com/shaunlebron/parinfer/issues/98. NO
3 shifting open-parens of multi-line expressions gif. SOMETIMES
4 comment lines cannot be included at end of a multi-line expressions https://github.com/shaunlebron/parinfer/issues/92. YES

Non-reversibility issues of (1) and (3) are related to removing unmatched, uninferred close-parens, which may be solved by highlighting the offending character and suspending rather than deleting it and resuming. This would prevent Parinfer from pretending to be a 100% solution, trying to always balance parens based on indentation by simply removing unmatched close-parens. Rather, with this change of highlighting them and suspending until addressed, Parinfer might be a 85% solution, which safely suspends and communicates the problem for the 15% of cases it cannot handle.

The feasibility of a 100% solution is being explored in cursive-ide based off some notes from parinfer's biggest critic. This will be done by mapping explicit actions based on keypresses, which was also explored by snoe in nvim-parinfer. This would throw away separate Modes as a mechanism for understanding user intention, and replace them with a direct mapping of Edit Type => Edit Action, for users to customize and compose their desired behaviors.

@shaunlebron
Copy link
Collaborator Author

shaunlebron commented Mar 17, 2017

from Zach Tellman's talk on defining boundaries of a utility:

...you'll see on hackernews where people will say—I use this for one project and I use it for another project which is slightly different, and so just by projecting that outward it works for everything, right? Just inductively, that must be true.

And I think that there are always boundaries to the utility of anything, because they're lossy, because they make certain assumptions about the world. And I think that in a lot of documentation, you see people talking about "this thing is great—it's great for this". But very rarely do you see someone saying "and here's where it breaks down. this is the boundaries. this is where you should not use this."

And I'd really like to see more of that. More of people saying that something is good for one thing and bad for another thing and not having that being sort of the reverse induction where if it's bad for this, it must be bad for everything because only a good abstraction must be perfect for all possible applications.

@shaunlebron
Copy link
Collaborator Author

On the contrary, a friend told me that if a tool jumps up and bites you every now and then, it decreases the desire to use it. The boundaries of the system should be designed with this in mind if the goal is to optimize the user experience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant