Brace Style

Sjmarf@sh.itjust.works to Programmer Humor@programming.dev – 1282 points –
156

Mom, can we stop and get some Python?

No, we have Python at home.

Python at home....

What if I prefer this?

#define CURLYOPENRIGHTCLOSEDLEFTBRACKET {
#define CURLYOPENLEFTCLOSEDRIGHTBRACKET }
#define CURVYOPENRIGHTCLOSEDLEFTBRACKET (
#define CURVYOPENLEFTCLOSEDRIGHTBRACKET )
#define PERIODWITHPERIODONTOP :
#define COMMAWITHPERIODONTOP ;

int main CURVYOPENRIGHTCLOSEDLEFTBRACKET CURVYOPENLEFTCLOSEDRIGHTBRACKET CURLYOPENRIGHTCLOSEDLEFTBRACKET
  if CURVYOPENRIGHTCLOSEDLEFTBRACKET 1 CURVYOPENLEFTCLOSEDRIGHTBRACKET CURLYOPENRIGHTCLOSEDLEFTBRACKET
    asm volatile CURVYOPENRIGHTCLOSEDLEFTBRACKET
      "mov $1, %%rax\n"
      "mov $1, %%rdi\n"
      "lea message(%%rip), %%rsi\n"
      "mov $4, %%edx\n"
      "syscall\n"
      PERIODWITHPERIODONTOP
      PERIODWITHPERIODONTOP
      PERIODWITHPERIODONTOP "%rax", "%rdi", "%rsi", "%rdx"
    CURVYOPENLEFTCLOSEDRIGHTBRACKET COMMAWITHPERIODONTOP
  CURLYOPENLEFTCLOSEDRIGHTBRACKET
  return 0 COMMAWITHPERIODONTOP
CURLYOPENLEFTCLOSEDRIGHTBRACKET

asm CURVYOPENRIGHTCLOSEDLEFTBRACKET ".section .data\n"
  "message: .ascii \"wut\\n\"\n"
  ".section .text\n" CURVYOPENLEFTCLOSEDRIGHTBRACKET COMMAWITHPERIODONTOP

You win a free trip to the Hague

They don't even deserve the trial. Straight to gulag.

Still need at least troyka to send to gulag. Or regular court outside of stalinism.

The taxi chauffeur can be judge and do it on the way to the gulag.

Obviously the sentence is predetermined.

Acceptable, just FYI I added a pre-commit git hook, please rebase your changes.

Idk why but i fell in love with this and might just use it now

It would be nice and easy if we had elastic tabstops

That's true, I wanted to port that to Kate for me to test, but I'm too dumb to port the Scala implementation to QT/KDE framework

1 more...

Looks like Python, but in an editor with a weird TUI scrollbar

High chance that it's a Python programmer who is really unhappy about having to work in Java, lol

Agreed. I saw this and thought it looked beautifully passive aggressive

Ha! Now I see it - that was very funny, sir!

Doesn't python need colons after if/else/for/etc. statements?

Heh, so in Python it's possible to overload operators in the context of objects. I bet it would be possible to overload tabs to do the same thing as colons inside a context manager, but that's pure speculation.

Perhaps I don't understand you, but I don't think there's a way to override spaces in python in any way. The spaces are handled by the parser.

You can define what happens for an object when an operator is applied (like +, /, or -) so that you can obj+obj. I wonder if there's a way to override "tab" such that it acts like a ":", but from inside the language (this is trivial if you edit the language itself like you suggest). Thinking about it more, I'm guessing not since ":" isn't an operator and this doesn't have a corresponding __operator__ function.

If Python has anything like Perl's source code filters, then anything's up for grabs, but Perl is kind of weird in a way that Python was specifically designed not to be. Or at least Python 1 was. Things may have changed in the intervening couple of decades.

If it's just plain overloading, then whitespace is probably off the table. Spaces, even required spaces, aren't so much syntax as they are structure. You could argue that the curly braces of some other languages are more syntactic than Python's whitespace, because it's actually Python's magic colon and the first unindented line (lack of whitespace!) that serve that specific syntactic purpose.

Examples of Perl's source code filters range from turning a program into binary representation of the syntax tree and still having it be executable, to new syntax, to writing programs entirely in Latin or something that looks almost but not entirely unlike it, anyway.

