6 ms·
I think I understand what OP means. I work with some smart people who use code like val x: Pair<String, Pair<String, String>> instead of say data cl
by muzani 4y ago
I think I understand what OP means. I work with some smart people who use code like
val x: Pair<String, Pair<String, String>>
instead of say
data class Status(key: String, value: String)
data class Item(name: String, status: Status)
val x: Item
To the smart ones who can keep everything in their head, the first block of code is trivial and obvious and they don't even notice that it's hard for others to read and easy to make mistakes in.
- zepolen 4y agoThe actual smart ones would realize they are writing code for others rather than themselves and go with the latter.
- delecti 4y agoThat's a very useful lesson. Also recognizing that you won't remember the code the next time you see it. It only took me a couple instances of "what moron wrote this? ...oh, it was me" before I started including myself in the "dumb future people" I'm writing my code for.
- killingtime74 4y agoYour way is better because when compiled it is the same bytecode and it’s clearer
- nohuck13 4y agoIt could also be inexperience. If your experience is limited to academic projects, grinding leetcode, even competitive programming, you've done things where first one is nearly always optimal. Once you are on a team optimizing for continued feature delivery over time, the cognitive load of picking up and understanding old code full of raw maps and strings starts to justify the overhead of a bit more semantic scaffolding in places. IMO the necessary judgment has to be learned even by smart, academically talented people.
- franciscop 4y agoI've rarely worked in a team where the extra scaffolding was ever worth it. In fact chasing the scaffolding scattered through varied files through the filesystem was a lot trickier usually than fixing the actual bug I was trying to fix.
- nohuck13 4y agoDesign pattern spaghetti is absolutely a thing. I feel like self-contained, self-describing, potentially self-validating data types like in the parent comment would tend to be complexity-reducing as long as they don't mix in control flow or deep deep inheritance hierarchies, though.
- collyw 4y agoAs someone getting close to 50, inexperience also seems to correlate with the ability to hold more in short term memory.
- CoastalCoder 4y agoAgreed. Same age, same experience. I'm also finding myself more allergic to unnecessary code complexity / non-standard designs, because they impede my ability to work with the code base. It's still a little painful to no longer be the smartest person in the room, but I think it makes me a better champion for regular programmers who will need to touch the code.
- collyw 4y agoI may not be the "smartest" in the room in terms of raw compute power of my brain, but as a result I'll write better code (more maintainable, easier for the next dev to understand). I want my code to be easy to follow. One of my personal rules I have through experience, is if I revisit a bit of code that I wrote a while ago, and I can't understand it easily, it's probably time to refactor it.
- protomolecule 4y agoI once worked with a guy with a rather good memory who wrote code like that and could maintain it for years. I was impressed with his ability until he hit his limit and made half a dozen of subtle bugs in one commit.
- peteradio 4y agoGeez never make a mistake in front of this guy or your years long reputation gets shredded.
- protomolecule 4y agoHe had been writing unmaintainable code for years and finally he experienced what it was like for everyone else. That's hardly a mistake.
- dusted 4y agoThat's not about being smart or not.. But about brevity and a bit of experience. I'd certainly recommend the first one, there's simply less stuff to parse, it's easier and quicker to read. x is a pair with key of type string and value of pair with key of type string and value of type string. The other one is overly verbose to read, it takes more effort to read and understand.. But it could have merit, for instance if you need to extract status into a variable of declared type later..
- collyw 4y agoUsed to do a lot of Perl, which is a wonderful language for writing obfuscated code. If something is an advanced feature of the language and I felt the need to use it, I would ad a comment explaining what the code was doing.
- dusted 4y agoIt's a good idea to write _what_ something does, especially when the algorithm seems very "generic". I'll a thousand times rather have // Create users from id's userList = theblackmagiconeliner; Than a 20 line version of it where I'm left having to read through it to determine "oh, it made users from a list of id's" or even just.. having to read through it to find out if there's other stuff plugged in because "it could go there" or even just finding where it ends and actual work starts. userList = userListFromUserIdList(userIds); is also perfectly acceptable, but if it's only used once in that file, I'd prefer the blackmagiconeliner.. If it's only used once in the project, I'd also prefer that to having another file just for that function. Just do the work and get on with it.
- stirfish 4y agoPut the 20 line version in a properly named function, even if it's only used once. There are two reasons for this: 1. You're probably doing something else where you don't want to stop and decipher a magic one-liner. That comment is a great name for that function. 2. Now that you have a function, write a test. Now that you have a test, your coworkers won't be tempted to tuck extra stuff in that function, because everyone hates editing tests.
- Olreich 4y agoWhich of these is better is a matter of distance and scope. If x is only used locally and within a screen or two of the declaration, adding a data structure screens or files away will make things harder to parse. If x is used in many places, passed around to many functions, or is otherwise far away from where it’s needed, it should be replaced with something that has better naming and more robust structure. If it’s the latter, you should rename it away from x as well, as the name of the variable is the first thing that should get documented as you increase distance. If you have a `Status` type already, then you should use that even if X is hyper-local. Of note, the nesting here seems suspect, why not use a three item tuple or a flattened data class? In many cases I find where people start arguing about naming or abstraction, there’s a way to simplify things further so it’s readable for everyone and easier to use inline. I always look for those now when I’m reaching for “you should rename this” or “you should restructure this” kind of comments.
- joelfried 4y agoI think you're missing the forest for the trees here somewhat. What I believe GP to mean is that rather than use written out names and data structure layouts that make code easy to digest for others on the team, some folks choose code that makes their personal mental models easy to construct. This can be extremely valuable, but is also very bespoke and difficult to maintain. I completely agree with your last point regardless: those kinds of arguments honestly held between well meaning team members are definitely a strong indicator that the implementation used is mismatching the use case at some level.
- gptgpp 4y agoHmmm, I don't know about this example. I'm kind of a certified idiot and the first one seems way more intuitive than the second one because it is succinct with much less abstraction. It's easier to "keep in my head" than the second one for me and, again, I cannot stress enough that I am not a clever man.