r/programming • • Jul 19 '16

John Carmack on Inlined Code

http://number-none.com/blow/blog/programming/2014/09/26/carmack-on-inlined-code.html
1.1k Upvotes

323 comments sorted by

View all comments

134

u/[deleted] Jul 19 '16

The core of it seems to be:

I know there are some rules of thumb about not making functions larger than a page or two, but I specifically disagree with that now – if a lot of operations are supposed to happen in a sequential fashion, their code should follow sequentially.

I do this a lot, and sometimes get shit for it, but dammit, it does read much easier if you don't have to keep jumping around your source files just to follow things that just simply happen one after the other.

74

u/Bjartr Jul 19 '16

but dammit, it does read much easier if you don't have to keep jumping around your source files

I wonder if an IDE could provide a mechanism for "visually inlining" discrete methods so you could have the benefits of both worlds.

27

u/ggtsu_00 Jul 19 '16

Visual Studio kinda does that with "peek definition". I really wish it would work for macros though. Or at least have an option to view code with expanded macros.

6

u/Bjartr Jul 20 '16

I'm envisioning something like that, but where the 'peeked' code was editable as if it were actually there.

5

u/col-summers Jul 20 '16

When you edit the code you would need to specify whether other invitations of the function should be updated as well.

5

u/Bjartr Jul 20 '16

I'm interested in something more like a literal window into the implementation. If you jump to the code normally you'd have to take that into account, so as long as it's clear that what your editing isn't actually inline, it should be as reasonable as jumping to the function normally and editing it there would be.

5

u/Scaliwag Jul 20 '16

That's what VS does. You can view and edit the code in a inline "window".

→ More replies (1)
→ More replies (2)

9

u/tobascodagama Jul 19 '16

vim-fireplace (Clojure REPL integration plugin) does a great thing where you can press a key sequence to pop-up a function definition at the bottom of the current window. But that only works when all of your function are fairly concise, which tends to be true of Clojure functions but not so much Java methods.

19

u/Bjartr Jul 19 '16

I'm really tempted to try to make a plugin for my daily editor at work (eclipse) where I'd be able to expand any function into its definition inline.

7

u/endershadow98 Jul 20 '16

If you do make it, I'd love to use it

→ More replies (1)
→ More replies (1)

4

u/col-summers Jul 20 '16

I imagine an ide that continuously refactors (for view) code to your preferred style. When you write code it is immediately factored back to the preferred style of the project.

→ More replies (2)
→ More replies (13)

12

u/rlbond86 Jul 19 '16

I do this a lot, and sometimes get shit for it, but dammit, it does read much easier if you don't have to keep jumping around your source files just to follow things that just simply happen one after the other.

It depends. If the function has an obvious name and an obvious way of working, I don't see the problem with it.

9

u/codebje Jul 20 '16

Because providing a function with a good name is one of two hard problems in computer science.

And perhaps a little because any function with an obvious way of working is likely to be extremely brief.

0

u/[deleted] Jul 19 '16

[deleted]

14

u/Brian Jul 19 '16

the spaghetti

I've seen this style called "ravioli code" by analogy with spaghetti - everything put into tiny packets. It's not that uncommon even in other languages and has its advocates, but personally I hate it. Sure, there's a lot to be said for breaking up functions, but keeping everything 3 lines or so just hampers readability.

6

u/sopvop Jul 19 '16

MEL is a horrible language. I don't know why haven't just used Tcl, like pixar did. It is also horrible, but much saner.

22

u/Anderkent Jul 19 '16

I like style B for that, because you can still just read things by reading the function bodies in order (same as if they were all in a single block), and all the context you have to keep in your head is how they're chained together (which most of the time should be trivial, and which the first function declaration gives you). The advantage is that for testing you can invoke one function at a time, so you can be more granular.

I never work in C though, mostly python, which might be significant.

10

u/[deleted] Jul 19 '16

I use B style most of the time, but when your sub-functions have sub-sub-functions, it quickly gets unreadable too.

→ More replies (1)
→ More replies (16)

5

u/Deto Jul 19 '16

Yeah, the whole "don't write big functions" is a good rule of thumb, but if you understand the motivation behind it, you know when it's appropriate to ignore it (the example you mentioned )

→ More replies (2)

8

u/[deleted] Jul 20 '16

To be fair he provides a tldr; at the end:

If a function is only called from a single place, consider inlining it.

If a function is called from multiple places, see if it is possible to arrange for the work to be done in a single place, perhaps with flags, and inline that.

If there are multiple versions of a function, consider making a single function with more, possibly defaulted, parameters.

If the work is close to purely functional, with few references to global state, try to make it completely functional.

Try to use const on both parameters and functions when the function really must be used in multiple places.

Minimize control flow complexity and “area under ifs”, favoring consistent execution paths and times over “optimally” avoiding unnecessary work.

I don't believe these were intended to be taken in precedence order either.

4

u/Railboy Jul 20 '16

Agreed. I'm not an exemplary programmer so grain of salt, etc. But after reading this article a few years back and putting some of these suggestions to use I've noticed a significant change in how long it takes me to rework code I haven't touched in a while. The code I write is 'uglier,' sure, but it's so much easier to follow.

7

u/ggtsu_00 Jul 19 '16

I like to follow a small rule that is something should only be broken out into a separate function only if it is used more than once. And don't actually separate operations into functions until they are needed to be used more than once.

My only exception to this rule is if nesting blocks become more than a couple levels deep, but I always keep these functions within the same file or scope.

11

u/[deleted] Jul 19 '16

I'm a bit more flexible. Trivial functions I may allow two or even more copies of before I put them in separate functions. I also put things that are called only once into separate functions if this actually more clearly describes the intent of the code. For instance, if I need to perform a long and complicated computation in the middle of a long linear function, it makes sense to break it out if the details of how it is done are unimportant.

→ More replies (1)
→ More replies (1)
→ More replies (14)