I see. I would love to be proven wrong, but I don't see a way this would work with tabs/spaces in python.

IIRC, Python handles whitespace indentation by having the tokenizer convert them to INDENT/DEDENT tokens. The grammar can then handle them equivalently to a curly brace language.

You can write Fortran Python in any language.

Literally me every time I want to program something slightly complex in Python.

It's just YAML...

YAML makes you appreciate Python's 4 spaces indentation.

I thought python allowed whatever indentation you wanted as long as it's consistent?

It does, but most style guides and autoformatters will use 4

Python is one of the few languages with an official style guide, I think that guide says 4 spaces.

Tabs!

I've set tabs to four spaces in vim because who the fuck defaults tab to eight spaces. That shit looks alien and pushes text off the screen fast.

Linux uses 8 spaces. Excerpt from the official style guide:

Tabs are 8 characters, and thus indentations are also 8 characters. There are heretic movements that try to make indentations 4 (or even 2!) characters deep, and that is akin to trying to define the value of PI to be 3.

Rationale: The whole idea behind indentation is to clearly define where a block of control starts and ends. Especially when you’ve been looking at your screen for 20 straight hours, you’ll find it a lot easier to see how the indentation works if you have large indentations.

Now, some people will claim that having 8-character indentations makes the code move too far to the right, and makes it hard to read on a 80-character terminal screen. The answer to that is that if you need more than 3 levels of indentation, you’re screwed anyway, and should fix your program.

In short, 8-char indents make things easier to read, and have the added benefit of warning you when you’re nesting your functions too deep. Heed that warning.

The reasoning seems sound, but I still prefer 4 personally.

I don't develop kernel modules, I use python. That's pretty interesting though.

I set my clang-format to tabs only (actual tabs ASCII 0x9, no alignment and there is a continuation tab instead), then anyone can set their editor to whatever tab length they feel like and look at their code however they want.

But no spaces on the left of my code. This is for C, C++ and JSON.

1 more...
1 more...
1 more...
1 more...
1 more...
1 more...
1 more...

Growing up with C made me assume semicolons and braces were needed to avoid subtle bugs, but experience with more recent languages showed me that it's possible to reliably parse the same semantic cues that humans use: indentation, parentheses, and other such context. (Perhaps this was less viable when C was invented, due to more constrained hardware.)

I was skeptical at first, but in practice, I have never encountered a bug caused by this approach in Python, Nim, or any other language implementing it consistently, over the course of a decade or two using them. Meanwhile, I have seen more than a few bugs caused by brace and semicolon mistakes.

So nowadays (outside of niche & domain-specific languages) I see braces and semicolons as little more than annoying noise and fuel for religious arguments.

In Java it’s quite difficult to forget semicolon and still have a syntactically correct program.

I think braces are incredibly important. With Python it can be confusing which indentation is correct when copying code between files. Different indentations can easily be still syntactically correct, but the outcome is vastly different. It’s often I have to double and triple check to verify I copied the code with correct indentation.

It’s often I have to double and triple check to verify I copied the code with correct indentation.

I vaguely remember facing that issue once or twice in the past, but certainly not often. It was because the pasted code was too long for its starting point to be easily found in my editor, even if I scrolled up a bit.

If this happens to you often, I wonder: perhaps the code you maintain should be broken into smaller functions?

If I was in that situation again, I think I would simply place a bookmark before pasting and then jump back to the bookmark to indent/dedent the pasted block appropriately.

Edit: Come to think of it, I would have to check and correct it regardless of the language and braces, since confusingly indented code is unwelcome in my commits.

Well, Python kind of does the reverse of a semicolon: If you want to continue a statement over multiple lines, then you have to \
escape it.
Python also then tries to avoid multi-line statements for that reason, but yeah, in most other languages this would be equally as annoying as semicolons are.

There are some languages which use neither, for example Scala, but I can at least say that while I consider the people behind Scala and Rust equally competent and the languages more or less equally modern, Rust just completely blew it out of the water in terms of error messages despite being much younger. (Not because Scala is bad, Rust is just incredibly good there.)

And yeah, I'm suspecting that Rust using semicolons makes the difference there.
While Scala will pretty much have to guess where a statement with compile error ends, Rust just knows it ends at most at the next semicolon.

