Why are people always trying to accomplish things "all in one statement" or "all in one regular expression"? Usually when I see these questions it gives me the impression that the asker can think of a way to do it, but it would take two statements/expressions (and that would just be too many!). And often times it's on IRC where by the time they've asked the question and gotten an answer (which probably consists of "why don't you just use two statements?"), they could have already coded something that would have worked but not taken only one statement/expression.
Is this an instance of premature optimization? Do they believe in the false economy that "less text" equates to "more efficient code"? Or perhaps as delirium's meditation seems to imply, they think that "less text" equates to "more elegant code"? Granted, there are some instances where it would make the code read better if there were a way to get some complex functionality into one expression, but you know what? We already have a way to do that; they're called subroutines. I think people need to realize that clarity trumps cleverness always (okay, except when your goal is cleverness like with golf or obfuscations)
Or is that it right there? Perl has a reputation of being clever, so users always want to do something clever in their code.
Where do you guys think this pervasive meme comes from? And are current methods of education stemming the tide of ignorance?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: All in one
by Roy Johnson (Monsignor) on Jan 12, 2004 at 19:48 UTC | |
There is a tendency among less experienced coders -- those who haven't had to go back and rework their programs months later -- to value "coolness" over clarity. That's a viewpoint that is usually self-correcting in time. Good points about clarity and subroutines. The PerlMonk tr/// Advocate | [reply] |
|
Re: All in one
by hardburn (Abbot) on Jan 12, 2004 at 20:03 UTC | |
In many cases, the second statement will require the programmer to assign a value to a temp variable. This can be avoided by merging two statements into a single one. This may or may not save memory or speed, depending on a number of details (like if they're returning an array vs. an arrayref). It may look particularly good for large list processing, such as with the Schwarzian Transform. I am not completely convinced if this is a bad thing to strive for or not. If anything, the programmer may learn something about the expressiveness of the languge in question, which carries its own reward. As an example, I've started using this idiom for filling HTML::Template loops based on Class::DBI objects:
Very expressive, and I think the double-curly looks sexy :) ---- : () { :|:& };: Note: All code is untested, unless otherwise stated | [reply] [d/l] [select] |
|
Re: All in one
by BrowserUk (Patriarch) on Jan 12, 2004 at 22:40 UTC | |
Personally, I think that there are several benefits of concise code -- as contrasted with either obfuscated code or "long-hand" code. They are same benefits that a VHLL has over a HLL. Doing the same thing, with fewer lines -- within sensible constraints of clarity -- mean that: Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham"Think for yourself!" - Abigail Timing (and a little luck) are everything! | [reply] |
|
Re: All in one
by ysth (Canon) on Jan 12, 2004 at 19:46 UTC | |
Where do you guys think this pervasive meme comes from?Perhaps from the expressiveness of the language. I think it attracts programmers who enjoy the process of translating what's in their head to what's on the screen. Then they find the process so enjoyable, they can't help playing with it. And are current methods of education stemming the tide of ignorance?No. | [reply] |
|
Re: All in one
by l2kashe (Deacon) on Jan 12, 2004 at 21:01 UTC | |
Others have already commented on Perl's allowance for expressiveness, and I think that is a direct factor. Also there is the statement of 'less code equals less bug opportunities'. Personally I have found myself doing the same thing, and at some point I step away and simply leave a #TODO: blah on the lines preceeding and move on. Other times I have fought the battle and won or lost. Every time I have found myself in this situation though, I end up in the docs. Just about everytime I'm in the docs poking around I tend to remember something I wanted to look up, or happen to read an entry I haven't seen before. I seem to always learn/refresh something during these times, which is always a good thing. Is the behaviour right or wrong? Depends on the situation. There is a reason the terms 'magic' and 'deep magic' exist. Someone spent the time, somewhere, to figure out exactly how to get the best performance out of a given piece of code. What happens if someone spends the time now, wrestling with a few different problems along this line? Next time they encounter the same situation, they can pull from past experience and apply the knowledge now. Read be more efficient. Whether that be with less code, or less time spent due to already having an answer. Now look at the flip side. Eh.. it's good enough as is. Probably can't/shouldn't do anything else with it. Then something isn't fast/efficient enough and the crunch is on. Bad time to start attempting to streamline code. Hacking code is, or should be in my opinion, fun. It's gratifying to be able to take something x lines long and reduce by y, while possibly adding functionality and/or abstraction at the same time. Someone's sig around here is something to the effect of 'I know I'm on the right path, when by deleting I'm adding functionality'. </ramble> use perl; | [reply] |
by ysth (Canon) on Jan 12, 2004 at 22:15 UTC | |
Every time I have found myself in this situation though, I end up in the docs. Just about everytime I'm in the docs poking around I tend to remember something I wanted to look up, or happen to read an entry I haven't seen before. I seem to always learn/refresh something during these times, which is always a good thing.I think professional programmers should expect to spend %x percent of their time on improving their knowlege of their tools and %y percent of their time improving the tools themselves. Even under deadline. Insert x and y as appropriate for your situation; I like 10. | [reply] |
|
Re: All in one
by Art_XIV (Hermit) on Jan 12, 2004 at 19:56 UTC | |
I don't think that the more experienced monks always try for the shortest/cleverest code that they can manage, but that they do often try for the most idiomatic code that they can, which will tend to produce short/clever code as a side-effect.
Hanlon's Razor - "Never attribute to malice that which can be adequately explained by stupidity"
| [reply] |
|
Re: All in one
by Abigail-II (Bishop) on Jan 13, 2004 at 10:29 UTC | |
Is this an instance of premature optimization? Do they believe in the false economy that "less text" equates to "more efficient code"? Or perhaps as delirium's meditation seems to imply, they think that "less text" equates to "more elegant code"? Granted, there are some instances where it would make the code read better if there were a way to get some complex functionality into one expression, but you know what? We already have a way to do that; they're called subroutines. I think people need to realize that clarity trumps cleverness always (okay, except when your goal is cleverness like with golf or obfuscations) Part of writing good programs involves making trade-offs, and to balance resources. There are many resources to deal with, and "screen estate" is one of them. A window can only display a limited amount of lines at a time - and a persons view usually even less. Tersity means a person going through the code needs to scroll less/move less with their eyes. (This is also one of the reasons I don't like to mix code with POD, and that I am not liberal with comments). Subroutines don't always make it easier to grok code. A program that can be read top to bottom is sometimes easier to figure out than a program where you have to jump all over the file to follow a programs logic (OO makes it even worse). Abigail | [reply] |
by duff (Parson) on Jan 14, 2004 at 20:17 UTC | |
Part of writing good programs involves making trade-offs, and to balance resources. There are many resources to deal with, and "screen estate" is one of them Aye, and "conceptual density" is another factor that often balances against screen realestate. I guess that, IMHO, most people try to accomplish things in one statement gratuitously (at the expense of clarity). | [reply] |
|
Re: All in one
by insensate (Hermit) on Jan 12, 2004 at 21:27 UTC | |
| [reply] |
|
Re: All in one
by delirium (Chaplain) on Jan 12, 2004 at 21:38 UTC | |
The achievement is solving the problem you picked. I want to see if I can be even more obtusely clever. On the other hand, your mind is being excercised just as though you were solving a practical problem. As a diversion, it certainly has more value than other monitor-based activities (TV watching, video games). But as a previous poster said, you remember some of the tricks you pick up on the way, and they might turn out to be truly useful some day. And are current methods of education stemming the tide of ignorance? People usually make it through life with their ignorance intact, education or no. | [reply] |
|
Re: All in one
by Abigail-II (Bishop) on Jan 13, 2004 at 10:18 UTC | |
Why are people always trying to accomplish things "all in one statement" or "all in one regular expression"?For trying to do it all in one regular expression, there could be valid reasons. Regular expression can be found in configuration files, web forms (search pages), or as arguments to programs (grep) or functions (split), where you don't always have the luxury of adding code. Abigail | [reply] |
|
Re: All in one
by jonadab (Parson) on Jan 13, 2004 at 01:32 UTC | |
Why are people always trying to accomplish things "all in one statement" I find myself doing this with some frequency, though usually I don't go so far as to ask someone else for help doing it. I think one of the main reasons I like to reduce multiple statements into one is, well, because I can. It's a diversion, something to do while you figure out how that next function (or whatever) is going to work. It's a little like playing Perl golf, but it's less work. Sometimes readability is enhanced by reducing the number of statements, especially in cases where it lets you cut out some temporary variables. Other times, you can go too far and actively harm readability, at which point sensible people should back off and leave it as two or more statements, unless what you're coding is an obfu or japh.
| [reply] [d/l] |
|
Re: All in one
by flyingmoose (Priest) on Jan 13, 2004 at 14:04 UTC | |
I'm going to agree with duff here, something like the map with double curly braces or a scary combination of a regex and multiple if's &&'s ||'s or's and various other operators has a downside. Maybe it's fast, maybe it was fun for the programmer to invent and maybe it makes him/her happy, but it's a maintainance problem. Every time a user runs into this new idiom, they have to try to grok it, and that takes time. Furthermore, simple statements rather than complex ones can be extended more easily to do other things -- which is usually what needs to be done from a maintainance perspective. Another problem is that the idioms that rely on niche corners of the language make porting between different versions of the language, or (more so) different languages This goes back to the earlier meditation on "elegance", where some one posted that one-liners are more elegant, and that clear and elegant were two different things. IMHO - first a program should be accurate and up to performance specs - then it should be easily extensible - then it should be readable - then it should be short - then it should be clever (in that order, and hopefully the top three goals are always met) There is zero room for obscurity in my book. I find it to be rather unprofessional, and detrimental to the inclusion of Perl in non-Perl-elite circles. There is a lot of bias against Perl, and while these statements are cool, when used in excess, they are to the detriment of the language in foreign camps. Just read any of the anti-Perl bias for the Python and Ruby folks. These languages are a lot alike, and really, they percieve Perl as an evil. Think about that, next time one decides to ponder one-liners and whether clarity and brevity are one in the same. I'll say they are not. I'll also agree with Abigail here that OO-jumping (especially Java-esque OO) over 15 subroutines and 15 files is a horrible way to do things. I'm not trying to steer people here. Simple maintainability is about transparency. Whatever is a barrier to groking the code should be removed. Sometimes this involves consolidation, sometimes expansion. Perl elegance? It's a Zen thing. Consider the pebble. | [reply] |
by hardburn (Abbot) on Jan 13, 2004 at 14:34 UTC | |
I'll also agree with Abigail here that OO-jumping (especially Java-esque OO) over 15 subroutines and 15 files is a horrible way to do things. This is one reason why a good design layout is important, probably with UML. You can view the complete design at once and immediately see how each class relates to the others, all in one diagram. No need to jump between a bunch of files. I remember first looking at the Freenet Project (external link), which has a reference implementation that is an excelent OO design. However, there isn't any sort of design document for how all these objects interact (at least, there wasn't back then--this might have changed). Figuring out this beast meant wading through a huge directory structure of Java classes, which may have little or no documentation on their own. I can get through a Perl obfu easier than I could work my way through that. ---- : () { :|:& };: Note: All code is untested, unless otherwise stated | [reply] [d/l] |
by Abigail-II (Bishop) on Jan 13, 2004 at 14:47 UTC | |
This is one reason why a good design layout is important, probably with UML. You can view the complete design at once and immediately see how each class relates to the others, all in one diagram. No need to jump between a bunch of files.I wasn't talking about the situation where you proudly show your design in a conference room using a spiffy powerpoint presentation. I was more thinking of a situation where it's 11:45 PM, the bug needs to be fixed at 9 AM or the customer (who's 6 timezones ahead of you) will have to be paid damages and you are trying to figure out what piece of code is mangling your data incorrectly. I've yet to see a UML diagram that indicates where the bugs are. Abigail | [reply] |
by hardburn (Abbot) on Jan 13, 2004 at 15:10 UTC | |
by flyingmoose (Priest) on Jan 13, 2004 at 14:53 UTC | |
You are partially right. UML does provide a nifty design file, but it does not proclude the creation of architectures that have dependencies on thousands of objects, evil beasts that require jumping through 15 methods to achieve reality. Note about UML -- Many times, though, UML is generated after-the-fact (from code using Rational's software) and in absense of actual design, planning, and API/design documentation. And this is encouraged in the industry. So when design is no longer a seperate step, it ceases to be design. Personally, I do design on whiteboards and with pencils, translate later, and if you start with UML you have already started too low-level. I like to work down from modular components that each have seperate purposes. The insides of those modules can be designed once their behavior and interfaces are defined, but mainly I care first about how the system acts, and what it is. Is it primarly an event loop, etc? I don't care if there is a SuperConductingEventLoopManagerDelegate, for instance. That's way too low level for the design phase. All of these processes (well, maybe not UML) are important everywhere, regardless of programming language, when projects rise about simple-helper-script level. I see a lot of UML thrown together at random, essentially boxes and arrows, and folks tend to call that a design. Well, no, a design is only such when you have a *good* configuration of boxes and arrows. As a final point, it's wise to note that Sun itself is guilty of the file-jumping I speak of. See how many pages of the J2SDK documentations you have to read to fully understand a particular method call. The calls and dependancies fly absolutely all over the place. If anything, if neglect of Perl side leads to obfuscation through compaction, Java leads to obfuscation through expansion and objects will multiply like rabbits. Is there a moral here? Nope. Just watch out for dragons. When was in college, I wanted to be a Software Architect. Java, in fact, was something I liked. Then, somehow, it scared me...I still love software design, and I'd do it all day if I could...but I am aware of the dragons of every approach, and even what the industry embraces hardest (Java, UML, XML/SOAP, etc) are only suitable if they can be employed well by those who know they have limitations. Zealots of any particular one-sided approach are the most dangerous foe to good programming. XML everywhere, SOAP everywhere, OO everywhere. Got to pick the best of both worlds...and design should not presume to pick certain tools above others until they can be weighed fairly. Again, Programming is looked upon as an Engineering Process. That's good, but the rules aren't nearly hard and fast as the physics of bridge design. There is a lot of art there, and a lot of gray areas. Hard and fast rules are often the enemy of innovation, but so are lack of any sort of rules. Yeah, it's a Zen thing. Ok, I guess I forgot what I was talking about :) | [reply] |
by hardburn (Abbot) on Jan 13, 2004 at 15:20 UTC | |
|
Re: All in one
by tilly (Archbishop) on Jan 13, 2004 at 19:07 UTC | |
| [reply] |
|
Re: All in one
by rkg (Hermit) on Jan 15, 2004 at 03:25 UTC | |
Constructs like resemble how we talk, rather than the more formal Somehow, opening and closing a block seems... burdensome. Burdensome not due to typing an extra character or two, but burdensome because the block and whitespace seem to make too big of a deal about something small, which at a subconscious level causes mild dissonance and slows down the brain. My two cents. LATER UPDATE I find myself trying to write code like this which feels more natural than opening a block (my dissonance theory) Similar is the use of $_ to mean "this" or "that" in natural language. All of these shortcut constructs are quicker and more like natural language -- and more difficult for someone entering the conversation late. | [reply] [d/l] [select] |
|
Re: All in one
by pboin (Deacon) on Jan 13, 2004 at 17:15 UTC | |
I admire routines (by others, and by myself) that are elegant taken as a whole. Many comments on this particular thread seem to be about the micro-logic of combining one or more statements into an impressive one-stroker. I suggest that the real wisdom, the real 'efficiency of code' comes from a macro level. Looking at a routine and realizing that we don't need to re-write sort again, that we don't need to re-write another find, etc. Great thoughts to be ponder, thanks.
| [reply] |
|
Re: All in one
by hessef (Monk) on Jan 13, 2004 at 16:42 UTC | |
Also, I have a personal dislike for 3-or-more nested if statements. Sometimes having one regular expression lets me eliminate an if statement without having to put used-one-time-only code in a function. | [reply] |
|
Re: All in one
by sfink (Deacon) on Jan 22, 2004 at 18:21 UTC | |
I often have the situation where a chunk of code "feels wrong" -- something seems a little clunky about it. I will attack those chunks by condensing them to the minimum possible amount of code. Often this will reveal a slightly more streamlined way of thinking about what the code is doing, and I will be able to recode it differently to more directly express that simpler mental understanding. (The new version may or may not be the maximally trimmed-down version; it may just be informed by it.) And at least as often, I will be immediately revolted by the hypercondensed version, and it will make me realize why things need to be expanded out. Once again, I will probably rewrite the code, but this time targeting the extra verbosity at the portion where it is really needed. The result won't be much shorter or longer than the original, but it will "feel" better. A typical example is when you have written a sequence of transformation steps using one or more temporary variables that don't really mean anything; they are merely intermediate data structures. If you eliminated all of them and just had one transformation feed directly into the next, then the result would be an opaque glob of scary code. But from that, you can choose what temporary values do mean something real, and break up the computation at those spots. (Good rule of thumb: if your temporary variable is named '@tmp' or '$x', there's a good chance you should get rid of it. If it has a meaningful name, it will probably help a reader figure out what is going on. If it has a meaningful name that doesn't match its meaning, you will need to avoid traveling to certain countries where you could be tried and hanged for Willful Codeslaughter.) | [reply] |