Casey's programming methods and encapsulation

Well the main reason I was struggling a bit with it's use was the fact that I was always taught to reduce the scope of variables/data when possible, for the same reasons you don't want global variables.

This is the problem. We are "taught" WAY to much, and learn way to little from our own experience. That is probably less true in the Handmade Network, but definitely true in the universities and at most companies.

After 3 years I have finally stopped listening when other people tell me how to code, and only do what works well for me. For example, all my data are accessible everywhere, all the time, in a super struct.

My best advice is to stop listening when people tell you how to do things, and just code code code. You will, by default, find the best way to code for you.
For larger projects minimizing complexity is crucial and breaking your program into discrete black boxes (ideally) that communicate (through well defined interfaces) with as few of each other as necessary, should almost always be a priority.

Yes! And that is why we have functions :) Whey solve this problem easily. And you don't even need interfaces. Only function hierarchies.
forkingpaths
I think that this kind of discussion (using globals, private vs. public, etc) tend to generate a lot of "general aesthetic" opinions, because the langages at hand (here C/C++) are not really good at providing what we want in term of invariants.

All the arguments ultimately revolve around how we enforce invariants or "state consistency" in a program, so that we can reason about it. Eg. "you should use accessors and not touch global shared state to ensure your data are always in a consistent state", vs "you don't want the langage to get in your way, and you can be disciplined enough to not touch what you're not supposed to touch".


Using accessors vs. direct access could certainly fall under opinions on "general aesthetics", but that's really a red herring as most of the rest of the discussion has centered around program complexity and not aesthetics. And calling something an opinion on "general aesthetics" is simply an out of hand dismissal.


forkingpaths

C style doesn't help you much to enforce anything beside minimal type correctness, so it's easy to have wrong assmuptions about what the state of the program can be when a particular piece of code is executed, which is the cause of most subtle bugs.


That's a pretty major assertion, perhaps you mean "most subtle bugs [for you]". Everyone has different skillsets/strengths/ways of reasoning/etc. so the idea that what's the most common cause of bugs for me is going to be the most common cause of bugs for you and most other programmers seems totally unfounded.

forkingpaths
More often I would like features to enforce invariants at the function/block level ie. declaring which state can be touched in a particular block of code (eg captures/lambda/something to be invented) rather than declaring which state can be touched inside a particular block of data (private/public).

If we had semantics that allowed us to choose which invariants we want to be true inside a particular piece of code, there would be no point in all these "best practices" opinions, because you would declare the invariants you need to reason about your code, and the discussion could not be detached from that particular piece of code.


That may be fine for you but there are also plenty of people out there for whom reasoning about global state is not a major cause of bugs nor a major productivity drag, so discussions like this one would be a good candidate to fall under the heading of "general aesthetic" opinions.

And calling something an opinion on "general aesthetics" is simply an out of hand dismissal.

Oh, sorry if that sounded like a dismissal, it wasn't my intention. I'm just saying that, while interesting, it's hard to find a solid ground for this kind of discussion because we're left with non-optimal choices by the languages.

Everyone has different skillsets/strengths/ways of reasoning/etc. so the idea that what's the most common cause of bugs for me is going to be the most common cause of bugs for you and most other programmers seems totally unfounded.

Yeah, what I tried to emphasize is not really the idea that most bugs come from global state, but that most subtle bugs (or, hard to spot / understand...) come from the fact that you have some wrong assumption on the state of the program, which means that even if you reason logically from there, you can't see what happens because the assumptions are wrong. In this way it's more tricky than just a faulting logic.

That may be fine for you but there are also plenty of people out there for whom reasoning about global state is not a major cause of bugs nor a major productivity drag, so discussions like this one would be a good candidate to fall under the heading of "general aesthetic" opinions.

Exactly, I was just saying that the language should let you decide on which invariant you want to be enforced, and not decide on you behalf which kind of safety you need. No need to turn my own words around, which weren't meant to be rude anyway. Of course, everyone here is talking from their own point of view and no one is trying to impose their ideas ! If you do not experience this kind of needs at all, or are not subject to bugs related to wrong assumptions about the state of your programs, that's great : Tell us what's your approach to this type of complexity, tell us what kind of bugs bite you more often, what features you would need to prevent it, etc...
forkingpaths
Exactly, I was just saying that the language should let you decide on which invariant you want to be enforced, and not decide on you behalf which kind of safety you need. No need to turn my own words around, which weren't meant to be rude anyway. Of course, everyone here is talking from their own point of view and no one is trying to impose their ideas ! If you do not experience this kind of needs at all, or are not subject to bugs related to wrong assumptions about the state of your programs, that's great : Tell us what's your approach to this type of complexity, tell us what kind of bugs bite you more often, what features you would need to prevent it, etc...