I will also say my experience is opposite of yours. I have managed multiple times to try to access a variable in Python, which wasn't in scope anymore, because the indentation wasn't enough of a visual cue to me.
And in any modern language, missing/missplaced semicolons or braces are a compile error, with clear error message where it's missing. I genuinely don't even know how you'd get a bug out of that.

Well, Python kind of does the reverse of a semicolon: If you want to continue a statement over multiple lines, then you have to \ escape it.

That's not true. Being within parentheses, brackets, quotes, etc. is enough for the parser to know you're continuing. In practice, I find that context is already present in most cases.

For the other cases, occasionally surrounding an expression in parentheses is easy enough. Long conditionals probably deserve parentheses anyway, for clarity.

Well, it mostly being already correct is what I meant with Python avoiding multi-line statements.

In JVM languages, Rust etc., it's for example popular to use Fluent Interfaces. These also reduce visual clutter and the number of variables in scope (and/or the need for mutability).

I did not know about enclosing them with parenthesis, but apparently that works, too, as this library shows: https://pypi.org/project/fluentpy/

I am a Scala and Rust fan. I can corroborate what you said

The part about no semicolons/curly braces I like in Scala is that I can write a function and it'll look virtually indistinguishable from a regular ol variable. Functions become much less of a ritual and integrate more nicely with the rest of the code. Other than that though, Rust definitely wins out because of the curly braces & semicolons. I use curly braces in most situations in Scala where I'd normally use them in Rust, and I would use semicolons everywhere in Scala if it weren't considered unidiomatic. Whitespace-significant syntax is just really annoying to deal with. Using Python or even maybe F# makes me want to die because I keep accidentally missing an indent somewhere or indenting too much somewhere else or using the wrong kind of whitespace and the entire program implodes. At least Scala and Kotlin keep it sane

Also it's just way harder to visually organize in whitespace based languages. You basically have to do a bunch of magic tricks to make the code look slightly different in a specific scenario than what the language wants you to. Rust allows you to actually visually organize your code easily while also having a strong style rules which you shouldn't stray too far from (or else the compiler will yell at you).

Fortran is ancient and does fine without ;

When Fortran was created, each line was a separate punched card. The syntax made sense for that medium.

C was setup from the start for use on teletypes with fancy line editors like ed.

It's kinda organic in python, but God forbid how often I made mistakes in yaml learning k8s

Haha... Yes, I've found yaml to be problematic in this area, too. Probably because it lacks the context cues and modularity of a programming language.

Context cues could be provided by jsonschema, but still it's unbearable in comparison even with json.

Plus any decent editor catches when lines are unreachable or in violation due to misformatting.

If not that, which seems unlikely, your unit tests would

GCC has separate warning when braces don't match identation

WE CAN DO THAT!?!??

.... whitespace is whitespace.

Or you could replace most of the whitespace with repeating semicolons. Makes the code much clearer!

I low key love it. It's unconventional, but it's not hard to read

it's not hard to read

Until there's missing brace somewhere

I think this could be better for reading but harder for writing. Like you could write a script that converts between this and the easier to write way if you are working on a project with others.

On braces are not used in if or for statements

I was like, "where are the braces?". Then, I turned to the right

Thank you. I couldn't see the problem.

And if this layout is auto generated, maybe I still don't see the problem.

This should be its own language. Pyava.

Or Jathon (pronounced like Mike Tyson would pronounce JSON)

Or we can round out the confusion and call it PythonScript

My credo on this kind of thing is never do something that will make your successor so mad that they find out where you live and post parts of your body to Interpol.

I kinda like it, easy to see unbalanced braces

Last day at the company, pushed over 5,000 commits. Just style changes, still passes all the checks.

This would never pass PR review.

I kinda like it..

I think you'll like Ruby. It has mostly done away with braces and code blocks end with end, e.g.

def create
  unless admin redirect_to new_session_path and return
  
  @product = Product.new product_params

  if @product.save
    flash[:success] = "New product has been created!"
    redirect_to edit_product_path(@product) and return
  else
    flash[:error] = "Something went wrong!
    render :new
  end
end

This is working code that I simplified a bit from an old project of mine.

Ruby syntax is nice although I prefer python way of enforcing indentation instead of adding "end"s. Personally I just want a statically typed language with enforced indent as syntax.

Funny, the forced indentation is what I hate about Python. If you think a missing semicolon can be hard to catch, don't ever think about a missing whitespace :p

