5 ms·
You know, naming things is hard, and it's not reasonable to argue that your code should always be in the optimal state. There are "on the way" states, and it s
by yebyen 8y ago
You know, naming things is hard, and it's not reasonable to argue that your code should always be in the optimal state. There are "on the way" states, and it seems like this feature can be used well by saving you from choosing a wrong name too early in the development stages.
Sometimes you haven't decided what a name should be yet. I do not want to see @1 @2 @3 in code 6 months later, either. That's the kind of thing that I'd search for in my codebase before I closed the project, and assign a name before it's too late for me to remember what that bit of code was for. (And look, how handy it's a completely original arrangement of characters that you can even grep for without straining!)
But sometimes you don't have a name ready and it's actually better to defer naming the thing until you know what it is. This feature enables that. You can save yourself from picking a wrong name, come back later when the code around that @# has solidified and it's clearer what to call it. I have never seen this feature before this article, but seeing the ways that people are arguing against it has given me a better understanding of the ways that it can be used well.
I've just been catching up on my tech lore and I'm watching Sandi Metz talks from RailsConfs gone by. There's one talk in particular "all the little things" where the subject is the gilded rose exercise, and how she would refactor it. In the course of the exercise the code complexity goes up (almost doubles) before the gains are realized, and suddenly there's this huge bit of code that can be safely deleted, now the complexity has gone way down and the code is good.
My only point in bringing this up is that there are intermediary states that, if observed in a vacuum, we'd all agree are badly formed and simply not exemplary. This strikes me as an example of one of those features. You can come back and make it better. This is just how it will look "on the way" to something better. (I know, "you won't come back" but that's not an argument that I'm ready to accept.)
- intertextuality 8y ago> it's not reasonable to argue that your code should always be in the optimal state. This is a strawman and not what I believe. I never said your codebase should always be optimal in every way. I believe @1 instead of even the most basic of variable names is actively an anti-pattern. > That's the kind of thing that I'd search for in my codebase before I closed the project, and assign a name before it's too late for me to remember what that bit of code was for. Maybe you might, but plenty of other people will not. I have also lied to myself and added "TODO" comments in some small projects I've worked on. Months and years later I sometimes see "TODO" comments because I ended up working on something else or forgot. It's simply way too easy to not go back and refactor or fix things. There is nothing more permanent than temporary code. Sometimes you have to go back and rename things multiple times. This is vastly better than what you know full well will happen: People will immediately gravitate towards the easiest option of @1, and then never change it because they've moved onto other parts of the code or different projects, etc. We should not be adding ugly, terse syntax to programming languages because it's "just more convenient" to not name things. That is not a tenable argument for a permanent change to a mature language. Being lazy is not an argument.
- yebyen 8y ago> Maybe you might, but plenty of other people will not. I have also lied to myself and added "TODO" comments in some small projects I've worked on. So it was cheaper to leave the TODOs in the perfectly OK code, sounds like you dodged a bullet there. This strikes me as a slippery slope. Start with "@1 is not an appropriate way to represent this variable" then move onto "I actually don't like the name you've chosen" and finally arrive at "this code isn't important enough for me to take care of those TODOs I placed before I'm old and gray, remind me why are we even worried about how this variable is called, now renaming it for the _third time_?" I'll usually take a collection of "xs" and iterate over each "x" without any pretense that I'm coming back to make it better. We can agree to disagree, but I'm arguing that it's not any better to do that, and it's actually harder to grep for which makes it actively worse. This is a better option.
- intertextuality 8y ago> sounds like you dodged a bullet there. My point is that I never went back and fixed it, because often people do not do that. I, however, can still read that code perfectly fine and well because it has variable names. Not @1 and @2 for hashes, etc. > now renaming it for the _third time_?" Things get renamed from time to time (and less than you're making it out to be, typically). It's part of programming. You will be fine. It's better to be oh-so-inconvenienced than to have to read other peoples' codebases where they just use @1 and @2. Why have any variable names at all then? Just use 0-999, if it's so annoying to have to think for a few seconds to a minute and pick an apt name.
- yebyen 8y ago> I, however, can still read that code perfectly fine and well because it has variable names. Not @1 and @2 for hashes, etc. If I do {@1 + @2} exactly once is that really harder to read than {|x, y| x + y}? If I'm doing it everywhere all over my code, sure that's a problem and it will make unreadable garbage. But then again it was already possible to make unreadable garbage code.
- jjuel 8y agoI don't program in Ruby and never really have, but there is one thing I know dealing with plenty of legacy code: Temporary code is almost always permanent.
- nathan_long 8y agoEverything is a tradeoff. You say: > sometimes you don't have a name ready and it's actually better to defer naming the thing until you know what it is You can do that without this feature; you can use throwaway variable names like "x" and "y". Taking an example from the post: > (1..9).each_slice(3).map { |x, y, z| x + y + z } vs > (1..9).each_slice(3).map { @1 + @2 + @3 } The shorthand saves you 7 characters in the rare case when you truly have no idea what to call your block parameters (even a single-character name can be descriptive, eg if x and y are coordinates). That seems minimally useful. Meanwhile, you've made your block parameters look like instance variables, and everyone else (including all tools that work with Ruby code) has to learn why they aren't. Seems like a poor tradeoff to me.
- Retra 8y agoNaming things is not hard. It's probably the easiest part of programming. @1, @2 are names, and they're no better than fst, snd.
- yebyen 8y agoI'm sorry, but there's a great deal of literature in support of this idea that naming things /well/ is one of the harder problems of programming. If you're arguing that "fst" and "snd" are better names than "@1" and "@2" then I think we have a disagreement. None of those are good names. (All of those might be perfectly "sufficient" names, though. For a local variable, I would argue that spending any time at all on naming is a mistake. Spend that time writing a descriptive method name instead.) https://martinfowler.com/bliki/TwoHardThings.html https://martinfowler.com/bliki/TwoHardThings.html https://hilton.org.uk/blog/why-naming-things-is-hard https://hilton.org.uk/blog/why-naming-things-is-hard https://www.quora.com/Why-is-naming-things-hard-in-computer-science-and-how-can-it-can-be-made-easier https://www.quora.com/Why-is-naming-things-hard-in-computer-... This is foundations of computer science stuff. If you choose a solidly descriptive but wrong name before the design is fully solidified, you may be stuck with it because it will work its way through dependencies. Even if you can rename it later during refactoring, the name will shape the formulation of those refactors. I think all of this is overblown when it comes to talking about local variables in a block scope. This is absolutely a case study in the "bikeshed problem" at this point in the thread. There are other features planned in Ruby 2.7 (like the :. operator) that actually make the operation of some code less discoverable and will hurt to see in your codebase for the first time, but we're not talking about them at all, because they're simply not as easy for us to hate on.
- Retra 8y agoA regularly repeated meme is not "a great deal of literature." To say naming things is hard is like saying that getting a golf ball into a hole is hard; It is not. Sure it is if you're using some artificial restriction that you have to whack it with a stick from 400 yards away. Naming your children might be hard if you're trying to solve world poverty via the child-naming process. And naming things might be hard for programmers if they are not allowed to rename things or document the meaning and history of their names. But that really doesn't have much to do with language design. >If you're arguing that "fst" and "snd" are better names than "@1" and "@2" then I think we have a disagreement. I'm not arguing that. I'm arguing that they are not worse names. And as you probably recognized, if names like (@1, @2) are a good enough solution, then certainly (a, b), or (fst, snd) have an equivalently high bar for rejection.