Here are the timecodes! Noisy Code 2:55 Unsustainable Spacing 10:44 Lego Naming 23:15 Underabstraction 31:25 Unencapsulated State 34:59 Getters and Setters 39:11 Uncohesive Tests 42:01
I've almost come to blows with arrogant programmers (one in particular, who complicated life for thousands of his customers) who insisted on the correctness of each of these. But this is the first time I've understood why I thought they were wrong. Thanks!
16:48 that is so true. I freaking hate that mentality. It's also a very common problem that's not only applicable to programming. If you write something that has the goal of being read and/or used by others, make sure they understand what you're trying to explain/accomplish with as little effort as possible. Thank you.
Minute 34:00 Code in the language of the domain. Comment: For example, use the hardware I/O signal names which are on the schematics in the code as constants or field names. Some people rename things unnecessarily making the connections harder to find. For example, code the mathematical formulas the same way users write their formulas, unless optimization is required. Use the same numerical units as the user in the code, again, unless optimization is required.
Many years ago while working with another team member to fix some broken code written by a dev who was let go, we ran across a try/catch block that ate an important error with a comment that said "Paula doesn't like this error". Holy hell.
Some of the points on indentation could be alleviated by mandating that everyone run an autoformatter before checking in... But that only works on teams that use a style that is amenable to autoformatting and even if they do, on legacy codebases it can be counterproductive to use autoformatters. :|
I kinda disagree on the exceptions. When reading through code a lot, you get used to seeing certain words, like "Exception". Then, when I have to form an impression about it, I see the word "Exception" in a class name somewhere, and I immediately get a quick and shallow perception of what it is doing; "This is an exception, here it winds up when something goes wrong. If I need to know exactly what went wrong, I can at any point read the full name of that class." I do not need to know or analyze the name "EntryPointNotFound" if I quickly see "Exception" as part of that word. It is four words I would have to put together in a sentence in my mind and make sense of it all, before I realize that it is an exception. All in all, great talk. Loved it!
If your code base is growing I think suffixes will be better. I prefer to set nice names for Domains, business logic and don't think about a nice name for Exception (I mean nice - without suffix).
The real reason most frameworks of any appreciable size (like .NET) use conventions like this is that they will often have several types related to the same concept, e.g. XyzException, XyzDescriptor, XyzEvent and in this context to not use a convention like consistent suffixes is, well to use Mr. Henney's words, unsustainable.
I prefer to have Exception as suffix to class name because it's easy for developers to discover at a glance which classes are exceptions when looking at a list of class names. It can save time.
Yes, it's established, but it's also useless. java.lang.IllegalArgumentException could easily do without the "Exception" and still be crystal-clear. Yes, you can instantiate an exception anywhere, like "Exception e = new IllegalArgumentException()", but it only really makes sense to either throw or catch an exception. This is not C++, where you can throw any kind of object or primitive, like strings or integers. There are very few exceptions in Java that become unclear when you remove the "Exception" from the name, with "NullPointerException" being the most obvious.
Yeh, in my code base (C++) I have a single TError class. I find that ultimately that works best, I can check if it's a specific error from a specific module (facility I call them) if desired. 99% of the time the catching code doesn't care what it is, it just wants to recover and continue, or clean up and re-throw. I think that the rule that exceptions should not be just a way to unwind the stack plays a part in this. I don't throw exceptions that are meant to be caught hardly ever, because that's then not an exception per se, it's a way to unwind the stack. There are some few legitimate places to do this, but not many, IMO. If you aren't throwing exceptions that are meant to be caught, then its a lot less likely anyone wants to to catch them by a specific type. Also, if you limit exceptions to purely exception situations, then you can use the debugger's 'stop on throw' mechanism very conveniently. Whereas if you are really using exceptions to unwind, you may be constantly hitting throws that are not really errors and so they are just annoying when debugging. If I hit a throw, it's 99.9% likely bad and something I want to stop and look at. Obviously you can derive all of your exceptions from a common exception class and catch via that common class. But I'm assuming that they get sliced in the catch if you do that? It's been so long since I looked at that that I don't remember.
Dmitriy Getman Interactive style isn't stupid. For somethings it is a very good idea. For Common Lisp style interactive (read: live) programming it is especially good to see how changes affect your program while it is running. It is also good for prototyping and exploratory programming. Common Lisp has the option of compilation, btw, which is great as it gives you the option for performant programs. However, to summarily disregarding something as stupid (and not respond meaningfully to comment. ie having intelligent discourse) means you are either a troll, or that my insight (or common sense) is just going to be wasted here. Ultimately you get to decide that.
Looking at the student code at kzclip.org/video/ZsHMHukIlJY/бейне.html for the RecentlyUsedList it looks like they didn't know about the [] operator or the Remove method, the rest of it more or less a different codestyle, but Kevlin for some reason also decided to change the order of the backing list, making items[0] to be the least recently used item instead of the most recently used that the student used, so he needs to do the whole items[Count - index - 1] shebang. The fixed student could would then be like Kevlins code but with Insert(0, newItem) instead of Add(newItem) and items[index] instead of his weirdness. Seems more readable to be honest.
Excellent talk... it covered many things I rant about that "other programmers" do..... and many of the things I do that the other programmers rant about when I'm not around.
I've wrote a lot of code following his best practice suggestions after writing a lot following his not so best notations. Certainly understand that pain of looking at some of those junk styles when some of my code base is over a decade old. Really though all that matters is that you pick a style that makes sense at a glance and stick with it. Also helps to remember we're all using wide screen monitors and most of us set our text to be roughly 36 pixels wide per character (9 or 10 with Lucidas, Consolas, Source Code Pro or similar semi-mono space fonts). We have the space, don't be afraid to use it.
I use a wide screen to split it into a bunch of panes, so I can see different related parts of code in a project at once. No sane person would use the horizontal space a wide display offers to fill it up with long lines. Long lines are hard to parse for the reader.
I disagree on the noise one. Well, not completely, but for better readability it can also make sense to point out obvious things like //class variables //Getters and setters //Constructors //public methods //private methods //general notes and testcode. The last section is mostly for yourself, but it doesn't hurt to include it. It's below all other stuff anyway. Also in some cases additional notes can make sense. Of course you shouldn't write too much, but some notes can help with the understanding of the code and when there are more complex things can tell the colleague how your way works. He'd figure out eventually but writing something like "//implementation of imaginary numbers" he knows what the code means and don't even has to try to understand it in many cases. Also it can make sense to explain some algorithms because they are based on what you thought and others think differently. This one is not unique to programming though. But of course you shouldn't use this as an excuse for sloppy code that's hard to read. Referring to getters and setters I always use what I need. Sometimes I need just a getter, sometimes both, sometimes just a setter and for many fields neither a getter, nor a setter. I thought that this is common practice. And why should I remove the word "get" or "set"? Sure, it has tons of meanings but in this case everyone knows what get and set means. Overall a nice presentation. But it had a lot of noise ;).
One of the reasons I like using python so much is because it fosters a small number of lines as well as enforced indentation. I can read my code a lot easier when I don't have to search through page after page.
Great talk! I don’t agree with everything, but I believe listening to and understanding the point of views (points of view?) of people with whom I disagree is just as important as listening to people with whom I agree. It’s the only way to open one’s self to new ideas. This talk has changed my views on several habits-I’m free to consume or discard whatever I believe to be valuable or invaluable. I don’t think he was saying, ”do away with comments”. I think he was saying don’t use comments to point out the obvious where your code should communicate on its own. Any developer knows comments are necessary to explain why something is being done, or what is being done if it just isn’t obvious. It happens. Sometimes I will write something that just isn’t clear to a passerby-I want them to understand what I am trying to do. Maybe they can write it a better way, and they can suggest a better solution. If anyone uses iOS beta versions, it’s also necessary to comment all the work-arounds for framework bugs :)
Comments are very useful when using DLLs. Is a user supposed to find out if the encapsulated list doesn't allow null values or duplicates via trial and error? When I'm using third party code, it is definitely easier if they over comment instead of under comment. What is obvious to the coder is not always obvious to the one reading the code.
Quick tip: always KEEP SLIDES ON SCREEN please! There's a reason a lecturer keep them visible, we need to be looking at them while listening to him. Unity-talks is a great example: slides full screen + small picture of a lecturer in a corner.
I agree with most of the ideas given (and have been applying them for decades). I had issues with a few of them.. some because the example was weak (even if the principle was valid, sometimes).. or they don't make sense in certain languages/contexts (e.g. how do you have a member variable named foo and a getter named foo, which returns variable foo's value? Even if the language allows it without collision, it would be very confusing).
i realize this is an old comment but perhaps other readers may appreciate this in c# a convention is to have the private variable start with underscore, and the property capitalized without underscore like this: private int _foo; public int Foo { get { return _foo; } }
I just forced all the colleagues with a gun to their head to use a common formatting engine. "Don't cry and beg for your life", I've said, "it will be better for all of you.. trust me". I'm glad I could share this story with you. We only got one day of Internet allowed here in a hospital for the criminally insane. They still use this common formatting engine at my prior workplace. They send me postcard with thanks every year.
Fantastic speech, really! :) I don't make many comments now days... my colleagues are on the same level as me, so as long as I name my functions and variables logically I see no reason for it. I can comment things like ajax requests and what I expect back or regexes maybe.
I liked some of the little quips and jokes. Interesting talk. Over-the-top complex naming and visual layout of code are important ideas that don't get discussed often enough.
Evolution of code finds its way. If it's to difficult to maintain it just gets abandoned and the software gets written from scratch. The process repeats over and over again. Some people see the absurdity and waste of resources in this as we just "reinvent the wheel"... This is what usually happens to open source projects. And that's why there are many wheels that do almost the same thing and not enough resources to maintain them.
I've seen production code (from a "Senior PHP Developer") that looks like the examples given here, including tests that just test individual methods. LOL. Another great talk. I learn so much from watching these videos. Thank you.
This tempts me to wonder whether it would be possible to actually derive a measure of 'signal to noise ratio' or 'cognitive load' for a body of code. It might take some experimentation, but I imagine it would be possible. I'd start with figuring out what other information is necessary to comprehend a given code file. Things like how many references to code defined in different places there are. If it uses 10 custom data types defined elsewhere, that's 10 references. Then weight that by the SnR of those declarations. So if your code, to be understood fully, requires consulting a great many other sources which likewise require consulting a great many other sources and so on before you actually get to enough 'meat' to comprehend the actual substance of exactly what the code is doing and how it is doing it, the score would be very low. Integrate that measure into an Eclipse plugin or something and see how peoples code changes when they've got a plugin evaluating it and telling them their code is 'substantial' or 'deplorable'. A dreadful amount of Java code in particular would receive cataclysmically bad scores, requiring you to venture through half a dozen large complex frameworks, hopping through a dozen levels of abstraction, understanding dozens of custom data types that provide almost nothing of substance just to grasp how a very simple operation is performed.
Except that 'number of references' is potentially a poor indicator. Just because I define my own class to handle something doesn't mean you need to understand the internals of that type -- if that type is clearly named and the properties, methods, etc. are as well. If I look at a code file and see a reference to some custom data type, but everything is properly named (And not overly-abstract), I can easily understand what is happening in the code I'm specifically interested in without needing to go look up the referenced type. If I, for example, see a class named Inventory in code that handles item movement in a game, I can easily picture what that Inventory class does (stores items, allows addition and removal of items, etc.), and don't really need to understand how it works internally. Especially if the methods are well-named and intuitive as well. Unfortunately, I have no more constructive ideas on what *could* be good metrics of SNR that could also be picked up by a program/plugin. The examples used in the talk have nothing to do with references and custom types. It's all about needlessly verbose code that could be shorter, with less logic.
On the topic of structuring his unit tests, how would it look when testing methods of a class? Any examples where he talks more in depth of this way of structuring it? I've always just stuck to the MethodName_TestingState_ExpectedBehavior but I can see where it is lacking.
Everyone should embrace _Elastic_ _Tabs_ for aligned indentation independent of symbol length. ... except that causes problems because not every editor that programmers on your team use support it.
Comments in code are for when you're fixing something, and only a hack will work, and you're explaining why the hack was necessary, and that you're really a good programmer, and are embarrassed by this hack, but it has to go in because time constraints. Honest.
Well, sometimes there are things that have to go in because your boss asks you to, but they're really wrong, but it just has to be that way, so I usually just write a comment that this HAS to be this way and it is "correct" just because...
He has a great sense of humor - I wondered at first if we just couldn't hear the audience laughing, but I have decided all but a handful must have been asleep, which is a shame!
but really, it's likely the language barrier. I see that all the time. english speaker in front of non-natives (with awful english). they look concentrated but they don't get half of it. trying to make a joke... a valiant effort
Hmm... I pretty much agree with everything except not having a getter and setter. If I have an container.Size() I usually think, "Size what?", I want to be explicit and know the action that we're performing, so I'm all in for container.getSize(). I think get and set in the context of programming have pretty refined and specific meaning, of course the people will have to know it first though. Of course you should only use get and set where it actually makes sense to do so. On another note, if it's a calculation, that can potentially take some time, and return type is a newly created value I might use a word "Calculate", for example "CalculateMatrix" on a 3D scene object. Some of the keywords I defined for myself over the years... Just as an example. "Update" for advancing simulations / managers, "Task" for multithreaded workloads, "Job" for individual workload within a "Task", "Manager" for an automated sub-system handling certain tasks, "Handle" for a managed object within a manager (usually used when destruction of the handle needs to inform some manager)...
the specific value I'll derive from this talk: show it to others that expect me to *justify* what I'm doing with better articulation than "why isn't all this _obvious_ to you?"
Excellent point about getters and setters. Objective-C uses the "no get for the getter" naming convention for properties, by the way. Also, FINALLY someone dares to declare what is THE visually correct way of arranging longish argument lists.
@Netherlands031 I disagree with how he used his examples to back up his reasoning for not using "get". He's playing word games. We withdrawMoney from an ATM, not only "getMoney". We "marry" someone, not only "get Married". A word game in the English language does not necessarily prove a contradiction to what we write in a program.
Nobody is stopping you from adding #{ and #} to your Python code, which, like formatters, should not be needed, as improper indentation doesn't run in Python 3 and Python 2 with the -tt switch. Code style 101 includes indentation and consistency.
Code becomes sensitive to leading spaces, which in turn results into errors and many will be very easy to miss, so it distracts. Editor side effects, perfectly fine or even greatly desired with other languages, became a source of error. Disallowing the coder control over formatting in a way that conveys real meaning is bad. It makes the language unworkable to anyone that knows what he's is doing and what a good way of conveying it is.
@meridjal In Python indentation affects the functional meaning of the code. It is possibly the worst mistake any language writer can make, just to get rid of the also visually useful { } brackets. Its like the typical Apple design, leave out what you need often and have others try to patch things up and work around it while they brag how great they are. This alone makes the whole language a no-go for me as this flags all the DO NOT EVER DO, language design 101 warning bells in my head. Python has sadly been adopted by a very interesting and hot domain, even if it is very far from the best choice. It is similar to using PHP for writing operating systems, just a bad mismatch. But as the subject is complicated, people tend to use libraries and thus the language they are written in, so it ain't going anywhere soon. I got some hope left its unsuitability will allow vastly different systems to eventually bring it down hard. But going away it never will, because there is code written in it. Even today there still runs COBOL and the like and coders in that language get well paid for what essentially is a mistake. The situation has bad incentives written over it, everywhere.
"There is one place to put your curly brackets...." the camera stays on Kevlin, who eventually clicks to the next slide and we never see the code. Nice.
It's below the parameters. It was shown briefly before he said that. Despite the bad rap about PHP, I learned to do it that way thanks to that language and PHP Mess Detector. It's much faster to count the parameters that way. You don"t have to parse entire lines of code.
Great talk but I just wanted to point out few things 29:00 I do agree that names should be simpler but exceptions should be the exceptions(haha). Exceptions are bad things and you don't want them. So you make them pop out like a sore thumb. They need to be verbose and unfriendly because people need to think twice when they see them. 35:20 Singletons are generally ad-hoc solutions for many cases but there are some cases that singletons are the most logical solution i.e. I/O. There is generally only 1 physical disk that the program has access to and it would be more confusing if there are several classes that handles I/O. 41:31 I prefer prepending "as" or "to" to the "hundredth" so it is clear that it is converting to something(or use a better language that supports property like C# or Kotlin) but I 100% agree that "get" is not the word.
22:54 My god I figured this out on my own in my first CS class, and I could never figure out why so many professionals and textbooks keep the opening curly bracket at the end of the last parameter
In JS, I use the following alignment for multi-argument parameter lists function foo( bar, baz, ) { // some code } This works great with ES2017's trailing function commas.
I have met many programmers who think that the more complicated the code looks, the better it must be. They make even the simplest things complicated, just so when you point out how inefficient it is, they can say, "you just don't understand it." I have come to believe that they are more invested in making sure no one can point out the flaws in their overcomplicated mess, than they are in actually solving the problem at hand. I have wasted a lot of time sifting through their code, just so I can point out exactly why it is bad, or where it goes wrong. All they are doing, is trying to hide the fact that they don't know what they are doing, and wasting their time, and my time, by trying to cover it up with layers and layers of unnecessary bullshit. In Hungarian, there is a way that they mock this behavior with a gesture, where you reach over your head to scratch the opposite side of your head, instead of just using the closer hand.
I dont think I've ever heard anyone, even a newbie who's only been coding several months maybe a year or so, say complicated looking code must be better.
"If you don't understand it, you should learn to read better -- it's not my job to make you understand it" said every really ugly code-writer ever. Victim-blaming is easier when they're OUR victims, because we never really cared about those people anyway. :-(
Hahaha yes. That German one is gold. I mean yeah this word appears to be kinda artificial but it's really awesome that you can string words together like that instead of getting all descriptive. This of that containing another thing vs thisthatcontainingy.
I have one I was watching the MS .NET Core two "experts" giving tuition on .NET Core 2 the other day. At the end they wrote a short loop to demo their new feature. One asked the other, "Shall we use 0 or 1 to start the index in the for loop?" the other replied "I am 0 person so lets go for 0". I screamed at the monitor and said no. It is not a mater or like, there is a logical reason behind it. If you are doing a loop counting real world objects, always use 1, since anyone reading and tracing the code can instantly workout the value is the real value and they do not need to add one to convert it. And guess what, when they compiled it they go an out of bound error and they said "Oh yes we need to subtract one". I was proven there and then. It is dangerous and unintuitive.
I feel like this is deep wisdom that will take years to process...I am intrigued, but probably only like the novice martial artist watching a 10th-Dan master practicing a routine...
34:47 I get that indexing can be not never clear, but ever since I switched over from Java to a non-strict OO language, it appears that getters and setters and the like are really just noise too. Take, for example, a vec3 class. Here is a bad example: pastebin.com/c4TQEh4N ... Here is a good example: pastebin.com/h7Ngnudu The difference between them is the getters and setters and making x y and z public rather than private. There is of no gain to make getter or setter leaf functions like this. It is only more typing or auto generation. A correct use case would be to process information in the getter or setter like seen in the magnitude function provided in each. This may leave you with the hunch of 'now I have to remember what is or isn't a function' which isn't an issue on its own, buuuut C# took a step and said, `here use these get and set and we will treat your inevitable function as a variable so you wouldn't have to be bothered` which has its ups and downs of masking what things do. When it comes down to having to do object.getThing(object2.readThing(object3.haveThing()))) You run into 2 problems. The first is you can't plainly tell that I have an extra closed bracket. Another is you now added more words to index what you are working with. Finally, they don't always match up... what the heck is haveThing()... oh a boolean? I much prefer object.things[object2.read(object.thing)] Especially with naming conventions for types, which helps when your popup or breadcrumbs takes 0.5-1 second to show anything useful. o1.aoThings[o2.read(o1.thing)]
An opening brace on its own line is a complete waste of vertical space, which is actually quite precious in terms of communicating information "by the screenful". If you doubt this, learn Python.
When Kevlin shows the Code replaced with only Xs to condense it to its the visual structure, the point however is that indentation matters the most. Putting the { at the end of a line starting a block does not break this rule. I'd say it's even clearer when the code introducing the block is the symmetrical counterpart to closing bracket at the end of an indented block.
Habits like putting Exception at the end of exception classes is to help programmers find exception classes in intellisense. Maybe we should learn other methods of finding classes than intellisense, like the object browser.
That should be an IDE issue, as in those that derive from Exception should show up when typing Exception Or maybe for it to work like C# attributes, where when you use it, it loses the "Attribute" suffix
In languages like C# combined with an IDE like Visual Studio, adding the word Exception to exceptions makes it possible for the programmer to discover exceptions within IntelliSense. You type in "throw" and a list of possible throwable things shows up. Type "Exception" and the IntelliSense list is filtered to only exceptions.
If you agree with everything I say, you weren't paying attention... I agreed with many of the things he said as most of them do make sense within some specific context. However, there are many things that I disagreed with... I'm self-taught in C/C++ and my main focus is within 3D Graphics Programming, Physics Simulations, Animations, etc. My next major interest is in Hardware Emulation still working in C/C++. Following that is a combination of Compiler Design and ISA Design(Assembler and Disassembler). This is just the software side of things... I also have an interest in the Hardware side of things which relates back to some aspects of the software side such as the ISA Design(Assembler and Disassembler) that focuses on the hardware design and implementation of the architecture. The final major topic of interest that I find myself looking into is A.I. programming and Machine Learning where I find myself diving into Python. I prefer to design and craft the backend portions of systems and applications as opposed to the front end such as Webpage development using JavaScript, HTML, CSS, etc... I like being closer to the metal with more control and with less abstraction, yet with just enough clarity to give my CPU or GPU the instructions that it requires to perform the tasks that I want. This now leads me to one of the biggest things that I do disagree with... The use of Singletons... If Singletons are designed properly and used within the appropriate contexts, they are very useful, powerful tools that also exhibit intent expressively. Considering that my main field of study and practice is within 3D Graphic and knowing that I will most likely be working in C++; I would design my application with a specific framework in mind. The main application or "user-front" will derive from an abstract base class which I just simply call "Engine"! If I have multiple engines for different things such as Sound, Graphics, I don't derive them from Engine to have `Engine::Graphics::Graphics()` as this is actually redundant. What I would typically do is have Graphics as its own object, Sound as its own object, Shaders as its own object, etc. The Engine class will contain all of those objects as the Engine is what Drives them all! Now, the Engine has to be able to store all of the Assets that are processed through those objects such as textures, sprites, fonts, models, skyboxes or skydomes, GUI elements, shaders, etc. which will give me various different types of collections and data structures from vectors to lists, to queues, dequeues, maps, multimaps, unorderedmaps, various kinds of tree structures such as BSP, Quad, and Octrees, a Scene Graph Tree structure that follows specific rules of what types of nodes can be nested under another, Batch processing, etc. With all of these integrated parts, I do and will have manager classes that specifically do just that but they are limited in number... I would typically have a TextureManager, FontManager, ShaderManager, AudioManager, AnimationManager as these classes are responsible for the storing of objects, checking if they already exist, return them when they are queried, removing them from the containers when they are no longer needed and cleaning up their memory, and to check if the data of the objects are in a valid state, has a valid range and domain. Now within my Engine class these are typically static pointers as all of these class derive from an abstract base class that is called Singleton. When this is designed properly, you can only ever instantiate one of those classes per application run. So if someone tried to do this: int main() { try { Application app(/*needed props*/); // Reminder: Application inherits from Engine and Engine is Abstract and is a Singleton! app.start(); // If you tried to do this: Application app2(/*needed props*/); // This will throw an exception because an Application object named app was already created during this application execution } catch(const std::exception& e ) { std::cerr
My primary use for comments is I'll wake up in the middle of the night with a solution get up program it for 10 or 15 minutes. Then go back to sleep wake up the next morning and look at the code and be dumbfounded. The comment is to remind why I did what I did. So far I've lucked out not one of these midnight half asleep programming excursions has been wrong. I honestly wish I could program as well when I am supposed to be awake as I do when I am half asleep. But once I've woken up and get what I did I delete the comments.
I agree with most of the comments here. Some good ideas followed up with truly awful and insufficient explanation, unclear examples and unnecessary waffling causing me to zone out despite being interested in the subject. Teaching clearly and succinctly is as much an art as programming is.
Very happy with his first point about curly brackets. Been doing that against a tide of comment and even insults for years. For exactly the reason he stated, it's visually meaningful. The best point made against it is however: that's not how WE do it. Where I am excluded as a part of WE for convenience. There is very little one can do about that. Being right isn't everything, in fact it's nothing. Enrolling others is way more powerful and I have failed to do so. I fear he has failed to do so too, but I live in hope.. For now my code gets reviewed with very strange metrics in mind. This is the main reason I like working alone :)
Use words like "exception" because you may know it's an exception but a future dev|debugger may not even know what "exception" is. Or be very explicit in your outputs with reference links to documentation
You definitely need code even if the code is clean. The code explains what you are doing. But sometimes it is not enough. You need to explain WHY are you doing that.
Some good points, but if everything he was ranting about was to be adopted then the resulting code would be a nightmare to work on as an outsider. Eg: We append "Exception" to an exception class so that it's function is immediately discernible when writing code within an IDE equipped with code sense.
had some good points & anecdotes. he's definitely right that you gotta disagree w/ him on some points. like 10:20 when he falls right into a classic "thinking you're right because you've used the word 'fallacy'," fallacy. obviously having somebody express in a more natural way their thought process would help them express the intent of their code - likely they'll even come up w/ a clearer refactor when commenting it. conceptually, writing comments for convoluted logic should frequently help both current & future developers, for the same basic reason we find whiteboards & wireframing tools useful
Anyway nice talk! Baaki sab common problems aap logon ki... but yeah I wud like to emphasize 'get' 'set' thing. Seen lot of codes even if not programmed anything... and seen that very stupid way of using these constructs... where they just not even required or nothing more than just some more noise in codebase in your terms. Even in famous standard libraries or renowned compiler implementations. The think best use of get set is to denote a situation where u specifically want to do processing during getting or setting value of some data. Whatever it maybe doesn't matter... could be simple check or some complex thing. But if u not doing it... then its just another senseless stupid noise. U can very easily get set data through '.' operator on object instance itself. What's the problem?... its straight forward clean code...at it should be or use to be in first place. But if u define a get set method compiler should enforce its implementation...and should complain that that method is still empty during build or in error, warning or pending log ...whatever... if it can handle live analysis. I mean this way its implementation makes some sense...it adds a new feature... otherwise its just nonsense I suppose. Which is the usual norm currently how contemporary compilers handle those things or coders codes things. I think compilers should sensibly address this lil issue. Using it just for the sake of it or like some more stupid alibi that u can access it through like this or that construct or way of accessing thing doesn't make much sense. It should add something to value than making just some more stupid clutter only. And that's nice way to gel old coding style with new.
adding a common suffix to a class makes it possible to find it in the repository and therefore enables programmers to reuse code the same for adding get and set, when you want to inspect an object and understand what it exposes, having a common prefix for all the methods that serve the same purpose makes it much easier
This is a symptom of the luxury of modern programming. No restraints on memory, execution speed, bandwidth, storage, etc, so we pontificate on the placement of white space. Brunelleschi, in the fifteenth century, built a double dome of bricks on an octagonal base, the largest ever constructed; Steve Jobs wanted the Pantone company to create a new beige for his Apple II casing. They had 2000 beiges already, but none of them was good enough for Steve.
Many different discussions about when To or NOT to write comments in code. I would rather see ZERO comments. Like I said, many discussions. But just like every child's question about "Why is the sky blue?" ends up with "Well, where did the Universe come from?"... so too does this discussion follow. And the end answer is Unit Tests. Your functional algorithms, where most comment enthusiasts REALLY push for comments, should be commented via its Unit Tests. a Unit Test method saying "If person throws corn then expect the sky to be blue". Your tests should explain your code. That becomes a Single Source of Truth.
Comments are for WHY, code is for HOW. When the code is too simple, it feels silly. But eventually you need them because otherwise readers waste time puzzling out WHY some things are the way they are. Your architecture decisions, your strange data structures, peculiar bugs.
@ernstig Since I wrote that comment - a year ago - I have read my share of papers. I still stand my position. Writing algorithms doesn't have much to do with writing applications. Both are very different fields. Therefore researchers are not qualified to teach any king of software development because they have never done it for a living. They only use programming at a syntactical level in order to express a calculation process. Most of the time it's pseudo code anyway.
@e-Sharp "researchers" invented most of the algorithms and wrote most of the successful programs you still use to this day. any researcher worth that name knows a lot more than just syntax
I would like to add to the things he said about the curly brackets, { and }. I have severe reading dyslexia. If you think he is making things up when it comes to readability, try again. Every time I see a code with curly brackets not on the same indentation for the same scope, I die a little of the sheer effort I must commit to in order to read just a few lines of code. Even though this effort practically disappears, if scopes are clearly made under the same indentation that makes it look far more uniform. Early exits help with this too, as long as it is in the very beginning of a function or method. Coding style matters dramatically for people with reading dyslexia, as it does not only effect them on natural language. I genuinely don't care about the quality of code as a reason to ask this of you.. I just want to be able to read your code without getting tired because the code is spatially all over the place.
I'm not at all dyslexic, but I can't stand opening curly brackets on the end of the previous line, either. The effort to look around to find where the block of code began is not worth the effort. My curly brackets have always lined up. It makes the code so much more readable.
24:50 - I'd argue that Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz is still a word, even if the law has been withdrawn. The fact that it no longer exits makes it no less of a word. That would be like arguing that "dinosaur" is no longer a word because there are no dinosaurs anymore.
True, but the word itself is not and was never the "longest word" in german. You can always make up a word that is longer, but still has some meaning and is valid grammatically.
Was expecting a horrible video judging from the comments, but was pleasantly surprised. This talk is great - informative and enjoyable. Sure, the video editing could have been better, but come on. You guys know that you can pause a KZclip video, right? Honestly, I had zero problems following despite the code samples not being 100% visible 100% of the time. And "too much noise"? I guess some people missed that it's a talk, not a textbook or lecture.
10:31 also I would disagree that a programmer who thinks his code might be hard to understand without comments couldn't do a better job using english or whatever spoken language he uses. If you're using some framework that relies on a lot of knowledge of its semantics or internals, comments really help a newcomer understand.
Example at 6:40 Left Side: Someone who clearly stopped learning C# at version 1.0. But Add-method is intuitive understandable. Right Side: Shorter, thanks to the use of higher integrated features. Needs the knowledge that Remove() ignores nonexistent items and the indexing operator throws by itself when out of bounds. Noise? Only relevant if someone does not use this as a black-box and has to maintain such code. In reality: Jim, he is dead! Let's use the next best library from XYZ that has a good rating and give a fuck about this one:) I know, I know. The librarians will hate me for this. But let's move to the next one:P
Slides for presentation: www.slideshare.net/Kevlin/seven-ineffective-coding-habits-of-many-programmers-69941600. They are not exactly one to one though
I disagree on the comment part. Yes, you can overdo comments and often they are just cluttering the environment with useless information. But they are actually useful for intellisense and peeking at references. People might get the wrong idea and eliminate them. Which is, in my opinion, bad practice if you're writing a lot of abstractions. Documentation blocks are absolutely necessary, inline comments are up for debate (but serve a function from time to time, when done correctly). Example: *// Code below equates to: a² + b² = c²* is actually useful information. The thing I actually find disgusting, when people use acronyms for everything AND don't even comment them
When I was younger I loved such videos. Each one of them was like a new revelation. "Yes! I always thought that way. This is so right." and so on. But then I start thinking if this is so good and obvious why there are still so many problems in this area? Nowadays I see too many issues with such talks. I will elaborate. First of all many points this guy has are kind of personal and more like a matter of taste. Trying to provide an argument to prove your taste is silly. Consistency is what matters. Another problem is that many points are laughably obvious. Seeing all these people seriously listening to the advice of not shitting without taking off your pants is just feels wrong. And the fact that it's happening is very very sad. And the most important thing. I strongly feel that these talks move people away from the real cause of the discussed problem. I will share my opinion on what it is. But I must say that this guy either does not understand it or is just hyping (like many others) on such problems. The fact that some codebases end up riddled with naming inconsistencies, redundant comments, misleading names, etc is because these lines of code were written by stupid developers who do not care. And unfortunately, there isn't much you can do about it. Doing this talk certainly won't change this a bit. You need what is called a "culture of programming" to avoid these problems. But to achieve that first you have to set a bar during the hiring process. Every project might have a unique culture but people who write bad code, don't see it and there's no potential for change. You need to share the same values with your colleagues for you to be effective as a whole. It is so easy and yet not many talk about it. I am not talking about the simply coding convention, development pipeline, etc. Feeling of what's right or wrong. Feeling of what's beautiful and what's ugly. Taste of what's good. Everything else will come to you naturally. Finding such a team or building your own is hard. This process is slow. It's not about just not seeing rationale as this dude thinks. It's about people being different. In conclusion, my key points would be: - Think about the common values of your team - Don't work with ineffective lazy idiots - Your's and your colleagues' uniqueness should not meddle with the consistency of the codebase - Use the same software tools and tweak them identically
Excellent points! “Bad programmers write bad code” is really a straightforward problem, but slow and difficult to solve, so consultants like to stay away from it. I still found plenty of great points in this talk, but the idea of “All we need to do is explain it again and again slowly and carefully - programmers will catch on” is provably false.
His final opinion on Curly Braces, which annoyingly flew by at 22:55, is a new line for Curly Braces. Which I personally find to be preferable and adds visual clarity imo. But I know Java and Javascript Devs may have a different opinion.
Here are the timecodes!
Noisy Code 2:55
Unsustainable Spacing 10:44
Lego Naming 23:15
Underabstraction 31:25
Unencapsulated State 34:59
Getters and Setters 39:11
Uncohesive Tests 42:01
You forgot about the ninja at 43:32
10:37 Mind the Gap (Scooter album)
Let's eat grandma! 7:50
I've almost come to blows with arrogant programmers (one in particular, who complicated life for thousands of his customers) who insisted on the correctness of each of these. But this is the first time I've understood why I thought they were wrong. Thanks!
16:48 that is so true. I freaking hate that mentality. It's also a very common problem that's not only applicable to programming. If you write something that has the goal of being read and/or used by others, make sure they understand what you're trying to explain/accomplish with as little effort as possible. Thank you.
Great lecture! Had me laughing out loud at times, and definitely changed my perspective on writing code. Thanks :D
Minute 34:00 Code in the language of the domain.
Comment:
For example, use the hardware I/O signal names which are on the schematics in the code as constants or field names. Some people rename things unnecessarily making the connections harder to find.
For example, code the mathematical formulas the same way users write their formulas, unless optimization is required. Use the same numerical units as the user in the code, again, unless optimization is required.
Many years ago while working with another team member to fix some broken code written by a dev who was let go, we ran across a try/catch block that ate an important error with a comment that said "Paula doesn't like this error". Holy hell.
Some of the points on indentation could be alleviated by mandating that everyone run an autoformatter before checking in... But that only works on teams that use a style that is amenable to autoformatting and even if they do, on legacy codebases it can be counterproductive to use autoformatters. :|
I kinda disagree on the exceptions. When reading through code a lot,
you get used to seeing certain words, like "Exception".
Then, when I have to form an impression about it,
I see the word "Exception" in a class name somewhere,
and I immediately get a quick and shallow perception of
what it is doing;
"This is an exception, here it winds up when something
goes wrong. If I need to know exactly what went wrong,
I can at any point read the full name of that class."
I do not need to know or analyze the name "EntryPointNotFound"
if I quickly see "Exception" as part of that word. It is four words
I would have to put together in a sentence in my mind
and make sense of it all, before I realize that it is an exception.
All in all, great talk. Loved it!
If your code base is growing I think suffixes will be better. I prefer to set nice names for Domains, business logic and don't think about a nice name for Exception (I mean nice - without suffix).
The real reason most frameworks of any appreciable size (like .NET) use conventions like this is that they will often have several types related to the same concept, e.g. XyzException, XyzDescriptor, XyzEvent and in this context to not use a convention like consistent suffixes is, well to use Mr. Henney's words, unsustainable.
I prefer to have Exception as suffix to class name because it's easy for developers to discover at a glance which classes are exceptions when looking at a list of class names. It can save time.
Yes, it's established, but it's also useless. java.lang.IllegalArgumentException could easily do without the "Exception" and still be crystal-clear. Yes, you can instantiate an exception anywhere, like "Exception e = new IllegalArgumentException()", but it only really makes sense to either throw or catch an exception. This is not C++, where you can throw any kind of object or primitive, like strings or integers. There are very few exceptions in Java that become unclear when you remove the "Exception" from the name, with "NullPointerException" being the most obvious.
Yeh, in my code base (C++) I have a single TError class. I find that ultimately that works best, I can check if it's a specific error from a specific module (facility I call them) if desired. 99% of the time the catching code doesn't care what it is, it just wants to recover and continue, or clean up and re-throw.
I think that the rule that exceptions should not be just a way to unwind the stack plays a part in this. I don't throw exceptions that are meant to be caught hardly ever, because that's then not an exception per se, it's a way to unwind the stack. There are some few legitimate places to do this, but not many, IMO. If you aren't throwing exceptions that are meant to be caught, then its a lot less likely anyone wants to to catch them by a specific type.
Also, if you limit exceptions to purely exception situations, then you can use the debugger's 'stop on throw' mechanism very conveniently. Whereas if you are really using exceptions to unwind, you may be constantly hitting throws that are not really errors and so they are just annoying when debugging. If I hit a throw, it's 99.9% likely bad and something I want to stop and look at.
Obviously you can derive all of your exceptions from a common exception class and catch via that common class. But I'm assuming that they get sliced in the catch if you do that? It's been so long since I looked at that that I don't remember.
Love the reaction shots of all the programmers just wishing he'd get to some point.
Best talk I've heard in a while.
It really changed how I think
about code.
@Mikko Räsänen in modern browsers you mean, and this comment is 2 years old.
@DarkMukke you can actually do LOT in modern CSS, before you hit the need to do JavaScript, if you should so please
Dmitriy Getman why brother?
this is your sarcasm right
Dmitriy Getman Interactive style isn't stupid. For somethings it is a very good idea. For Common Lisp style interactive (read: live) programming it is especially good to see how changes affect your program while it is running. It is also good for prototyping and exploratory programming. Common Lisp has the option of compilation, btw, which is great as it gives you the option for performant programs. However, to summarily disregarding something as stupid (and not respond meaningfully to comment. ie having intelligent discourse) means you are either a troll, or that my insight (or common sense) is just going to be wasted here. Ultimately you get to decide that.
Looking at the student code at kzclip.org/video/ZsHMHukIlJY/бейне.html for the RecentlyUsedList it looks like they didn't know about the [] operator or the Remove method, the rest of it more or less a different codestyle, but Kevlin for some reason also decided to change the order of the backing list, making items[0] to be the least recently used item instead of the most recently used that the student used, so he needs to do the whole items[Count - index - 1] shebang. The fixed student could would then be like Kevlins code but with Insert(0, newItem) instead of Add(newItem) and items[index] instead of his weirdness. Seems more readable to be honest.
One of my top concerns with coding is nomenclature and structuring. Haven't finished the vid but I think its going in a way I will like.
Excellent talk... it covered many things I rant about that "other programmers" do..... and many of the things I do that the other programmers rant about when I'm not around.
I've wrote a lot of code following his best practice suggestions after writing a lot following his not so best notations. Certainly understand that pain of looking at some of those junk styles when some of my code base is over a decade old.
Really though all that matters is that you pick a style that makes sense at a glance and stick with it. Also helps to remember we're all using wide screen monitors and most of us set our text to be roughly 36 pixels wide per character (9 or 10 with Lucidas, Consolas, Source Code Pro or similar semi-mono space fonts). We have the space, don't be afraid to use it.
I use a wide screen to split it into a bunch of panes, so I can see different related parts of code in a project at once. No sane person would use the horizontal space a wide display offers to fill it up with long lines. Long lines are hard to parse for the reader.
What about when I am coding on production in vi? I joke I joke..I kid I kid...
I disagree on the noise one.
Well, not completely, but for better readability it can also make sense to point out obvious things like //class variables //Getters and setters //Constructors //public methods //private methods //general notes and testcode. The last section is mostly for yourself, but it doesn't hurt to include it. It's below all other stuff anyway.
Also in some cases additional notes can make sense. Of course you shouldn't write too much, but some notes can help with the understanding of the code and when there are more complex things can tell the colleague how your way works. He'd figure out eventually but writing something like "//implementation of imaginary numbers" he knows what the code means and don't even has to try to understand it in many cases.
Also it can make sense to explain some algorithms because they are based on what you thought and others think differently. This one is not unique to programming though. But of course you shouldn't use this as an excuse for sloppy code that's hard to read.
Referring to getters and setters I always use what I need. Sometimes I need just a getter, sometimes both, sometimes just a setter and for many fields neither a getter, nor a setter. I thought that this is common practice.
And why should I remove the word "get" or "set"? Sure, it has tons of meanings but in this case everyone knows what get and set means.
Overall a nice presentation. But it had a lot of noise ;).
One of the reasons I like using python so much is because it fosters a small number of lines as well as enforced indentation. I can read my code a lot easier when I don't have to search through page after page.
until some jokester sets your .vimrc file to interpret tabs as 8 spaces! :-O
Great talk! I don’t agree with everything, but I believe listening to and understanding the point of views (points of view?) of people with whom I disagree is just as important as listening to people with whom I agree. It’s the only way to open one’s self to new ideas. This talk has changed my views on several habits-I’m free to consume or discard whatever I believe to be valuable or invaluable.
I don’t think he was saying, ”do away with comments”. I think he was saying don’t use comments to point out the obvious where your code should communicate on its own. Any developer knows comments are necessary to explain why something is being done, or what is being done if it just isn’t obvious. It happens. Sometimes I will write something that just isn’t clear to a passerby-I want them to understand what I am trying to do. Maybe they can write it a better way, and they can suggest a better solution.
If anyone uses iOS beta versions, it’s also necessary to comment all the work-arounds for framework bugs :)
Ugh. My new line whitespace between paragraphs wasn’t preserved when posting my comment above.
Comments are very useful when using DLLs. Is a user supposed to find out if the encapsulated list doesn't allow null values or duplicates via trial and error? When I'm using third party code, it is definitely easier if they over comment instead of under comment. What is obvious to the coder is not always obvious to the one reading the code.
Quick tip: always KEEP SLIDES ON SCREEN please! There's a reason a lecturer keep them visible, we need to be looking at them while listening to him.
Unity-talks is a great example: slides full screen + small picture of a lecturer in a corner.
I agree with most of the ideas given (and have been applying them for decades). I had issues with a few of them.. some because the example was weak (even if the principle was valid, sometimes).. or they don't make sense in certain languages/contexts (e.g. how do you have a member variable named foo and a getter named foo, which returns variable foo's value? Even if the language allows it without collision, it would be very confusing).
i realize this is an old comment but perhaps other readers may appreciate this
in c# a convention is to have the private variable start with underscore, and the property capitalized without underscore
like this:
private int _foo;
public int Foo
{
get
{
return _foo;
}
}
I just forced all the colleagues with a gun to their head to use a common formatting engine. "Don't cry and beg for your life", I've said, "it will be better for all of you.. trust me". I'm glad I could share this story with you. We only got one day of Internet allowed here in a hospital for the criminally insane. They still use this common formatting engine at my prior workplace. They send me postcard with thanks every year.
Thank you ever so much for an engaging, illuminating and beautifully delivered talk, Kevlin.
Fantastic speech, really! :)
I don't make many comments now days... my colleagues are on the same level as me, so as long as I name my functions and variables logically I see no reason for it. I can comment things like ajax requests and what I expect back or regexes maybe.
I've seen several presentations about coding habits. This is by far the best.
I liked some of the little quips and jokes. Interesting talk. Over-the-top complex naming and visual layout of code are important ideas that don't get discussed often enough.
Cool, I guess I independently discovered this and fixed it in my code years ago. Good to know I'm not the only one noticing this problem.
Evolution of code finds its way. If it's to difficult to maintain it just gets abandoned and the software gets written from scratch. The process repeats over and over again. Some people see the absurdity and waste of resources in this as we just "reinvent the wheel"... This is what usually happens to open source projects. And that's why there are many wheels that do almost the same thing and not enough resources to maintain them.
I've seen production code (from a "Senior PHP Developer") that looks like the examples given here, including tests that just test individual methods. LOL. Another great talk. I learn so much from watching these videos. Thank you.
在英语中释义最多的单词前三里,get 和 set 这两个词占据了两个位置,把 get 的释义全部列出来的话,可以占据35页的空间。很多开发者在代码中大量使用这两个词,觉得这像是英语的惯例,而且两个看似互为反义的两个词用起来很和谐……并不,从语言学的方面来讲,set 的反义词是 reset 或是 unset。不过在某些条件下,人们让他们的 IDE 自动把 getter 或是 setter 整合在代码里,这听上去很棒,错误的事情被迅速完成了,而人类还能对此避重就轻。大部分情况下,我们的对象内需要一个 getter 但并不需要一个 setter,此外我们应该摆脱这两个单词,因为在英语中「get something」通常会产生一些深远的副影响。
Thanks for sharing. T-SQL, or general SQL code formatting best practices would be appreciated.
THANK you for mentioning argument lists, I was always dissatisfied with lining the arguments up on the right
This tempts me to wonder whether it would be possible to actually derive a measure of 'signal to noise ratio' or 'cognitive load' for a body of code. It might take some experimentation, but I imagine it would be possible. I'd start with figuring out what other information is necessary to comprehend a given code file. Things like how many references to code defined in different places there are. If it uses 10 custom data types defined elsewhere, that's 10 references. Then weight that by the SnR of those declarations. So if your code, to be understood fully, requires consulting a great many other sources which likewise require consulting a great many other sources and so on before you actually get to enough 'meat' to comprehend the actual substance of exactly what the code is doing and how it is doing it, the score would be very low.
Integrate that measure into an Eclipse plugin or something and see how peoples code changes when they've got a plugin evaluating it and telling them their code is 'substantial' or 'deplorable'. A dreadful amount of Java code in particular would receive cataclysmically bad scores, requiring you to venture through half a dozen large complex frameworks, hopping through a dozen levels of abstraction, understanding dozens of custom data types that provide almost nothing of substance just to grasp how a very simple operation is performed.
Except that 'number of references' is potentially a poor indicator. Just because I define my own class to handle something doesn't mean you need to understand the internals of that type -- if that type is clearly named and the properties, methods, etc. are as well. If I look at a code file and see a reference to some custom data type, but everything is properly named (And not overly-abstract), I can easily understand what is happening in the code I'm specifically interested in without needing to go look up the referenced type.
If I, for example, see a class named Inventory in code that handles item movement in a game, I can easily picture what that Inventory class does (stores items, allows addition and removal of items, etc.), and don't really need to understand how it works internally. Especially if the methods are well-named and intuitive as well.
Unfortunately, I have no more constructive ideas on what *could* be good metrics of SNR that could also be picked up by a program/plugin. The examples used in the talk have nothing to do with references and custom types. It's all about needlessly verbose code that could be shorter, with less logic.
On the topic of structuring his unit tests, how would it look when testing methods of a class? Any examples where he talks more in depth of this way of structuring it? I've always just stuck to the MethodName_TestingState_ExpectedBehavior but I can see where it is lacking.
Everyone should embrace _Elastic_ _Tabs_ for aligned indentation independent of symbol length.
... except that causes problems because not every editor that programmers on your team use support it.
...or just use spaces which look the same in every browser and IDE.
Comments in code are for when you're fixing something, and only a hack will work, and you're explaining why the hack was necessary, and that you're really a good programmer, and are embarrassed by this hack, but it has to go in because time constraints. Honest.
Well, sometimes there are things that have to go in because your boss asks you to, but they're really wrong, but it just has to be that way, so I usually just write a comment that this HAS to be this way and it is "correct" just because...
😂😂😂 I am offended because this makes so much sense
He has a great sense of humor - I wondered at first if we just couldn't hear the audience laughing, but I have decided all but a handful must have been asleep, which is a shame!
but really, it's likely the language barrier. I see that all the time. english speaker in front of non-natives (with awful english). they look concentrated but they don't get half of it. trying to make a joke... a valiant effort
perhaps there were many germans in the audience. germans know, when they laugh, they sound frighteningly sinister.
:)
Theres some concepts he touches on that I have never heard mentioned anywhere.
Hmm... I pretty much agree with everything except not having a getter and setter.
If I have an container.Size() I usually think, "Size what?", I want to be explicit and know the action that we're performing, so I'm all in for container.getSize().
I think get and set in the context of programming have pretty refined and specific meaning, of course the people will have to know it first though.
Of course you should only use get and set where it actually makes sense to do so.
On another note, if it's a calculation, that can potentially take some time, and return type is a newly created value I might use a word "Calculate", for example "CalculateMatrix" on a 3D scene object.
Some of the keywords I defined for myself over the years... Just as an example.
"Update" for advancing simulations / managers, "Task" for multithreaded workloads, "Job" for individual workload within a "Task", "Manager" for an automated sub-system handling certain tasks, "Handle" for a managed object within a manager (usually used when destruction of the handle needs to inform some manager)...
the specific value I'll derive from this talk: show it to others that expect me to *justify* what I'm doing with better articulation than "why isn't all this _obvious_ to you?"
Excellent point about getters and setters. Objective-C uses the "no get for the getter" naming convention for properties, by the way. Also, FINALLY someone dares to declare what is THE visually correct way of arranging longish argument lists.
@Netherlands031 I disagree with how he used his examples to back up his reasoning for not using "get". He's playing word games. We withdrawMoney from an ATM, not only "getMoney". We "marry" someone, not only "get Married". A word game in the English language does not necessarily prove a contradiction to what we write in a program.
Nobody is stopping you from adding #{ and #} to your Python code, which, like formatters, should not be needed, as improper indentation doesn't run in Python 3 and Python 2 with the -tt switch. Code style 101 includes indentation and consistency.
Code becomes sensitive to leading spaces, which in turn results into errors and many will be very easy to miss, so it distracts. Editor side effects, perfectly fine or even greatly desired with other languages, became a source of error.
Disallowing the coder control over formatting in a way that conveys real meaning is bad. It makes the language unworkable to anyone that knows what he's is doing and what a good way of conveying it is.
'it rings language design 101 bells in my head' is not really an argument, why is indentation instead of braces bad again?
@meridjal
In Python indentation affects the functional meaning of the code. It is possibly the worst mistake any language writer can make, just to get rid of the also visually useful { } brackets. Its like the typical Apple design, leave out what you need often and have others try to patch things up and work around it while they brag how great they are.
This alone makes the whole language a no-go for me as this flags all the DO NOT EVER DO, language design 101 warning bells in my head.
Python has sadly been adopted by a very interesting and hot domain, even if it is very far from the best choice. It is similar to using PHP for writing operating systems, just a bad mismatch. But as the subject is complicated, people tend to use libraries and thus the language they are written in, so it ain't going anywhere soon.
I got some hope left its unsuitability will allow vastly different systems to eventually bring it down hard. But going away it never will, because there is code written in it. Even today there still runs COBOL and the like and coders in that language get well paid for what essentially is a mistake. The situation has bad incentives written over it, everywhere.
"There is one place to put your curly brackets...." the camera stays on Kevlin, who eventually clicks to the next slide and we never see the code. Nice.
It's below the parameters. It was shown briefly before he said that.
Despite the bad rap about PHP, I learned to do it that way thanks to that language and PHP Mess Detector. It's much faster to count the parameters that way. You don"t have to parse entire lines of code.
I caught it. And he's right... you need to put them exactly where I put them - in the correct place.
its at 22:55, just pause the video! :)
🙂
Well I got it - watch again
Great talk but I just wanted to point out few things
29:00 I do agree that names should be simpler but exceptions should be the exceptions(haha). Exceptions are bad things and you don't want them. So you make them pop out like a sore thumb. They need to be verbose and unfriendly because people need to think twice when they see them.
35:20 Singletons are generally ad-hoc solutions for many cases but there are some cases that singletons are the most logical solution i.e. I/O. There is generally only 1 physical disk that the program has access to and it would be more confusing if there are several classes that handles I/O.
41:31 I prefer prepending "as" or "to" to the "hundredth" so it is clear that it is converting to something(or use a better language that supports property like C# or Kotlin) but I 100% agree that "get" is not the word.
22:54 My god I figured this out on my own in my first CS class, and I could never figure out why so many professionals and textbooks keep the opening curly bracket at the end of the last parameter
A line less is why. But I agree. It makes code (and scopes) more readable.
You put the word 'exception' in exceptions so that you can pull up a list of all the exceptions in your autocompleting IDE.
In JS, I use the following alignment for multi-argument parameter lists
function foo(
bar,
baz,
) {
// some code
}
This works great with ES2017's trailing function commas.
I have met many programmers who think that the more complicated the code looks, the better it must be. They make even the simplest things complicated, just so when you point out how inefficient it is, they can say, "you just don't understand it."
I have come to believe that they are more invested in making sure no one can point out the flaws in their overcomplicated mess, than they are in actually solving the problem at hand. I have wasted a lot of time sifting through their code, just so I can point out exactly why it is bad, or where it goes wrong. All they are doing, is trying to hide the fact that they don't know what they are doing, and wasting their time, and my time, by trying to cover it up with layers and layers of unnecessary bullshit.
In Hungarian, there is a way that they mock this behavior with a gesture, where you reach over your head to scratch the opposite side of your head, instead of just using the closer hand.
I dont think I've ever heard anyone, even a newbie who's only been coding several months maybe a year or so, say complicated looking code must be better.
dunning kruger effect,
like when people say coding is easy shortly after just starting because they know how to write a simple console app.
"An idiot admires complexity, a genius, admires simplicity" - Terry Davis.
"If you don't understand it, you should learn to read better -- it's not my job to make you understand it"
said every really ugly code-writer ever.
Victim-blaming is easier when they're OUR victims, because we never really cared about those people anyway.
:-(
Comment is hilarious and mildly informative. You got my upvote.
Hahaha yes. That German one is gold. I mean yeah this word appears to be kinda artificial but it's really awesome that you can string words together like that instead of getting all descriptive. This of that containing another thing vs thisthatcontainingy.
I have one
I was watching the MS .NET Core two "experts" giving tuition on .NET Core 2 the other day. At the end they wrote a short loop to demo their new feature. One asked the other, "Shall we use 0 or 1 to start the index in the for loop?" the other replied "I am 0 person so lets go for 0". I screamed at the monitor and said no. It is not a mater or like, there is a logical reason behind it. If you are doing a loop counting real world objects, always use 1, since anyone reading and tracing the code can instantly workout the value is the real value and they do not need to add one to convert it. And guess what, when they compiled it they go an out of bound error and they said "Oh yes we need to subtract one". I was proven there and then. It is dangerous and unintuitive.
I feel like this is deep wisdom that will take years to process...I am intrigued, but probably only like the novice martial artist watching a 10th-Dan master practicing a routine...
This guy is my absolute favourite
For someone that believes in using words to convey meaning, I very succinctly learned he loves hearing himself talk.
Brilliant talk!
34:47
I get that indexing can be not never clear, but ever since I switched over from Java to a non-strict OO language, it appears that getters and setters and the like are really just noise too. Take, for example, a vec3 class. Here is a bad example: pastebin.com/c4TQEh4N ... Here is a good example: pastebin.com/h7Ngnudu
The difference between them is the getters and setters and making x y and z public rather than private. There is of no gain to make getter or setter leaf functions like this. It is only more typing or auto generation. A correct use case would be to process information in the getter or setter like seen in the magnitude function provided in each. This may leave you with the hunch of 'now I have to remember what is or isn't a function' which isn't an issue on its own, buuuut C# took a step and said, `here use these get and set and we will treat your inevitable function as a variable so you wouldn't have to be bothered` which has its ups and downs of masking what things do.
When it comes down to having to do
object.getThing(object2.readThing(object3.haveThing())))
You run into 2 problems. The first is you can't plainly tell that I have an extra closed bracket. Another is you now added more words to index what you are working with. Finally, they don't always match up... what the heck is haveThing()... oh a boolean?
I much prefer
object.things[object2.read(object.thing)]
Especially with naming conventions for types, which helps when your popup or breadcrumbs takes 0.5-1 second to show anything useful.
o1.aoThings[o2.read(o1.thing)]
Amazing, one of my favorites
K&R solved the { question in their book when they said it was put at the end to save space for printing, but did not recommend it as a coding style.
An opening brace on its own line is a complete waste of vertical space, which is actually quite precious in terms of communicating information "by the screenful". If you doubt this, learn Python.
When Kevlin shows the Code replaced with only Xs to condense it to its the visual structure, the point however is that indentation matters the most. Putting the { at the end of a line starting a block does not break this rule. I'd say it's even clearer when the code introducing the block is the symmetrical counterpart to closing bracket at the end of an indented block.
Excellent Talk! Very simple yet most effective ways of improving code quality!
Habits like putting Exception at the end of exception classes is to help programmers find exception classes in intellisense.
Maybe we should learn other methods of finding classes than intellisense, like the object browser.
That should be an IDE issue, as in those that derive from Exception should show up when typing Exception
Or maybe for it to work like C# attributes, where when you use it, it loses the "Attribute" suffix
In languages like C# combined with an IDE like Visual Studio, adding the word Exception to exceptions makes it possible for the programmer to discover exceptions within IntelliSense. You type in "throw" and a list of possible throwable things shows up. Type "Exception" and the IntelliSense list is filtered to only exceptions.
If you agree with everything I say, you weren't paying attention...
I agreed with many of the things he said as most of them do make sense within some specific context. However, there are many things that I disagreed with... I'm self-taught in C/C++ and my main focus is within 3D Graphics Programming, Physics Simulations, Animations, etc. My next major interest is in Hardware Emulation still working in C/C++. Following that is a combination of Compiler Design and ISA Design(Assembler and Disassembler). This is just the software side of things... I also have an interest in the Hardware side of things which relates back to some aspects of the software side such as the ISA Design(Assembler and Disassembler) that focuses on the hardware design and implementation of the architecture. The final major topic of interest that I find myself looking into is A.I. programming and Machine Learning where I find myself diving into Python. I prefer to design and craft the backend portions of systems and applications as opposed to the front end such as Webpage development using JavaScript, HTML, CSS, etc... I like being closer to the metal with more control and with less abstraction, yet with just enough clarity to give my CPU or GPU the instructions that it requires to perform the tasks that I want. This now leads me to one of the biggest things that I do disagree with... The use of Singletons...
If Singletons are designed properly and used within the appropriate contexts, they are very useful, powerful tools that also exhibit intent expressively. Considering that my main field of study and practice is within 3D Graphic and knowing that I will most likely be working in C++; I would design my application with a specific framework in mind. The main application or "user-front" will derive from an abstract base class which I just simply call "Engine"! If I have multiple engines for different things such as Sound, Graphics, I don't derive them from Engine to have `Engine::Graphics::Graphics()` as this is actually redundant. What I would typically do is have Graphics as its own object, Sound as its own object, Shaders as its own object, etc. The Engine class will contain all of those objects as the Engine is what Drives them all! Now, the Engine has to be able to store all of the Assets that are processed through those objects such as textures, sprites, fonts, models, skyboxes or skydomes, GUI elements, shaders, etc. which will give me various different types of collections and data structures from vectors to lists, to queues, dequeues, maps, multimaps, unorderedmaps, various kinds of tree structures such as BSP, Quad, and Octrees, a Scene Graph Tree structure that follows specific rules of what types of nodes can be nested under another, Batch processing, etc. With all of these integrated parts, I do and will have manager classes that specifically do just that but they are limited in number... I would typically have a TextureManager, FontManager, ShaderManager, AudioManager, AnimationManager as these classes are responsible for the storing of objects, checking if they already exist, return them when they are queried, removing them from the containers when they are no longer needed and cleaning up their memory, and to check if the data of the objects are in a valid state, has a valid range and domain. Now within my Engine class these are typically static pointers as all of these class derive from an abstract base class that is called Singleton. When this is designed properly, you can only ever instantiate one of those classes per application run. So if someone tried to do this:
int main() {
try {
Application app(/*needed props*/); // Reminder: Application inherits from Engine and Engine is Abstract and is a Singleton!
app.start();
// If you tried to do this:
Application app2(/*needed props*/); // This will throw an exception because an Application object named app was already created during this application execution
} catch(const std::exception& e ) {
std::cerr
The "one true brace style" is "whatever your team is already using".
My primary use for comments is I'll wake up in the middle of the night with a solution get up program it for 10 or 15 minutes. Then go back to sleep wake up the next morning and look at the code and be dumbfounded. The comment is to remind why I did what I did. So far I've lucked out not one of these midnight half asleep programming excursions has been wrong. I honestly wish I could program as well when I am supposed to be awake as I do when I am half asleep. But once I've woken up and get what I did I delete the comments.
I agree with most of the comments here. Some good ideas followed up with truly awful and insufficient explanation, unclear examples and unnecessary waffling causing me to zone out despite being interested in the subject. Teaching clearly and succinctly is as much an art as programming is.
This is "must watch and follow" video in my team. -)
Very happy with his first point about curly brackets. Been doing that against a tide of comment and even insults for years. For exactly the reason he stated, it's visually meaningful.
The best point made against it is however: that's not how WE do it. Where I am excluded as a part of WE for convenience. There is very little one can do about that. Being right isn't everything, in fact it's nothing. Enrolling others is way more powerful and I have failed to do so. I fear he has failed to do so too, but I live in hope.. For now my code gets reviewed with very strange metrics in mind.
This is the main reason I like working alone :)
Always loved that first point about my name... except for having to spell it a million times.
Use words like "exception" because you may know it's an exception but a future dev|debugger may not even know what "exception" is. Or be very explicit in your outputs with reference links to documentation
You definitely need code even if the code is clean. The code explains what you are doing. But sometimes it is not enough. You need to explain WHY are you doing that.
Some good points, but if everything he was ranting about was to be adopted then the resulting code would be a nightmare to work on as an outsider. Eg: We append "Exception" to an exception class so that it's function is immediately discernible when writing code within an IDE equipped with code sense.
Great talk!
I think this stems from programmers comparing themselves to plumbers than writers.
had some good points & anecdotes. he's definitely right that you gotta disagree w/ him on some points. like 10:20 when he falls right into a classic "thinking you're right because you've used the word 'fallacy'," fallacy. obviously having somebody express in a more natural way their thought process would help them express the intent of their code - likely they'll even come up w/ a clearer refactor when commenting it. conceptually, writing comments for convoluted logic should frequently help both current & future developers, for the same basic reason we find whiteboards & wireframing tools useful
Anyway nice talk!
Baaki sab common problems aap logon ki... but yeah I wud like to emphasize 'get' 'set' thing. Seen lot of codes even if not programmed anything... and seen that very stupid way of using these constructs... where they just not even required or nothing more than just some more noise in codebase in your terms. Even in famous standard libraries or renowned compiler implementations.
The think best use of get set is to denote a situation where u specifically want to do processing during getting or setting value of some data. Whatever it maybe doesn't matter... could be simple check or some complex thing.
But if u not doing it... then its just another senseless stupid noise. U can very easily get set data through '.' operator on object instance itself. What's the problem?... its straight forward clean code...at it should be or use to be in first place.
But if u define a get set method compiler should enforce its implementation...and should complain that that method is still empty during build or in error, warning or pending log ...whatever... if it can handle live analysis.
I mean this way its implementation makes some sense...it adds a new feature... otherwise its just nonsense I suppose. Which is the usual norm currently how contemporary compilers handle those things or coders codes things. I think compilers should sensibly address this lil issue. Using it just for the sake of it or like some more stupid alibi that u can access it through like this or that construct or way of accessing thing doesn't make much sense. It should add something to value than making just some more stupid clutter only. And that's nice way to gel old coding style with new.
adding a common suffix to a class makes it possible to find it in the repository and therefore enables programmers to reuse code
the same for adding get and set, when you want to inspect an object and understand what it exposes, having a common prefix for all the methods that serve the same purpose makes it much easier
getUnits() purpose is to return Units, getCurrency() is to return the currency - it's a different purpose.
Wonderful talk.
This is a symptom of the luxury of modern programming. No restraints on memory, execution speed, bandwidth, storage, etc, so we pontificate on the placement of white space. Brunelleschi, in the fifteenth century, built a double dome of bricks on an octagonal base, the largest ever constructed; Steve Jobs wanted the Pantone company to create a new beige for his Apple II casing. They had 2000 beiges already, but none of them was good enough for Steve.
Beige really is the ugliest of all colours tho
29:10 I have no issue with _this_ being redundant naming. Exceptions are a special case and should be rarely seen.
Best talk ever!
I wish my company would value code style like this guy promotes. They pretty much don't care.
Fantastic talk
Love the talk!
Amazing!
Professor: I deduct points for uncommented code.
Me: //display the string
I remember writing a whole page of comments and inserting a few lines of code in between for homework in freshman year :D
Many different discussions about when To or NOT to write comments in code. I would rather see ZERO comments. Like I said, many discussions. But just like every child's question about "Why is the sky blue?" ends up with "Well, where did the Universe come from?"... so too does this discussion follow. And the end answer is Unit Tests. Your functional algorithms, where most comment enthusiasts REALLY push for comments, should be commented via its Unit Tests. a Unit Test method saying "If person throws corn then expect the sky to be blue". Your tests should explain your code. That becomes a Single Source of Truth.
Comments are for WHY, code is for HOW. When the code is too simple, it feels silly. But eventually you need them because otherwise readers waste time puzzling out WHY some things are the way they are. Your architecture decisions, your strange data structures, peculiar bugs.
@ernstig Since I wrote that comment - a year ago - I have read my share of papers. I still stand my position. Writing algorithms doesn't have much to do with writing applications. Both are very different fields. Therefore researchers are not qualified to teach any king of software development because they have never done it for a living. They only use programming at a syntactical level in order to express a calculation process. Most of the time it's pseudo code anyway.
@e-Sharp "researchers" invented most of the algorithms and wrote most of the successful programs you still use to this day. any researcher worth that name knows a lot more than just syntax
I would like to add to the things he said about the curly brackets, { and }.
I have severe reading dyslexia. If you think he is making things up when it comes to readability, try again.
Every time I see a code with curly brackets not on the same indentation for the same scope, I die a little of the sheer effort I must commit to in order to read just a few lines of code. Even though this effort practically disappears, if scopes are clearly made under the same indentation that makes it look far more uniform. Early exits help with this too, as long as it is in the very beginning of a function or method.
Coding style matters dramatically for people with reading dyslexia, as it does not only effect them on natural language. I genuinely don't care about the quality of code as a reason to ask this of you.. I just want to be able to read your code without getting tired because the code is spatially all over the place.
I'm not at all dyslexic, but I can't stand opening curly brackets on the end of the previous line, either. The effort to look around to find where the block of code began is not worth the effort. My curly brackets have always lined up. It makes the code so much more readable.
Kind of a nice way to describe clean code. Not Sooo much new stuff
Why are we never taught this stuff, such a good talk.
@Lepi Doptera Sounds incredibly inefficient, lol
Because you should be able to figure out the obvious on your own.
That man is brilliant! Impressive talk.
re: agglutinative terminology. My favorite was an event called "SomethingHappenedThatCouldChangeTheNavigationWizardButtons"
24:50 - I'd argue that Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz is still a word, even if the law has been withdrawn. The fact that it no longer exits makes it no less of a word. That would be like arguing that "dinosaur" is no longer a word because there are no dinosaurs anymore.
I agree. But there are dinosaurs, though. Today we call them birds.
True, but the word itself is not and was never the "longest word" in german. You can always make up a word that is longer, but still has some meaning and is valid grammatically.
Was expecting a horrible video judging from the comments, but was pleasantly surprised. This talk is great - informative and enjoyable. Sure, the video editing could have been better, but come on. You guys know that you can pause a KZclip video, right? Honestly, I had zero problems following despite the code samples not being 100% visible 100% of the time. And "too much noise"? I guess some people missed that it's a talk, not a textbook or lecture.
10:31 also I would disagree that a programmer who thinks his code might be hard to understand without comments couldn't do a better job using english or whatever spoken language he uses. If you're using some framework that relies on a lot of knowledge of its semantics or internals, comments really help a newcomer understand.
Example at 6:40
Left Side: Someone who clearly stopped learning C# at version 1.0. But Add-method is intuitive understandable.
Right Side: Shorter, thanks to the use of higher integrated features. Needs the knowledge that Remove() ignores nonexistent items and the indexing operator throws by itself when out of bounds.
Noise? Only relevant if someone does not use this as a black-box and has to maintain such code.
In reality: Jim, he is dead! Let's use the next best library from XYZ that has a good rating and give a fuck about this one:)
I know, I know. The librarians will hate me for this. But let's move to the next one:P
I like the topic and the content - thx for the video
Slides for presentation: www.slideshare.net/Kevlin/seven-ineffective-coding-habits-of-many-programmers-69941600. They are not exactly one to one though
I enjoyed the talk!
I disagree on the comment part. Yes, you can overdo comments and often they are just cluttering the environment with useless information. But they are actually useful for intellisense and peeking at references. People might get the wrong idea and eliminate them. Which is, in my opinion, bad practice if you're writing a lot of abstractions. Documentation blocks are absolutely necessary, inline comments are up for debate (but serve a function from time to time, when done correctly). Example: *// Code below equates to: a² + b² = c²* is actually useful information.
The thing I actually find disgusting, when people use acronyms for everything AND don't even comment them
When I was younger I loved such videos. Each one of them was like a new revelation. "Yes! I always thought that way. This is so right." and so on. But then I start thinking if this is so good and obvious why there are still so many problems in this area? Nowadays I see too many issues with such talks. I will elaborate.
First of all many points this guy has are kind of personal and more like a matter of taste. Trying to provide an argument to prove your taste is silly. Consistency is what matters. Another problem is that many points are laughably obvious. Seeing all these people seriously listening to the advice of not shitting without taking off your pants is just feels wrong. And the fact that it's happening is very very sad. And the most important thing. I strongly feel that these talks move people away from the real cause of the discussed problem. I will share my opinion on what it is. But I must say that this guy either does not understand it or is just hyping (like many others) on such problems.
The fact that some codebases end up riddled with naming inconsistencies, redundant comments, misleading names, etc is because these lines of code were written by stupid developers who do not care. And unfortunately, there isn't much you can do about it. Doing this talk certainly won't change this a bit. You need what is called a "culture of programming" to avoid these problems. But to achieve that first you have to set a bar during the hiring process. Every project might have a unique culture but people who write bad code, don't see it and there's no potential for change.
You need to share the same values with your colleagues for you to be effective as a whole. It is so easy and yet not many talk about it. I am not talking about the simply coding convention, development pipeline, etc. Feeling of what's right or wrong. Feeling of what's beautiful and what's ugly. Taste of what's good. Everything else will come to you naturally. Finding such a team or building your own is hard. This process is slow. It's not about just not seeing rationale as this dude thinks. It's about people being different.
In conclusion, my key points would be:
- Think about the common values of your team
- Don't work with ineffective lazy idiots
- Your's and your colleagues' uniqueness should not meddle with the consistency of the codebase
- Use the same software tools and tweak them identically
Excellent points! “Bad programmers write bad code” is really a straightforward problem, but slow and difficult to solve, so consultants like to stay away from it.
I still found plenty of great points in this talk, but the idea of “All we need to do is explain it again and again slowly and carefully - programmers will catch on” is provably false.
Great talk
His section on Lego Naming makes me wonder if he's ever had to write and maintain a large-scale software application.
He won my like with the point about curly braces. :D
His final opinion on Curly Braces, which annoyingly flew by at 22:55, is a new line for Curly Braces. Which I personally find to be preferable and adds visual clarity imo. But I know Java and Javascript Devs may have a different opinion.