Timeless wisdom from Kate once again. Thanks for this great talk! Every dev - no matter the language! - should watch and embrace this. On a personal note, I have to do lots of work for certifiable software, and most certification processes are inherently very, very hostile towards code refactorings. Effectively, refactorings are often too expensive to be made because while the tools do it in sub-seconds, the subsequent paperwork will take days or weeks. So often times, code is not allowed to be made better in the spirit of this talk, and that is an extremely unpleasant thing to experience.
Several important parts of this talk (meaningful names, short functions, caring about the reader of code, etc.) are very, very similar to "Clean Code" practices, as praised by Robert C. Martin a.k.a. Uncle Bob. While "Clean Code" mostly referred to Java, Kate's approach is C++ oriented - which I find very valuable. I was practicing clean code for over 3 years already, personally and with my students. And I can easily observe how much the quality of code improves. Especially my beautiful code ;) So go for it Kate! And big thanks for this wonderful talk :)
Clean Code isn't referred to Java. Uncle Bob's Clean Code and Clean Architecture is applicable to any language. He even talks about specifics of applying the techniques in different langauges.
I've often seen experienced developers writing a lot of hardly understandable and complex code along with a ten line comment that's even harder to understand. An attitude associated with this is that they think their code is great, because it "works" and nobody else is remotely able to understand it without spending a lot of time. That is detrimental to product development and team work. The real art is to write code that's simple yet capable of doing the job.
I work for someone who can't describe requirements simply and clearly. It's very rarely possible to implement those requirements except as a long list of special cases. Drawing little matrices of input conditions and program states leading to outputs seems to be required, and it gets messy. After 4 years I'm convinced that he doesn't exist in a systematic world (whether that matches external reality is largely irrelevant, I don't have access to it).
mozismobile That doesn't sound good. I'd recommend you talk to them and if that doesn't help, get out as soon as possible. You shouldn't be driven by someone's purely technical requirements even if they were well worked out. That external reality you describe should be the driver of your work and you should have access to it. Let me know if you need help. I'm sure we'll find a way to connect.
Yeah, thanks, but I think having someone else filtering customer requirements is a benefit to me. My code has to deal both with the internet and with people, so it's necessarily quite complex. Whether there exist simple rules describing any of the systems I deal with is only known when it's negative. Like "what can go in a UDP packet" where the answer is either "anything" or a long, long list of "if this then that" type rules.
@radbarij Yes, it's easy to say and hard to do in practice. That's the whole point of the video, isn't it? Feel free to demote "Simple yet capable of doing the job" or "As simple as possible, but not simpler" as "weasel words" if you like, but this is the only general thing one can really say to address your point. Everything else is problem-specific, hence writing simple code is hard work as outlined in the video.
This talk is great. There are two kinds of people who don't like it. Those who already do everything she says, and the talk really isn't for them, and those that like their complexity and don't think they need it...if they get thru it without being convinced, it probably isn't for them either. I knew a lot of these, but do I always DO them? No, and it makes a difference.
Recently i did finally use the immediately-invoked-lambda-initialisation. It was handling a user-input that sets some context-specific member-value - with the option of default-values and for different types. For tracing and styleguide we have to trace out the old and new value and the name of the member that was changed. It is not simple code but a dedicated function for a single-use object that requires several variables of the surrounding scope also seemed excessive. But sure as hell i want that "newValue" to be const as i had previously seen people doing a *"if(newValue = -1)"* and then wonder for ages why it does not work like they intended.
If you think your whole codebase needs to be rewritten, you have already lost. Instead, learn how to "Work Effectively With Legacy Code". As Kate said, that UpdateDatabase() function that might be 12,000 lines long doesn't need rewritten if it does it's job. It's effectively 0 lines long to you, the caller. *If* however, there's a bug in it and you need to change it, that's what you start identifying seams and making gentle refactorings; maybe get some characterizations tests in place first. Start sprouting functions or classes, maybe use "form method object" to tackle long functions, etc etc.
Great talk. In 20' I would add that "auto don't justify the absence of const" Moving from for( auto p: people) to for( auto& p: people) will not protect you from modifying p. If you need performance, don't forget correctness for( auto const& p: people) Another core rule "Don't forget const when using auto if you want immutability"?
Modifying p and auto are orthogonal. The first is a copy, and the second is a reference to the thing in the collection. Both are modifiable, just one has side effects. You can use const without auto.
I have done Simplicity a few times before. This was an expanded version and also a rearranged one. I think it's a lot better than the previous versions
For the const recommendation, at least give our Constificator plug-in a try (as part of the Cevelop IDE). It will recommend adding const where appropriate and do so for you.
This talk is about obvious things. Sad thing is that I'm keep seeing code which is in contradiction with this simple rules and when I'm pointing it out in code reviews I'm ignored :(. So we need more presentation like this, which in simple words explains why magic numbers are bad, why long functions are bad and so on.
like 4 minutes in and sure, teach what you're trying to teach. But the problem of not showing error checking is that NO ONE EVER TRIES TO TEACH ERROR CHECKING. Therefore, it's NEVER shown and no one ever learns it from others because it's simply not taught. Until it matters, hopefully. Agree with essentially everything else :) Not sure I agree invisible functions are 0 lines long but that's an issue when it's an issue or you want a challenge (that you're willing to verify your solution to) xD
I want to see a presentation on a console program that asks your name and says "hi $name". And then goes over the fuzzing, malicious input, unit testing exception handling...
const everything is really great until you accidentally prevent a copy elision. Don't const variables used as operands to return statements when their type matches the return type.
46:57 the conditions are not flipped. They *seem* to be flipped, but for floating point numbers, (x < 0 || x >= 0) is not generally true. Not considering Not-a-Number values is a serious mistake and a subtle cause of bugs. If you need (x > 0), use if (!(x > 0)) { errorRoutine(); } because (x
"chase the const" is when you try to identify where in your code a value is being changed when it wasn't supposed to be. if you add `const` to one spot and then re-run the code or re-test it, and your bug still appears or your values keep changing but in new and unexpected ways, then you have to keep trying to chase what changes and protect it with const as values and objects are passed from module to module. it's an argument in favor of 'const correctness,' which you have probably heard of. if not, read this to start: isocpp.org/wiki/faq/const-correctness
@ 38:00 + 39:37 She willfully ignores that one is clearly Windows platform specific C code , and the other is C++. @ 32:50 - She mentions a wall of variables at the top, and why didnt you assign when you declare? Because that comes from C.
C++ is a superset of C. A lot of older or poorly designed C++ codebases have either (1) legacy C code or (2) developers from a C background that wrote their code to be 'C with Classes'.
Your point is valid and I've added it to my slide notes. Both slides are live code (before and after) from a real project. Yes, the original used TRUE and FALSE and I switched it to true and false. It was Windows-specific, it was being compiled as C++, and I replaced it with C++ that was (at least in that function) no longer Windows-specific. That made the code better, which was my point with the two examples.
This is kind of why I hate the c++ community. It's utterly embarrassing that this room of experts needs such a basic talk. The standard library design is garbage, boost APIs are garbage. Pretty much every C++ book is full of garbage code too. If someone writes C++ and only C++ and has done it for a long time, there's a high chance that they just write garbage because they go through their careers without ever seeing a good example of professionalism. I do like Kate Gregory and enjoyed a lot of what she had to say but I agree with the guy's point at the end that seemed to go straight over her head. Architecture is required for testability. We don't abstract so we can switch out mythical production components. We abstract so we can mock. But the lack of decent unit testing and dependency injection infrastructure in the language and tooling means this isn't part of the consciousness in some parts of the community.
The mocking part really sucks for C++. I had to give up mocking because none of the frameworks are good, or the one that was good was unstable. I wish it was as easy as say Java. I also dislike the insanely and wildly varying code styles, they differ so much between projects that I feel like I'm reading a new language. I've never had this experience in any Java or C# project yet (and I do this for a living, though from a devil's advocate point of view I might have just worked at good places).
I totally agree that we continuously write simpler and simpler code, especially when the underlying system is inherently complex or would gain some precision or needed quality when being able to make it more deep. Generally, pushing 3 dimensional thing into 1 dimension of text is over simplification. I support that 1 dimension of code is self-explaining what i does, 1 is doing error checking, 1 is for debug output, 1 is for comments. Similarly this video is like billion codes in 1 dimension used to encode the idea, but pushing it to X & Y & t dimension, makes it shorter... Consists of language that the watcher knows, not some other language. Same with code - if your audience is old-skool embedded C gurus, it would feel overly verbose to write/read 1 screenful of code into 4 screenfuls for new-age high-level-lang / scripters or beginners audience. Not worth to write: variable_stored_in_stack_as_first_input + variable_stored_in_stack_as_second_input. a + b loses less of the meaning as reading time is limited too. There's a compromize making code longer or deeper. For example: if call stack is already 20 different functions deep, just to keep all function short and 10 lines long instead of 20 lines long and 10 levels deep...
Her course on coursera "Beautiful C++: STL algorithms" really changed the way I code C++ and made me appreciate it much more. Awesome talk!
it's on Pluralsight, I think
Timeless wisdom from Kate once again. Thanks for this great talk! Every dev - no matter the language! - should watch and embrace this. On a personal note, I have to do lots of work for certifiable software, and most certification processes are inherently very, very hostile towards code refactorings. Effectively, refactorings are often too expensive to be made because while the tools do it in sub-seconds, the subsequent paperwork will take days or weeks. So often times, code is not allowed to be made better in the spirit of this talk, and that is an extremely unpleasant thing to experience.
Several important parts of this talk (meaningful names, short functions, caring about the reader of code, etc.) are very, very similar to "Clean Code" practices, as praised by Robert C. Martin a.k.a. Uncle Bob. While "Clean Code" mostly referred to Java, Kate's approach is C++ oriented - which I find very valuable.
I was practicing clean code for over 3 years already, personally and with my students. And I can easily observe how much the quality of code improves. Especially my beautiful code ;)
So go for it Kate! And big thanks for this wonderful talk :)
The book was mentioned by an audience member in the end too :p
Clean Code isn't referred to Java. Uncle Bob's Clean Code and Clean Architecture is applicable to any language. He even talks about specifics of applying the techniques in different langauges.
Thank you for this talk. I'll buy pizza for my department and we'll be watching it together over an extended lunch.
Kate, you are a treasure
Love the way this woman simply presents the stuff! I am a simple man, love simple women, and i must learn simply simple things.
Brilliant talk. Clear, concise, well explained. Thanks, Kate.
I've often seen experienced developers writing a lot of hardly understandable and complex code along with a ten line comment that's even harder to understand. An attitude associated with this is that they think their code is great, because it "works" and nobody else is remotely able to understand it without spending a lot of time. That is detrimental to product development and team work. The real art is to write code that's simple yet capable of doing the job.
I work for someone who can't describe requirements simply and clearly. It's very rarely possible to implement those requirements except as a long list of special cases. Drawing little matrices of input conditions and program states leading to outputs seems to be required, and it gets messy. After 4 years I'm convinced that he doesn't exist in a systematic world (whether that matches external reality is largely irrelevant, I don't have access to it).
mozismobile That doesn't sound good. I'd recommend you talk to them and if that doesn't help, get out as soon as possible. You shouldn't be driven by someone's purely technical requirements even if they were well worked out. That external reality you describe should be the driver of your work and you should have access to it. Let me know if you need help. I'm sure we'll find a way to connect.
Not all algorithms can be implemented in a simple way.
Yeah, thanks, but I think having someone else filtering customer requirements is a benefit to me. My code has to deal both with the internet and with people, so it's necessarily quite complex. Whether there exist simple rules describing any of the systems I deal with is only known when it's negative. Like "what can go in a UDP packet" where the answer is either "anything" or a long, long list of "if this then that" type rules.
@radbarij Yes, it's easy to say and hard to do in practice. That's the whole point of the video, isn't it? Feel free to demote "Simple yet capable of doing the job" or "As simple as possible, but not simpler" as "weasel words" if you like, but this is the only general thing one can really say to address your point. Everything else is problem-specific, hence writing simple code is hard work as outlined in the video.
She is great, entertaining speaker, no doubt about it.
This talk is great. There are two kinds of people who don't like it. Those who already do everything she says, and the talk really isn't for them, and those that like their complexity and don't think they need it...if they get thru it without being convinced, it probably isn't for them either. I knew a lot of these, but do I always DO them? No, and it makes a difference.
Writing complex code requires experience, simplifying complex code requires mastery.
Recently i did finally use the immediately-invoked-lambda-initialisation.
It was handling a user-input that sets some context-specific member-value - with the option of default-values and for different types. For tracing and styleguide we have to trace out the old and new value and the name of the member that was changed. It is not simple code but a dedicated function for a single-use object that requires several variables of the surrounding scope also seemed excessive. But sure as hell i want that "newValue" to be const as i had previously seen people doing a *"if(newValue = -1)"* and then wonder for ages why it does not work like they intended.
I like it simple. It can be so easy. Great talk!
Absolutely awesome talk! Thanks!
Wonderful talk! Thank you :)
What a great and inspiring talk.
Your comment is very much appreciated.
A fantastic talk.
Good advice, very pleasant to watch and listen to.
The main question is how to convince the management that code base should be rewritten because it is not maintainable?
If you think your whole codebase needs to be rewritten, you have already lost. Instead, learn how to "Work Effectively With Legacy Code". As Kate said, that UpdateDatabase() function that might be 12,000 lines long doesn't need rewritten if it does it's job. It's effectively 0 lines long to you, the caller. *If* however, there's a bug in it and you need to change it, that's what you start identifying seams and making gentle refactorings; maybe get some characterizations tests in place first. Start sprouting functions or classes, maybe use "form method object" to tackle long functions, etc etc.
I like simplification too - "Make Simple Tasks Simple!" (c)
Clicked like button 1 minute because i know talk will be awesome!
Fantastic video Kate. Much stuffs for reflection.
I need more C++ talks!
So true. Great talk.
Ngl, the one thing i do when i use other people's libraries: i wrap them around to 1( Simplify it, 2) To make it fit my code style.
Great talk.
In 20' I would add that "auto don't justify the absence of const"
Moving from
for( auto p: people)
to
for( auto& p: people)
will not protect you from modifying p.
If you need performance, don't forget correctness
for( auto const& p: people)
Another core rule "Don't forget const when using auto if you want immutability"?
Modifying p and auto are orthogonal. The first is a copy, and the second is a reference to the thing in the collection. Both are modifiable, just one has side effects.
You can use const without auto.
Old talk, CppCon deserved a new talk from the great Kate...
She always does the same talk. Well, I think so, I can't watch to the end.
I have done Simplicity a few times before. This was an expanded version and also a rearranged one. I think it's a lot better than the previous versions
WalderFrey I buy
Taw Moto mlhumtuuiuok
For the const recommendation, at least give our Constificator plug-in a try (as part of the Cevelop IDE). It will recommend adding const where appropriate and do so for you.
This talk is about obvious things. Sad thing is that I'm keep seeing code which is in contradiction with this simple rules and when I'm pointing it out in code reviews I'm ignored :(. So we need more presentation like this, which in simple words explains why magic numbers are bad, why long functions are bad and so on.
like 4 minutes in and sure, teach what you're trying to teach. But the problem of not showing error checking is that NO ONE EVER TRIES TO TEACH ERROR CHECKING. Therefore, it's NEVER shown and no one ever learns it from others because it's simply not taught. Until it matters, hopefully.
Agree with essentially everything else :)
Not sure I agree invisible functions are 0 lines long but that's an issue when it's an issue or you want a challenge (that you're willing to verify your solution to) xD
I want to see a presentation on a console program that asks your name and says "hi $name". And then goes over the fuzzing, malicious input, unit testing exception handling...
const everything is really great until you accidentally prevent a copy elision. Don't const variables used as operands to return statements when their type matches the return type.
If u have mastered a certain language, her message is easily obvious without anyone teaching you
Walls vs fences: it's not a wall until your co-workers start blindly applying it during code review
But the logical "&&" is just great.
simple and simpler
46:57 the conditions are not flipped. They *seem* to be flipped, but for floating point numbers, (x < 0 || x >= 0) is not generally true. Not considering Not-a-Number values is a serious mistake and a subtle cause of bugs.
If you need (x > 0), use if (!(x > 0)) { errorRoutine(); } because (x
47:08 "it is a possible bug so tests will help you".
Care to try to apply this to assembly language? Or is that a pipe dream.
58:00 - what's 'chase the const'?
"chase the const" is when you try to identify where in your code a value is being changed when it wasn't supposed to be. if you add `const` to one spot and then re-run the code or re-test it, and your bug still appears or your values keep changing but in new and unexpected ways, then you have to keep trying to chase what changes and protect it with const as values and objects are passed from module to module.
it's an argument in favor of 'const correctness,' which you have probably heard of. if not, read this to start: isocpp.org/wiki/faq/const-correctness
@ 38:00 + 39:37 She willfully ignores that one is clearly Windows platform specific C code , and the other is C++.
@ 32:50 - She mentions a wall of variables at the top, and why didnt you assign when you declare? Because that comes from C.
C++ is a superset of C. A lot of older or poorly designed C++ codebases have either (1) legacy C code or (2) developers from a C background that wrote their code to be 'C with Classes'.
Your point is valid and I've added it to my slide notes. Both slides are live code (before and after) from a real project. Yes, the original used TRUE and FALSE and I switched it to true and false. It was Windows-specific, it was being compiled as C++, and I replaced it with C++ that was (at least in that function) no longer Windows-specific. That made the code better, which was my point with the two examples.
49:27 7/10 joke
This is kind of why I hate the c++ community. It's utterly embarrassing that this room of experts needs such a basic talk. The standard library design is garbage, boost APIs are garbage. Pretty much every C++ book is full of garbage code too. If someone writes C++ and only C++ and has done it for a long time, there's a high chance that they just write garbage because they go through their careers without ever seeing a good example of professionalism.
I do like Kate Gregory and enjoyed a lot of what she had to say but I agree with the guy's point at the end that seemed to go straight over her head. Architecture is required for testability. We don't abstract so we can switch out mythical production components. We abstract so we can mock. But the lack of decent unit testing and dependency injection infrastructure in the language and tooling means this isn't part of the consciousness in some parts of the community.
The mocking part really sucks for C++. I had to give up mocking because none of the frameworks are good, or the one that was good was unstable. I wish it was as easy as say Java.
I also dislike the insanely and wildly varying code styles, they differ so much between projects that I feel like I'm reading a new language. I've never had this experience in any Java or C# project yet (and I do this for a living, though from a devil's advocate point of view I might have just worked at good places).
disagree.
Simple, but TL;DW :lol:
I totally agree that we continuously write simpler and simpler code, especially when the underlying system is inherently complex or would gain some precision or needed quality when being able to make it more deep.
Generally, pushing 3 dimensional thing into 1 dimension of text is over simplification.
I support that 1 dimension of code is self-explaining what i does, 1 is doing error checking, 1 is for debug output, 1 is for comments.
Similarly this video is like billion codes in 1 dimension used to encode the idea, but pushing it to X & Y & t dimension, makes it shorter... Consists of language that the watcher knows, not some other language. Same with code - if your audience is old-skool embedded C gurus, it would feel overly verbose to write/read 1 screenful of code into 4 screenfuls for new-age high-level-lang / scripters or beginners audience.
Not worth to write: variable_stored_in_stack_as_first_input + variable_stored_in_stack_as_second_input. a + b loses less of the meaning as reading time is limited too.
There's a compromize making code longer or deeper. For example: if call stack is already 20 different functions deep, just to keep all function short and 10 lines long instead of 20 lines long and 10 levels deep...