in reply to Re^2: open and list context (?)
in thread open and list context (?)
- Cᴀᴠᴇᴀᴛ Lᴇᴄᴛᴏʀ:
- If by chance you’re one to be easily bothered by strong opinions, especially those against which you have an irrational, emotional reaction, please do us all a favor and skip reading this posting. 🙈 🙉 🙊
On Monday, 13 June 2011 at 10:28 ㏂ ᴍᴅᴛ, chromatic in quoting yours truly has done me the honor to write:
› Always use parens on you[r] function calls…Quite so! Rem acū tetigistī!I’ve given that advice too, but what makes open a function call and die not?
Not merely a just question, it would also seem a perfectly straightfoward question as well. The operative term there is seem, as your seemingly simple question comes accompanied by seriously subobvious traps to trouble both the unwary and the hypervigilant alike.
Sorry it took me so long to answer … 💬
☣ Caveat wrǽððu
I had fully intended to answer you the same day you posted your question, but this was not to be. So first please accept my sincere apologies for not responding sooner. I hope the unscheduled delay has not banished the question from your mind.Frustrating my whilom goal of a quick turnaround is a somewhat messy tale, although one mostly of personal (but not private) concern only. It turns out that during the target response period, my body, mind, and soul have like so many spoils of war been variously divvied up in a trilateral crapshoot between Mycoplasma pneumoniae, Alces alces shirasi, and Camelus dromedarius quartus. Multiple winners have each claimed their pound of flesh, even going so far as to further quarrel over these small spoils.
As I have not myself been so fortunate as to be numbered amongst said victors, there just hasn’t been enough of me (in a nonphysical sense) to go spreading myself still thinner without risking becoming even more the wrathful wraith than I am already become.
’Nuff said.
The reason that die is neither a function call nor a subroutine, method, procedure, or anything else of that ilk is because of what subroutines at their machine‐level foundation really are. When you factor out matters of register allocation and arugment transmission, they all of then do one key thing: they push on the (per‐thread, per‐intepreter) sᴘ the address of the next ᴘᴄ to be executed after the intended subroutine call eventually returns.
This would work a bit like -(SP) = PC; PC = FUNCNAME. Then at the end of the “call”, the subprogram pops the return address off the stack and hies itself thither with PC = (SP)+. There exist simpler solutions involving fancier instructions like JSR and RTS, but you must get the central idea here. And die just doesn’t work that way — at all. Functions that return fewer times than they’re called, and in some cases, even return more times than they’re called, are sneaky little buggers that strain any reasonable definition of what a function call really is.
Other functions that break the function model outlined above and therefore give call‐graph analysis programs serious conniptions include not just exit but even moreso longjmp and setjmp. That’s because setjmp returns more times than it’s called (as so too can open!), while longjump, like exit and die, never bothers to return at all.
Interesting though all that may be, I suspect that wasn’t what you were really asking. I recognize that I may be wrong, though, and so it is just barely conceivable that you really were asking the subtler question, not the simpler one.
Even though code I’ve written ever since v1.0 of Perl for the most part looks pretty much as it always has, my own coding practices have changed a little over the years. I like to think they’ve converged on a degree of stylistic consistency that facilitates not just the reading of my code, but also its predictability.
Yes, that does mean that today’s code does not always quite match up exactly with yesteryear’s in all possible regards, so please do not go digging up prehistoric Perl code of mine to tout as though it were someone an examplar of cavalier inconsistency. It wouldn’t be. More importantly, it just doesn’t bear discussing.
Nevertheless, I believe that if you examine any of my recent code, such as the many examples found in my Unicode Tool Chest, you will quickly see a clear and consistent style used not religiously, but consistently in all of that code.
In fact, I would even go so far as to say that if ever you find exceptions to larger stylistic patterns in that code, you have either discovered a more specific rule than the general rule you had believed you had been previously operating under, or as is more likely, you have discovered a style bug that I myself would prefer to see updated for consistency’s sake.
I am not fond of using parentheses for functions and methods whose dative (or ablative (or instrumental)) slot is occupied, because the result looks disconcertingly Lispish. That means I avoid parens for things like print, printf, map, grep, and sort — just to name a few. Additionally and for precisely the same reason (although somewhat moderated by pipelined, left‐to‐right listop stacking and on certain perlocentric syntactosemantic exceptions discussed below), I also tend to avoid parentheses on methods‐qua‐listops.
I recognize this runs somewhat counter to the bashfulᵃʰᵉᵐConventional Wisdom that spooks up an intensely aversive reaction in many novice Perl programmers who just don’t know any better. But since I actually do know where their peculiar ambiguities lurk in stealthful ambuscade, I simply do not write them in an ambiguous fashion, and the payoff is improved readability. It really is a nonissue for me, and I have never once been gotchaed as so many others report having befallen them.
It is also a tiny niche in one little corner of the language, one which for me does not even arise with any great frequency. Given that, it generates a level of controversy I feel wholly unreasonable and disproportionately larger than it has any business doing. This is itself distressing. Why do that? Let’s not and say we didn’t. Just let it go, ok please?
For me, the parens are needed to tell my brain where the argument list stops. A semicolon or a close round/square/curly bracket will all do this. But if you expect the argument list to stop for any other reason, I get nervous. I am far too aware of the ways that prototypes change the parse to trust any funny business there. I do not like trailing English words changing the parse, either, since the function likely started as a leading English word. That’s why I’ll write:
As in the point that you yourself have raied, there are times I relax that, and indeed it’s usually on things like print or die. As should be immmediately obvious from the code fragment cited above, one thing that’s especially important to me is interlineal vertical alignment. That isn’t quite properly stated, but the idea is that if the code that looks the same should be in the same column despite being on different lines so that the eye can quickly pick out the parts that are different. We’re very good at that as humans.pod2usage(0) if $Opt{help}; pod2usage(-exitstatus => 0, -verbose => 2) if $Opt{man}; @ARGV = (1) unless @ARGV; pod2usage("$0: missing arguments") if @ARGV == 0;
That’s just one of the many reasons I always use the more readable form of the vexing Logical-ᴏʀ, although there are other reasons for that, too. Please note very very carefully, that even without the alternate, hard‐to‐parse newfangled construct anywhere to be seen or unseen, my own code — mirabile visu! — is simultaneously safe, clear, and unconfusing. “They” tell this can’t be done, but “there” are demonstrably wrong, considering how I never, never, never make the pernicious and pervasive operator precedence errors that seem to plague most Perl programmers, especially those who put too much stock into contemptible mindless cargo‐cult pseudo‐rules instead of in actual thought.
Do things for reasons other than because you were told to: learn the whys and wherefores, not the rules. But if there is one rule to follow without giving it further thought, please make it this one:
Please, please, please think of those who’ll come after you — preferably before they do so — and use parentheses to delimit the arguments to your functions calls.
Nevertheless, I do believe that taken as a whole, my personal style is consistent, predictable, readable, and pedagogically useful. I should’t be surprised if it were found to be so idiosyncratically mine that it would prove readily identifiable as tchrist–code by one of those clever machine‐learning program trying to identify plagiarism.
The fiftyish programs in my Unicode Tool Chest are often a lot more useful, or can be used in many clever ways other than are immediately apparent. Some of those that I use daily or more include:
There are around 50 programs, modules, and libraries in that directory, almost all having to do with Unicode. Some are one‐shots, some are well‐documented standard tools I use daily, and all I believe have something to say about Perl (and sometimes C and sometimes Java) programming. Some delightful little simpletons are genuine lifesavers, but you’d never know it without playing around with them a bit. And some are just downright hilarious in the extreme.
You’ll see.
|
|---|