6 ms·
This post misses the IMO best indentation scheme for lisp, which I used for my college class where we had to use MIT scheme: (define (match:element variabl
by lihaoyi 2y ago
This post misses the IMO best indentation scheme for lisp, which I used for my college class where we had to use MIT scheme:
(define (match:element variable restrictions)
(define (ok? datum)
(every
(lambda (restriction)
(restriction datum)
)
restrictions
)
)
(define (element-match data dictionary succeed)
(and
(ok? data)
(let ((vcell (match:lookup variable dictionary)))
(if vcell
(and
(equal? (match:value vcell) data)
(succeed dictionary)
)
(succeed (match:bind variable data dictionary))
)
)
)
)
element-match
)
It may not be densest or most compact indentation scheme, but damn is it readable for someone without a lisp/scheme background!
- rayiner 2y agoThat is blasphemy.
- DonHopkins 2y agoNicely indented easy to read blasphemy is the most dangerous kind!
- shawn_w 2y agoThe uncuddled closing parens are a sure sign of a sick mind; probably corrupted by C or the like.
- andriamanitra 2y agoThey make line-by-line diffs nicer. And it's quite nice to be able to swap/move lines without messing up the closing paren, especially when not using a structural editor.
- varjag 2y agoTo be fair in C they don't put semicolon on its own line either.
- Pxtl 2y agoMaybe they should? I mean otherwise why not do void MyFunc() { DoStuff(); DoOtherStuff();} If the close-parens being on its own line is so wrong, why is it right for braces?
- deleted 2y ago[deleted]
- simplify 2y agoYou may not like it, but this is what peak lisp indentation looks like :) Honestly though, this style for ending parenthesis of block-type nodes makes a lot of sense to me. And you still retain the benefit of macro-ing your own syntax when you need it.
- JBiserkov 2y agoOne thing I dislike about the compact style is how adding/removing a let block causes a diff line that is just adding/removing a parent.
- kazinator 2y agoDo you really think it's just a matter of style whether or not you must add or remove a parenthesis? Or whether that change shows up in a diff?
- acheron 2y agoExactly what I was thinking.
- nine_k 2y agoA blasphemy is a very useful thing in cases when a discipline turns into a religion. (Yes, I know about jokes.)
- aartaka 2y agoThat is
- deleted 2y ago[deleted]
- maiar 2y agoI’ve been in too many arguments about Lisp indentation but that actually comes close to decent with a couple of changes: move the singleton closing parens up, and reduce to, say, 2 spaces.
- n8henrie 2y agoAs a hobbyist that keeps trying to break into lisp, I think the absence of an obviously good formatter for lisps has made things much harder. This looks like how I've naively tried to format things, and having started with python kind of makes sense. But trying to read / edit code with 5 parentheses bunched together, I have the hardest time telling if they are matched or where. Thank goodness for vim / helix auto-matching.
- skydhash 2y agoThe way to have a good time with lisp is using Emacs and Slime/Sly. And if you like shortcuts, you can try Paredit for structural editing. I just use the Tab key for indenting and it always work for me (there's a logic on where to break line to get correct indenting, and it makes it easy to see if you misplaced a parenthesis. Also, both Emacs and Vim, highlight the matched parenthesis, so I never wonder about if I have the correct number of closing parenthesis.
- JBiserkov 2y agoYou can also try "rainbow parens" color scheme that makes nesting much easier to see.
- kazinator 2y agoYou are looking at the wrong thing. Nobody looks at bunched parentheses for any reason, unless they are investigating a suspicion that the code's indentation is wrong. In that situation, all that matters is whether the bunch contains the correct number of parentheses, not which specific closers match which specific openers. (foo (bar (baz (xyzzy arg)) (bar arg)) We know from the indentation that this is supposed to be a closed unit: (bar (baz (xyzzy arg)) But it needs three closing parens ))) not just )). If this problem is not accidentally compensated by a ) in the wrong place elsewhere, this code will error out. One simple thing you can do is just automatically reindent the whole block. The indentation will then match the incorrect parentheses and the problem will be clear. Undo the temporary reformatting and fix it.
- n8henrie 2y ago
- Pxtl 2y agoHonestly that's the indentation format I use for every language. Doing it in Lisp just makes sense. My "OTBS all the things" rules: - Never horizontal align. Indentation is a simple tree, with each set of children indented 1 layer deeper, which can be 4 spaces or 1 tab. ThisKindOfThing( foo, bar, baz); is generally dumb. - If a block is worth indenting for, the end of the block deserves its own line. Just do OTBS but also for parentheses if you've a long function call. ThisKindOfThing ( foo, bar, baz ); Is just more consistent and easier to manage while still being legible. - if you're ever splitting something across multiple lines there must be an indent. myObj .Foo() .Bar() .Baz(); - you're allowed to double-dip on tree depth - that is indent only one level for like 3 levels of tree, as long as the opening of that 3-deep jump is a clear one-liner and the end of it is a line that says ")))". Foo(Bar(Baz( someVal ))); - when splitting lines on infix operators, anything but commas go at the start of the line (also, bedmas counts as tree depth) foo + bar + baz + ( var1 * var2 * var3 ) + quux;
- varjag 2y agoThat's pretty awful even for other languages.
- Pxtl 2y agoIs this better? void MyFunc() { DoStuff(); DoOtherStuff();}
- TOGoS 2y agoThis is exactly the set of rules I happen to have ended up using. I suspect this is one of the few styles that you inevitably arrive at if you search the space for a format that looks okay, is easy to read, doesn't cause things to shift around when functions are renamed, and is relatively simple and self-consistent.
- b4ckup 2y agoThis is mostly how I indent my code. I don't know why so many people hate it. We have huge screens and spacing conveys structure so I use spacing when appropriate, like a ')' in its own line. I work in a *very* small team though and I write most of the code.
- davvid 2y ago> This post misses the IMO best indentation scheme for lisp [...] Likewise, a lispier(?) and more compact compromise?: (define (match:element variable restrictions) (define (ok? datum) (every (lambda (restriction) (restriction datum)) restrictions)) (define (element-match data dictionary succeed) (and (ok? data) (let ((vcell (match:lookup variable dictionary))) (if vcell (and (equal? (match:value vcell) data) (succeed dictionary)) (succeed (match:bind variable data dictionary)))))) element-match)
- nine_k 2y agoIt becomes much harder to notice if you have closed all the right matching parens, and hence where a token after the closing paren belongs. When the closing paren is exactly below the opening paren, on the same column, it becomes much easier to see the structure. It's a very good thing for students who just learn Lisp.
- ludston 2y agoBut all the cool kids are using paredit or parinfer which means you don't actually ever write the closing parens yourself. Counting parens is silly when the editor can do it for you.
- nine_k 2y agoWriting code is usually easier than reading!
- ludston 2y agoIf you're not used to the language, the conceptual models of the codebase you are working on, or you're working with obfuscated code. Otherwise it should be much faster to read and understand the code somebody else wrote than to write it from scratch?
- stackghost 2y agoThose poor lonely parens!
- Pxtl 2y agoDo the poor lonely braces in Algol-style languages indented OTBS-style bother you? Should we be doing this?: void MyFunc() { DoStuff(); DoOtherStuff();}
- stackghost 2y agoParens are like penguins, they need to snuggle. Get out of here with your vile curly braces.
- kazinator 2y agoOnce you have even a small amount of that background it's complete shit. Or else if it isn't, nobody wants to work with you. But at that point that probably suits you fine. If you want to work completely alone, yet be maximally productive, you've landed in a good language family.
- donio 2y agoFor Lisp users this is 35% extra vertical space for zero readability benefit. Or negative readability rather. When I see this formatting style I have to fix it before I can read it. It's like trying to read C code with an extra blank line after every single closing brace.
- aartaka 2y agoWhy 35%? I can't seem to align with you on the math here.
- donio 2y agoYou are right, I made the classic mistake of doing the percentage backwards. Once properly formatted I am counting 16 lines and it goes up to 25 so it's a 56% increase.
- nine_k 2y agoLisp users are a diverse crowd. I won't be so bold as to sign off for all of them.
- pasc1878 2y agoThe main reason to use it is not for reading it is to work with version control which is all line orientated. The reading is not that bad as the indentation tells you where the brackets are and you don't really notice them.
- deleted 2y ago[deleted]
- draven 2y agoAdmit you posted this only to trigger lispers.
- aartaka 2y agoI'm a Lisper myself, lol.
- EFreethought 2y agoI am sure there are some Emacs modes or plugins for other editors that could go back and forth between this and the more commonly-seen style.
- mcv 2y agoYeah, I'm surprised the article doesn't address this obvious case. It's pretty much my default indentation scheme for any language, and while I see a lot of lispers here complain about the wasted vertical space, it's undeniably easy to see which parentheses match and what the block structure is. I'll happily tolerate some wasted space in that trade-off.
- Avshalom 2y agoMore of an allman Lisp guy myself ( define (match:element variable restrictions) ( define (ok? datum) ( every ( lambda (restriction) (restriction datum) ) restrictions ) ) ( define (element-match data dictionary succeed) ( and (ok? data) ( let ((vcell (match:lookup variable dictionary))) ( if vcell ( and (equal? (match:value vcell) data) (succeed dictionary) ) (succeed (match:bind variable data dictionary)) ) ) ) ) element-match )
- dmos62 2y agoThe only thing that's missing is moving most of nested logic into `let` assignments.
- varjag 2y agoThis is one of the most disgusting things I read on HN.
- kleiba 2y agoHaha, good one! (I hope?!)
- deleted 2y ago[deleted]
- thiht 2y agoI don't use Lisp but this is very readable to me, actually way more than the examples in the article by a lot. I actually understand this code, just because of how it's formatted. Maybe I'd just use 2 spaces instead of 4 but otherwise, looks good. Granted I'm not the one to optimize for since I don't use Lisp, but this just seems sane and easy to automate, and it looks like other non-Lisp languages.