Live data from Hacker News

John Carmack on inlined code (2014)

number-none.com

51–60 of 402 posts

Re: John Carmack on inlined code (2014)

#51
post #38
post #28

Earlier quoted context omitted.

My 'principle' for DRY is : twice is fine, trice is worth an abstraction (if you think it has a small to moderate chance to happen again). I used to apply it no matter what, soi guess it's progress...

I really dislike how this principle ends up being used in practice. A good abstraction that makes actual sense is perfectly good even when it's used only once. On the other hand, the idea of deduplicating code by creating an indirection is often not worth it for long-term maintenance, and is precisely the kind of thing that will cause maintenance headaches and anti-patterns. For example: don't mix file system or low-…

I think the main problem with these abstractions that they are merely indirections in most cases, limiting the usefulness to several use cases (sometimes to things that never going to be needed).

To quote Dijsktra: "The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise."

Re: John Carmack on inlined code (2014)

#52

Always read older stuff from Carmack remembering the context. He made a name for himself getting 3D games to run on slow hardware. The standard advice of write for clarity first, make sure algorithms have reasonable runtimes, and look at profiler data if it's slow is all you need 99% of the time.

And before that, 2D games (side-scrolling platformers were not a thing on PC hardware until Carmack did it, iirc). I think his main thing is balancing clarity - what happens when and in what order - with maintainability. Compare this with enterprise software, which is orders of magnitude more complex than video games in terms of business logic (the complexity in video games is in performance optimization), but whose…

>Compare this with enterprise software, which is orders of magnitude more complex than video games in terms of business logic

I dont buy it in games like gta, cyberpunk or witcher 3

Re: John Carmack on inlined code (2014)

#53
post #38
post #28

Earlier quoted context omitted.

My 'principle' for DRY is : twice is fine, trice is worth an abstraction (if you think it has a small to moderate chance to happen again). I used to apply it no matter what, soi guess it's progress...

I really dislike how this principle ends up being used in practice. A good abstraction that makes actual sense is perfectly good even when it's used only once. On the other hand, the idea of deduplicating code by creating an indirection is often not worth it for long-term maintenance, and is precisely the kind of thing that will cause maintenance headaches and anti-patterns. For example: don't mix file system or low-…

I can't remember where I picked it up from, but nowadays I try to be mindful of when things are "accidentally" repeated and when they are "necessarily" repeated. Abstractions that encapsulate the latter tend to be a good idea regardless of how many times you've repeated a piece of code in practice.

Re: John Carmack on inlined code (2014)

#54
post #21

> Inlining functions also has the benefit of not making it possible to call the function from other places. I’ve really gone to town with this in Python. def parse_news_email(…): def parse_link(…): … def parse_subjet(…): … … If you are careful, you can rely on the outer function’s variables being available inside the inner functions as well. Something like a logger or a db connection can be passed in once and then us…

> Inlining functions also has the benefit of not making it possible to call the function from other places. Congrats, you've got an untestable unit.

Congratulations, you are writing test for things that would not need test if weren't put behind a under-defined interface. Meanwhile sprint goals are not met and overall product quality is embarrassing, but you have 100% MC/DC coverage of your addNumbersOrThrowIfAbove(a, b, c).

Re: John Carmack on inlined code (2014)

#55
I wish languages had the following:

  let x = block {
     …
     return 5
  } // x == 5
And the way to mark copypaste, e.g.

  common foo {
    asdf(qwerty(i+j));
    printf(“%p”, write));
    bar();
  }
  …(repeats verbatim 20 times)…
  …
  common foo {
    asdf(qwerty(i+k));
    printf(“%d”, (int)write); // cast to int
    bar();
  }
  …
And then you could `mycc diff-common foo` and see:

  :: common
  :: common
  …
  ::
    @@…@@
    -asdf(qwerty(i+j));
    +asdf(qwerty(i+k));
    @@…@@
    -printf(“%p”, write));
    +printf(“%d”, (int)write); // cast to int
With this you can track named common blocks (allows using surrounding context like i,j,k). Without them being functions and subject for functional entanglement $subj discusses. Most common code gets found out and divergences get bold. IDE support for immediate highlighting, snippeting and auto-common-ing similar code would be very nice.

Multi-patching common parts with easily reviewing the results would also be great. Because the bugs from calling a common function arise from the fact that you modify it and it suddenly works differently for some context. Well, you can comment a common block as fragile and then ignore it while patching:

  common foo {
    // @const: modified and fragile!
    …
  }
You still see differences but it doesn’t add in a multi-patch dialog.

Not expecting it to appear anywhere though, features like that are never considered. Maybe someone interested can feature it in circles? (without my name associated)

Re: John Carmack on inlined code (2014)

#56
post #53
post #38

Earlier quoted context omitted.

I really dislike how this principle ends up being used in practice. A good abstraction that makes actual sense is perfectly good even when it's used only once. On the other hand, the idea of deduplicating code by creating an indirection is often not worth it for long-term maintenance, and is precisely the kind of thing that will cause maintenance headaches and anti-patterns. For example: don't mix file system or low-…

I can't remember where I picked it up from, but nowadays I try to be mindful of when things are "accidentally" repeated and when they are "necessarily" repeated. Abstractions that encapsulate the latter tend to be a good idea regardless of how many times you've repeated a piece of code in practice.

Exactly, but distinguishing the two that requires an excellent understanding of the problem space, and can’t at all be figured out in the solution space (i.e., by only looking at the code). But less experienced people only look at the code. In theory, a thousand repetitions would be fine if each one encodes an independent bit of information in the problem space.

Re: John Carmack on inlined code (2014)

#57

His overall solution highlighted in the intro is that he's moved on from inlining and now does pure functional programming. Inlining is only relevant for him during IO or state changes which he does as minimally as possible and segregates this from his core logic. Pure functional programming is the bigger insight here that most programmers will just never understand why there's a benefit there. In fact most programme…

Some grasp it but see its trade-off contract, which is demanding.

Re: John Carmack on inlined code (2014)

#58

> Inlining functions also has the benefit of not making it possible to call the function from other places. I’ve really gone to town with this in Python. def parse_news_email(…): def parse_link(…): … def parse_subjet(…): … … If you are careful, you can rely on the outer function’s variables being available inside the inner functions as well. Something like a logger or a db connection can be passed in once and then us…

The latter pattern is very popular in Python web scraping and data parsing niches as the code is quite verbose and specific and I'm very happy with this approach. Easy to read and debug and the maintenance is naturally organized.

Re: John Carmack on inlined code (2014)

#59
There is actually a major problem with long functions - they take a long time to compile, due to superlinear complexity in computation time as a function of function length. In other words breaking up a large function into smaller function can greatly reduce compile times.

Re: John Carmack on inlined code (2014)

#60

There is actually a major problem with long functions - they take a long time to compile, due to superlinear complexity in computation time as a function of function length. In other words breaking up a large function into smaller function can greatly reduce compile times.

That honestly feels like a minor problem, and not something to optimize for. Also an aggressively inlining compiler will experience exactly the same problem. AFAIK at least clang always inlines a static (as in internal linkage) function if it's used only once in the translation unit, no matter how large it is.
Post reply on HN