4 ms·
All indentation does is tell you that there is a hierarchy of some sort. The fact something is one level deeper than another still doesn't tell me generally wha
by tabtab 7y ago
All indentation does is tell you that there is a hierarchy of some sort. The fact something is one level deeper than another still doesn't tell me generally what it does, because that depends on what the parent(s) does. And it's not a difference maker because "regular" language can also use indents.
Further, the coder decides the indentation, and I'm not convinced it's consistent enough. In my example, a curly brace is a curly brace regardless of a coder's preference. It's enforced by the rules the language, not the coder.
Another thing I'd like to point out is that languages like JavaScript provide two levels of common abstraction. Using curly braces, parenthesis, and square brackets as an example, you spot them and immediately know the forest-level category something is: code block, function call, or array/structure index.
With Lisp, all you are guaranteed have is the function name (first parameter), which you have to do a mental name-to-purpose lookup, which could involve thousands of names. Splitting the lookup into levels improves the mental lookup performance, at least in my head.
It also helps one quickly know to ignore something. For example, if I'm looking for a code block, I know I can probably ignore array indexes, and vice versa. It's forest-level exclusion, which is hard to do with single-level lookups because the list is too long: it has to contain the general category of each name. It's extra mental accounting.
Hard-wiring in big-picture categories into the syntax allows quickly making forest-level reading decisions, and which individual coders generally can't change.
When it comes to team-level read-ability, consistency usually trumps abstraction and many other things.
Maybe Lisp can do something similar with "let", bindings, and body, but then it starts to resemble "regular" languages, along with their drawbacks, which is typically less abstraction ability. Consistency "spanks the cowboys", both the good cowboys and the bad cowboys. But at least you know what you have, and can estimate and plan accordingly.
- lispm 7y ago> All indentation does is tell you that there is a hierarchy of some sort. As I said, it's not just indented, but also layouted. As a Lisp developer I see a LET and then know that a binding+body structural pattern is following. binding+body and variations of those is used in a bunch of operators. That's a simple sequence: 1) identify the operator on the left 2) it determines the layout pattern 3) visually apply pattern recognition based on the layout pattern and classify the blocks Lisp is actually quite well to read, but you have to learn the basic structural patterns for a few days. The biggest hurdles are mental blocks and prior exposition to other types of syntax systems. > the coder decides the indentation He doesn't. Lisp does it. There are indentation rules provided by the development environment. If Lisp does the layout, it uses a complex layout system to adjust the code to the available horizontal space, taking into account the constructs to layout. That's why Lisp developers use these indentation and layout tools for decades. Lisp code itself is fully insensitive to formatting. Tools (editor, Lisp, ...) do the indenting and sometimes also the layouting for the user. > Using curly braces, parenthesis, and square brackets as an example, you spot them and immediately know the forest-level category something is: code block, function call, or array/structure index. Lisp uses symbolic names for that. People are extremely good at reading names. Since Lisp names are always at the beginning of a form, there is no guess/backtracking needed to find out the most top-level form. Where as with languages with infix operators I would need to parse the whole thing, finding out the operators and select the one with the highest precedence. > With Lisp, all you are guaranteed have is the function name (first parameter), which you have to do a mental name-to-purpose lookup, which could involve thousands of names. Splitting the lookup into levels improves the mental lookup performance, at least in my head. Lisp has not just functions, but also macros and special operators. Function calls have a fixed syntax and there is not much to understand. Special operators and macros usually signal with their names the kind of structure and thus the layout expected to follow. For example there are a bunch of macros which begin with WITH- . Those signal this pattern WITH- items and property list BODY Where 'items and property list' is something like (name item :option1 value1 :option2 value2 ...) For example a file will be opened like this: (with-open-file (stream file :direction :input) (read stream)) I read WITH-OPEN-FILE and know that it is a WITH- type macro. Then I know the basics of the structure of the code. Lisp has a number of these built-in patterns.
- nickbauman 7y agoWith lisp you stop thinking about syntax rules anymore (because the program is in a very simple form) so you can focus purely on semantics. Some things, like you say, are too overloaded in Clisp, for example: (defun averagenum (n1 n2 n3 n4) (/ ( + n1 n2 n3 n4) 4)) Clojure recognizes this goo problem and expresses the parameters in a vector instead of how Clisp does it in a list (defn averagenum [n1 n2 n3 n4] (/ ( + n1 n2 n3 n4) 4)) Helps a lot.
- kbp 7y agoThat isn't how that defun would normally be formatted, though. Lisp knows that the 'body' part starts with the 3rd argument (the same way Clojure knows it starts with the second), so it indents the lambda list farther right (if it doesn't fit on the first line, otherwise it would go there). For my eyes, [] aren't distinct enough from () to make the second style preferable. I'd rather have indentation to set it apart.
- nickbauman 7y agoI just made them consistent. It certainly helps me visually. Also a list implies you intend to evaluate it by executing a function. A vector implies you do not intend to call a function.
- kbp 7y agoYeah, it's definitely a taste thing, but as the first style isn't used in Lisp, comparing its readability doesn't really make sense. Indentation is important to reading Lisp. Indenting it in an odd way makes it harder to parse. It's a bit like giving def foo(x) bar(x) end as an example of Ruby syntax being overly homogeneous.
- lispm 7y ago(defun averagenum (n1 n2 n3 n4) (/ (+ n1 n2 n3 n4) 4)) The typical pattern is DEFSOMETHING name arglist body A Lisp programmer reads those structural patterns, not the delimiters. Lisp programming is more about thinking of trees of code and their possible manipulation - even independent of a visual notation and especially independent of the exact delimiter used. The delimiters are in shape recognition much less important than the shape itself.