Your clarifications definitely all make sense. A lot of subtleties get lost communicating across a forum.

C++ is obviously an abomination of a language (even if you like it), or at least that seems to be the consensus view around here. But so much of the criticism leveled against C is that it's lacking this or that and I can't help but to feel like so much of this is just people projecting their weaknesses onto the language. Like, I'm not good at X so I wish that C had Y to make X easier for me. A opposed to, well maybe I should get better at doing X. C is an awesomely robust language and there's really very little you can't do with it if you're industrious enough.
Yes, many times it boils down to practice and (a lot of) discipline. But I think we also want quick ways of "ensuring" that some assumptions hold true, as it frees us from keeping a large amount of contextual information in our head while reasoning about some part of the code. Eg. to get back to the public/private member discussion, you don't have to remember if this member has been touched in some weird way because you know its private. The "no globals" rule of thumb is a rather extreme version of this : you don't have to remember how you manage global state because there's none (although it carries its own price). It's not necessarily the kind of assumption I need, but I understand that it might facilitate some people's thought process.

I personally lean to a C style approach and try to be disciplined, because I find that C++/OOP style puts safeguards where I don't really need them. But sometimes I get lazy or I just forget something, and I get hurt by bugs that would be easy to spot and fix if I had a better way to specify invariants.
For instance, with a state-related bug, if I specified that these functions A and B are purely functional, I don't have to spend time investigating them and can concentrate on this other function C, where I specified that only these variables will be touched, etc... (Also maybe it's just me having a hard time remembering a lot of context in a sufficiently large code base, and I just need practice.)

A lot of subtleties get lost communicating across a forum.

Yeah, and English is not my native language, which doesn't help. I most certainly lack some sense of nuance compared to a native speaker, so don't be offended !

Edited by Martin Fouilleul on
forkingpaths
Yeah, and English is not my native language, which doesn't help. I most certainly lack some sense of nuance compared to a native speaker, so don't be offended !


You're more eloquent than a huge segment of the United States' population; I think miscommunications are simply due to the nature of text-based messaging. :)
I played devil's advocate with Jon on the the value of encapsulation. The resulting conversation may interest folks: http://handmadedev.show/ep-10-2016/ (section: 'On the utility of abstraction')

TL;DR: Abstractions help programmers temporarily forget details, and that can be useful. Some best practices on how to encapsulate, however, are questionable.

Edited by Abner Coimbre on
@Delix : Thanks ! :-)

I played devil's advocate with Jon on the the value of encapsulation. The resulting conversation may interest folks: http://handmadedev.show/ep-10-2016/ (section: 'On the utility of abstraction')

I almost forgot about this, I'm going to listen to it again ! Do you plan to make any new interview ?

Jon's talks on Jai are also very thought provoking about the other ways we might handle abstraction. One that got me very enthusiastic was his idea of block level lambdas, although i'm not sure if he meant "restrict access to said variables", "take a snapshot of said variables when the block is executed" or something closer to a closure. But anyway this is the kind of feature that could help making assumptions on your program while keeping it non encapsulated / unabstracted.

By the way, how's the compiler going ? :-)

I played devil's advocate with Jon on the the value of encapsulation. The resulting conversation may interest folks: http://handmadedev.show/ep-10-2016/ (section: 'On the utility of abstraction')

TL;DR: Abstractions help programmers temporarily forget details, and that can be useful. Some best practices on how to encapsulate, however, are questionable.

Thank you so much for this man. I've actually listened to a lot of Jon Blow's interviews and what I like about him is how he has this uncanny ability to explain complex topics in a very easy to understand way. What I also like is he seems to validate what I and I know a lot of other people tend to think when learning about programming, despite being taught the opposite.

For example, in that talk Jon talks about how abstractions, while vital, really only ever make a program more complex and this is something that must be taken into account by the programmer. At a certain point, more levels of abstraction really only obscure the purpose of that particular code and make things harder, not easier, to understand. This definitely goes against the grain of most C++ books and discussions which value abstraction/encapsulation as on of the main end goals of any particular piece of code and never really emphasize the trade-offs of doing so. I know in my experience, when trying to understand certain C++/OO code bases I tend to get completely lost in the abstractions and find things very difficult to follow.
boagz57
At a certain point, more levels of abstraction really only obscure the purpose of that particular code and make things harder, not easier, to understand. This definitely goes against the grain of most C++ books and discussions which value abstraction/encapsulation as on of the main end goals of any particular piece of code and never really emphasize the trade-offs of doing so. I know in my experience, when trying to understand certain C++/OO code bases I tend to get completely lost in the abstractions and find things very difficult to follow.


