1. 14

I have long used and appreciated whitespace significant languages. Those languages currently include F#, Haskell, and Python. But lately I have been using OCaml, and lo! Here is a language without any significant whitespace that for the most part, reads very well. Semicolons are only for sequencing statements, which you rarely need to do, and functions need no end delimiter thanks to a well defined syntax. Braces are reserved for records; an unimpeachable choice. The only end delimiter I can think of is for whole modules (and module public interfaces), which hardly sours me.

So I am wondering again: with all the benefits to having a whitespace insignificant language… If a language can look as good as OCaml*, is significant whitespace a good idea?

Is significant whitespace a bad idea?

What is your personal experience with this?

*please don’t bring up top-level, that is admittedly bad


  2. 21

    Why does the title lead to the lobsters story submitting page?

    1. 4

      Looks like they submitted the new story url instead of leaving the url field empty.

      1. 4

        Ah! Okay, I think I fixed it. :)

        It would still be great to know how that happened.

        1. 2

          Thanks Irene!

      2. 2

        Great question! I have no idea. :D @jcs?

        1. 4

          Heh, very off topic but it would be very nice if @username references would create (email) notifications.

          1. 7

            They do.

      3. [Comment removed by author]

        1. 7

          I think you get the same readability advantage from having an auto-formatter (eg gofmt), without adding so much complexity to the parser.

          1. [Comment removed by author]

            1. 3

              Amen to that!

              I’ve seen too many hours lost in discussions about code format issues.

              Today, I expect any language I work in to have an automatic, command-line formatter. Even if the style does not match my preferences, I prefer uniformity over customization.

              Add automated refactoring tools and I’m sold.

              Any modern language should be thought from the start to make those kind of tooling possible.

              1. 1

                I know of http://clang.llvm.org/docs/ClangFormat.html and for Python https://github.com/google/yapf

                Yapf kind of is the example that even though Python indentation is mostly right, there are a lot of other code-layout questions to be layed out in code.

                1. 1
                  1. 1

                    Dart, though not so popular, has some pretty decent tools, including a formatter… https://github.com/dart-lang/dart_style. Must be something in the water in Mountain View :-)

              2. 12

                The biggest issue with whitespace significance is for program-handling programs. This includes structure editors, as @dwc mentions, but refactoring tools are the largest area where it’s an issue.

                Whitespace rules that humans find usable need to have a lot of corner cases, and it usually winds up that the only correct implementation is the one that’s part of the compiler. And to do any sort of programmatic code transformation, you need both a parser and a generator, which are two separate ways of understanding the rules and idioms and generally two separate sources of bugs.

                Lisp and Go both go radically further, trying to minimize the room for variation at the formatting level. I haven’t used Go enough to comment on how well that works for it, but in my experience with Common Lisp it was always very refreshing to not need to have style conversations, at least not about purely syntactic points. :)

                1. 7

                  The go team considered adopting significant whitespace early on.

                  The decision not to go ahead with it was informed by, amongst other things a bug that had appeared in a python code-generator program when a class containing a here-document was moved and de-indented.

                  Rather than causing the code to become invalid, the de-indented code short-circuited the conditional it was meant to be placed after!

                2. 11

                  I originally loved significant whitespace in python, but came to dislike it after experiencing s expressions and clojure. So now I feel limited when I redactor or move portions of code.

                  Sign. Whitespace then makes autoindenting hard, I.e. it is a major obstacle for good tooling. Selecting all code contained in a brace or a parents is so much easier (in vim the % movement) than if you have to walk lines.

                  1. 1

                    Why? Is this just about macros?

                    1. 6

                      This is not about macros, not at all. I only mentioned clojure because Paredit-Mode lends itsself to pick up autoindentation commands and workflows that depend on it.

                      Suppose you have some code

                      def myfunction(....):
                          for i in xrange(10):
                              for j in xrange(20):
                                  # snip start
                                  if .....:
                                  # snip stop

                      When you move the code in the inner loop body into a separate function, or if you would move the for loop over i, outside of myfunction, than you have to readjust the indentation. Of course I readjust the indentation in any case, but with an indent sensitive language, I just cannot call the readjust function of vim (= in command mode), I must manually shift the code (visual mode selection, and apply as many < or > as appropriate.

                      The point is, that in my experience with a language where whitespace is not significant, it is more easier to do such things, as tooling can determine the indent levels automatically. In Python this is not always the case (Especially determining when to dedent is problematic I think).

                      So my preference from most- to least preferred is

                      1. non-signifcant whitespace with logical grouping with parens ,brackets, etc.
                      2. non-significant whitespace with explicit block terminators (ruby style, etc)
                      3. significant whitespace
                  2. 8

                    Note: Python et al. have significant indentation; whether I write x=a+b or x = a + b does not change the semantic of the statement.

                    Personally, I like to have explicit delimiters; this makes it easier for a tool to format the whole program (e.g. Emacs’s indent-region command or Go’s gofmt command-line tool), it’s less likely that moving code around causes problems, and if you need to generate code, delimiters allow you to have one fewer thing to worry about.

                    1. 8

                      After trying to write a parser for a language that used it. Never again.

                      1. 7

                        IMO It pretty much just doesn’t matter. Even in languages without significant whitespace, you still (generally) indent your blocks. Python especially would look basically identical if it used curly-braces instead of whitespace.

                        The only problem I have with significant whitespace languages isn’t one with the whitespace or the language, it’s with my stupid brain: I always forget which languages use which style when switching between them. I usually write a lot of Python, but the current project is in Go so about 100 times a day I start a block with a colon and an indent and then have to go back and fix it when gofmt yells at me. Then again, I do it with other stylistic things too, like accidentally naming a function do_thing instead of DoThing.

                        1. 6

                          I like the ability to have either. For example, in Haskell you can make use of significant white space, but wrapping up with some {} and using semicolons and now white space is no longer significant.

                          1. 2

                            Well, if you’re using significant white space you can still accidentally run into whitespace problems.

                          2. 6

                            I am firmly on the side of “who cares?”. Of all language design decisions, i think it’s one of the least important.

                            1. 6

                              “Why are we still programming using lists of characters?”

                              1. 3

                                That one’s easily answered: Because every attempt I’ve seen or interacted with to try moving away from that is godawful.

                                It might have something to do with the keyboard producing a stream of characters, so interfaces where that stream of characters aren’t respected on input tend to be jarring. And if you have a well formed file, recovering the structure is no harder than interpreting the input that you got from the keyboard in the first place.

                            2. 5

                              Spending time maintaining Perl by an author who didn’t believe in indenting Python’s significant indentation seemed like a fantastic idea. I haven’t really written Python in anger though, and understand it to be a bit of an obstacle to refactoring. (I really like lisps here.)

                              Can’t believe nobody brought up Makefiles yet. I’m still sore about the hours I wasted debugging a makefile that had eight leading spaces rather than a tab–and it’s about 15 years ago. (I had only just learnt about make, and didn’t have my editor set up to highlight tabs specially yet.)

                              1. 5

                                Good for reading, bad for refactoring.

                                1. 2

                                  I used to love significant whitespaces in Python, until I tried Go with gofmt, which convinced me significant whitespaces are a mistake. They make formatting, refactoring, generating and sharing code by email or chat harder.

                                  1. 2

                                    This seems like a troll question.

                                    The answer is entirely personal opinion and neither option is “bad” or “good”, but the question is posed in a way that favors one option over the other.

                                    On top of that, the same “issue” is discussed in a million other places, and there’s little reason to believe there will be any new insight here.

                                    Some people love significant whitespace/indentation, others hate it, some people don’t care, and there are people all over the spectrum.

                                    1. 2

                                      Based on sometimes painful experience (cf Apple’s ‘goto fail’ security issue, among others), we know that indentation and other white space in source code will be treated as significant by people reading that code. As a result, I feel that the existing indentation in the source code should be at least significant enough that it’s a syntax error if it doesn’t match the code’s block structure. I somewhat favour languages also having explicit, required block delimiters on top of this; Python’s indentation-only approach has its own flaws too, where you can accidentally indent or outdent things.

                                      If you have both explicit block delimiters and checked indentation, I feel strongly that you should also have a gofmt like tool that takes improperly indented code and fixes it to match the explicit block delimiters. Even without checked indentation I think that a gofmt equivalent with a fixed language formatting style and a culture of routinely running code through it is a good idea to avoid confusing, error-creating mismatches between indentation and explicit block delimiters.

                                      1. 2

                                        I am ok either way. I prefer indentation for readability, whether it’s significant or not. I have a buddy who writes things like for(var i=0;i<someVar;i++){} and I find it very difficult to read.

                                        This goes for things like poorly named variables as well. Make your code for someone else to read!

                                        1. 1

                                          Here is a language without any significant whitespace that for the most part, reads very well.

                                          Unless you try match inside match, in which case you’ll have to add parens which makes it both ugly and confusing and you’d wish for significant whitespace.

                                          1. 1

                                            I prefer using begin and end for that, since it at least looks a bit nicer than the parens. But I agree, it can get rather inconvenient to deal with. There’s been some proposals for explicitly ending all match expressions with end recently, though, so that could be a possible solution.

                                          2. 1

                                            Whitespaceissignificantinalmostallprogramminglanguages. Or did you mean significant indentation?

                                            1. 1

                                              Counter example: Fortran 77.