Rubarian Notation
I recently bought the book "The Best of Ruby Quiz" by James Edward Gray II. This is a fun little book of simple programs to write in Ruby, and a number of solutions to those programs written by folks in the Ruby community.
The very first problem is a simple game of Mad Libs. As I read trough the solutions at the end of the book, I found that I did not care for any of them.
Don't get me wrong, I thought the solutions were clever, and I learned a lot from them. I just didn't think they were particularly clear or clean. So I decided to see if I could do better. And, of course, I think I did.
That was about three weeks ago. Today I went back to the program I wrote to see if I could clean it up even more. I found that I was tempted to do something very strange. Here's the snippet of code that started that temptation:
def translate(text)
questions_and_text = split_questions_from_text(text)
answers_and_text = replace_questions_with_answers(questions_and_text)
answers_and_text.join
end
I looked at this and realized that I didn't remember the type of the variable questions_and_text.
Now, type is an interesting concept in Ruby. Variables don't have a type. Instances do, but variables are simply untyped references to those instances. So what kind of instance was this questions_and_text variable referring to?
I was pretty sure that the instance behind the variable was a simple list of strings. Although "simple" isn't quite the right word. It was a list of strings in which every other string was a mad-libs question. You know, like "verb", or "adjective", or "name of girl in room". So the questions_and_text variable held a list of strings of alternating questions and text.
I didn't want to have to reason this out the next time I read this. So I was strongly tempted to change the name of the variable to list_of_alternating_text_and_questions; but this seemed pretty long to me. So I naturally thought of abbreviating it to ls_alternating_text_questions. The abbreviation made me think that I should come up with a suite of standard abbreviations that helped to indicate the type of a variable. And then I stopped myself.
Now this embarrasing chain of reasoning took less than two or three seconds. But it scared me. I had, in that short space of time, nearly convinced myself that Ruby requires Hungarian Notation!!! Indeed, this thought is still quaking around in my brain. Am I really so bound to statically typed languages that I need to encode the type of a variable in it's name? Or is there a better way?
Of course there is a better way. We should be naming our variables for what we do to them, not for what they contain. That implies that we should create variables that we do things to, rather than variables that simply hold data. Indeed, that's just OO, isn't it?
Stay tuned...
!commentForm -r
Those of us in the "more strongly typed" worlds tend to really want to specify a type FIRST and then a variable name thereafter. It always seems to bit me in the backside when typing SQL where the column name comes first and then its type second, since I'm so used to typing the TYPE first in C/C++ and then the name second. Furthermore, "typeless" languages seem to annoy me to death. I frantically look through the code trying to figure out the types and finding naught gives me cause for undue concern. In other words, I can see how your impulse to "typify" Ruby with Hungarian came about.
I had an online discussion with a guy who was then (a few years ago) learning Ruby where I mentioned that using (system) Hungarian was a convenience for those who wanted to know the type of the variable throughout the code. I originally advocated keeping the "type info" with the variable as a matter of convenience when looking through code, but eventually realized that if your code wasn't able to "depict" the type within the context of its use, then you (meaning me) weren't properly naming your variables. Moreover, if a variable declaration is "too far" from its use, then another problem exists with the code, IMO. This is one of the MAJOR annoyances that I have with C++ that is, thankfully, completely adjudicated by modern code editors such as SlickEdit[?] and other "Intellisense" type editors. The notion of "storing" all of the member variables in a header file and then trying to "remember" them in an implementation file always seemed "bass ackwards" to me.
Java tends to improve upon the "variable defined in the header" only slightly as a result of not using headers, but in a very C-like way that tends to lump all of the "class member" variables at the top of the code or wherever the class "definition" is found.
I'm still a Ruby novice, mostly because I'm "more strongly typed" and have a hard time with VBScript and JavaScript[?] as much as Python and Ruby and other languages where the type is resolved at runtime. I still can't help myself and find that I HAVE to type the type first, the variable name second and that leads to some kind of justification for "System Hungarian."
More than anything, I think that we, individually and as a group, need to evolve as programmers such that we do apply "best practices," even if tomorrow's newest learnings completely refutes them. Why else would refactoring be of value?! :D
Take Care.
Rob!
I had an online discussion with a guy who was then (a few years ago) learning Ruby where I mentioned that using (system) Hungarian was a convenience for those who wanted to know the type of the variable throughout the code. I originally advocated keeping the "type info" with the variable as a matter of convenience when looking through code, but eventually realized that if your code wasn't able to "depict" the type within the context of its use, then you (meaning me) weren't properly naming your variables. Moreover, if a variable declaration is "too far" from its use, then another problem exists with the code, IMO. This is one of the MAJOR annoyances that I have with C++ that is, thankfully, completely adjudicated by modern code editors such as SlickEdit[?] and other "Intellisense" type editors. The notion of "storing" all of the member variables in a header file and then trying to "remember" them in an implementation file always seemed "bass ackwards" to me.
Java tends to improve upon the "variable defined in the header" only slightly as a result of not using headers, but in a very C-like way that tends to lump all of the "class member" variables at the top of the code or wherever the class "definition" is found.
I'm still a Ruby novice, mostly because I'm "more strongly typed" and have a hard time with VBScript and JavaScript[?] as much as Python and Ruby and other languages where the type is resolved at runtime. I still can't help myself and find that I HAVE to type the type first, the variable name second and that leads to some kind of justification for "System Hungarian."
More than anything, I think that we, individually and as a group, need to evolve as programmers such that we do apply "best practices," even if tomorrow's newest learnings completely refutes them. Why else would refactoring be of value?! :D
Take Care.
Rob!
I'm doubly appalled. I didn't think that even C needed hungarian ("Barbarian Notation"), though I have had to put up with it. Worse yet, I've seen it in Java. shudders
I would naturally think of that structure as a map of questions to their answers. I have found that indexing (especially with weird, implicit "even numbers are questions" semantics) would drive me nuts. To do funky indexing, I have to have more variables, and which list or array to apply them to, and what it will mean when I do so. This bugged me with the bowling game too. I think that tricky subscripting is never 'the simplest thing' but can often be 'the most primitive thing' -- and I don't think they're the same statement.
I suppose it would be better if it were a map or a list of two-tuples. Of course, if you use two-tuples you might as well define a class with named members. In fact, it may be that old bugaboo of having "too much cool" in the builtin types biting at you once again.
I would naturally think of that structure as a map of questions to their answers. I have found that indexing (especially with weird, implicit "even numbers are questions" semantics) would drive me nuts. To do funky indexing, I have to have more variables, and which list or array to apply them to, and what it will mean when I do so. This bugged me with the bowling game too. I think that tricky subscripting is never 'the simplest thing' but can often be 'the most primitive thing' -- and I don't think they're the same statement.
I suppose it would be better if it were a map or a list of two-tuples. Of course, if you use two-tuples you might as well define a class with named members. In fact, it may be that old bugaboo of having "too much cool" in the builtin types biting at you once again.
I got a bit of a chuckle out of this, because it brought one of Joel Sposky's rants to mind. It turns out (at least according to Joel) that what most of us think of as Hungarian notation is a perversion created by the Microsoft operating system people of what Simonyi originally used for the early versions of Word and Excel.
http://www.joelonsoftware.com/articles/Wrong.html
Now, I'd never use this in a statically typed language like Java or dotNet if I was really rigorous about creating a new class for each distinct concept. In a language without type declarations, I suspect Joel might have a point.
John Roth
http://www.joelonsoftware.com/articles/Wrong.html
Now, I'd never use this in a statically typed language like Java or dotNet if I was really rigorous about creating a new class for each distinct concept. In a language without type declarations, I suspect Joel might have a point.
John Roth
Add Child Page to RubarianNotation