Keep in mind that most mainstream C++ books are targeted at the lowest common denominator, the average case (i.e. not very good) being programmers who are essentially cogs in some large company machinery. In this context the additional abstractions, guards rails, etc. may make perfect sense. Game engine programmers/expert programmers/lone wolfs/etc. fall well on the margins (or entirely outside of) the target audience of most of these kinds of mainstream books.
NelsonMandella
boagz57
At a certain point, more levels of abstraction really only obscure the purpose of that particular code and make things harder, not easier, to understand. This definitely goes against the grain of most C++ books and discussions which value abstraction/encapsulation as on of the main end goals of any particular piece of code and never really emphasize the trade-offs of doing so. I know in my experience, when trying to understand certain C++/OO code bases I tend to get completely lost in the abstractions and find things very difficult to follow.


Keep in mind that most mainstream C++ books are targeted at the lowest common denominator, the average case (i.e. not very good) being programmers who are essentially cogs in some large company machinery. In this context the additional abstractions, guards rails, etc. may make perfect sense. Game engine programmers/expert programmers/lone wolfs/etc. fall well on the margins (or entirely outside of) the target audience of most of these kinds of mainstream books.


True, but that does in no way mean that C++/OO is better, or even as good in huge codebases on huge companies. I have worked in several now, and ALL of them have in common that parts made in C (sometimes all of their code) are stable, fast, and reliable. The C++ parts are always slow buggy messes. This have been the rule in ALL of them so far.
forkingpaths

I almost forgot about this, I'm going to listen to it again ! Do you plan to make any new interview ?

New interviews aren't planned for now, but I do miss the live conversations. What I did this year was make sure the current ones have a proper home with references and annotations (thanks Miblo!)

forkingpaths

By the way, how's the compiler going ? :-)

Serious robustness / testing / debugging phase, and preparing for the long-awaited closed beta. Likely specific updates will happen again in 2018, though it's not me who would give them!

boagz57

What I also like is he seems to validate what I and I know a lot of other people tend to think when learning about programming, despite being taught the opposite.

It ties back to Nelson's remark, in that the people I interviewed fall well outside the margin of the target demographic these websites and books optimize for. But hey, if we don't like the existing online communities, we (literally) make our own ;)




Edited by Abner Coimbre on
Telash
NelsonMandella
boagz57
At a certain point, more levels of abstraction really only obscure the purpose of that particular code and make things harder, not easier, to understand. This definitely goes against the grain of most C++ books and discussions which value abstraction/encapsulation as on of the main end goals of any particular piece of code and never really emphasize the trade-offs of doing so. I know in my experience, when trying to understand certain C++/OO code bases I tend to get completely lost in the abstractions and find things very difficult to follow.


Keep in mind that most mainstream C++ books are targeted at the lowest common denominator, the average case (i.e. not very good) being programmers who are essentially cogs in some large company machinery. In this context the additional abstractions, guards rails, etc. may make perfect sense. Game engine programmers/expert programmers/lone wolfs/etc. fall well on the margins (or entirely outside of) the target audience of most of these kinds of mainstream books.


True, but that does in no way mean that C++/OO is better, or even as good in huge codebases on huge companies. I have worked in several now, and ALL of them have in common that parts made in C (sometimes all of their code) are stable, fast, and reliable. The C++ parts are always slow buggy messes. This have been the rule in ALL of them so far.


I used the word "may" because I have absolutely no idea wether or not its true, but I'm willing to remain open to the possibility despite my own personal skepticisms. As an example, certain subsets of C++ may very well be the optimal choice in terms of either productivity or maintainability when you're talking about organizations of 200-300 mediocre programmers working on a 2-5 million line project. But change one parameter, like make the programmers great, or shrink the organization size and C++ may become suboptimal. I'm merely speculating as to how one might conceive of such a problem, but my point is that its probably hard to generalize about what's optimal when it comes to large scale projects undertakes by organizations.

On a related note, I recently came across a very interest idea about how large projects often evolve to reflect the organizational structure that they grow out of. The rest of the video is near valueless in my opinion, full of common oop tropes and what you'd find in popular books more or less.
boagz57
I know in my experience, when trying to understand certain C++/OO code bases I tend to get completely lost in the abstractions and find things very difficult to follow.


AMMMMMEEEENNNNNNN..... I actually have an easier time understanding assembly many times...

Bad.

Edited by Todd on