sábado, 1 de mayo de 2021

Wait a sec..., did I just ask for paredit-convolute-sexp?

So, After years of lisping, and using paredit (feeling that paredit is not for me, and realizing that "if paredit is not for you, you have to become the person who paredit is for", and becoming that person), I found a need for a command I wish it existed, and turns out it did.

After getting used to paredit, you just love it and miss it in non-lisps. But there is this paredit command that is basically a big question mark. You read about it when you were learning paredit, it didn't make sense then, and you moved on with your life, barfing, raising, and splicing sexps.

So it just clicked today, (now that I'm back to lisp (clojure)). I was thinking "there should be a way to do this", and then remembered there are a few paredit commands that I didn't find use for when I learned about them. And Bingo! It's just one of them!: paredit-convolute-sexp.

So the situation where it's useful is when you want to "swap" 2 "wrapping macros".  By "wrapping macros" I mean any macro or special form that expects a body. Such forms are "let", "binding", "with-redefs", "db/transaction"... you know, all those.

And by "swapping", I mean changing who wraps who. Here's a before/after 


See? Instead of a "let" wrapping a "binding", we get "binding" wrapping a "let".

If the binding forms (the pairs in square brackets) live in the same line as the special form function (like the previous example), and if you would be using evil, you would just swap the lines with ddp and reindent. 

But if the binding forms live in different lines, it's not as straightforward anymore.   I hope you know where I'm going now...

Well, paredit-convolute-sexp helps in those situations. Your only task is to put the cursor in inner expression, exactly in the place where you want the split to happen: before the first form that belongs to the &body. Then you press M-? (now, I think I even "see" why the shortcut). And magic happens.

The movement and the results are weird to explain, but with proper examples, it is easier to get a feel for it. Just try it in different positions with code with lots of nesting.