Naming Things in Code

Sdílet
Vložit
  • čas přidán 20. 05. 2024
  • It's hard to come up with good names in code, but its also easy to get wrong. By looking at some examples, we can get 80% of the way there. Access to code examples, discord, song names and more at / codeaesthetic
    0:00 Introduction
    0:31 Variables with a single letter
    1:08 Never Abbreviate
    2:06 Types in your names
    2:36 Units in your variable names
    3:37 Types in your types
    4:30 Naming a class "Base" or "Abstract"
    5:45 Don't name code "Utils"
    7:09 Conclusion
    #softwaredesign #code #programming

Komentáře • 4,4K

  • @somebodyoncetoldme1704
    @somebodyoncetoldme1704 Před rokem +10018

    Single letter variables do tell you something about the variable. They say "I'm not important", "my scope is as small as I am", "I'm fleeting" and "I'll be gone in 2 lines".

    • @keco185
      @keco185 Před rokem +758

      Yeah exactly. The more imposing the variable name is the bigger the scope. Since letter variables are for a few lines of code in the middle of a function. Large screaming snake case constants are constants that span 1 or more files.

    • @LeeorVardi
      @LeeorVardi Před rokem +481

      Still doesn't justify using i instead of index, or using i, j instead of rowIndex, colIndex. or k,v instead of key, value, or......
      you catch my drift.

    • @xcraftminebb
      @xcraftminebb Před rokem +921

      @@LeeorVardi I think it does!

    • @Daren6111
      @Daren6111 Před rokem +40

      @@xcraftminebb why?

    • @xcraftminebb
      @xcraftminebb Před rokem +527

      @@Daren6111 as the original comment says. Just for very simple variables which have no meaning other than iterative variables like “int i”, or “char c” for one line variables. Or, like lambda function parameters (k, v) for map’s. Though I do see value in naming row / col.

  • @davidharmeyer3093
    @davidharmeyer3093 Před rokem +3518

    There are only two hard things in computer science: Cache invalidation, naming things, and off-by-one errors.

    • @charg1nmalaz0r51
      @charg1nmalaz0r51 Před 11 měsíci +188

      off by one errors are like trying to plug a usb into its slot. You always bugger it up first try despite doing the same thing forever. Sometimes a third attempt is needed somehow 🤣

    • @williamdrum9899
      @williamdrum9899 Před 11 měsíci +81

      I disagree. There are three hard things: Cache invalidation, naming things, preventing buffer overruns, and hunter2

    • @invictuz4803
      @invictuz4803 Před 10 měsíci +114

      I disagree. There are three hard things: Cache invalidation, naming things, and developers agreeing.

    • @MatheusAugustoGames
      @MatheusAugustoGames Před 10 měsíci +68

      There are only two hard things in computer science: Cache invalidation, naming things, and off-by-one errors, and cache invalidation.

    • @markjouh
      @markjouh Před 10 měsíci +3

      secondthead orz

  • @avatarcowboy2435
    @avatarcowboy2435 Před 3 měsíci +330

    Retired engineer here - started with Fortran with punched card decks and of course assembly code. I remember when "real engineers could do everything in 8k of core". Every byte was precious. It was beat into our heads to write tight code. As a young engineer in the late seventies I recall struggling with code maintenance and reuse. I shared my frustrations with another engineer who asked a key question that changed everything for me. He said something like "when was the last time you had problems fitting a program into memory?" I couldn't remember. Our newest designs had faster CPUs and more memory. After that I programmed for readability and reuse. Execution time critical or "real time" code was kept separate and avoided when possible. Thanks for sharing these tips with others.

    • @frankfrei6848
      @frankfrei6848 Před 19 dny +7

      Embedded systems engineer here. The last time I had trouble fitting code into memory was yesterday.

    • @PiterDeVries
      @PiterDeVries Před 2 dny

      Instead of asking about fitting programs into memory, we should asking about AAA games from multibillion dollars companies having stutters, fps drops, fitting on SSD, fitting into memory with Discord, MSI Afterburner, OBS and browser running...
      And the answers will be today, all day, everyday.

  • @henrybecker2842
    @henrybecker2842 Před 8 měsíci +192

    Back in the 60’s variable names were limited to seven character. Additionally, by default variables starting with the letters I, j, k, l, m, and n were by default integers. We often used i, j, … as loop counters.
    Hungarian notation was named after Charles Simonyi, a programmer who worked at Xerox PARC circa 1972-1981, and who later became Chief Architect at Microsoft.

    • @erato1
      @erato1 Před 4 měsíci +3

      I used to like Hungarian. it made reading the code so easy.

    • @snesmocha
      @snesmocha Před 3 měsíci +1

      aka why implicit none exists now 💀

    • @0x5D
      @0x5D Před 3 měsíci

      ​@@erato1look into "apps hungarian" vs "systems hungarian"
      tldr: hungarian notation in its original form is good, but the windows API guys corrupted it

    • @zf4hp24
      @zf4hp24 Před 16 dny

      @@erato1 I still use it in C/C++. "pcwszLastName". Just by looking at it away from the declaration you now know it's a pointer to a const UTF-16 character string that's zero terminated. And it's buried 5 levels of nesting deep in a 200 line linear function with a single return at the bottom. With a comment block on top. Horrors!

    • @BartonChittenden
      @BartonChittenden Před 3 dny

      It should also be noted that when Simonyi referred to 'types' he was *not* referring to variable types... he organized the code by the 'type' of thing that it was doing... drawing a window on the screen, capturing mouse movements, etc... the variables might be windowMenuBarHeight, windowMenuBarWidth, or mouseXCoordinate, mouseYCoordinate... the 'type' was essentially a tag that kept things organized semantically. Simonyi worked in the Microsoft applications division... when Hungarian Notation was adopted by the operating system group, the rule that 'variables should start with their type' got communicated, but the meaning of 'type' was lost.

  • @Hector-bj3ls
    @Hector-bj3ls Před rokem +4658

    The actual version of the starting quote should be:
    "There are only two hard things in computer science: Cache invalidation, naming things, and off by one errors"

    • @nicreven
      @nicreven Před rokem +47

      hah

    • @BuyMyBeard
      @BuyMyBeard Před rokem +148

      Off by one isn’t hard because, well, it’s off by one

    • @modolief
      @modolief Před rokem +29

      Top comment.

    • @evanbelcher
      @evanbelcher Před rokem +151

      I've heard this quote be a hundred different things, only "naming things" seems to be consistent

    • @nicreven
      @nicreven Před rokem +216

      @@evanbelcher because that's the joke most of the time
      "There are only two hard things in CS
      [literally anything], and naming things"

  • @narnigrin
    @narnigrin Před rokem +3221

    The "if you're having trouble naming something, it probably means something needs to be restructured" rule of thumb is honestly my biggest takeaway from this.

    • @josk8936
      @josk8936 Před rokem +154

      Or... It's 3am and you're too tired to name the variables hahah

    • @narnigrin
      @narnigrin Před rokem +228

      @@josk8936 When you look at your code the next morning and start finding variables named "fuck_it" and "iGiveUp", that's your cue to maybe sleep more lol #soivebeentold

    • @marcotroster8247
      @marcotroster8247 Před rokem +47

      @@mk_jdilla Is it an integer because of i prefix? 😂😂😂

    • @mk_jdilla
      @mk_jdilla Před rokem +66

      @@marcotroster8247 bYes

    • @Soutame
      @Soutame Před rokem +2

      Many times refactor cost too much. Find more solutions that will prevent refactoring.

  • @kosnk
    @kosnk Před 11 měsíci +633

    You can use abbreviations, even single-letter variables, just in the right context / scope. This is especially true with lambdas, which are often a single-line operation.

    • @NihongoWakannai
      @NihongoWakannai Před 7 měsíci +170

      People who insist on "index" or "iterator" instead of just "i" are some of the most annoying types of people

    • @Lodinn
      @Lodinn Před 7 měsíci +56

      @@NihongoWakannai I would love to see any remotely large computation written with full words. Ah yes,
      easingParameter < 0.5 ? 4 * easingParameter * easingParameter * easingParameter : 1 - pow(-2 * easingParameter + 2, 3) / 2;
      is sooo much more readable than
      x < 0.5 ? 4 * x * x * x : 1 - pow(-2 * x + 2, 3) / 2;
      Especially given the entire thing is pretty much always fully encapsulated.
      It's just hardly anyone actually interacts with math at this level in code anymore. If all you're doing is implementing a textbook PDE computation or whatever, there's hardly any reason to invent new names.

    • @mytuppenny
      @mytuppenny Před 7 měsíci +23

      Definitely, but even then I think you should ask yourself: is there useful information I could be conveying here?
      It made a surprising difference for readability when I changed, e.g.
      df.apply(lambda x: log(x.inc+1), axis=1)
      to
      df.apply(lambda row: log(row.inc+1), axis=1)
      Or something like
      for car_i, car in enumerate(cars):
      ...
      My feeling is, x means a number, i means an iteration index which really doesn't represent anything, and most other things should be named.
      I work a lot with code that models the real world, though. If I were writing like a crypto library where the vector is just a vector and it doesn't represent anything, I can imagine using single letters more.

    • @Lodinn
      @Lodinn Před 7 měsíci +10

      @@mytuppenny On some level, a crypto library is less likely to use single letters because it deals with concrete implementations.
      You may be writing an abstract library with lots of real world applications, but heavily grounded in math - that's where most of equation-like code comes from. Or consider physics sims. Between E, emf, and electromotive_force, emf would likely the best option to use in code.

    • @blablablablubhjkhgkj
      @blablablablubhjkhgkj Před 7 měsíci +12

      writting lambdas is so nice. I looks very cool and is quick. But have you ever tried debugging a complex lambda you didn't wrote yourself?! :X

  • @Deveyus
    @Deveyus Před rokem +122

    I'm a big fan of verbNoun naming on functions, it is a great way to say what the function does, and in many cases, clues you in on what i might return in a preloading sort of way. Not just in terms of raw types, but in terms of the meaning of what it's trying to do. so things like a getMovie() function, or a getMovies() function, tells me I'm going to get back single objects, or likely an array.
    Another is to always name arrays and their ilk with a plural, and the singular instance with... well a singular.
    These aren't ground breaking by any means, but they go a long way to helping you write code that is easy to mentally parse with common structures, like for..of loops.

    • @kernelpickle
      @kernelpickle Před 9 měsíci +3

      That plural versus singular idea gets really problematic really quickly, because if you had an array of Things and just one Thing , you’re only one letter off from an autocomplete or typo messing up your day.
      If one of something is getting called Thing, you’d be better off using another longer word to append after it.
      Back in the day they always liked putting the type or whatever abbreviated in front as mentioned in the video, because that’s how they taught us to write code in a VB Class over 20 years ago. I prefer flipping that around so I can easily see the slightly more thing first, followed by the descriptor. So, for an array of more than one Thing, I would go with Thing_Array or Thing_List, that way if I go searching for “Thing” I can see where I used both forms of it, just in case I forgot what the prefix I came up with was.
      Sure, I could put a wildcard before the word I’m looking for, but I like putting them afterwards because that’s how I’m built.

    • @UnknownGamer40464
      @UnknownGamer40464 Před 8 měsíci +11

      ​​@@kernelpickle
      You're entitled to your methods but not a compelling argument imo.
      messing up your day being like messing up 30 seconds max since even just a linter should catch this, and this never happens to me despite doing this all the time.
      It would take longer to fix in dynamic languages, but even python has type hints.
      Autocomplete requires your input, if you need an array, you're already looking for plural, if not, you're already looking for singular. The autocomplete should not have to do your thinking for you.
      And definitely not a fan of the postfix hungarian notation alike.
      Document your function in the documentation, not in the name.

    • @NihongoWakannai
      @NihongoWakannai Před 7 měsíci +4

      ​@@UnknownGamer40464 yeah, you're never gonna confuse a single object with an array, they're not interchangeable in code, your IDE will yell at you immediately

    • @MrCmon113
      @MrCmon113 Před 7 měsíci +5

      Function_Maker_Factory.make_function_maker(function_maker_factory, function_maker_params_dict)

    • @LindaJuffermans
      @LindaJuffermans Před 3 měsíci +3

      One problem with this is that some words don't have a singular and plural version. For this reason, I will name my functions getMovie() and getMovieList().

  • @iatheman
    @iatheman Před rokem +1916

    “Abbreviations rely on context you may or may not have.”
    What a perfect summary right in the intro.

    • @imqqmi
      @imqqmi Před rokem +22

      I ran into this today, got a piece of old Amiga C code I wrote as a teenager 30 years ago and couldn't for the life of me figure out what it meant. Really glad I've stopped doing that later in my programming life lol!
      And there were many other bad habbits like experimental code that's left in the code base without comments or documentation, it's no longer used. I kept it as a repository so that I could refer later to it. There was no version control back then. And GUI, util, handlers all mashed together AND spread apart in multiple files. It's a total mess! No wonder that the code was in a half baked state. I've managed to get the base functionality working again, thanks to the debugger, which I didn't understand how to use back then.
      Another mistake I made back then was naming functions inconsistently like CloseProjectWindow vs ProjectWindowClose and confusing the two. And then using PICloseWindow, using an abbreviation I don't remember and ordering it in yet another way.

    • @TheOnlyGhxst
      @TheOnlyGhxst Před rokem +5

      I bumped into this when trying to modify an open source game, but I couldn't figure out what anything did because all the variables were incredibly vague abbreviations.

    • @TuomoKalliokoski
      @TuomoKalliokoski Před rokem +18

      If you don't have context, you don't have enough information to mess with the code.

    • @TryHardNewsletter
      @TryHardNewsletter Před rokem +6

      Even with context they can be hard to read, and without context they are impossible to read
      I do think he should have explained why code (in particular old code) used abbreviations. Maybe because it required less typing in a world without intellisense? If you consider the function DefWindowProc (in the Win32 API from 1995), does "Def" mean "Default" or "Define"? Does "Proc" mean "Process" or "Procedure"? The function header is:
      LRESULT DefWindowProc(
      HWND hWnd,
      UINT Msg,
      WPARAM wParam,
      LPARAM lParam
      )
      What is an "LRESULT"? What is an "HWND"? What is a "UINT"? What is a "WPARAM"? What is an "LPARAM"?
      "HWND" is a WindowHandle. A handle is the ID of a resource managed by Windows. Not a pointer (so nothing to do with physical addresses), just an ID that identifies it (like a social security number identifies a person). "WindowsId" is more descriptive than "handle", but the word "Windows" is overloaded because it could be talking about the operating system or an actual window. So "WinId" might be better than "WindowsId". So maybe "HWND" could be "windowWinId" instead?
      "UINT" is an unsigned 32-bit integer. Why not call it unsigned32bitInteger? If the 32 needs to be flexible (maybe 64 or 128 some day) then it could be unsignedNativeInteger? Integers are common enough that "uint32" would probably be an okay abbreviation (the fact that the value 1 is physically stored as 15 zeros, then a 1, then 16 zeros is a whole other can of worms but I'll ignore that for now). And how is a "Msg" (maybe "message" would be better for the name for the parameter) which is usually something human readable that is meant to be read by humans just an integer in this case? Is it an instruction to the window? Maybe "windowInstruction" would be better than "Msg"? Even in a world without intellisense, a lot of abbreviations make no sense because it takes more effort to remember the abbreviations than it does to type out non-abbreviated versions.
      But... BUT... abbreviated code fits nicely in a 320x240 screen. So, we should all use abbreviations like "WPARAM wParam, LPARAM lParam". 640x480 killed the need for abbreviations. But it was just "the way things were done" so the practice went on for a long time after 640x480 was mainstream. Now a days we even have 800x600 so... yeah...

    • @falcontomto
      @falcontomto Před rokem +12

      I personally wouldn’t go that far. While abbreviations like URL and DAO do require some context, I’d rather write ImageUrl or somethingDAO rather than imageUniformResourceLocator or somethingDataAccessObject. Somehow these names are less comprehensive than their abbreviations.

  • @Sweenus987
    @Sweenus987 Před rokem +1907

    "You shouldn't name variables with a single letter" - *sweats in vectors*

    • @Hector-bj3ls
      @Hector-bj3ls Před rokem +491

      Coordinate systems and loop variables are my exceptions to this rule. xyz, rgb, uv, hsl, ijk, etc. If you don't know what those mean then you probably shouldn't be messing with the code that deals with them.

    • @bolvarsdad3825
      @bolvarsdad3825 Před rokem +37

      Prefix them with vec

    • @casualoutlaw540
      @casualoutlaw540 Před rokem +108

      @milk guy I'd call hsl "hue/sat/lum". Short but also enough clarity.

    • @BuyMyBeard
      @BuyMyBeard Před rokem +183

      Yeah, I take what was said in this video with a grain of salt. Sometimes, especially for variables with a short lifespan, abbreviating them makes the code a lot cleaner. Otherwise it’s just a mess with a bunch of variable names for simple operations

    • @keineahnung1919
      @keineahnung1919 Před rokem +6

      @@Hector-bj3ls also functional stuff

  • @WS12658
    @WS12658 Před 7 měsíci +102

    I'm guilty of having a "Utils" class quite often, but mostly it's for when I have a bunch of fairly generic functions that I don't want to have 7 different classes each with a single function... Although I'm now moving towards having those classes, but putting them in a directory called "Utils" which is tidier. Speaking of which, I'd love to have a video on structuring projects in terms of the file system. I.e. what directories do you have, how best to split up different classes, that sort of thing.

    • @purple...O_o
      @purple...O_o Před 4 měsíci +16

      agreed - sure, it's a clear sign you should ask yourself some questions
      'is there a better place right now?' and 'how unwieldy/disorganized is this utils file?'..
      But also: 'am I letting perfect be the enemy of the good enough?' ... but in my experience, the answer is context dependent. Many times the best organization is something that reveals itself over time and overthinking/overworking it now ends up being a waste.

    • @porkypig7170
      @porkypig7170 Před 3 měsíci +1

      I often start with a utils class but usually end up refactoring its contents into dedicated classes that make more sense

    • @skewty
      @skewty Před měsícem +4

      Training (CZcamsrs teaching) typically rely on contrived and overly simplistic examples because ugly real world examples often require compromise. Few really experienced developers would want to deal with the comments section of social media.

    • @bobbobert9379
      @bobbobert9379 Před 7 dny

      I never have a Utils class, but I do often have a utils file that contains common, reused utility functions.

    • @PiterDeVries
      @PiterDeVries Před 2 dny +1

      "Moving standalone functions into classes" isn't a very good advice... Or at least, it's a contraversal advice, because it directly contradicts with official C++ Core Guidelines by Bjarne Stroustrup and Herb Sutter, section C4: "Make a function a member only if it needs direct access to the representation of a class".
      A lot of times I see suggestions on the internet about clean code and coding standards that doesn't take into conderation any other existing documents and practices.

  • @myew8238
    @myew8238 Před 6 měsíci +9

    omg thank you for making this. Trying to learn from forums that use single letter abbreviations in their examples gets confusing so fast.

  • @markjohansen6048
    @markjohansen6048 Před rokem +862

    One other rule I'd add: If you have two variables that contain similar or related data, give them names that tells me what's different about them. One maddening example I ran into was an order processing program that calculated shipping cost. And it had three variables named "frght", "freight", and "freightcost". I eventually figured out that one of them was the freight cost currently on an order that was being updated, another was a standard shipping cost taken from a table, and the third was a calculated shipping cost using a formula that only applied in some special situations. But wow, figuring that out took a lot of effort. If the original author had just called them, say, "currentFreightCost", "standardFreightCost", and "specialFreightCost" or some such, it would have saved me a lot of time.

    • @2bfrank657
      @2bfrank657 Před rokem +35

      Urgh, what a headache. People should not be allowed to write code like that.

    • @BLiZIHGUH
      @BLiZIHGUH Před rokem +28

      I was just scrolling down to write the same thing! This is a huge trap that's a lot more common, and a lot harder to deal with, than anything mentioned in the video imo. So often in commercial codebases I'll see functions with variables like "fileList," "fileArr," and "fileTable," -- why do we need three copies of the same thing? What's different about them? Why is this one updated here, but not the other two? It boggles the mind and leads to a lot of wasted energy, especially when the original developer is long gone.

    • @RamsesTheFourth
      @RamsesTheFourth Před rokem +9

      Better than f1, f2 and f3 :)

    • @jgharston
      @jgharston Před rokem +20

      No no no no no. FreightCostCurrent, FreightCostStandard and FreightCostSpecial. Then they are all FreightSomethings.

    • @upsxace
      @upsxace Před rokem +6

      One thing that helps is also commenting your code ._.
      I don't understand why people are simply ignoring the easiest way of solving all those misunderstandments(even though, of course, naming variables good is the best and most efficient way).

  • @dumonu
    @dumonu Před rokem +1728

    I think the one exception to the "no single character variable names" rule is the naming of for-loop iterators. It's extremely common for such iterators to be named "i" and "j". If a developer looks at some code with an "int i;", they immediately know it's such an iterator.

    • @awesomecronk7183
      @awesomecronk7183 Před rokem +165

      I'll break this rule in Python if I'm iterating an iterator other than "range". "for item in cart" works well, but "for iteration in range(5)" really doesn't especially once you start nesting loops.

    • @JoeSteele
      @JoeSteele Před rokem +114

      I used to agree with this BUT I almost always avoid for() loops in modern code. Usually when I am iterating across a collection, I want the iterated elements but not the actual index. And when I do want the index it is actually nice to have it called "index". Of course if you are still coding in C99 or earlier, then the pattern of using "int i;" makes a lot more sense

    • @char8169
      @char8169 Před rokem +165

      Another one i can think of is if you are expressing coordinates/position, then you could have like an x and y variable denoting the position along the x and y axes

    • @kleko
      @kleko Před rokem +72

      i & j is a bad combination as they are visually easy to mix up, especially for people with dyslexia.
      You also find another version of the problem with i & y or c & z. Both these pairs are a pain if you have to verbally talk about your code.

    • @charlesm.2604
      @charlesm.2604 Před rokem +27

      @@JoeSteele No you're right, there shouldn't be exceptions to the rule.
      If you need the index your standard library has a function for it.
      Pseudo code:
      for item in collection {
      ...
      int index = collection.indexOf(item)
      print(index) // There ya go bud
      }
      Another major issue of one letter iterators is that sometimes you have multiple loops with references to different iterators at different scopes.
      Things like working with multi-dimmenssionnal arrays for example.
      You will need to write multiple loop with i, j, etc... and use those iterators at different "level" of iterations which just make the entire code confusing.

  • @QayLikeKay
    @QayLikeKay Před 8 měsíci +10

    Base, I-prefix, etc are handy in cases where as a user you may need to handle both the base class and the derived/concrete classes at different points. It's important to remember your API communicates with other programmers not just in the context of a single function, but in the context of potentially many different problems they are trying to solve. Understanding that something is a base or even has a base can help the programmer understand the API easier and know how to use it to solve later problems. e.g. I'm programming something that doesn't care about the given truck so it takes in BaseTruck, but that signals to me that there are several different kinds of Trucks potentially, so if my code needs specifically a DumpTruck I may be able to find it. It also tells me that I might be able to inherit from BaseTruck and make my own truck if the library doesn't provide 100% of the functionality I need.

  • @sharlottes0018
    @sharlottes0018 Před 11 měsíci +1

    Your examples and content, description are really good and acceptable, understandable. I'll definitely reference these videos in your channel when I explain something related this to someone.
    also, good variable naming is also a part of "the semantic programming".

  • @markjohansen6048
    @markjohansen6048 Před rokem +246

    My absolute favorite example of naming variables in a program: The original programmer named all the integer variables i1, i2, i3, etc and all string variables s1, s2, s3, etc. And then apparently to "save memory" or something, he would re-use variables in different parts of the program for different things. After banging my head against the wall for hours trying to figure out how to make the changes I had to make, I decided to take a step back. I studied the program and figured out what each variable actually was, and did a search-and-replace to rename it to something sensible.

    • @ichigo_nyanko
      @ichigo_nyanko Před rokem +80

      hahah you basically had to reverse engineer it exactly like people really reverse engineer decompiled code

    • @matthewread9001
      @matthewread9001 Před rokem +40

      so he did what the cpu does with registers. Only have 8 so reuse when one goes out of scope.

    • @thedreadedgman
      @thedreadedgman Před rokem +20

      I've had to clean up code like this... took hours to figure out what so many tmp and num and a and b and c... tmp2 variables actually did

    • @mauricestardddude8317
      @mauricestardddude8317 Před rokem +19

      Reusing variables might just come from ASM times
      Back then there weren't really things like names
      You just had some adress in memory you wrote onto
      And when the data at the adress fullfilled its purpose there'd be no reason to keep it occupied with no longer used data
      And with how important micro-optimsation could appear there was a good reason to do so
      But as soon as things hit anything that scoped variables there shouldn't possibly be any upside to reusing variables

    • @Bitfire31337
      @Bitfire31337 Před rokem +3

      That's the only sensible way to deal with such code. Rather put in some more work once than banging your head against a wall each and every time you have to get back to it.

  • @Crozz22
    @Crozz22 Před rokem +466

    Gets to the point immediately, concise and clean presentation, not too long, speaks clearly, ends when the subject is complete. This is a recipe for a lot of subs

  • @riesigerriese666
    @riesigerriese666 Před rokem +2

    Actually: this video is phantastic: exactly the right length, very good examples, concisely explained.
    Wonderful.
    I personally like refactorings that end in deleting unnecessary stuff.

  • @georgeflores5382
    @georgeflores5382 Před 4 měsíci

    Just discovered this channel and I really enjoy the way you present concepts. Other videos it's hard to sit still, but this is just done so well.

  • @gazehound
    @gazehound Před rokem +687

    The C# interface naming convention exists because C# code (including the .NET libraries) makes extensive use of interfaces, and often has classes that implement those interfaces but have the same name as the interface they implement. There's an argument to be made that this itself is an antipattern, but when you're dealing with just as many interfaces as you are classes, it really helps to be able to differentiate them at a glance, and to know what types you can and can't instantiate.
    Tangential, but when I was first learning to code I didn't really get the interface pattern (or many OOP principles) and I very quickly learned that you couldn't use the "new" keyword on any type with a name that began with an "I" - this encouraged me to figure out what exactly an interface even was.

    • @DarthJane
      @DarthJane Před rokem +64

      This. It is also the reason why if I write code for myself I actually use `A` for abstract classes. It's always annoying to try to instantiate those then find out "oh it's abstract, so I have to search which types even implement that"
      In my opinion it's even good for readability `AStream` or `AWriter` or `ATruck` makes immediate sense.

    • @Robert-G
      @Robert-G Před rokem +32

      there’s value in following the conventions of the eco system you work in.
      There are rules for dotnet APIs, pascal case for externally visible identifiers, camel case for parameters, when to use Pascal case for abbreviations (at least 3 chars -> pascal case instead of all caps)
      That makes it a lot less jarring reading and working with code from different libraries, yours just being one of them.
      Arbitrarily adding something to public identifiers (like classes that get an A prefix) makes your code not just look weird. Imagine everyone would think they’re above those conventions.
      Then everything would look different for no good reason, except different individual pet peeves of individual authors, but in the end most programs would look like a mess.
      Because they are an aggregate of custom code but also using a lot of 3rd party libraries.
      I for interfaces is mostly due to it inheriting a lot of stuff from COM, and lots of COM interfaces had the I prefix for decades.
      Interfaces are different enough in semantics and performance characteristics (they force structs to be boxed when used as interface), that having the I is a very good compromise.
      It’s also clear that you can implement them however you want, as opposed to abstract classes, that will always have some things wired in a way that cannot be overridden.

    • @WeslomPo
      @WeslomPo Před rokem +6

      @@DarthJane we go even further, we call OUR enum with E (and abstract A too). Maybe this is bad, but this is our convention and this is helping us.

    • @DryBones111
      @DryBones111 Před rokem +15

      Indirection is an epidemic in OOP. While I personally stick to the style guide in C#, I do think that if you can't think of a descriptive name for your interface implementation that doesn't clash with its interface (without the "I"), then you probably don't need an interface.

    • @w00tklumpWn
      @w00tklumpWn Před rokem +3

      @@DarthJane "It's A Truck" - hm, i like that actually

  • @Erotemic
    @Erotemic Před rokem +639

    I was on the no-single letter names train for a long time. I've since come around. Single letter variables can be incredibly useful as aliases when you need to repeatedly refer to the same item multiple times in the same line. The trick is the single letter name should be very short lived. It needs surrounding context so someone can infer what it is. Consider the Python code `new_columns = ['prefix.' + c for c in columns]` versus `new_columns = ['prefix.' + column for column in columns]`. I think the first one is much easier to read.

    • @stylishskater92
      @stylishskater92 Před rokem +20

      Thats true, i think it is an acceptable exception. I do this sometimes in very small scoped / short lived arrow functions or lambda expressions as well, like persons.filter(p => p.getAge() < 16), if the surrounding context is immediate or its a long chain of one liner stream operations. In such cases you dont need very long or descriptive names really as they may just lead to more breakds and prolonging the lines of code in the method/function you want to keep small (but readable). But in arrow functions which are a bit longer or its less clear i still use full names as i do in pretty much any other case. I was trained in my first professional environment during an apprenticeship by a real "oldschool" hardcore senior Java dev for 2 years, who was a very kind and brilliant man - i read many important books because of him and learned from him that no name is too long and i adopted this ever since (of course, there is such a thing as too long, but you get the gist). I only went to university after i spend years in the industry, and my fellow (younger) students were sometimes really confused why my code is so "long" (not vertically, but horizontally). Or why i split code in so many functions/methods/classes. Funnily enough, to them it made to code "less readable/understandable". But that is usually born from a lack of practice in both writing and reading code at that point still. They are not "used" to how code looks and reads other than throwing some stuff at the wall until something sticks and the compiler is mute enough (with suppressed warnings) to fulfill some early grade assignments. Not used to scopes larger than 1-2 files. I guess theres still a core of truth to staying "as brief as possible", which is subjective.

    • @m__42
      @m__42 Před rokem +17

      @@stylishskater92 There is the famous saying - "any fool can write a program a computer can understand, but only good programmers write code a human can understand" 😉
      For the splitting of functions/methods/classes, I believe a sensible middle ground has to be found. Often, splitting is really useful for self-documenting code. On the other hand, I saw people replace "if (end < begin) { invertFunction() }" by "if (shouldInvertFunction(begin, end)) { invertFunction() }". The first one is clearly more concise AND it tells you right away what the condition actually is. Here extracting makes the code harder to understand.
      Also, it obviously does not make sense to build a nice API with fluent builders, if people then extract the construction of an object to a method like "createObject(id, name, foo, bar, anotherProperty)"...
      As for single letter vars, I fully agree. OK for lambdas, list comprehensions etc, maybe as a loop counter (if anyone still runs classic for loops...?) but otherwise, something to avoid.

    • @Keithfert490
      @Keithfert490 Před rokem +4

      Should probably be [f"prefix.{c}" for c in columns], but I see your point

    • @nvcbl
      @nvcbl Před rokem +13

      Or "for (int i = 0; i < iterationsNeeded; i++)"

    • @m__42
      @m__42 Před rokem +5

      @@nvcbl Very true. Extracting a variable CAN make sense in this case to avoid re-evaluating every iteration, but please call it after what it contains, not after what it's for ;-)

  • @matthewbeck6847
    @matthewbeck6847 Před měsícem +12

    Another nameing convention I've adopted is this: if I have a class that belongs to some "feature", like a "knife" belonging to a "watermelon" feature, I prepend the feature to all the classes that support that feature: "WatermelonKnife" - next, if this class has a reference to another class within the same feature, for example, "WatermelonKnifeSharpener", I will omit as many of the shared prefixes in the reference property name - to just "sharpener" in this highly contrived example. Then, my code might read something like "MyWatermelon.Knife.Sharpener...." instead of "MyWatermelon.WatermelonKnife.WatermelonKnifeSharpener..."

    • @dusankodzopeljic4605
      @dusankodzopeljic4605 Před 24 dny

      This is a good example!
      I find GoLang extremely useful for this since it is a package oriented language. And you are obligated to specify the name of the package as a prefix, except if you are in your own package.
      E.g.
      Let’s say I have a domain ‘vehicle’ logic and I want to have a factory that makes vehicles.
      In another package, the type would be represented as ‘vehicle.Factory’ and you would make it as ‘vehicle.NewFactory’ instead of ‘vehicle.NewVehicleFactory’.
      I find this extremely useful since it’s built into the language and I don’t have to battle with my colleauges about good names.
      Also, another tip for naming files:
      If you have a ‘vehicle’ that’s an interface, that interface would go in ‘vehicle.go’ file. The implementations would each have their own separate file called ‘vehicle_car.go’, ‘vehicle_truck.go’, ‘vehicle_cached.go’.
      This way, the interface and all the implementations are grouped together in a directory structure and not scattered across the directory, plus they are easy to search and access.

  • @berkeleymorrison
    @berkeleymorrison Před 8 měsíci +1

    its beautiful, it reminds me that sometimes coding isn't always about producing but also about consuming. we hand our codes from one to another until it reaches the user.

  • @danya023
    @danya023 Před rokem +166

    Re units for variables: if your language has support for "newtypes" -- zero overhead wrappers for an existing type (like Haskell's newtypes, Rust's single-component structs or Python's typing.NewType) -- then consider using those. If you want a distance variable, then its type could be Millimeter, which is actually a u32. Then you can call it "distance: Millimeter" and not "distanceMillimeters: u32".

    • @Hector-bj3ls
      @Hector-bj3ls Před rokem +25

      The newtype pattern is especially useful when you have a functions that accept multiple of the same type with different semantics. Like two different hash outputs that are both u32. It'd be easy to accidentally pass the wrong one. If you gave each a newtype then the compiler will stop you.
      Just like you were saying with distance. Also applies to time and a whole bunch of other things.

    • @GekoPoiss
      @GekoPoiss Před rokem +6

      Or if your language specifically allows denoting units for types, like F#

    • @andrewlalis
      @andrewlalis Před rokem +1

      In D, you can define a public alias for your type, which can help to simplify logic a lot.

    • @idylosee
      @idylosee Před rokem +17

      In my opinion it can make the problem worse. Now you have a new arbitrary type that you don't know what it is at a first glance. Is "distanceMillimeters" an integer or a floating-point type? Or maybe it's actually a new type with its own structure? Furthermore, this "type aliasing" can cause a type-hell where you start to do things like "intVector" instead of "vector" - this makes you question whether a function parameter is of a special type that contains some special logic.
      While it's sometimes a nice idea, it's not something you should do all the time (maybe except using enums instead of booleans, although this is an actual new type, not just an alias).

    • @someunknownuser
      @someunknownuser Před rokem

      Scala also has newtypes

  • @marcusmajarra
    @marcusmajarra Před rokem +442

    I tend to be wary of good practices that revolve around the words "always" or "never" because they reinforce dogmatism rather than an understanding of the conventions for coding.
    For example, advising to never abbreviate (or use acronyms for) variable names may seem like a good suggestion, but the main motivation behind it is that abbreviations introduce ambiguity. Therefore, I would be more inclined to suggest avoiding abbreviating when it results in ambiguity rather than objecting to it as a rule. I don't think I'd enjoy reading through code that systematically turns "id" into "identifier" for this reason. Or one that expands a well-known abbreviation from the domain that domain experts routinely use in an abbreviated form.
    On another note, I see a lot of value in making type names expose their abstract nature. Sure, from the point of view of client code, it doesn't really matter whether you're consuming an abstraction or a concrete type as far as API usage goes. However, this ceases to be the case when you need to start writing tests for your client code as concrete classes carry an overhead in that they need to be instantiated within tests. And within test environments they might be difficult to configure in such a way that the client code you're testing behaves in the expected way.
    Now, you might argue that this merely reinforces the notion that we should aim to express dependencies through abstractions, but establishing a convention around identifying pure abstractions with an easily recognizable feature (such as the leading I in C# interfaces) makes it much easier to identify dependencies that can be easily mocked within tests. It also allows code reviews to more readily identify sources of strong coupling between client code and a particular implementation of a dependency. Lacking a clear identifier forces the reviewer to need to look up the dependency to make that assessment.

    • @amateurtries7542
      @amateurtries7542 Před rokem +5

      Agree with the third paragraph.
      I personally have sometimes benefitted to some extent by using terms such as BaseService, although I use it sparingly.

    • @jacknguyen5220
      @jacknguyen5220 Před 9 měsíci

      I agree that there is value in making type names clear as to whether or not something is abstract or not but disagree with the Hungarian approach. This can lead to the laziness pointed out in the video of things like BaseTruck. Instead, things should be named based on how they're really abstracting something. Take these class names for example: Vehicle, MotorVehicle, Truck, TrailerTruck, or Animal, Pet, Dog, GermanShepherd. It's easy to identify is a class is concrete or not if the name of concrete classes are specific and the name of abstract classes are more general. The only thing this leaves out is if a class is an interface or an abstract class, but I would argue that this is less important than being able to understand a clear hierarchy as in my example and also that you're going to need to know more about the classes anyways in order to implement them regardless.

    • @NihongoWakannai
      @NihongoWakannai Před 7 měsíci +8

      Yes, I use single letter or abbreviated variables all the time and it makes the code MORE readable. Any time I see people spreading dogma about coding style like this it makes me think they don't actually program and just regurgitate what they heard online.

    • @kirasmith1147
      @kirasmith1147 Před 7 měsíci +1

      From your first points, I disagree in that I think `ALWAYS`, `NEVER`, `MAY`, and `SHOULD` are all great, super important words for hard rules. You're looking at these rules in the video and I think the main problem is that the rules in the video are just plain naive and badly thought out. Well crowd analyzed ideas that include these words can be excellent, and a rule defined this way doesn't prevent being given context to understand it

    • @ramirosandoval781
      @ramirosandoval781 Před 7 měsíci +1

      my man, why in the goddamn world would you want to save characters?

  • @randyleberknight7049
    @randyleberknight7049 Před rokem +5

    Well reasoned and mature, with just the right amount of flexibility.
    I've seen some awful advice on the internet, and it is refreshing to see this!
    As for single letter names, 40 years ago programmers did not type well, editing was hard (sometimes on punched cards!), and the space a character took up in storage actually mattered. So in those days it made sense. Nowadays I definitely teach programmers to use very specific names.

  • @RVillani
    @RVillani Před 8 měsíci +25

    I agree with most of it, but I find typed types pretty useful.
    I believe the "I" prefix for interfaces is quite helpful in understanding how the code is structured. For instance, I don't have to go to the source of a type to know it's being used for dependency injection when it's prefixed with "I" and within a certain context. I also know that to actually find what the calls to it do, I'll have to find implementations, not its own source. That goes a long way when navigating code I didn't write myself.
    In Unreal Engine, for example, you have T for template types (like TArray), F for structs and other prefixes that are helpful to know what usages, limitations and capabilities you can assume from those types without having to read their full source.
    Not to mention distinguishing things at a glance. E for Enums, for instance, so when I see EName::Value in C++, I know Value is not a static property of some class, it's an enum value.

    • @edgarmagalhaes18
      @edgarmagalhaes18 Před 8 měsíci +5

      This! 💯

    • @renejotas
      @renejotas Před 4 měsíci +5

      Also if you press "I" your IDE will suggest you every interface relevant to that context

  • @natrixnatrix
    @natrixnatrix Před rokem +556

    I think the reason why the IThing naming pattern is standard in c# is because you almost always want to deal with interfaces and not classes directly. Which means you always have to come up with two names. One for your class and one for the classes interface. Having a standard way of naming interfaces is, therefore, very convenient. It would also be incredibly confusing if you opened up a project where the interfaces had different names than their implementations even if where they only had a single implementation each.

    • @swapode
      @swapode Před rokem +48

      Not that I use either but I think I'd prefer the way that it's done in Java (albeit less frequently, Java traditionally hasn't been as focused on interfaces as C#). Instead of IThing and Thing you'd have Thing and ThingImpl. It makes the interface you should use anyway have the "main" name and the default implementation comes alphabetically directly after the interface, making their connection obvious in most listings, be it of types or files.

    • @diadetediotedio6918
      @diadetediotedio6918 Před rokem +50

      ​@@swapode
      I think using Impl in the name of type makes it a bit of ugly, but I do respect your point.
      But, in defense of C#, prefixing interfaces with 'I' makes them easier to identify in code and even using intellisense, as we have both classes and structs in C# and having something more to differentiate interfaces turns the differentiation to be easier. It also helps with the naming of things a bit, as we can think on interfaces as they where simple units of contracts for specific things (or even traits nowadays), like "IDriveable" (it reads like, I driveable or I am driveable, you could also write IAmDriveable) or "ICanFly" or "ICachedDao", for the most part it's actually interesting.
      So instead of having interface Car and CarImpl, you can actually have the interfaces IHaveRoads, IDriveable, IGasBased, etc... and have a concrete type Car implementing these.

    • @tabularasa0606
      @tabularasa0606 Před rokem +10

      It's there because C# is basically MS Java. And Java had it first.

    • @diadetediotedio6918
      @diadetediotedio6918 Před rokem +60

      @@tabularasa0606
      At this point C# is much more than Java ever was.

    • @jeremypnet
      @jeremypnet Před rokem +31

      ThingImpl is a disaster. It implies that you will only ever have one class that implements Thing. It tells me that you have have been told to use interfaces everywhere and you’ve applied the rule without any thought.
      The c# convention sucks even worse. It has the same problem but the additional “feature” that everything in your public API starts with an I. That’s not great for readability.

  • @emilemil1
    @emilemil1 Před rokem +215

    I think there are often good reasons to keep names short, even single characters at times. This serves to show that the thing is of little importance and short-lived.
    For example consider this:
    button.onClick = (e: Event) => this.buttonClicked(e)
    In this case you know that e is an event, it is already given by its type and by knowing that you only assign event handlers to "onX" properties. The variable is also used immediately on the same line and never again. Naming it "event" or "clickEvent" or "click" in this case doesn't make your code any easier to read, but rather makes it bloated and takes your attention away from the important parts, which is the assignment and handler.

    • @Acaykath
      @Acaykath Před rokem +58

      for (int primaryClassArrayIterator = 0; primaryClassArrayIterator < cArr.length; primaryClassArrayIterator++) {
      for (int secondaryClassArrayMemberIterator = 0; secondaryClassArrayMemberIterator < cArr[primaryClassArrayIterator].getArray().length; secondaryClassArrayMemberIterator++) {

    • @aleksadacic
      @aleksadacic Před rokem +2

      you missed the point here

    • @BrianMelancon
      @BrianMelancon Před rokem +36

      Using the words "always" and "never" invites lots of "what about"s. I think the guideline (not rule) should be "Favor readability over terseness". There are obviously some things so common no one would get confused; like using i for a loop iterator, using x and y for 2D coordinates, etc. I would say in the latter case, Player.pos(x,y) is much more readable than Player.screen_position(screen_x_coordinate, screen_y_coordinate).

    • @HavyrlValdoria
      @HavyrlValdoria Před rokem +8

      @@BrianMelancon whats why you should never use "always" and "never". I say that sentence often and yes, the using of the word never is to underline the point :-D

    • @BenRangel
      @BenRangel Před rokem +4

      Yes! There's a small amount of conventions like "e" or "evt" for eventhandlers and "e" or "ex" for exceptionhandlers

  • @quinnv.3499
    @quinnv.3499 Před 11 měsíci +5

    "we have massive 4k screens"... we?

  • @yadaKiKhula
    @yadaKiKhula Před 10 měsíci +121

    As a firmware developer, prefixing variable names with datatypes is very useful. When I see a variable s16Speed, I immediately know that the variable can hold a max value of 32767 and a min of -32768 and having that info in the back of my mind can save a lot of time while debugging.

    • @stringlarson1247
      @stringlarson1247 Před 9 měsíci +12

      I started doing firmware in '84 in assembler and then C. I agree with you on that front.
      I've always been a big proponent of having a written coding convention/standard that can be passed along to new hires (others) that come into a project.
      I've seen WAY too much code where this doesn't exist, and 'the next guy' comes along and just does whatever they feel like doing. The result is never good.

    • @juanjoseleonvarea2495
      @juanjoseleonvarea2495 Před 9 měsíci +4

      From my experience translating programs from one language to another or reviewing old code that I remember almost nothing about, it helps a lot to add the type. And also use types that specify the size, like Int16, Int32, etc.

    • @deistormmods
      @deistormmods Před 8 měsíci +1

      Why wouldn't it already be prefixed as ushort? Is it not C?

    • @marccygnus
      @marccygnus Před 8 měsíci +15

      I'm an embedded engineer too and I absolutely loathe Hungarian notation. I've never found it useful, and what I have seen is type changes made without updating the var names. But when you DO update the var names, then suddenly your code commits have noise in them, likely obscuring actual changes. Never used it, never have regretted it.

    • @stringlarson1247
      @stringlarson1247 Před 8 měsíci +6

      @@marccygnus I haven't worked with C/C++ etc. in years. We never used type in variable names. We also never wrote functions/methods that were so long that one would get lost in a mess of code and not be able to see the declarations.
      I gave up on writing comments except for those special outlier cases or for API/interfaces. I can't tell you how many bazillion lines of code/comments I've run into that didn't match due to changes.

  • @MarcCastellsBallesta
    @MarcCastellsBallesta Před rokem +75

    Back at university I shared my exercises with a friend who wasted an afternoon trying to figure out why I was multiplying something by 1.0. I spend the next morning trying to figure out my own code.
    I was converting an integer to a float. That's what the 1.0 was doing there.
    I will never forget the lesson I learned that day. Write in a way you will understand the code if you read it after 6 months. And comment everything without being overly explaining.

    • @Andrew-rc3vh
      @Andrew-rc3vh Před rokem +17

      You can't comment everything without being over explaining - that's having your cake and eating it. Just use comments where you are doing something which is not that obvious, and a good way to do that is when rereading the code, if you spend a while thinking what does this do, then that's where a comment is needed. Less comments kind of make the ones that are important stand out. It's like councils putting safety signs on walls. Warning - these stairs are dangerous, make sure you are holding on tightly.

    • @xlerb2286
      @xlerb2286 Před rokem +19

      @@Andrew-rc3vh I once worked for a company where one person would write the code and another dev would add the comments. They'd just work through the code and any bits they didn't get after a moment's thought they'd add a comment. Pass it back to the original author to check they'd got the comments right (and rework the code where possible to make it clearer) then send it round for review. Worked pretty good. I tend to over comment my code while I'm working on it but I do a pass before sending it out for review where I strip most of that out - it was only for me as I was thinking through the code anyway.

    • @Andrew-rc3vh
      @Andrew-rc3vh Před rokem +3

      @@xlerb2286 Well if you have a good naming convention the code itself becomes far more readable. I think the problem with the system you describe is probably the most important comments of all are the times where the code is unconventional and may rely on things some distance away from where you are commenting. It depends on how complicated the system is you are building, but without certain comments it can take hours to figure out. The other trap is if the comment says something different to how the system works, such as if the system was altered and the comment out of date. It's one reason I prefer to rely on reading the code than too many comments. Consistency is the number one thing which makes the code readable.

    • @axjkhl7699
      @axjkhl7699 Před rokem

      @ the brogrammers with the “good code speaks for itself” mentality: just learn to write a meaningful comment about what it does, I know it’s hard for you considering the advanced level of autism

    • @KRYMauL
      @KRYMauL Před rokem +2

      @@Andrew-rc3vh Even then it’s usually easier to just build the logic into a tester and comment what you want to do.

  • @zsmith200
    @zsmith200 Před rokem +76

    For Python you can also use type hinting as a middle ground where the variable name doesn’t have the type and you get the clarity you’d have with explicit types.

    • @mitchellmebane1668
      @mitchellmebane1668 Před rokem +4

      Python also has the datetime.timedelta class. It's a little weirder than the equivalents in some other languages, but it works well enough.

    • @jocassid1
      @jocassid1 Před rokem

      I've been using type annotations in Python 3.8. In 3.8 they're kinda clunky (i.e. forward refs were added in Python 3.9).. they're still very useful. They help readability. Help you plan out functions (i.e. "I want to pass in these types of arguments and get these kinds). And they help Pycharm provide do type-checking, auto-complete, and find usages of a function or class.

    • @khuntasaurus88
      @khuntasaurus88 Před rokem

      ​@@jocassid1 if you feel like regular type annotations are not enough, you can do "import typing" for mkre such as Iterator, Generator etc. Pydantic is also a way to make your code simultaneously more and less readable at the same time

    • @igorthelight
      @igorthelight Před rokem

      @@khuntasaurus88 "Pydantic is also a way to make your code simultaneously more and less readable at the same time" - so:
      import pydantic as quantum_pydantic
      ;-)

  • @Flowery0
    @Flowery0 Před 8 měsíci +49

    There are reasons to use single letter variables, such as for position. You'll know what x y and z stand for because they always stand for position

    • @WindowsDaily
      @WindowsDaily Před 7 měsíci +9

      Of course working with position, x/y/z makes complete sense. for other places where there is no context like that, is what is being referred to here.

    • @ABZZDEV
      @ABZZDEV Před 5 měsíci +9

      even then xPos *could* be better

    • @blockify
      @blockify Před 5 měsíci +7

      In most cases yes, but say if you are working on a voxel engine where you have world coordinates and chunk coordinates, it’s nice to specify in the functions that it’s looking for xChunkPos, yChunkPos OR xWorldPos, yWorldPos

    • @geekzombie8795
      @geekzombie8795 Před 5 měsíci +1

      @@ABZZDEVYes!

    • @ajoshdoingthings541
      @ajoshdoingthings541 Před 4 měsíci +2

      Plus possible local positions within (child) components. But in general I tend to go more with "globalX/globalY/globalZ", "chunkX/chunkY/chunkZ" and/or "localX/localY/localZ". For rotational information I tend to stick with what I'm used to from CNC machines and apply the same "syntax" with A, B and C for the rotational axis.
      Like that there's really no way to mix them up and whoops by that we accidentally made a vector able to describe any given position and orientation in 3D space while mostly sticking to industrial standardisation xD@@blockify

  • @rthsw
    @rthsw Před 10 měsíci

    I LOVE your shows. I use it since 30 years, long time before in know WHY i use it. I only discovered my Code is more stable, easier to modify and for others easier to understand. But i need longer time to code something! Because sometimes i'm thinking more minutes to "How to name" or "Which symbol for the menu" or "How to make the tooltip short as possible and still easy to understand" than the coding itself. And until today, i can still read my code from 1995... and others can read it too... and the code needs to be read very seldom because it still does his work... sometimes. Thanks for naming my thoughts.

  • @davidjournot1741
    @davidjournot1741 Před rokem +26

    It happened to me multiple times that my code felt difficult to reason about, and then finding the right name for a class made everything much more clear and simple. Going out for a walk sometimes helps finding the name 😀.

  • @fletchcanny717
    @fletchcanny717 Před rokem +368

    I think "never abbreviate" is a good bit of advice for someone addicted to it, but for some code it's fine. I'll name something x if it makes sense to, because I don't wanna write a 5th order polynomial where ever x is "firstOperand". This is the first thing everyone thinks with array languages, but terse notation is good. It's also important to make sure the user has the context for it first, and to justify the learning curve. Sometimes you can (I love array languages and maths-y code), but mostly you can't.

    • @ZealanTanner
      @ZealanTanner Před rokem +52

      Also if I’m doing something like a lil for loop I’d rather use i for convenience

    • @TheodoreWard
      @TheodoreWard Před rokem +56

      To me i is a standard way to specify a simple index variable.

    • @eveleynce
      @eveleynce Před rokem +24

      also, code comments are like, a thing, so if you want to keep the variable names short for convenience you can always just describe them in the comments, and there's no point having the names long if you ALREADY have to describe them in comments anyway

    • @michaelzomsuv3631
      @michaelzomsuv3631 Před rokem +43

      It's not about abbreviation, it's about context. If your context gives you enough information already, then you can abbreviate to xyz because you know what it's about. But if you are missing the context around it, then you should not abbreviate because this is obfuscating the code. The rule could be called: "never abbreviate context" rather than just "never abbreviate".

    • @keineangabe8993
      @keineangabe8993 Před rokem +48

      @@eveleynce i think this is a really bad practise. Dont choose bad names and describe them in comments. Choose good names and dont comment.

  • @caliwolf7150
    @caliwolf7150 Před 8 měsíci

    This is the most relaxing thing I'v seen all week, thanks!

  • @xdevs23
    @xdevs23 Před 10 měsíci

    I agree with this. I've been using these techniques for quite a while and it has made working with code a lot easier.

  • @sethrenshaw8792
    @sethrenshaw8792 Před rokem +104

    I remember reading that Hungarian Notation actually came from one of the early programming leads for MS Word. The initial character actually had nothing to do with the type of the variable, it was meant to specify the type/units of the data. Was this a screen-space pixel? Maybe you have s_Width and s_Height. But for where you are on the document, you'd be measuring things in inches, so maybe i_Width (for inches) or d_Width (for document units). It was meant to inform the programmer about potential conversion issues that a simple 'int' wouldn't tell you.
    The other limitations of the time probably played a big part in them using small prefixes instead of writing out the whole words (or creating new types, like we could now). The real problems with Hungarian Notation came from other departments attempting to mimic the Word team, but not using (or knowing of?) the team's naming guidelines.
    I don't use Hungarian Notation myself, but I think it gets a lot of derision without knowing the original intent of the convention.

    • @philscherer1605
      @philscherer1605 Před rokem +26

      The very next recommendation after 'don't put types in variable names' was 'do put units in variable names'. Which, as you said, was the original intention of Hungarian notation. It's an interesting coincidence.

    • @MattDunlapCO
      @MattDunlapCO Před rokem +17

      This. The original Apps Hungarian guidelines also specified to use "from" naming rather than "to" naming for conversation functions. For example, to convert from screen space to inches you might write:
      i_width = i_from_s(s_width);
      This made it easier to visually identify type mismatches because the prefixes on the left and right should always match.

    • @vdozsa77
      @vdozsa77 Před rokem +3

      Never heard of the term Hungarian Notation before. I prefix types into variable names simply for better readability of the code. It can be useful if I hadn't worked on a project for months and I have to look into it for some reason.

    • @mikedelhoo
      @mikedelhoo Před rokem +2

      So now we can deride it while knowing its original intent ;-)

    • @bobbyfeet2240
      @bobbyfeet2240 Před rokem +7

      "the early programming leads for MS Word."
      Charles Simonyi. He was the lead for developing office (and is quite wealthy now got his trouble). He also has a PhD in computer science, so he's not just a business flak.
      I've read (and poked around in) C++ code that was a large ten effort that used Hungarian notation. It was pretty helpful, actually. Just because the type is declared *somewhere* didn't mean it's not way easier to determine it where you're looking in the code.

  • @T33K3SS3LCH3N
    @T33K3SS3LCH3N Před rokem +310

    1. Abbreviations are fine if they're readable enough and widely understood. If it's a "everyone in the industry knows, but it might be hard for a beginner"-cases, I like to use docs (like the XML annotation in C#) to spell out the full name.
    Even though it's true that screensize has expanded, there is still a point at which length makes names annoying to read.
    2. Totally agreed with units! Use a type of you can, a variable name, or at the very least add documentation. Don't make me guess!
    3. Utils are contextual. In smaller projects, I like to keep a fairly general Util class with generic stuff like float equality checks with epsilon. Never had a problem with those.
    In bigger projects it's sensible to look for a more formalised approach... but the last 20 million line project I was working with still had a simple static Util class and that was one of the few things which just worked while everything else was a mess ¯⁠\⁠_⁠(⁠ツ⁠)⁠_⁠/⁠¯

    • @andersenzheng
      @andersenzheng Před rokem +55

      2. i enforce this rule in my company. and additionally, if a variable or function returns a specific data type, especially if it returns boolean, state the variable/function name in a way the boolean would answer it like a yes/no question. E.g. instead of "checkAuth", write "canLogin" or "hasAccess"; if a function checks whether all systems are online, instead of "allSystemsOnline", say "areAllSystemsOnline" because "allSystemOnline" could be performing an action that makes all system online, but if a function is called "areAllSystemsOnline", then it is obvious that function is only going to perform a check rather than actually trying to bring all systems online.
      Also, please please please, bar some really rare scenarios, don't use negative words in names. !$user.inactive is just that much harder to read than $user.active. we are dealing with enough logical challenges already, no need to add double negative into the mix, ain't nobody got time for that.

    • @BenRangel
      @BenRangel Před rokem +20

      1. True. In some cases single char vars are ubiquitous. Like the "i" in loops. Or short names for "exception" in a try-catch. But in custom cases like "durationSeconds" I'd strongly prefer using that name as the var name - as opposed to a short name and a documentation/comment. As less docs/comments is just...less source and fewer stale things that can become outdated

    • @vibovitold
      @vibovitold Před rokem +22

      @@BenRangel yeah. if it's milliseconds though, then "durationMs" is fine for me, because "ms" is a very well established abbreviation (as long as it's obvious that it refers to time context / duration).
      relying on extensive documentation is fine if you're writing an API or a library.
      out of my experience, comments generally aren't read (even when they should be) - developers seem to develop some sort of a "comment blindness", probably because they're so often outdated or incomprehensible to begin with, so people kinda give up on them by default.
      i'm doing my best to avoid having to write any comments. if i find myself in a situation when i'm tempted to write one, more often than not it means the code needs to be rewritten. you need to explain what those 10 lines accomplish? extract those 10 lines into a well-named function; make that name take care of it.
      cases where comments are unavoidable happen sometimes - like a complex workaround required by a quirky bug in a third party library - but they're few and far between.

    • @BenRangel
      @BenRangel Před rokem +10

      @@vibovitold Agree with everything. All devs are familiar with "ms" ✅ and docs are worth if it's used by lots of people, especially public apis ✅
      I think it's fine to comment methods in a format that shows up as hints in editors. But wouldn't do it in my own teams codebase - I figure most of the time if the method name and args are simple and clear we don't need that comment. I don't hate them though. But I mostly use comments as a rarity to make people look carefully.
      I mostly comment weird stuff. Such as business decisions that seem wrong. Like "this format is obscure but we need it for marketing"
      (used to rely on git history for that type of stuff but after migrating between repos and file structures that kind of history can become obfuscated)

    • @5hunt3r
      @5hunt3r Před rokem +3

      In my company we use Utils for misc functions and extensions which are used in mutliple projects. Something like calculating a hash for some data which just doesn't warrants making a complete single funtion class out of.
      And some Extensions for EnitityFramework like AddIfNotExists or stuff like that.

  • @MrHadiSatrio
    @MrHadiSatrio Před 9 měsíci +1

    Loving this. These days where people revere complex frameworks and sophisticated abstractions, foundational details like these are often overlooked.

  • @TheShadowfox117
    @TheShadowfox117 Před 8 měsíci +2

    You can enforce a type in python if you are creating a function. For instance
    def extract(content:str, datatype='str'):
    adding :str or :int forces and prompts the user to supply a variable of that type. The same is true if you set a variable equal to something in the signature. setting a variable equal to something will prompt the user to supply a variable of that type as well as give a default value if no variable was given

  • @spaghettiking653
    @spaghettiking653 Před rokem +8

    Thanks for making this video. I've seen a lot of videos that churn on for 15 minutes about a single, overengineered design pattern for "improving" your code, but these tips are super useful because I've personally suffered from a few of these mistakes quite a bit.

  • @Hector-bj3ls
    @Hector-bj3ls Před rokem +204

    The super class having 'Base' in the name actually hurts a lot in the code I work on at work. We're in the kitchens industry and we have a thing called a base unit (or base cabinet in the US). So if you see a class 'BaseUnit' is that the base class of 'Unit' or is it the class representing a base unit? Well, the earlier devs didn't realise this so we have a bunch of confusingly named classes.

    • @pcre
      @pcre Před rokem +22

      Reminds me of working with Joomla CMS. The convention there is to name ORM model/ActiveRecord classes "Table". Meanwhile, the application domain was publishing web content in HTML tables. Hence the not at all confusing name "TableTables" 🙃

    • @Kenionatus
      @Kenionatus Před rokem +3

      pain

    • @lassipulkkinen273
      @lassipulkkinen273 Před rokem +21

      Let's not forget about HTMLHtmlElement.

    • @dreamdrunk539
      @dreamdrunk539 Před rokem +1

      This is so sad

    • @RyanFlores9
      @RyanFlores9 Před rokem +3

      @Ian Gregory this reminds me of some legacy databases I've sometimes work with. We have tables prefixed with the name of the database. For example, cms.cms_user, cms.cms_permission, etc. Makes me cringe whenever I come across those and I seriously want to write a migration to rename all those. What's worse is seeing column names following the same pattern where they're prefixed with the table's name, like user_firstname, user_lastname, user_username. AHHHHH! CRINGE!

  • @vijaydhanakodi5591
    @vijaydhanakodi5591 Před 3 měsíci

    One of the best channels I have come across. Please do videos on design patterns

  • @semsomify
    @semsomify Před 7 měsíci +1

    Utils classes always felt a bit off for me, now finally a solution for them that makes sense! Thanks

  • @eccentricslayer
    @eccentricslayer Před rokem +5

    This video is amazing! I really love the production value! Hearing others just talk about code is very inspirational and motivating. Please don't stop making these videos!

  • @DevNugget
    @DevNugget Před rokem +193

    In an oddly specific case, if you are using Applesoft BASIC on an ancient machine. You have to abbreviate your variables to 2 characters because the language differentiates and refers to the variables via their first 2 characters.

    • @whannabi
      @whannabi Před rokem +12

      It's obviously a general rule and you will recognize when you can't do that for one reason or another.

    • @Aeduo
      @Aeduo Před rokem +13

      Commodore basic is the same way. I think they're both based on microsoft basic? so maybe a microsoft basic quirk. Also I think Ti calculator BASIC is limited to single character variables? At least on the old z80 ones?

    • @IndellableHatesHandles
      @IndellableHatesHandles Před rokem +39

      Programmer: **needs 677 different variables**
      Apple: skill issue

    • @craftsmanwoodturner
      @craftsmanwoodturner Před rokem +8

      That's a bit like criticising driving schools for advocating the use of indicators (turn signals) because a Model T Ford doesn't have them...

    • @yaiirable
      @yaiirable Před rokem +6

      @@craftsmanwoodturner They were making an interesting trivia comment, rather than criticising the video.

  • @eftinile3613
    @eftinile3613 Před 8 měsíci +1

    Hungarian notation can be particularly advantageous in embedded systems scenarios where uncertainty about variable length exists or when memory conservation is a concern.

  • @go_better
    @go_better Před 11 měsíci

    Thanks, man. So many good points. I'm in awe. And subbed.

  • @paokalexthes
    @paokalexthes Před rokem +8

    This is the channel that was missing from my life. You can learn algorithms and practice and learn advanced techniques but it's like no one sits down to help you learn these kinds of things. Thank you so much, subbed.

  • @Jonaleko
    @Jonaleko Před rokem +7

    Ok, I just watched both of your videos and noticed those were all of them. I'm amazed at how great your content already is, those are some good tips and the vibe and quality of your videos are amazing. I'm definitely subscribing and keeping an eye on it for more!

  • @cometmace
    @cometmace Před 4 měsíci

    I like Hungarian notation. I had code that worked with dates. Sometimes the variable stored the date as a string, sometimes as milliseconds from a zero reference date, sometimes timezone aware, sometimes in UTC, sometimes the local timezone. Prefixing the variables with type made it so much easier to read the code. Also, it avoids having to constantly refer back to another location in the source file to determine what type the variable is.

  • @PUZO37RS
    @PUZO37RS Před 8 měsíci

    Such a cool style of telling. Bravo!🎉

  • @philcoulson
    @philcoulson Před rokem +48

    Wise words! I think the most important word in all of this is "guidelines". Yes, most of this makes sense most of the time, but there are times when deviation makes more sense (x,y,z coordinates etc). Another important concept is consistency - I hate to see numMovies and movieCount used in the same codebase.

    • @kristianjensen5877
      @kristianjensen5877 Před rokem

      Well it could get confusing if the programmer, for some assmad reason, had decided to use y for the 1st. horisontal axis, z for the 2nd. horizontal axis and x for the vertical axis.
      I guess one could technically name them horizontalX, horizontalY and verticalX or something to ensure less ambiguity even in contexts with "implicit" conventions like in coordinate systems.

    • @andrry_armor
      @andrry_armor Před rokem

      I definetly use only movieCount. Num or number is an ambitious word for amount of something (and 'amount' itself, too).

    • @ferrumignis
      @ferrumignis Před rokem +3

      Well said. People treating guidelines as some kind of immutable law makes code worse, not better.

    • @jettaeschroff6924
      @jettaeschroff6924 Před rokem

      @@kristianjensen5877 this does piss me off, in minecraft, your coordinates are x and z for where you are in the world, and then y is height. it annoys me, but i got used to it. i'll never do that in my code because no

  • @Vinylll04
    @Vinylll04 Před rokem +3

    Love to see a new computer science channel definitely subscribed! Love the way you explain and describe things and love you’re aesthetic and vibe of your videos!

  • @frequencymanipulator
    @frequencymanipulator Před 9 měsíci

    Thanks, I needed this.

  • @shadowlordalpha
    @shadowlordalpha Před 8 měsíci

    A good point to add is the code you work with is for you and anyone else with access to your code. The compilers is amazing and will do its job shrinking and removing a lot of parts but when you come back to your code after a few months of not using it you still need to be able to know what it does. Documentation helps but code that self documents is even better

  • @mb98765
    @mb98765 Před rokem +40

    Great editing, very clean presentation

  • @Ryutsashi
    @Ryutsashi Před rokem +55

    I found it helpful to have prefixes to methods, getters and such that return booleans. For example: "active" -> "isActive". "needsUpdate", "isRoot", "hasTag", etc. Not a rule, but a guideline. Makes it easy to know exactly what you're asking for and what you're getting at a glance.

    • @MichaelPohoreski
      @MichaelPohoreski Před rokem +19

      The naming convention of VerbNoun is a _very_ handy one.

    • @pedrobraz2809
      @pedrobraz2809 Před rokem +4

      This is pretty much the same as Hungarian notation, just a little better.

    • @licriss
      @licriss Před rokem +4

      Yeah this for booleans is one of my favourite naming conventions

    • @benhetland576
      @benhetland576 Před rokem

      @@MichaelPohoreski Yes, but when the underlying language is English then I found the "verb" part (too) often be indistinguishable from a noun. English just has too many words that are identical as noun and verb: capture, run, start, stop, display, screen, filter, tag, mark, file, store, jump, find, loop, click, push, in-/decrement, in-/decrease, change, set, update, call, signal, message, ....

    • @matthewwatt2295
      @matthewwatt2295 Před rokem +1

      Ruby allows for question marks in method names so you can replace (for example) 'isValid' functions with 'valid?'. Really enforces the idea that you're asking a question and getting a boolean answer.

  • @RafalAndHisThoughts
    @RafalAndHisThoughts Před rokem +3

    Great video. It restores my faith in the existance of good programmers. Cheers!

  • @YashKumar6352
    @YashKumar6352 Před 9 měsíci +1

    About the "dont name code Utils": the examples shown couldve easily stayed in a Utils namespace if they were made more generic. assignDefaults could've taken any object and filled in missing fields using the fields of another object. Then the Movies class could've made a more specialized version of assignedDefaults, effectively currying the second parameter with the defaults for the Movie class.
    A Utils namespace isnt an antipattern when made generic enough

  • @ZynthProductions
    @ZynthProductions Před rokem +5

    Why does this video so informative yet so calming at the same time. Good job!

  • @satyamsovan123
    @satyamsovan123 Před rokem +110

    Wow, this is like 3Blue1Brown teaching coding practices. You’re an awesome teacher 🙏

  • @thomasreese2816
    @thomasreese2816 Před 9 měsíci

    Adding Base to a class/variable can be very useful if it is the base for something bigger.
    A BaseButton in a component library that will be used by other libraries to define their actual Button makes sense.

  • @larsmeeuwsen859
    @larsmeeuwsen859 Před rokem

    Amazing video I definitely do some of these things like bundling in a utils or creating a base class. I have always had the feeling that it's not a good practice but just carried on. I will definitely keep these tips in mind

  • @jackwraith3504
    @jackwraith3504 Před rokem +132

    Verbs in function names are vital. For my projects, get should always refer to getting something from memory, which should not be confused with "pull" which might contain a get or a post request, "load", "write", "serialize"which contains io, or "calc" which contains some sort of calculation. This is key when it comes to something like a double for loop inside an update method. Saves hours during debugging phase.

    • @Jabberwockybird
      @Jabberwockybird Před rokem

      get is commonly used for code that does a GET request

    • @jackwraith3504
      @jackwraith3504 Před rokem +2

      @Jabberwockybird maybe for some, but never for my projects

    • @fiona9891
      @fiona9891 Před rokem +3

      wouldn't "request" as a verb make more sense than "pull"?

    • @jackwraith3504
      @jackwraith3504 Před rokem +6

      @@fiona9891 depends, there is also a subtle difference there too: 'reqXxx()' implies the remote host may potentially reject the request, whereas 'pullXxx()' implies that the remote host only servers to provide information.

    • @XoXFaby
      @XoXFaby Před 11 měsíci +18

      ​@@fiona9891 the one I've seen and prefer is "fetch"

  • @LocalPlantFern
    @LocalPlantFern Před rokem +3

    I know nothing of code, but I would love to learn from someone in this style of video! It's extremely educational, providing concise examples, and providing what seems to be important information toward the topic at hand. (in this case abbreviations within code!)
    Keep up the great work!
    I hope I can look back on these video(s) for useful tips and tricks someday :)

  • @keshavsaraogi8753
    @keshavsaraogi8753 Před 10 měsíci

    This YT Channel has helped me a lot in my understanding of code outside of the IDE

  • @iivarimokelainen
    @iivarimokelainen Před rokem +15

    interfaces are prefixed because you usually have a concrete impl of the same name, also because of var it doesn't matter that it has a prefix - the interface is mentioned in like two places only

    • @fletchcanny717
      @fletchcanny717 Před rokem +3

      Yeah but his other point kinda covers that. You have an interface with the same name as another type, you should rename one of them. I used to think a little bit of hungarian notation was fine (I learned to program in game maker so half the assets in my game started with spr_ and obj_) but after learning a bit of Haskell and Rust (where the type straight up won't compile if it's not PascalCase, and variables won't compile without camelCase/snake_case respectively) I realized how unnecessary it is to ever use hungarian notation.

    • @oghus
      @oghus Před rokem +1

      It's probably about convention or maybe something inherent in a programming language I don't know but if there is only one planned implementation for the interface (which is implied by the interface and the implementing class having the same name) then why bother with the interface at all?

    • @lahodal
      @lahodal Před rokem

      @@fletchcanny717 Renaming them just for the sake would be stupid, you would be forced to come up with artificial names all the time. I'm so glad we're prefixing interfaces in C#.

    • @fletchcanny717
      @fletchcanny717 Před rokem +1

      @@lahodal if you're struggling to come up with good names for your interfaces thats a good indicator that it's a bad abstraction. So many problems are made easier without the complexity of polymorphism.

  • @BuwnyCinnamon
    @BuwnyCinnamon Před rokem +6

    Super useful !! just when I thought I wouldn't learn anything new this opened my eyes; I have a tendency to use 'Util' classes and always thought there were ugly but did not know what to make of them, this will help me get that sorted out, thanks!

  • @mwwhited
    @mwwhited Před rokem +1

    I'd also point out that for the most part the only thing that cares about the actual type of an object is the compiler. Having a short line of code with something like `var` or `auto` and just naming the variable better is much nicer to work with. Also makes refactoring easier and makes the code read more easily... and no one cares what your `IList keylist = GetKeyListForUser(userId)` actually returns as long as it works.

  • @capnthepeafarmer
    @capnthepeafarmer Před 8 měsíci +1

    I do still work on older hardware, and the Hungarian notation is useful in those situations, because while they do have variable declarations on them, when you're seeing them in code, and in places that they are not declared, you cannot see what type of variable they are. And with the old hardware because the screen size is the limited, it does help when sorting things because you can't always sort by the variable type, sometimes you have to sort only by variable name to find what you need. So we have continue to use that Hungarian notation just as a cause of habit and standardization with that particular hardware.

  • @JohanWalters
    @JohanWalters Před rokem +7

    Only half-agree with the 'no utils' rule: yes, put functions close to where they make most sense, BUT also don't unnecessarily pollute Movie class with quirky business logic that you'd rather evolve separately from the class itself. Also not everything has to live inside an OO object, take inspiration from how functional languages organize data and code separately -- but close to each other where it makes sense.

    • @TheEmperor000
      @TheEmperor000 Před rokem +2

      You are right... I think the rule here is that if you have a Utils class, then all its methods must be static. If one of you methods needs to persist state, then you need to have a dedicated class for it, or should go directly to where it makes sense

  • @maxwellaiello
    @maxwellaiello Před rokem +163

    The most important thing is consistency. If you have a variable for the amount of cookies you have, there are so many ways to name it.
    Cookies
    cookie
    amtCookies
    Cookie_Amount
    Come up with a naming system that works with you, and it will avoid so many issues down the line.

    • @DeepVertex
      @DeepVertex Před rokem +4

      " int nbOfCookies; " is the one that i use

    • @thephoenixsystem6765
      @thephoenixsystem6765 Před rokem +17

      n_cookies has become my standard form since doing a neural net book. It's clear and concise. What more could you need? :)

    • @ararune3734
      @ararune3734 Před rokem

      int cookiesNum;

    • @tubefu
      @tubefu Před rokem +7

      I prefer nCookies

    • @kesterharding4362
      @kesterharding4362 Před rokem +25

      I would use cookieCount myself. If I saw "cookies" in code I'd assume it was the actual cookies, not a numeric.

  • @nate-wilkins
    @nate-wilkins Před 10 měsíci +1

    I appreciate the `delaySeconds` callout. It aligns with my thoughts on unrefactored code where I will prefix things with a "namespace" or larger container first approach. ie `delay_seconds`, `delay_minutes`, `event_click`

    • @LindaJuffermans
      @LindaJuffermans Před 3 měsíci

      Except click is always an event; close_button_click would be more descriptive.

  • @chad5696
    @chad5696 Před 7 měsíci

    Thank you. Everytine I have to work on old code I run into nonsensical names and no comments that force me to take more time to go though each line in an attempt to understand what they were trying to do. It's the same feeling I get when seeing someone opt not to wash after using the toilet, the option to wash is readily available yet they choose not to

  • @Hector-bj3ls
    @Hector-bj3ls Před rokem +185

    I think the single letter variable names came from a combination of low memory machines and 80 column wide monitors.
    Also, some exceptions to the no single letter name rules are: i, j, and k in loops and things like x, y, z; u, v; or r, g, b; etc... Any of those axis labels in coordinate systems.

    • @impromptu222
      @impromptu222 Před rokem +34

      You are right about the origin of the single letter variables and that's the same reason hungarian notation was around, as an helper, for old programmers the letters aren't gibberish, for newer programmers they definitely sound like that. 'strCwd' sounds like a seizure but an old programmer will recognize that it's a string representing the Current Working Directory. We don't live in a low memory world anywore and we should work ourselves up to write good variable names for the future. As for the axis, x_axis would be better in my opinion, or even horizontalAxis. As programming progresses many people that aren't from the field approach it and many fields outside programming acquire programming in their daily schedule, if a math major finds an x he might solve for it, if a pirate finds an x he might start digging, if I find an x, I would likely hope she doesn't notice me because it would be weird. In short, you should make sure that every other person reading your code who isn't in aware of your context can understand the code! :)

    • @Hector-bj3ls
      @Hector-bj3ls Před rokem +31

      @@impromptu222 I can see your point, but I would still say thay things like coordinate system labels are fine as single letter names.
      If, for example, you're in the code that deals with uv coordinates and you don't know what uv means then you probably shouldn't be messing with my procedural mesh generator.
      I wouldn't want to work with a vector library that named the axes horizontalAxis, verticalAxis, and depthAxis instead of just x, y, and z. I also wouldn't want to work with a colour library that used full names instead of rgb or hsl, etc.
      Sometimes the single letter names have a we'll known meaning in a particular domain. In which case the single letters are fine.
      I'm not saying it doesn't make it harder for new people to said domain to understand what the variables mean, but even having full names in those cases probably doesn't make the code much easier either.
      But, before we have a disagreement about something we don't disagree on, let me reiterate I agree that in general full variable names are a good thing. Especially when you work with developers whoes first language is not English. Abbreviations may seem obvious to some, but full words enable easier translation.

    • @darioabbece3948
      @darioabbece3948 Před rokem +3

      Also Fortran had pre-inizialized variables that start with specific letter

    • @yjlom
      @yjlom Před rokem +9

      other use for single letter variable name: variables that have no real meaning
      for a dumb, simple example, compare:
      add leftAddend rightAddend = leftAddend + rightAddend
      add x y = x + y

    • @ZenoDovahkiin
      @ZenoDovahkiin Před rokem +6

      @@impromptu222 A mathmatician who sees a member variable be called Vector3.x will not try to solve for it.

  • @kb-zealot
    @kb-zealot Před rokem +7

    counter examples:
    when something is a unit of time or distance among other variables of the same units names like "t" and "x" are ok.
    abbreviations: when the abbreviation is obvious and saves a lot of space it can sometimes make code easier to read, not harder. having more characters on screen also means you have to take more time to scan that same screen, i started programming long after the days of 80 char terminals, but i don't think that just being able to fit more on a screen justifies longer variable names
    "don't put types in your name". Hungarian notation really pisses me off and i hate it so much ... That being said, sometimes boolean variables might have a name that doesn't work as is* and it's easier to name it as "b_*"
    units: when your whole program is small and uses the same unit, i.e. milliseconds, and you know that's as specific as you'll ever need to be, or at least it will be in 90+% of the variables, it's ok to omit the unit.
    prefixing with "I": i have nothing for this one
    naming something *Base: suppose the derived class is templated and the base is not, that could be the reason it's been split into 2 classes, and perhaps the derived one is the one that will be more commonly used.
    utils classes: this seems like an argument of OO vs procedural more than an argument about naming. Many times one may want to create simple reusable functions that deal with basic data types, and put them in a namespace like "string_util" or "math_util", or sometimes even just "util" if you can't find a better group for it. The idea functions with even only a single data type should only exist as a method is an unfortunate perception of OO design, it might not bother you until you realize that it would be really convenient to have a "bool startsWith(std::string, std::string)" availiable in a lot of places

    • @r.t.5767
      @r.t.5767 Před rokem +2

      This should be pinned
      I also thought about "Node", a very general type/struct name (it doesn't tell you anything about what kind of structure it describes), yet if you use only one data structure in your program there's no need to be overly specific, generic names aren't always bad

    • @kb-zealot
      @kb-zealot Před rokem

      @@r.t.5767 Thanks, agreed on "Node" and similar short names. If you have a program with only 1 kind of node there's no point in making an over-long name, and if you add a different data structure in the future you can always just rename Node, either with macros if you're using vim or with a refactoring tool

  • @MrCalyho
    @MrCalyho Před 9 měsíci

    Spot on video!
    Just something to add maybe: It is ok to abbreviate if it captures the jargon of the business. The names should reflect the problem that you are solving, not the solution. The purpose of writing code is modeling the problem domain and this starts with naming. It is also handy if all platforms - Andoid/iOS/Web etc that all build the same thing on different platforms also use the same names for things.

  • @coulomb1
    @coulomb1 Před 9 měsíci

    I want to see one of this man’s projects

  • @gamesandstuff7724
    @gamesandstuff7724 Před rokem +95

    I think utils is fine for extremely general purpose functions that are used in many places in the code

    • @TheSaintsVEVO
      @TheSaintsVEVO Před rokem +6

      I think it’s also useful for creating helper methods for working with external libraries

    • @TheSaintsVEVO
      @TheSaintsVEVO Před rokem +1

      But idk I’m still a junior so maybe there’s a better way

    • @licriss
      @licriss Před rokem +11

      It can be, but is definitely an overused name just like "Shared" and "Common"
      All work sometimes but if a more specific name can be given then that often makes code easier to read, packages easier to navigate and when you forget the name of the method but kept the class name simple gives you a much shorter list of methods to scan through when you're looking for it

    • @bohs2000
      @bohs2000 Před rokem +1

      also good for unit testable methods without having to expose all the methods in a class that would otherwise contain these methods

    • @mayorc
      @mayorc Před rokem +3

      Agree but i would add a suffix or a prefix to specify what kind of utils they are, to avoid multiple utils having same names.

  • @bobybobcol127
    @bobybobcol127 Před 8 měsíci

    Bad style guides are better than no style guides.
    What a quote, I love it.

  • @TrueZutyro
    @TrueZutyro Před měsícem

    Beautiful video and very informative. I have been doing most of these without thinking, so I wonder if my teachers taught me that without me even realizing.

  • @Crashman1012
    @Crashman1012 Před rokem +232

    Your channel is awesome and I can’t wait to see it grow! One tip is possibly lowering the music volume. It was slightly distracting in my opinion and I totally get that it takes some fine tuning but figured I’d give a little advice if it helps!

    • @CodeAesthetic
      @CodeAesthetic  Před rokem +76

      Thanks for the feedback. I'll definitely lower the volume next time

    • @Crashman1012
      @Crashman1012 Před rokem +8

      @@CodeAesthetic thanks, keep up the good work!!

    • @Calz20Videos
      @Calz20Videos Před rokem +3

      I was gonna say the same thing it’s a little overpowering sknskdnf

    • @grepgrok8735
      @grepgrok8735 Před rokem +18

      @@CodeAesthetic honestly, don’t be afraid to just get rid of the music. Music for the sake of filling sound can become more distracting than anything. Have it at key points if you want (it helps make an impact) but let it fade out during explanations. Also, you voice alone sounds nice and is nowhere near the grating others have that need music to drown out.

    • @GabrielVuelmaRomanzini
      @GabrielVuelmaRomanzini Před rokem +4

      @@grepgrok8735 Complety agree with you. Found myself way more confortable at 6:40 whem the music stopped, even without voice, but coding in the screen. Apart from that, really good content, keep it up!

  • @rebane2001
    @rebane2001 Před rokem +192

    I think the I-prefix can still make sense for interfaces when they appear as file names. It's arguable for sure, but I think having the name in the filename makes a big difference on the impact of the prefix.

    • @SeanLavery
      @SeanLavery Před rokem +33

      Yup, and when you glance at the code you know its an interface and can plan accordingly. Its more readable.

    • @FireSiku
      @FireSiku Před rokem +21

      If i worked with a library or framework specialized for apple or apple products, I would be disappointed if there werent i-prefixes everywhere.

    • @ABaumstumpf
      @ABaumstumpf Před rokem +9

      We use exactly that - "I" prefix if it is an interface-class, "_t" suffix if it is a plain data-class, and very few other rules on naming stuff. It does make it easier.

    • @kris.yochev
      @kris.yochev Před rokem +17

      I believe that the I-prefix is just a variation on the Base- or Abstract- thing. Like, a WeatherService and IWeatherService could be better named as GoogleWeatherService and WeatherService.
      I would keep the I-prefix in languages where the standard library uses that naming scheme, but still apply the more-specific class name (i.e. in that case they would be GoogleWeatherService and IWeatherService).

    • @danducky4741
      @danducky4741 Před rokem

      bep

  • @Whitecroc
    @Whitecroc Před rokem +34

    The number one thing I tell new group members on student projects is to *use positive boolean names*. It is very easy to get wrapped up in chained negations when programming and in my experience it helps immensely if all of your booleans (and other types too, for that matter!) are named under the assumption that "true" describes a straightforward state, even if that state is different from what the variable is expected to evaluate to. For instance, "isHidden" is suboptimal because it inverts the concept of visibility. Even if an object being hidden is its default state, you should use "isVisible" instead to make it easier to parse what is being checked for. And be consistent with this rule! I've found that just the one inversion can make your logic a mess.
    Here's another example: "isNotInside" can be improved to "isOutside" -- but if you're describing an object that encloses a space, it might be more semantically meaningful to track what's *inside* the object. You can (probably) just name the variable "isInside", thereby keeping the apparent internal logic of the object straightforward.
    I think the I-prefix on interfaces might be due to how how C# is kinda the sanitized Java, and Java in turn is kinda the sanitized C++. I don't really know what the chain of logic might have been, but it seems like it had to do with how Java ditched multiple inheritance and low-level controls and C# tried to claw back that space a little bit. Perhaps it was felt that multiple inheritance being messy in C++ was something that could be solved partially by properly separating interfaces and classes.
    I'm guilty of doing the BaseType thing, and it's probably a habit I should break, but I find it signals effectively that the class is not for general use. Remember the lessons of self-commenting code: signal your intent. Calling something "Base" implies not only that it is abstract, but also that you should use that particular class (rather than any potential superclass) as your foundation if it matches what you want to do.

    • @mleise8292
      @mleise8292 Před 7 měsíci

      Ha! And here is the comment I was watching the video for. Because I generally use positive Boolean property names, but wondered when I had a “hasConstraints()” function. Because it is used in a heuristic, I am only interested in a decisive “false”, while a “maybe” and a “yes” can be merged in the “true” return. So for this particular case it would be more straight forward to make it “isUnconstrained()”. 😅

    • @Whitecroc
      @Whitecroc Před 7 měsíci +1

      @@mleise8292 I'd go with the former, because that extra "un-" can throw a spanner in the logical works.

    • @creativecraving
      @creativecraving Před 4 měsíci

      Re base types, maybe it signals that the class is not fit for _any_ use! 😅 All jokes aside, I am guilty of this, too; and although I disagree with some of what was said, in this case I plan to change my ways.

    • @Whitecroc
      @Whitecroc Před 4 měsíci +1

      @@creativecraving I don't think I will, personally. I worked at a place where the convention was to have subclasses share at least one word with their superclass whenever possible. So the abstract class might be called WindowBase, then there would be a concrete Window class, and that one might subclass into a DualWindow class, which in turn might be the base for a DualScreen class.
      Okay, so this is kind of a messy example. But it made sense for WPF stuff. The point is that it was easy to tell by sight if there was any inheritance going on, and made naming easier.

  • @zekiz774
    @zekiz774 Před 2 měsíci

    Im rediscovering this video after a year and it kinda surprises me how much of it stuck with me.

  • @TimFSpears
    @TimFSpears Před rokem +44

    I think an exception to the Utils naming is when the natural owner is a sealed class. For example in Java you might have a utility to get next midnight after a date in a time zone: public Date nextMidnight(Date after, TimeZone timezone). Ideally is you had extensions (like swift) you could just add it to the Date class - however in Java you can’t and are forced into DateUtils static methods.

    • @licriss
      @licriss Před rokem +14

      Yeah this is fine imo
      I think the real problem is with names that are essentially just euphamisms for "miscellaneous" as in they have no qualifiers of what they relate to at all, like "utils", "shared", "common", "globals", "constants"
      Often these things contain a bunch of random methods or values, that could actually be organised but just aren't because the thought didnt occur or a good name was just not happening

    • @vibovitold
      @vibovitold Před rokem +3

      @@licriss and let's not forget the immortal "SomethingManager"

    • @Moohasha1
      @Moohasha1 Před rokem +1

      I was going to say the same thing. If you're using a 3rd party library and cannot simply add new methods to existing types, this can be useful. In C++, I would go with a utils namespace, or perhaps a {module}_utils namespace, rather than a class.

    • @LeoFuso
      @LeoFuso Před rokem +1

      You could build a class to extended it. A decorator of sorts. You might want to avoid creating unnecessary objects, tho.

    • @Moohasha1
      @Moohasha1 Před rokem

      @@LeoFuso Yeah, I wouldn't create a class if I don't need state.

  • @arcstur
    @arcstur Před rokem +159

    I think abbreviation has advantages. Smaller names occupy less visual space on the screen, making it cleaner. Very big names makes the code harder to read, in my opinion. Some abbrevations are completely fine, like "std" for "standard", which is commonly used. Also, in the example following, you use "NumUsers", whici is another good abbreviation.

    • @sarahkatherine8458
      @sarahkatherine8458 Před rokem +47

      I agree. Not using abbreviation is only good for relatively simple class, but not when you need to get data from member of member of member of an object, and all of them have long names.
      Also not everyone has 4k monitor. I'm still working on my 1080p laptop and a sub 1366x768 monitor.

    • @gazehound
      @gazehound Před rokem +19

      Eh, it makes sense to abbreviate if the abbreviation is more canonical (like "i" in for loops) but gone are the days of 80 column displays. We have the aspect ratio to display slightly more verbose names, and I'd much rather read code which has too descriptive variable names than too short names

    • @isodoubIet
      @isodoubIet Před rokem +37

      @@gazehound Screens have gotten bigger, but our brains haven't.

    • @christopheroverbeck3662
      @christopheroverbeck3662 Před rokem +9

      Abbreviations are mostly bad. Except in such cases as the abbreviation is so well known that it's effectively a proper noun. It should be common enough that even if the reader does not know it, they can pop it into google and the first result is the definition.
      I would definitely just call it "Users" with an integer type. Unless I also want to also work with an array of users, in which case it would be preferable to do len(Users) instead of having it as a separate variable.

    • @FrozenBusChannel
      @FrozenBusChannel Před rokem +21

      I think abbreviation is fine, but don't over-abbreviate
      Like, "std" and "NumUsers" are understandable, but "s" and "NU" aren't

  • @darkobakula5190
    @darkobakula5190 Před 7 měsíci

    Absolutely agree with the initial statement of the video. Naming things while coding is one of the hardest things I've had to do. Realizing my code is hard to read when I approach it a year later makes scratch my head and I turn to debugging or trying to figure out what the code intended to do, based on what I remember or what the final product is which is time consuming. Legacy way of naming things such as the hungarian notation does not help either, its deprecated way of doing things. I've realized the way to name variables properly from reading good java code where the intention of the code is clear.

  • @olinkirkland
    @olinkirkland Před rokem +47

    This might be the best channel on CZcams. It hits that perfectionist urge and answers questions I didn't know I had about my code style. THANK YOU for the slick editing and soothing music. I actually pay attention and learn stuff!

    • @varadinagypal
      @varadinagypal Před rokem

      Well, I wouldn't go that far, but Herr Jürgen* does agree with most of what is said here. *A mythical figure, a twisted meticulous nemesis hunting down bad coders.

    • @juliocezarsilva5979
      @juliocezarsilva5979 Před rokem

      I 100% agree with you, Olin. I would, indeed, go that far.

  • @eduardsukhavenka9750
    @eduardsukhavenka9750 Před rokem +4

    Pls make more videos and don't give up on this. You're incredible! Your videos are so relaxing, your voice, the speed you're talking with, everything is perfect to me. I can even donate a little bit to support you.
    Btw. What's the name of the background music?

  • @cccccc864
    @cccccc864 Před 7 měsíci

    Omg, man, you got me 100%. Thanks for such great video.

  • @thedave1771
    @thedave1771 Před 4 měsíci +1

    For the most part, I’m with you. I still like i as an iterator, and then, for any other incrementing number. as far as C# goes, I think it’s just that there’s so many interfaces that the prefix helps avoid collisions, but I’m still very new to C#.
    BaseTruck makes sense to me when you’ll have non-English developers who won’t immediately recognize vehicle is a likely base for truck, while car isn’t. I don’t know, but I work with non-English speakers and I’ve often looked up a word and suddenly things made more sense because I got more context. This applies to writing code outside your knowledge domain where you list don’t know (or care to learn) domain-specific nomenclature.

  • @konstantinsotov6251
    @konstantinsotov6251 Před rokem +5

    Ah yes, i remember that day when i figured that C++ compiler I was using could process variable names in Cyrillic, and Used it to obfuscate code for my teacher to be unable to read it.
    Like, naming one variable "c" in english, and other "с" in Cyrillic 'n stuff
    I could have this line:
    int xp = 10, хр = 0, ko = 15, ко = 0;
    And it would work

  • @FiksIIanzO
    @FiksIIanzO Před rokem +45

    Base and I prefixes in C# in my experience can be useful. Of course, they're easier to find because you can filter out derived classes and implementations, but they also indicate that whatever you're currently using is definitely something else, because you can't make an instance of an interface or an abstract class which a base class ought to be. It helps keep track of abstractions.

    • @penguindrummaster
      @penguindrummaster Před rokem +9

      Maybe I'm biased coming from C#, but I find the interface prefix I-, and the base class previous Base- useful in understanding the contract I'm making with consumers of my code. Especially in TypeScript, there's a noticeable difference between saying "I expect an interface that implements this method" vs "I expect an abstract base class that defines these members" vs "I expect a concrete class of this type, or a subclass". This is the difference between passing curly-braces with a named function, a custom class that extends a base, or the need to use the provided types

    • @hyilpoulle
      @hyilpoulle Před rokem +10

      I wonder what is video-maker's job. It all sounds great when we're talking about real objects, but when you get into more abstract object and business logic, it's not as obvious if you're expecting the user to implement an interface or just reuse some explicit class.
      I work in a space where the "I" or "Base" is very useful.

    • @scriber36
      @scriber36 Před rokem +1

      I believe according to Liskov substitution principle, it shouldn't really matter if the declared type of the received object is abstract or not - you'll receive an object matching the type's contract. I assume it matters while writing low-level, performance-oriented code, because then abstracting away implementation details is no longer beneficial. That said, C# is a high-level language, where I don't think it matters that much. From what I see, ITruck is not better in any way than just Truck, for they define the very same contract, the contract for the functionalities of a truck. Hence, I don't see how these prefixes help in any way to organize abstractions, for abstractions are all about their contracts, not about through which otherwise transparent language feature they force those contracts. Knowing what contract apply to the creation of the argument objects in my opinion is not the responsibility of the function. The function should perform its action on the object and call it a day. The contracts of how and where such objects can be created should be defined within the type itself and only be cared about during implementation of said class. Plus, in many IDE's, as in VS, interface names are even highlighted with a different color.
      All that said, I guess most people just got used to do things in a certain way, so it just feels right to them. When I wrote C# I did follow their naming conventions. After that, I carried that naming to my private Java projects, but there it felt like clutter and I reverted back to Truck instead of ITruck and never miss them ever since.

    • @TML233
      @TML233 Před rokem +7

      Yes, I and Base prefixes definitely helped while coding. Way better than those Java implementation classes adding Impl suffixes. And I still remember that I was dead trying to create an instance of List in Java. C#'s I prefixes just makes it so much clearer.

    • @FiksIIanzO
      @FiksIIanzO Před rokem

      @@scriber36 While you are mostly correct in terms of contract handling by machines, humans don't think of OO code in terms of contract. They think of OO code in terms of types. Knowing this, providing as much useful information about what you're currently using as practical is great for making maintainable code.
      LSP and other SOLID principles make code functional and robust, proper naming makes it readable.
      As for syntax highlighing: there is way too much of it to just tell what it is at a glance. Color coding needs to be, well, decoded. An I in front of an interface tells you immediately and definitively that it's an interface.
      While I appreciate you sharing your experience of not needing them in your code, I am currently managing a 20,000+ lines project spread across 12+ microservices with up to 5 levels of abstraction of dozens of interfaces and base classes and hundreds of derived classes. I found proper, informative, distinct and consistent naming paramount in managing something like that.
      Also, while making a base class abstract isn't strictly necessary as per SOLID principles, it is very useful to signify that you must use a derived class if using the base class makes no sense, which is often the case in a complex hierarchy of multiple implementations.

  • @7th_CAV_Trooper
    @7th_CAV_Trooper Před 3 měsíci +1

    When I started programming in 1978, BASIC supported two character names and C supported eight character names. That's why we used to abbreviate. It never had anything to do with screen width. But that's okay, the guidelines in this video are right on.