- 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
ping 10.2.1.52 ping 010.002.001.052
Admin
Furthermore, is there a unit of measurement for how much something "sucks"? For example, could one say that JavaScript's Date API sucks at 1.21 giga-biebers?
Admin
Suckiness is measured in inches of mercury.
Admin
My project's original (10 years ago) codename, and its namespace, is 'Mercury'.
:S
Admin
TRWTF is that Dates in JavaScript were designed to be (real year - 1900). It was only later that methods were added to handle the year as is. As such, writing wrappers to the date library is not a WTF by itself.
Admin
Admin
I thought it was in milli-Tory Blacks.
Admin
Admin
Interesting. I don't understand why you would write a second library for dates and times for Java. Jon's writeup about his design sounds to me exactly like how I use Date and Calendar objects in Java.
Date objects are good for marking the instants in time he describes, with long milliseconds being useful for performing durations. It would be nice if you could add or subtract milliseconds from a Java Date, but it's easy enough to just use get/modify/set. Not ideal, but the resulting code is generally easy enough to understand.
When it comes time to think in terms of human terms like months, days, hours, etc., you use Java Calendar objects. You manipulate these human-understood objects, and there are easy-to-use converters between Date objects and Calendar objects. Again, the API isn't perfect, with constants to indicate field selection, but the resulting code is generally easy to understand.
I find the main reason people run into problems with dates and times in Java is when they use the wrong object for the job. This is usually because they either aren't aware of how best to use Date and Calendar objects, or because they are just not terribly good at thinking through clean solutions to programming problems. I have yet to see a time or date problem that could not be solved fairly elegantly using these two classes.
Now, once you start interacting with database timestamps from Java, that's another story entirely. :-)
Admin
Admin
How'd you guess my IP Address???
Seriously though, that is pretty weird. Especially when you consider that 10.0.1.52 is a valid IP Address.
Admin
Fortunately the designers of JSON (JavaScript Object Notation) did something right. They decreed that a number can start with "0" only if "0" is the only digit to the left of the decimal point (or if no decimal point, the only digit). You cannot write a number in octal, and you cannot write a number that JavaScript would interpret as octal.
Admin
I sure hope you code more cautious than you read.
Admin
That ParseInt replacement isn't the worst I've seen... http://support.microsoft.com/kb/191434
Admin
That's an octal 0, of course!
Admin
The problem of counting seconds has its origin in the chaotic legal situation between any one country and any other. See http://www.ucolick.org/~sla/leapsecs/epochtime.html for the sad story. It's important to be sure what standard is being followed, or not, by all the hardware and software.
Admin
Admin
Regrettably, the insanity of treating leading zeros as Octal infects the core C-library, and everything that depends on atoi(). This includes PHP, C, Javascript, and plenty of other cases.
Starting with "0b" for binary and "0x" for hex is perfectly sane, but the idea of leading 0 for octal is lunatic. Why not "0o" if we must. Nobody ever deliberately uses this mis-feature, but it catches the unwary so often.
Admin
GNU 'find' can probably handle it. Try something like "find -stupidcode -delete", and let us know if it works.
Admin
"Starting with "0b" for binary and "0x" for hex is perfectly sane, but the idea of leading 0 for octal is lunatic. Why not "0o" if we must. Nobody ever deliberately uses this mis-feature, but it catches the unwary so often."
The historical reason was that C had a leading 0 for octal and everything else was decimal. 0x was invented later. Hexadecimal was already in use on mainframes but the inventors of C didn't predict that minis would evolve to the stage where hex would be convenient.
Microsoft uses 0o for octal in resource files.
Elsewhere, it would be nice if Microsoft used this wrapper for parseInt because they sure need it. In a country where it is conventional to input two-digit numbers for months, Microsoft's scripting blew up on 08.
Admin
That r_parseInt() function is not a bad piece of code. The reality is that you rarely if ever want to parse an int that is not base 10, however if you have a string starting with a 0 this will be parsed as octal.
I'd argue that is a completely reasonable piece of code that resolves a bug in javascript.
Admin
Supporting octal in this way makes sense in C. It makes no sense in Javascript.
Idiots might be too mild a term.
Admin
Not really. Perhaps in certain niche uses it makes sense, but I've never intentionally used octal constants in 15-odd years of C coding.
Admin
Also, following the previous comments, I'm pretty sure the Mercury (Quality Center) is the standard by which all suckyness relates. So on a scale of 1-10, MQC would be a 10, as well as anything Peoplesoft and lots of Oracle.
As for Date APIs, I'm curious as to specific problems people have with them.
Admin
Given that 99.98% of all users would type a base 10 number into the computer. (Yes, I made up the percentage. So?) It's only wonks like us that think in terms of octal.
I am reminded of a long-ago program that told me (paraphrased):
When designing things (such as, for example, parseint) the default behaviors should always be the thing most commonly required and/or that which is least likely to be the wrong thing.
Admin
Admin
Agreed - if in any doubt, abort, and let the user know there's a problem. By all means provide suggestions as to what you think they might have intended, but never try to guess.
Admin
An API should be as close as possible to the thinking of the programmer. If you have to translate what you think into what the computer thinks, it sucks. But sometimes the human thinking is wrong. Humans understand timezones but not datezones.
Humans have been numbering months 1-12 for two thousand years; any API that numbers months 0-11 sucks.
Admin
Oh yeah, that's always a favorite - both Java and Javascript annoy me with that behaviour. Although no less annoying is that the java.util.Date class uses years offset from 1900, so if you ask it for the current year, you get 110.
I can live with that kind of crap from fossils like COBOL, but Java's not so old as to excuse Y2K braindeadedness like that. Yeah, I know the method's been deprecated since 1.1, but that just proves the point - it was just as stupid fifteen years ago, as it is today.
Admin
What about Sep 1752?
Admin
My favorite part is how you can call spin(32) to redefine a month as infinitely long.
Admin
Sorry for nagging, but attaching a logger does neither prove nor verify but only validate that it isn't skipping a day. :)
Admin
Admin
Admin
Admin
I don't understand people that actually go and implement mechanical processes in programming. I've had a pretty bad discussion with a lot of people in a game forum once over a poker engine, where they would shuffle an array of 52 elements to distribute hands, while I just picked up a random number out of 13 and another out of 4 for each card. To them, apparently my argument that random should be random was flawed.
Admin
Great, two Ace of Spades in my hand then! (Or did you check against old occurences and tried and retried and retried until a solution was found?)
Admin
This was an undocumented (as far as I could see) "feature" in TCP/IP for Windows 3.1 / MSDOS 5 and possibly earlier. When reading it's configuration text file, the MS TCP/IP stack would silently interpret IP address octets starting with 0 as octal (even if they had an 8 or a 9 - 018 was read as 16 and 019 as 17). I'm surprised (well, not really) that it has survived 'til now.
I remember literally weeks and weeks of troubleshooting seemingly random disconnections from our newly migrated (from NetBEUI) TCP/IP network, until it finally clicked.
This was before there was a standard easily available DHCP server for Windows, so we had hundreds of PCs with static IP addresses, of which some (about 20%) had leading 0's in their IP addresses (depending on whether one particular staff member had done the initial configuration). When two PCs had a duplicate IP address, the second workstation to be started in the morning would knock the first one off the network. So the first user would reboot, and when they reconnected it would knock the second PC off the network, which would then be rebooted and knock the first PC off again, and so on ad infinitum. This was before the days of any obvious error messages, so all the user would know was that their PC had been disconnected again and they had to reboot again. Because the IP addresses were "obviously" not the same, no-one ever suspected duplicate addresses. The way that non-octal digits were acceptable also helped to mask the problem.
Admin
Which C# are you using? The one written and maintained by MS, because as far as I know it's not a dynamic language (yes, I know 4.0 and DLR, etc.).
The compiler will let you know if you've done something stupid, and as far as syntactic sugar goes: what do you mean? Lambdas, anonymous types, LINQ (deferred execution), etc.? Learn to use and embrace them; don't hate what you don't understand. There is no magic, everything is in the documentation.
You would have to do something out-of-the-way kind of stupid to sneak a WTF past the compiler (like explicit casts, or using strings for everything, or just a bad design).
Please be specific, and don't just throw out weak and ridiculous accusations.
Admin
I think I've seen a few that rock, but that's a matter of opinion.
But this isn't about the API so much as the implementation. Whether or not the API sucks, a set implementation which takes O(n) time to add or remove items does, in fact, suck more than one which takes O(1).
Admin
To cut a long story short, I needed to build up a query sequentially based on a set of given filter criteria. I needed the underlying SQL to comprise of the logic ((A and B) or (C and D)). That is not a complicated query by any stretch of the imagination but it is physically impossible to express with lambda statements. Of course, lambda statements are just syntactic sugar for the Expression<Func<T, bool>> class. In order to get the logic I needed, I had to create instances of these classes then manually manipulate them with functions such as the following:
I had to learn about the underlying classes and it's pretty obvious that code such as that above is a lot more complicated than lambda statements. But hell, it ain't rocket science and I learnt very quickly that you can do so much more if you understand and use the underlying classes directly.For some reason, Microsoft would prefer you to use some watered down syntactic sugar that barely even scrapes the surface of what is possible. They hide and abstract the real classes, dumbing down the code and taking a huge amount of power out of the hands of the developer.
I'm a smart guy who can handle these concepts perfectly well without needing them dumbed down and presented behind a layer of syntactic sugar that robs me of the ability to solve complex problems. Maybe you're different, I don't know, but I for one do not want this; I want to work with real classes and actually understand how they work, instead of just cargo-culting it with silly syntax tricks.
Is that specific enough for you?
Admin
Admin
I must be missing something important.
Admin
Admin
I agree with that as well. "Guessing" is bad, because it means that there are criteria the compiler uses to go this way vs. that way that may not be clear. The "parseint" problem is a perfect example.
There's nothing wrong with defaults, though, so long as they are always predicatable; even if they are wrong (though wrong can be annoying). In the case of "parseint" again, there is nothing wrong with it assuming a default of base 10, so long as it always assumes that.
(It would be okay if it defaulted octal. That might be annoying, because you have to supply the 10 every time, but at least you know how it's going to behave if you omit the 10.)
What caused the problem with it was its semi-unpredicatable guessing: "Well, I think this looks octal, so we'll do that;" vs "This isn't octal so it must be base 10." That type of nonsense is an invitation to program faults.
Admin
Or even popping up an exception from the database telling you it doesn't like the value, if the programmer of the class thought that hidden persistence is a good idea.
CAPTCHA: persto = persist in octal
Admin
Addendum (2010-12-07 15:33): Since you decided that "using the underlying classes" is important, I'll add this so that you don't focus on that, and instead actually show what the problem is:
Admin
And yet while some APIs use 0-based months in complete inconsistency with human expectation, I'm not aware of a single one that takes the obvious next step of using 0-based days. Because having 7 be the 8th of the month would just be confusing - yet having 11 be the 12th month is fine?
Admin
You said you must be missing something important and you were. I specifically said I needed to build up a query sequentially, although maybe I should have said dynamically. Anyway, the point is that you don't always have all your filter criteria up-front to build a single lambda statement with. Very often you need to build up a statement piecemeal based on various conditional logic. This is where lambdas fall down, because using the syntactic sugar only lets you build statements in one hit, there is no good way to progressively build up a statement as you go.
So I've produced a dramatically simplified example for you based loosely on my scenario. The table you are querying with LINQ to SQL consists of 4 columns; SourceId, SourceName, TargetId and TargetName. Your query method accepts a criteria object that has properties matching the columns, so we have Criteria.SourceId, Criteria.SourceName, Criteria.TargetId and Criteria.TargetName. Any of these may be null but any that are provided should be used to filter on the appropriate column. The critieria object contains an addtional property - Criteria.TwoWaySource. If this is true, you need to return all the rows where the source criteria values appear in either the source columns or the target columns. In other words, you need to return all the rows where ((SourceId = Critieria.SourceId [AND SourceName = Criteria.SourceName]) OR (TargetId = Criteria.SourceId [AND TargetName = Criteria.SourceName])). The bits in angle brackets are just there to indicate that you may have to additionally filter on these properties if they are provided, but as I already said, any of these properties could be null in which case that property should be ignored.
Please satisfy these requirements using lambda expressions. Don't even think of resorting to a separate "if" statement for every single possible combination of criteria states because in the real thing there are way more values than this so an if statement to cover every single permutation is totally unrealisitic, it would span thousands of lines and be completely unmaintainable. You're going to have to query each property and dynamically build up your statement so that any possible permutation generates the right SQL. This is just some pseudocode to give you an idea:
Well, I've given you more than enough information on the requirements, let's see you achieve this using nothing but lambda expressions.
Admin