Fork me on GitHub
#parinfer
<
2017-06-15
>
cfleming01:06:18

@shaunlebron I used to use it but removed it.

cfleming01:06:58

It created too many edge conditions in IntelliJ in non-standard editors.

cfleming01:06:35

Actually yesterday I found an annoying side effect of not having it enabled, though:

cfleming01:06:21

(my-fn x y|)
I press enter, but I’m planning to continue entering more parameters for my-fn.
(my-fn x y)
       |
I end up with this. But I can’t remember the parameters, so I ask for parameter info. But Cursive doesn’t show it since I’m no longer inside the function invocation.

cfleming01:06:56

Worse, that call is probably nested inside some other call, so I’ll probably get the param info for the outer call, which is confusing.

cfleming01:06:44

I assume the same applies to Emacs et al

shaunlebron04:06:11

@cfleming: thanks for the example

shaunlebron04:06:21

incidentally, that case is handled by the patch I landed today that replaces previewCursorScope

shaunlebron04:06:42

paren mode is run whenever a leading close-paren is found

shaunlebron04:06:00

you can see the new behavior in the demo: http://shaunlebron.github.io/parinfer/demo

shaunlebron04:06:21

v3 isn’t released yet, but will at end of the week

cfleming04:06:08

I still haven’t commented on your v1 vs v2 issue, sorry, but in general I agree with Chris - keeping things balanced seems like a fundamental promise parinfer makes.

shaunlebron04:06:28

that’s the last issue I’m going to address hopefully tomorrow

cfleming04:06:28

Inserting unbalanced close parens should just not insert anything IMO.

shaunlebron04:06:50

yeah, that’s currently landed

shaunlebron04:06:13

i feel good about the new inline inference that’ll fix the rest of it to keep it balanced

shaunlebron04:06:50

@cfleming: btw I think the new linter will help fix the race condition in intellij that prevented paren mode from preprocessing a file

cfleming04:06:19

I meant to ask you about that actually - how would that help?

shaunlebron04:06:12

well, I mean, if a team agrees to run paren mode on all their files before committing, that tool lets them do that

shaunlebron04:06:44

but more than the tool is the accompanying readme to help clear up the types of changes and to help convince people it’s not a bad idea to use it

shaunlebron04:06:47

more concretely: cursive won’t have to process files with paren mode if it’s already processed before opening

cfleming04:06:57

Ah, ok, thanks.

cfleming04:06:17

I’m still convinced that some kind of local processing will ultimately prove to be more palatable.

cfleming04:06:33

But I haven’t had time to prototype it yet.

cfleming04:06:06

i.e. only processing the range of sexps touched by the deltas of a change.

cfleming04:06:41

Working out that range is actually a pretty hard problem I’m hammocking at the moment

shaunlebron04:06:57

that would be very valuable

cfleming04:06:35

If you can do that, then you don’t need to pre-process, and you could just show a warning if the range actually affected isn’t indented correctly.

shaunlebron04:06:19

so it would be a stateful thing to track which lines are changed? and only process those lines?

cfleming04:06:04

So this is tied in with how IntelliJ does things, and I’m not sure how generally applicable it will be.

cfleming04:06:18

But yes, as a tldr

cfleming04:06:40

In IntelliJ, I’m not reacting to specific actions. I see a fair amount of the parinfer doc/online literature referring to “on keypress” or “on <some specific thing, like paste>“. I can’t really do that, since there are far too many actions for me to be able to reasonably anticipate them.

cfleming04:06:31

I basically have to react to document changes, so on a doc change I get: change position, old length, new length, old text, new text.

cfleming04:06:04

I’d keep track of those for a particular change, which is basically an undoable thing.

cfleming04:06:32

This is trickier in IntelliJ than in most editors, since something like a rename can affect a lot of locations in the file, or even across multiple files.

cfleming04:06:26

The difficulty tracking modified ranges is that each new change creates a new document “co-ordinate space”, so if I want to get an sexp range from the original document which was affected by a series of deltas, I have to map them all back through the previous changes to get the correct range in the original doc affected by each change.

cfleming04:06:00

Then, once I have those ranges I can work out the sexp ranges which cover them all, and then I have to map that forward to get the correct range in the resulting doc.

shaunlebron04:06:35

makes sense, yeah

shaunlebron04:06:27

on keypress => any change, would be a fair mapping I think

shaunlebron04:06:38

not sure about others

cfleming04:06:42

Yeah, pretty much - it’s actually a hard problem, especially to do it efficiently - it’s quadratic in the number of changes, and for something like a file reformat that can be a lot.

cfleming04:06:22

Not sure if I can special case reformat, and just process the whole file at that point.

cfleming04:06:01

Well, keypress is just an action, and some keypresses are more complicated than others and can lead to reformatting changes (tab, backspace, delete, enter)

shaunlebron04:06:03

well, it should really reformat on any keypress

cfleming04:06:53

I mean that the IntelliJ action will format things, before I get to see it.

cfleming04:06:13

Or at least, the resulting reformatting will be part of the changes communicated to me via document events.

shaunlebron04:06:26

oh, yeah, that’s not good

cfleming04:06:57

I’m actually curious how this works in e.g. Emacs. A lot of the complexity in the IntelliJ integration is around making it work in a very general way, since I can’t anticipate all the changes that either IntelliJ or any installed plugins might make.

cfleming04:06:38

