- 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
if this one was trickier, one wonders what the "really low hanging fruit" entailed.
Admin
The article does contain a WTF though. Indeed it contains two of them!
The first being the stupidity of using 0 as a prefix for Octal instead of something sensible like they do for binary and hex. The second is the fact that everyone after that has copied them until it became a standard.
Admin
I've seen people who had not been a newbie for a long time making similar mistakes. Octals may have been all in vogue in the 1970s, but they should have died a long time ago. Or replaced by something which makes more sense, like
0o123
.Admin
LZ79LRU - well, if you want to go back far enough [I am talking 1960's and before] --- Octal was the default!!!! One had to "do something" to make a literal be base-10....
Admin
Back in the good old days, yes. But so were punch cards. And you don't see those sticking around.
There simply is no excuse for modern programming languages to not adopt something more sensible than 0 as a prefix. And that is assuming they even want to support octal at all which frankly they don't have to. C# did away with it entirely and nobody cried.
Admin
TheCPUWizard - Octal was not the default in Fortran or COBOL or BASIC, the big languages of the 60's and before. Wasn't it only true for assembly languages?
Admin
In Python. In Javascript, it's a decimal. Welcome to the wonders of agile language design.
Admin
Good ol' octal never disappoints.
Admin
TRWTF is that octal is implied by the leading zero. If I were designing a language today, I'd require octal to be
0o
prefixed (like how hex is0x
prefixed). Maybe even make a leading zero a configurable syntax warning. But we all still live with the bad design decisions from C (which was created on an octal machine) that made sense at the time.Admin
But why follow C? Why should the designers of a modern programming language follow reverse compatibility with something like octal when they are willing to break the norm on virtually everything else.
I mean, for crying out loud Python literally uses whitespace as characters which means you can't ever make your code look pretty and readable. And yet they follow C in one of the worst decisions it ever made.
Admin
Well, if you really wanted to follow hex, you'd have to take the third letter, so the prefix would be
0t
...Addendum 2023-04-04 09:40: And
0o
has other problems, like the point that the "o" should follow the "x" of hex, and be accepted if it is uppercase.0O23
???Admin
TRWTF is that, irrelevant to not knowing that a leading zero would be interpreted as octal, making 09 an invalid value, is the fact that the person converting strings to numbers left the leading zeroes.
True, we don't live in a world where every byte of storage and memory is precious (like when octal was the default) so that's not a concern (like it used to be), but for readability it makes sense to say (1, 5, 9) rather than (01, 05, 09).
Admin
Newbie was lucky there were only two digits.
09
is a syntax error;012
is a silent error.Admin
The project they were working on was in Python 2, which is now obsolete. In Python 3, 01 is also a syntax error, and octal numbers require the 0o prefix.
Admin
There have been other ways of indicating bases, such as a prefixed $ (common in assembly language) or a suffixed H for hexadecimal (in the latter case, the number must start with 0-9). I've also seen the use of a suffixed Q for octal (it might've been a choice of O or Q), which had the advantage that it looks like the letter O of Octal but the tail makes it clear that it's not a zero.
Admin
Oh, I love that. Q is perfect. Not only will it work but it's going to make people confused as to why Q.
Admin
"I've seen people who had not been a newbie for a long time making similar mistakes. Octals may have been all in vogue in the 1970s, but they should have died a long time ago. Or replaced by something which makes more sense, like 0o123."
And this notation has the advantage that it makes all your octals look like they're boggling at something.
Admin
Fortunately, Python did away with all this nonsense in 2008. (Anyone forced to still be using Python 2 when 3 has been out for 15 years now has my sympathy.)
SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers
Admin
I ran into this exact error when doing a little bash script - I forgot what exactly it did, but it involved parsing the output of "date -I". The script worked on every single day EXCEPT on the 8th and 9th. Pretty clear once you figure it out, but infuriating up until this point: 01-07 are all octal, but they are VALID and correspond to 1-7 in decimal, so no error. 10-31 are all decimal, so no problem there. But 08 and 09 are INVALID octal, just like in this very story...
Admin
8#01234567# (Ada)
Admin
I was expecting the punchline to be that the newbie did a search and replace on 07 to 09 and broke basically everything.
Admin
"8#01234567# (Ada)"
Clear, unambiguous, and highly extensible while not being overcomplicated. Obviously, you can see why Ada never caught on.
Admin
In JavaScript, "parseInt('011')" used to be octal until they changed it to decimal in ECMAScript 5. Sane JavaScript code will always call parseInt with a second argument of 10 anyway.
https://www.w3schools.com/jsref/jsref_parseint.asp
Admin
Better yet: a six bit wide unsigned octal in Verilog is 6o'42. Integer literals are: <width>'<radix><number>. Radix is b, o, d, h for unsigned, and sb, so, sd, sh for signed. And unfortunately, that language has caught on.
Admin
The problem with cpython is that it was written and maintained by c programmers who actually believed that the c library was the only technically possible way of doing math and strings.
It probably started out as just a simple standard way of implementing a new language (I never saw Rossum discuss the issue), but I had discussions with the developers and maintainers on the mailing list 20 years ago, and they literally thought that the c library implementation was the only theoretical way of doing floating point math, repr, and strings.
Admin
I like WTFs like this. You can see it coming, kind of like watching a train wreck in slow motion. Except smaller scale, so more like watching a runaway shopping cart run into a parked car.
Admin
Phone numbers get stored in a database as a string, because here in Australia, phone numbers start with 0, sure you could make it +61 and drop the 0, but eh, too difficult for a lot of office type people to understand, especially since where I work, we don't deal with international numbers, only aussie numbers.
Barcodes need to be stored in a database as a string, because otherwise a barcode that has a leading 0 drops it off.
I swear, using a 0 to denote an octal is a stupid idea in modern days.
Admin
oqtal, clearly.
I bet systemd has suffixes for all combinations of byte, short, int, long, longlong etc. and octal, hex, binary and decimal.
Admin
That octal syntax is the (poisoned) gift that keeps on giving. I've been hearing folks get tripped by that for forty years now, and that's probably because before I wasn't aware of it.
Admin
It's obvious enough why they left the leading zero — they did a search and replace for something along the lines of "s/'([0-9]+)'/\1/"... i.e. search for quoted numbers and strip the quotes, because that's what they'd been told to do.
I mean, sure, it wouldn't have been much more work to remove trailing zeroes — but if you're a newbie who doesn't know the octal gotcha and doesn't know good coding practices, why would you bother?
Admin
Not on leading zeros..... "4/5/2023" i(no quotes) s recognized as a Date by Excel --- but 04/05/2023 is NOT.....
And yes, Octal as default was (largely) for Assembly language, rarely the "Business" or "scientific" languages, much easier to parse for the days of very limited memory.
@Ray - A number is something you can do Math(s) on... Really has nothing to do with the characters used...
Admin
Phone numbers should be strings though. That is what they are in a logical sense.
Admin
If they only had 2 digit values with leading zeroes they dodged a bullet - a 3 digit value like "012" would have changed in meaning when stripping off the quotes.
Admin
If they only had 2 digit values with leading zeroes they dodged a bullet - a 3 digit value like "012" would have changed in meaning when stripping off the quotes.
Admin
"Phone numbers get stored in a database as a string, because here in Australia, phone numbers start with 0, sure you could make it +61 and drop the 0, but eh, too difficult for a lot of office type people to understand, especially since where I work, we don't deal with international numbers, only aussie numbers.
Barcodes need to be stored in a database as a string, because otherwise a barcode that has a leading 0 drops it off."
If you're working with either phone numbers or barcodes as integers, then you are most emphatically Doing It Wrong, regardless of what language you're working in or how it encodes number bases.
Admin
Wonderful write-up Remy. I'm constantly amazed that you can take the dross that comes in and spin it into golden WTFs. And for those wondering, yes this was Python2 and happened a long time ago when it was reasonable to be maintaining a Python2 program.
Admin
I suspect the x in 0x was chosen because it "sounds like" hex, not because it's the Nth character. There's no letter that sounds like "oct" or "octal", so the first letter makes more sense.
Admin
I'm going to counter with 2r01, 8r01234567 and 16r0123456789ABCDEF (Smalltalk). I'm not sure whether underscores are permitted, but it is/would be helpful in longer sequences of digits.
Admin
Where did I say I was working with them as integers?
I never said that.
What I did say is that they are numbers, at least over here.
Pretty much every barcode out there used in the retail world is EAN-8 or EAN-13, both of which are numerical.
And phone numbers, well, they are numbers too, it's only the formatting that formats them into something more readable with brackets and dashes and whatever else you might wish to add.
But no-where did I say I was storing them as integers, quite the opposite, they get stored as 'character' in the database.
MSExcel on the other hand when working with CSV files, well, that tries to be smart, it sees a number (despite it starting with a 0) and so it drops the 0 off the beginning and converts the cell to a number.
Sometimes I wish MSExcel would be more like LibreOffice and default to showing the data wizard instead of just auto-guessing.
Admin
How about the early versions of g77 that treated 0.1 as an octal number (1/8, not 1/10)?
Admin
But the literal 010 is still converted to 8. Honestly, in that case, I'd still prefer to have 09 fail. 007 008 009 010 011 results in 7, 8, 9, 8, 9 which is possibly the least sensible way to handle things.
Admin
It's still true that 09 is not a valid octal digit (though "numeric literal" is a more accurate description than "digit" here). It may be a valid numeric literal in Javascript, but it's not an octal one, and is only valid because it's not octal.