> I have gotten much more bullish about pure functional programming, even in C/C++ where reasonable: (link) The link is no longer valid, I believe this is the article in question: https://www.gamedeveloper.com/programming/in-depth-functiona...
Probably the more important link. He's basically saying his old email is outdated and he does pure FP now.
John Carmack on inlined code (2014)
61–70 of 402 posts
Re: John Carmack on inlined code (2014)
#62> 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…
Re: John Carmack on inlined code (2014)
#63Earlier quoted context omitted.
Yes! I work with many folks objectively way younger and smarter than me. The two bad habits I try to break them of are abstractions and what ifs. They spend so much time chasing perfection that it negatively affects their output. Multiple times a day I find myself saying 'is that a realistic problem for our use case?' I don't blame them, it's admirable. But I feel like we need to teach YAGNI. Anymore I feel like a sa…
I’ve had the opposite experience before. As a young developer, there were a number of times where I advocated for doing something “the right way” instead of “the good enough way”, was overruled by seniors, and then later I had to fix a bug by doing it “the right way” like I’d wanted to in the first place. Doing it the right way from the start would have saved so much time.
I'm pretty long-in-the-tooth and feel like I've gone through 3 stages in my career:
1. Junior dev where everything was new, and did "the simplest thing that could possibly work" because I wasn't capable of anything else (I was barely capable of the simple thing).
2. Mid-experience, where I'd learned the basics and thought I knew everything. This is probably where I wrote my worst code: over-abstracted, using every cool language/library feature I knew, justified on the basis of "yeah, but it's reusable and will solve lots of stuff in future even though I don't know what it is yet".
3. Older and hopefully a bit wiser. A visceral rejection of speculative reuse as a justification for solving anything beyond the current problem. Much more focus on really understanding the underlying problem that actually needs solved: less interest in the latest and greatest technology to do that with, and a much larger appreciation of "boring technology" (aka stuff that's proven and reliable).
The focus on really understanding the problem tends to create more stable abstractions which do get reused. But that's emergent, not speculative ahead-of-time. There are judgements all the way through that: sometimes deciding to invest in more foundational code, but by default sticking to YAGNI. Most of all is seeing my value not as weilding techno armageddon, but solving problems for users and customers.
I still have a deep fascination with exploring and understanding new tech developments and techniques. I just have a much higher bar to adopting them for production use.
Re: John Carmack on inlined code (2014)
#64Earlier quoted context omitted.
Yes! I work with many folks objectively way younger and smarter than me. The two bad habits I try to break them of are abstractions and what ifs. They spend so much time chasing perfection that it negatively affects their output. Multiple times a day I find myself saying 'is that a realistic problem for our use case?' I don't blame them, it's admirable. But I feel like we need to teach YAGNI. Anymore I feel like a sa…
I’ve had the opposite experience before. As a young developer, there were a number of times where I advocated for doing something “the right way” instead of “the good enough way”, was overruled by seniors, and then later I had to fix a bug by doing it “the right way” like I’d wanted to in the first place. Doing it the right way from the start would have saved so much time.
There are always exceptions, but there's typically order of magnitude differences between globally doing "the right thing" vs "good enough" and going back to fix the few cases where "good enough" wasn't actually good enough.
Re: John Carmack on inlined code (2014)
#65When I first heard the maxim that an intelligent person should be able to hold two opposing thoughts at the same time, I was naive to think it meant weighing them for pros and cons. Over time I realized that it means balancing contradictory actions, and the main purpose of experience is knowing when to apply each. Concretely related to the topic, I've often found myself inlining short pieces of one-time code that mad…
You are probably reaching for Hegel’s concept of dialectical reconciliation
So, more like Heraclitus's union of opposites maybe if you really want to label it?
Re: John Carmack on inlined code (2014)
#66I think that summarizes the case pro inlining.
Re: John Carmack on inlined code (2014)
#67I 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)); @@…@@…
auto x = []{
/*...*/
return 5;
}();
There is/was an attempt to introduce a more of a first-class language construct for such immediate "block expressions":https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p28...
I'm not convinced that automatic checking of copy-paste errors of such blocks make much sense though. At least I think the false positive rate would be way too high.
Re: John Carmack on inlined code (2014)
#68> 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.
On visibility, one of the patterns I’ve always liked in Java is using package level visibility to limit functions to that code’s package and that packages tests, where they are in the same package (but possibly defined elsewhere.)
(This doesn’t help though with the reduction in argument verbosity, of course.)
Re: John Carmack on inlined code (2014)
#69His 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…
Re: John Carmack on inlined code (2014)
#70I 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)); @@…@@…