But the same must apply to Emacs if someone is using clj-refactor - a particular action can cause a lot of changes to be made in multiple places/files.

cfleming04:06:39

And people extend Emacs such that a particular action does crazy things all the time. Are those people just not using parinfer?

shaunlebron05:06:16

@cfleming: it was recently added to spacemacs as a core plugin I think

cfleming05:06:22

So it looks like the Emacs integration only runs on one of a hard-coded set of commands.

cfleming05:06:30

Unless I’m missing something, my elisp is not great.

shaunlebron15:06:41

i can’t tell by skimming right now

mattly18:06:35

I use parinfer in spacemacs/main (that PR is still in develop), setting it up was fairly straightforward

mattly18:06:22

I use it alongside smartparens and paredit

shaunlebron19:06:38

@mattly: cool, does it work well?

mattly19:06:47

@shaunlebron for me it does. I've been slowly moving off of spacemacs (though I still use spacemacs for work) and I just setup parinfer by itself and it feels off

mattly19:06:23

I'd link my config but for whatever reason the slack electron app decided to stop interacting with my system clipboard

shaunlebron19:06:42

@mattly it might feel off due to lack of structural editing stuff

shaunlebron19:06:55

but it was always my hope that it would be compatible if you want add those layers, so glad it’s fitting okay

mattly19:06:56

yeah, paredit is next on my list of things to setup

mattly19:06:46

parinfer has been a helpful sell to my lisp-phobic co-workers that come and pair with me though

shaunlebron20:06:41

what type of lisp are you using? and how are you introducing it to your project? (kind of interested in how folks do this)

mattly20:06:33

it's.. a bit odd, really; Clojure/Script, in a group that's otherwise Rails/Ember/Elixir

mattly20:06:35

my project is somewhat alien compared to what everything else is, it's a free-from analytics tool for asking questions from a variety of HIPAA-protected data sources

mattly20:06:10

whereas all the other projects in the group are closed-ended tools for accomplishing specific tasks

mattly20:06:57

before I came on, one of the other senior devs had tried prototyping this project in rails/ember and it was a mess

mattly20:06:48

my specialty is this sort of thing – interfaces for doing data analysis – and I had enough trust from the dev team (most of whom I've known for a while) to make a strong case for doing this in clojure/script, and it's been a huge success in that regard

mattly20:06:33

the original prototype centered around a single type of query from a single datasource, and it had like 2000 lines of string concatenation in ruby to construct a sequel query

mattly20:06:50

I boiled that down to 20 lines of logic and 100 lines of data in clojure

mattly20:06:03

and that got people interested

shaunlebron20:06:22

trust + direct comparison to show benefit

mattly20:06:48

I've gotten one or two of the fronend people on another project interested in re-frame

mattly20:06:05

they're both using Atom, so of course I set them up with parinfer

shaunlebron20:06:06

yeah? what do you think their general impression is?

mattly20:06:34

they think it's neat but have a hard time understanding how to build something complex in it

mattly20:06:44

oh, of parinfer, not re-frame

mattly20:06:18

one of them said, "ok, so you were right, the parens aren't really that big of a deal"

shaunlebron20:06:35

I tried getting david to make the cljs repo compatible with parinfer, but it was kind of a big ask to add so many whitespace changes without some kind of evidence that newcomers are using parinfer

shaunlebron20:06:24

I’m going to setup some kind of survey asking for people to share stories like this to help build a better case

dominicm20:06:03

@shaunlebron biggest use for me in parlinter was just identifying dumb indentation mistakes.

shaunlebron20:06:39

@dominicm yeah, your point about revealing “confusing indentation” made it into the parlinter readme, i thought that was a good way to say that

shaunlebron20:06:36

we actually caught an accidental expression nesting in the cljs repo using it

dominicm20:06:15

My #1 comment about parinfer is always: > Parinfer puts parentheses where they look like they should be. I've found so many bugs by locating the indent button in people's editors. Parinfer solves this

shaunlebron20:06:33

maybe a good example of this—the mistake caught in cljs repo:

;; before
(is (= nil (s/index-of sb "z" 100))
(is (= nil (s/index-of sb "z" -10))))))

;; after
(is (= nil (s/index-of sb "z" 100))
 (is (= nil (s/index-of sb "z" -10))))))

shaunlebron20:06:17

yeah, indentation was wrong

mattly20:06:18

I've had a few instances of that as well

dominicm20:06:29

That's a perfect example.

shaunlebron20:06:05

when parens are inferred, i think the question most people ask is—so why are they even there?

shaunlebron20:06:11

i showed the project to jeremy ashkenas before i had a fancy website for it, and his reaction was “…so i guess the next step is to remove the parens”

shaunlebron20:06:13

i kind of got a blank stare when i tried to explain the benefits of explicitness and consistency, but I think it remains the second half of the problem of introducting lisp—that parinfer only elucidates the how of parens rather than the why

mattly20:06:58

... oh god

mattly20:06:22

fleeing from coffeescript's indecisiveness is what drove me to lisp

shaunlebron20:06:38

it’s definitely what drove me back to js

shaunlebron20:06:52

i think it was a great experiment that took philosophy of implied behavior to its extreme, and taught me that it’s not a very good thing for a language to have

shaunlebron20:06:11

it also taught me how to market a new idea in a very straightforward way

shaunlebron20:06:21

that website was so good

dominicm21:06:22

RE "why are they even there"

shaunlebron21:06:52

I’d be interested in reading why those never caught on