Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

I don't think the indentation is a big deal. It's just a surface detail that people new to the language tend to bitch about, like all of those parens in Lisp, ; vs . in Erlang, indexing from 1 in Lua, + vs +. in OCaml, etc. Once you're using the language idiomatically, it isn't a big deal. Good semantics beat good syntax any day.


sort by: page size:

My guess is that most people that don't like the indentation have never used it. It is notably more readable when looking at someone else's code, and makes wonderful use of whitespace.

Now if only there were some formatting standard to get rid of some of that parens in Lisp without loss of power.


I still can't get next to the idea of a language where indentation has semantic meaning to the interpreter.

Yuck.

Call me old fashioned but I find code with e.g. curly braces much more readable.


Unless experienced, you have no clue how a piece of code will be parsed. With ocaml, where is very little ambiguity; and indentation tools can take care of proper formatting, you only need to break lines.

And it can be pretty bad with haskell, which has complex semantics compared to, say, python.

With whitespace sensitive syntax, I feel like in the dark age of manual indentation.


Indeed, and I'm not really criticizing it, it's a matter of taste, and arguing over that is generally fruitless.

However, while I could make such a choice in CL, or modify Clojure, the standard including indentation for such a fundamental part of a language is controlling, and if I want to be part of the community I have to follow it.


>> The parenthesis do require that you have at least a moderately capable editor to navigate them effectively.

I disagree, with a caveat--writing code using a terrible editor requires knowledge of the indentation rules for the language, regardless of whether that language is a lisp, Perl, Ruby, etc.

However (the caveat), although the indentation rules for Perl, C, Python are relatively simple (indent after a '{' or ':', line up arguments), each function/macro in a lisp can have different indenting rules (e.g. in CL compare `let' to `multiple-value-bind' to functions, to lists, to the various `with-*' macros, etc).

Once you know the library for a specific implementation, the indentation rules become more obvious; at this point, using (e.g.) Notepad isn't particularly terrible (until that knowledge is acquired, though, yikes).


It's still very easy to make mistakes reading it that way. If you are reading it by indentation anyway you may as well use a parser that closes parentheses for you at indentation changes. (Like the ML family and Haskell and Python all decided to do.)

Indentation is visible. Conservatively estimated, tens to hundreds of thousands of programmers don't have any real problem with syntax based on indentation.

Maybe this sounds nitpicky but I'm just not a fan of languages that use indentation to denote block structure. It turns trivial code manipulations into tedious line-by-line exercises. I don't like it in Python or Haskell either.

Other than that I see a lot to like in CS though.


I think it's a bit of a bikeshed-type issue.

Subjectively, languages with significant indentation (Python, F#, Nim, Coffeescript, Haskell, etc) are often thought to have nicer-looking syntax.


Significant indentation is a good thing. Haskell and Python do it too.

It's much easier to read indentation than it is to match up pairs of brackets in your head. In other languages, if the indentation doesn't match the brackets, you'll naturally read the indentation first and get the wrong impression of what the code does. In those languages, the indentation is supposed to match the brackets anyway. Why be redundant like that?


Indenting styles is, humorously, a massive problem for the lisps.

Consider, say,

  for (i in [1, 2, 3]) {
    x(i);
    y(i);
    z(i);
  }
The indentation here very naturally demarcates between control structures and non-control code.

Compared to similar lisp-y code:

  (map
    #(-> % x y z)
    (range 3))
The indentation doesn't give the programmer any hints that map is actually a control structure fulfilling the same role as a for loop.

Given that indentation is critical enough to be a major language feature of something like Python, lisps have a weakness here that isn't dealt with very often. This so-called 'semantic indenting' doesn't go far enough - programmers want much more of it if Python and C-like languages are any indicator. I think there is a very desirable equilibrium here; something where the indentation changes based on the semantic intention of the function. I don't want all my Clojure functions to indent the same way, map/reduce/recur/let/etc are special.


That style of indentation is more common in Haskell libraries, and I'm not sure what you don't like about the whitespace.

I think they share my distaste of languages (like python) that use indentation instead of brackets to signify a code block. People have different preferences and it's totally valid, whatever the reason for those preferences.

As a recent Haskell learner, I found the indentation part of Haskell hard to learn and a little undiscoverable/hard to google.

The number of times I've used curly braces, single lines or expression substitution to bail me out is many...


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.


I know Python's indentation is a big turn off to most people coming from another language; it seems almost invasive of the interpreter to pay attention to whitespace. But you get used to it, and it becomes quite nice.

It's not a huge problem, but lack of understanding of how the compiler delineates blocks of code makes the code hard to reason about. I like to know what the compiler will do with my code, and what is and isn't valid through something other than trial and error. Scheme's perfect regularity makes that easy. Haskell... doesn't.

I am aware that the information exists somewhere, and I think I got a link a bit back, so I'll have to go track that down. But it is absolutely baffling that people don't discuss it more. Would you be able to write Python if nobody told you about the indentation rules? Of course not.

I'll have to find that link...


Python's significant indentation is also off-putting for a lot of people who are no longer newcomers to the language. I think some people are also unhappy with its effects without realizing that the significant indentation is contributing to those effects, such as how significant indentation interacts with other language features to force trade-offs between some programming techniques and longer lines of code.

Code I write for work these days (not including Puppet config, which is Ruby, or shell scripts) is all Python, and I still dislike the significant indentation. I do not dislike significant indentation per se, but I do dislike some of its effects in concert with other language design decisions. I did have a knee-jerk negative reaction to Python's significant indentation by itself when I first encountered the language a long time ago, but I got over it when exposed more to a couple other languages with significant indentation where it felt less off-putting. For instance, I never had a problem with Haskell's use of the off-side rule for specific block types (though I'm far less familiar with Haskell in general than Python), and did not even realize the language used the off-side rule for a while because it blended so seamlessly and naturally with the "obvious" way to organize code in every case where the rule applies. To repeat and clarify my feeling on the matter, though, I still dislike the off-side rule in Python, because of its interactions with other language features.

I don't want to distract from Nim discussion to create a whole separate debate, so I may not respond to further questions on the subject here -- I just wanted to point out that significant indentation is not devoid of its trade-offs for the benefits some people enjoy. I understand that some people like significant indentation so much that the other concerns that arise might end up beneath their notice, and others may hate it just out of some stubborn attachment to the conventions of other languages, but it is worth noting that it really does come with trade-offs, and there are also many people who dislike it specifically for the effects those trade-offs have on their code, and that this is a perfectly valid and reasonable position to take (even for those who find it difficult to identify or articulate the specific, undesirable causes of those effects they dislike). There are problems in practice, but not problems so big that one cannot reasonably ignore them if one likes the positive effects of significant indentation.

My usual solution to the problems Python's significant indentation solves would just be to fire people who lack such attention to detail that they cannot learn to format code nicely, though. As such, the language enforcing it offers less benefit for me than it might for others.


I have encountered indentation problem in Python far way often than the problem with a misplaced paren in any Lisp. It is very rare and every editor/compiler/linter has ways to detect that and help you fix it.

Readability is indeed subjective. Few years ago I myself would strongly oppose my own words about Lisp being readable. Several years ago even plain English was pretty much unreadable for me. I guess it's a good thing I haven't dismissed it, otherwise we wouldn't be having this conversation :)

next

Legal | privacy