- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Why hasn't anyone made an American Airlines joke yet?
Admin
Sounds like the president's father will have to utilize his special skills...
[image]Admin
That's not a WTF, that's very good practice, exactly the kind of thing comments should be documenting - that while the code might look bad, it's done that way for a reason.
Admin
Office VBA is redundant now we have PowerShell, you say? Naah: I write new automation code in Office VBA for my employer all the time. Currently, what I'm mostly writing is code to automate the running of Crystal Reports, and the formatting of the results in Excel. This saves the company several man-weeks per year compared to when "someone" had to do those same tasks manually. It may not be bleeding-edge stuff, but it pays my rent.
Would I want to try doing all that automation using PowerShell instead? NO! PowerShell is fine for the kind of sysadmin scripts that used to be done with VBScript and WMI: like listing the RAM available in every computer on the LAN, or managing AD, and maybe even writing some output into an Excel workbook. But for day-to-day automation tasks within Office, I'd rather use Office VBA every time: after all, it was written for the purpose!
Plus, I need never worry about whether a given user's computer even has PowerShell installed: many sysadmins ensure that "user" computers DON'T have PowerShell on them.
Admin
VBA is hosted within Office applications (with its own IDE, yet!); VBScript is, as you say, a language supported within WSH, and it has no IDE.
FWIW, I agree that VBScript is dead/dying. But: I haven't yet seen any viable alternative to VBA. Suggestions on that are welcome, if anyone has any? And no, AutoIT and similar "action-scripting" applications don't count!
Admin
Absolute bollocks. You have to unlearn a lot of nonsense that you learned, or you'll always be a danger to yourself and the rest of the world. You are confusing one method of implementing pointers that is currently in fashion with what pointers actually are. The fashion has changed, and can change again.
Even in a language like C, believing that "pointers are integers" means you can't understand null pointers, function pointers, restrict and const restrict pointers, related pointers, thread specific storage, and lots of other things.
Admin
If I was bughunting in an application where I found a variable intProjectNumber = "QR-1554-PL", I'd be having a good hard look at why it is so...(although I generally have the luxury of C so that sort of nonsense would make the world cry a lot). I don't really agree with hungarian notation per se', but I think it can be very useful to use snippets of it to show intent (and to some degree to identify variable scope gSomething immediately identifies that this feller might be global and if I play games with this little sucker I might break something else).
When you work in an environment where you are (and always will be) the only person who fiddles with the code you can choose to {not} use whatever standards you want. When you are playing in a sand pit with lots of other script kiddies, it becomes important to have standards that can help all of you play together nicely. Hungarian Notation is probably at one extreme of the spectrum, however the idea "it is evil to embed type information in a avariable" is probably the polar opposite, and as with most things there's some middle ground somewhere that might be a better option...
Admin
What about English Pointers?
Admin
Sounds like you need a class with some properties that do conversions...
Admin
Until one day, you userid changes representation, and is stored as a long int instead. Then you have to change both type and name of the variable everywhere you use it. And while you might remember, your colleague might not. It's brokenness waiting to happen.
In most of your functions, the type should be easily inferred from either the formal parameter type, a local declaration. The exception are object members, of course.
But if you need hungarian notation to clarify your code, there are good chances your code isn't clearly written to begin with. See "Clean Code" of R. C. Martin.
Finally, instead of "guidUserID", a someone not in love with HN might want to write "userGuid"...
Admin
The difficulty is that the important thing about a variable is what it means, what its purpose is, what data it holds, not its type. The important thing about guidUserID is not that it is a GUID, but that it is a user id. The type is important, sure, as far as making the code mechanically work. But not to the logic and purpose of the code.
Hungarian notation gets this backwards, putting the stuff that doesn't matter at the front of the name, and obscuring the business logic.
Admin
Well, that's not what most people mean by HN.
In a similar vein what you are suggesting, primitive numbers that are not counts should always be suffixed with a unit of measurement.
Never: int remainingTime; Always: int remainingTimeSec, remainingTimeMin, remainingTimeDays;
This applies to variables, method names, parameter names, and member names. It saves a universe of hurt.
Rule 2 is: never use floating point except for physical measurements accepted to be approximations or for statistical averages. In particular, never use it for units of (billable) time or for currency. Ever. Store these quantities as integer multiples of the smallest division you will need.
Had one project which kept track of hours. Then a requirement came to track half hours, so they made time a float. Dear God, you would not believe the mess …
Admin
Seconded. Simple, concrete example: on the x86 architecture, the first half of a 32-bit pointer was a page and the second half was offset within that page. Pages were interleaved 16 bytes apart, meaning that pointers were basically 5-byte quantities. Treating the whole 32 bits as an integer yields nonsense.
An integer is a number. A number is something that you can add and multiply another number with. If it doesn't make sense to add and multiply it (e.g.: phone numbers, any sort of code), then it isn't an integer. That you can add 1 to a pointer to get another pointer isn't sufficient.
Admin
Admin
Admin
Admin
I think it may be VBA - which renders all the discussions about IDEs and CVS a bit off the mark.
Admin
Admin
If you have a pointer in C++ and you try to use it like you would an integer, you'll get a compiler error. Heck, with modern compilers even if you try to pass it off as integer as an argument to printf, you'll still get a warning.
Besides, saying that pointers are "occasionally" used in C++ is a bit crazy IMHO. Yes, modern C++-11 APIs can be designed without the use of pointers without any loss of performance. Anything that predates C++-11 has no choice but to use pointers as necessary.
Admin
Heck, C++ makes it quite easy to express the fact that something is a USER guid as opposed, to, say COMPANY guid, and those shouldn't be assignable to each other, for example. C++ makes expressing such basic business logic requirements reasonably easy in its type system, and such things are then checked at compile time.
Admin
When you use C++, you've got compiler to do all this checking and enforcement for you. Heck, you can even allow automatic conversions in certain circumstances. The fact that you resort to bogging down a human developer with tracking this stuff in variable names is beyond me. It's stupid, it's a clear indication that you don't know the most basic elements of design of code in C++.
Never mind that std::string is a joke when you actually try to use it in a business application, it misses pretty much everything a real life application needs. QString and friends (or similar classes in other frameworks) is what you need to stay productive.
Admin
Admin
Admin
Admin
Admin
Admin
Admin
Admin
The way you completely ignore Scotch pointers is racist.
Admin
And that's a Windows API, which generally has to be rather stable. In application code changing types (in a compatible way, but breaking SHN) is much more common.
SHN is also a huge misunderstanding of the Simony's original article.
This is poor man's variant of what should better be done by actually using the type system. Most widely done in Haskell, but C++ and C# are well suited for this as well as most dynamic languages, actually. Instead, you should have with conversions either implicit or by conversion functions as suitable for particular code.In C++ this requires a bit of boilerplate, which can't beat Haskell's
(might have missed some instances to derive), but is well worth it for often used types like this.I've actually done this to ensure that all strings presented in the user interface either went through localization machinery or were explicitly marked as not needing to in past project. I've also seen it used for the exact case of proper escaping in a statically typed system in Yesod and in dynamically typed system in Genshi.
For the example (distinguishing between screen-relative and canvas-relative coordinates) from Simony's original article, Boost.Units can be used to great effect. Since C++11 they even have syntactic support.
It should be noted that Java is particularly badly suited to these techniques, because it has efficient primitive types with standard operators, but any wrapper has to be class, which is less efficient and can't use the standard operators.
Admin
Admin
The history is not irrelevant - by looking at the history you can see that the concept expressed (pointer != single simple integer) is more than just a theoretical concept, and that there are no (absolute) guarantees about the (relative) sizes of any integer type and pointer types. Nor even that all pointers are the same size. Perhaps your remark was meant to be directed at faoileag, in which case you'd have done better to quote him rather than me.
Admin
Actually, much of the Windows API (whether Win16, Win32 or Win64) is a sort of bastard hybrid of SHN and AHN. Consider the number of parameters and structure fields that are 'cbSomething' - this is AHN because the cb prefix shows that this variable is contaminated with the "byte count" property. A window procedure's 'wParam' parameter is notionally a WORD, in the "finest" SHN...
Yes, provided you're using a language with a suitable type system. AHN has its origins in the days of languages like C, remember.My comments were more about what you'd use AHN for, not so much whether it's automatically a good idea, nor if it is necessary with modern systems. I'd agree in general that it's better to use the type system to enforce this, so that you can get the compiler to report the bogus usage rather than the code reviewer.
But of course Spolsky's article is showing one example of removing the "smell of wrong" about code. In a language whose type system is strong enough to support AHN-by-types rather than AHN-by-names, you concern yourself with other things.
And the C++ boilerplate you mention can have some not entirely desirable side effects, unless you get into curious perversions like having the base string class support CRTP:
Note in passing that we need to have somewhere a set of operations/implicit conversions, most likely expressed as pseudo-copy constructor and assignment operations within the derived types, but each of the derived classes inherits the fundamental string operations for itself from the templated base class. This makes them incompatible without introducing the goofy weirdness that is private inheritance.Admin
Microsoft used it, everybody followed.
And the reason Microsoft used it? Because adding a letter or two at the start of every class/variable name avoided name clashes with the existing codebase.
Admin
I've lost count of the number of times I've seen that article trotted out as a justification for all sorts of programming practices. It's done untold damage to impressionable young programmers minds in the years since it was written.
Mind you, Joel is also anti strongly-typed languages. He's shown many times that he simply fails to grok C++. That sort of practice is probably all he has to cling to in his world of scripting languages where variable types can morph right before your eyes.
Admin
What, because we can't do this?
Admin
I don't search for an int, I search for some useful piece of data. I don't look for all int's and then look for ID, I look for ID (because that's what I need) and then the IDE tells me it's an int.
If your first step in looking for a particular variable involves looking for the type, then you are doing it wrong.
Admin
In any real IDE, right-click and Rename.
As I've said, your problem is stupid people, not a stupid naming convention.
Admin
Why use some sad movable thing with generally less than 5 buttons when you got another thing with about 100 buttons that you don't have to move around?
Admin
I think you would like Haskell. These kinds of constructs are built in, at a few levels of abstraction.
For example, we can create so-called newtypes to create a new type from a type:
This code uses a few other Hungarian-like conventions I like. The 'un's are a simple way to remember how to deconstruct a newtype, for example.
We can also abstract from these into newtypes with free type variables:
We can use these for situations when many different things can be made SqlSafe, for example, by parsing and validating:
The notation is starting to grow unwieldly, though. We can use a final type class to deal with dispatch in a type-safe way:
Also, those newtypes with free type variables are useful for another reason. We can thread computation through the free variable. That takes us into the realm of functors, applicatives, and monads, which I won't go into. But, it's a nice topic which deserves some motivation. We might want to construct SqlSafe queries. If we use the applicative interface, we can write composable getters like so:
Also, in writing this example, I felt the pull to abstract the SafeSql type class to accept multiple parameters, so that we can parse more than just UserInput types into SqlSafe types. Something like:
In this way, we can generate SQL or whatever using data from many sources. For example, User Input, Configuration, the results of SqlSafe actions. Indeed, if we restructure SqlSafe slightly, so that it carries around more information, we can use the monad type class method:
to compute Sql joins! (I would suggest this should be done by modifying and issuing a single query rather than issuing many queries and calculating the join in code...) That's actually pretty neat, since it demonstrates that SQL joins are joins on the lattice of relations.
Admin
Sounds like a drink that's half Scotch, half Fireball.
Admin
I think that I'm misunderstanding you. Is the "sad movable thing" the stupid person that I'm talking about?
Admin
"Did I call it DateOfYellingAtUser or YellingAtUserDate...I guess I'll have to try both, or just scroll a lot..."
Admin
Pointers aren't always plain addresses, even in modern architectures. Function pointers are most likely these days to run afoul of such assumptions.
Admin
AN IDLE HORSE, and an Ass laboring under a heavy burden, were traveling the road together.
The Ass, ready to faint under his heavy load, entreated the Horse to assist him, and lighten his burden, by taking some of it upon his back.
The Horse was ill-natured and refused to do it; upon which the poor Ass tumbled down in the midst of the highway, and expired.
The countryman then took the whole burden, and laid it upon the Horse, together with the skin of the dead Ass.
Admin
Well, also, they initially programmed much of Windows in assembly code, and the type information is actually useful in that environment.
Admin
Is it REALLY that hard to take the extra half second to type clientFlag or clientCount? Or are you like half these people I work with who are somehow programmers when they can't even type properly?
Admin
This is why type safety was invented about 50 years ago.
Admin
Many decimal fractions can be stored just fine. I'm surprised no one else corrected you. As an example, we can store 2.5 (dec) just fine in floating point (0x40200000). Only some numbers are endlessly repeating fractions. If floating point couldn't represent any fraction usefully, why would it even exist?
Admin
The hungarian notation you speak of isn't the actual hungarian notation, it's the wrong way that somehow became the popular way.