The end keyword really isn't a big deal for me. I find it to be a good way to easily spot the end of a method. But if you wouldn't like it I'd still find it a good compromise to avoid syntax issues due to whitespace.

i can count on one hand how many times ive had white space issues in 15 years of using python. its just not an issue

Same and agreed, especially if you keep your functions small and focused as you should. 3-5 indents is nbd to keep track of, and if you need more than that... No you don't, refactor.

I've had way more hangups with brackets then indentation, personally, not that either is a super frequent issue, but I'm indenting anyway, so brackets are redundant and just another thing I have to keep track of

} helps me easily spot the end of stuff. end just blends into the statements.

Just add a linter to your build lol. Now if it's indented wrong it breaks!

That's just Algol instead of B. Most languages use the one or the other, then there's sexpr-based languages (lisp, scheme), lua (technically Algol but not needing semicolons while also not needing newlines so it's definitely special), and layout syntax (Haskell, or, if you want a bad implementation, python).

Who's going to write the extension so that they are all hidden and automatically inserted?

Might check out the Haskell layout rules.

Basically, when you leave out the '{' then Haskell uses your intendation to insert ';}' on later lines between the leading whitespace and the first token.

There some really old Haskell code out there that lines up the '{;}' characters on the left under block-introduction keywords.

It's not just old Haskell code that's how you write Haskell if you want explicit braces. Well, mostly generate, but it's still the idiomatic formatting (and when you generate you always generate braces because it's easy to get layout subtly wrong when generating).

Haskell also does the whole

data Foo = Bar
         | Baz
         | Quux

foo = [ Bar
      , Baz
      , Quux
      ]

thing, makes sense to apply it to braces especially as they're seen only very rarely. Single-line, yes, but not multi-line.

Honestly, looks neat, might adopt this

That would be very cool to have in a code autoformatter

I'm not a coder, and.... Well... Thanks, I hate it.

Even I know this is horrific. Where the fuck does this statement end? Which of these brackets refer to this section of other brackets. Idfk.

I could give a shit less if it was just for a single block per or something but ";}}}" hurts me.

Well the code indentation explains that, like python. The issue is not reading it. You would rather quit your job than edit this.

tooling would have to do it all after the fact or something

Auto formatter as part of the expected language tooling is Go's greatest move, even if their formatter doesn't go far enough.

Rust does this too I think (or just everyone uses rustfmt).

I’m more concerned about that poor stack with all those recursions.

It’s also O(n^2) O(n!). I’m not sure what they’re trying to do, but I’m sure it can be done in O(n) (or at least polynomial).

Reject.

Automatically enforced deterministic formatting is the best, there's nothing that beats it. The productivity in just being able to format on save knowing that the code will be in the ideally formatted state, along with the anti-bikeshedding properties of this strategy, makes it unbeatable.

gofumpt and gofmt are the best. One of the reasons if I have a choice I'll code in go. I heard rumblings that rust was working towards having rustfmt be a standard crate.

Go is in a good position, yeah. JavaScript has prettier, which is nice. Java has google-java-format. Python has ruff, which is quite good. Kotlin has ktfmt, which I believe made a mistake with their standards by not following the standard formatting guidelines for the language, but whatever. Uniform and deterministic for the win.

What do you mean? rustfmt is the de facto standard and is easily run using cargo fmt. Most projects use it along with clippy, the standard linter.

I had no idea it was standard. I had heard they had issues with it not being able to handle certain constructs so they were working on getting it to a place it would perform better. Has this changed? I'm not a rust person, but I intend to be. I've barely made it 1/4th way into the book (just started in the past month and I've been busy), but I have a good background in programming and so far it's been super easy. I'm really enjoying how specific the compiler is, and the binary sizes vs Go.

What amazes me is that someone either did that manually or wrote a formatter to do that - I doubt that any standard style config would do this.

How happy I am with prettier. This is just a thing in an ancient past for me now.

Recently tried biome for a web project. It's a combined linter and formatter, and it's so good. Compatible with prettier too.

Are you referring to autoformat like most linters and IDEs can do or does prettier have some special transpilation capability to hide braces?

why stop at curly brackets? Do all of them: parentheses, square brackets, angle brackets, and curly brackets. Also, strings should be liberated. Move all non-escaped quote characters to the end of the line too.

And escape the newlines that you introduce in the strings