972

What is, in your opinion, the most surprising, weird, strange or really "WTF" language feature you have encountered?

Please only one feature per answer.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Andreas Bonini
  • 44,018
  • 30
  • 122
  • 156
  • 5
    @gablin I think if you combined LISP delimiters with PERL regex using javascript parsing you would cover 90% of the WTF... – Talvi Watia Sep 19 '10 at 23:41

320 Answers320

1855

In C, arrays can be indexed like so:

a[10]

which is very common.

However, the lesser known form (which really does work!) is:

10[a]

which means the same as the above.

Edan Maor
  • 9,772
  • 17
  • 62
  • 92
  • 758
    that's because a[10] means *(a+10) ... and 10[a] means *(10+a) :) – Michel Gokan Khan Jan 03 '10 at 14:50
  • 77
    Don't forget "Hello World"[i]. Or i["Hello World"] – Richard Pennington Jan 03 '10 at 15:12
  • 167
    Or, more usefully, "0123456789abcdef"[x & 0xf] – Dipstick Jan 03 '10 at 15:33
  • 8
    For an in depth look at this: http://stackoverflow.com/questions/381542/in-c-arrays-why-is-this-true-a5-5a – Dinah Jan 04 '10 at 20:54
  • 2
    Consider debugging code like this: `printf("%c", [!!flag]"FT")`. – David R Tribble Jan 05 '10 at 00:55
  • 3
    Loadmaster: `[!!flag]"FT"` is invalid syntax. –  Jan 05 '10 at 12:40
  • 2
    I'm pretty sure that's supposed to be: `"FT"[!!flag]` -- which actually isn't so bad if you're used to C's treatment of strings as aarrays and booleans as integers. It's not nearly as bad as C++ code that uses badly designed operator overloading. – Nate C-K Jan 06 '10 at 17:10
  • 4
    @Edan Moar: it is invaluable if you want to compete in the obfuscated C contest (http://www.ioccc.org/) ;) – Confusion Jan 06 '10 at 21:20
  • 3
    One should notice, that this only works as expected if sizeof(a[0])==1. So it works fine for char, but meaning differs for wchar_t. – Frunsi Jan 06 '10 at 23:45
  • 17
    @frunsi: It *always* works as expected. Pointer addition is not the same as simple integer addition on addresses. It is commutative *no matter* what size is the type in question. – R. Martinho Fernandes Jan 07 '10 at 02:23
  • It is even useful. Actual code extract (compacted to fit in comment): `do { tmp = val; val /= 10; *p++ = "9876543210123456789"[9+tmp-10*val]; } while(val); ...` - guess what its doing? – Frunsi Jan 08 '10 at 00:27
  • 5
    frunsi: That code snippet is not using the `number[array]` format in this answer: indexing a string like that is not strange at all. –  Jan 08 '10 at 01:38
  • 1
    @Martinho Fernandes: I don't understand how this can work with larger datatypes. Suppose it's a short[]. Then a[10] = *(a+2*10) right? How would the compiler know that 10[a] is the same thing? a is just a big number, and 10 is just some un/misallocated memory location. (Just thinking about this made me feel smarter. Imagine that. 10 years after I did anything in C.) – mcv Jan 12 '10 at 14:24
  • 12
    @mcv - a[10] is the same as "* (a+10)", where the expression "a+10" is pointer arithmetic (and since a is a short, in your example, a + 10 means 'start at a's address, and move 10 shorts, i.e. 20 bytes'). The expression 10[a] is interepreted as "* (10+a)", where "10+a" is *also* pointer arithmetic, and is treated exactly the same way. – Edan Maor Jan 12 '10 at 15:03
  • 5
    Guys, guys! Astonishingly, this crazy syntax can be, in fact, useful... http://stackoverflow.com/questions/469696/what-is-your-most-useful-c-c-utility/470221#470221 – Stefan Monov May 22 '10 at 21:30
  • 5
    I don't see it as a feature - so much as exposing the core of what C is about. Its all about pointers and getting to the memory directly with as little indirection as possible. Kind of beautiful, really. – Michael Neale Aug 14 '10 at 03:29
  • I've known this one for years. This was in the original C FAQ that was a dos program similar to man. You can probably still find it on x2ftp – graham.reeds Sep 10 '10 at 10:05
  • @Edan: I had the same q as @mcv and @frunsi, so I'm trying to follow your explanation. I'm with you right up to `"10+a" is also pointer arithmetic, is treated exactly the same way"`. If it were treated literally the same way, we would expect "10+a" to mean 'start at address 10, and move `a` shorts, i.e. a*2 bytes', which would give an incorrect result. If the key is that the compiler distinguishes between the address (`a`) and the index (`10`) based on their datatype, then I think that point is a crucial one that needs to be stated. However this is covered in q 381542. – LarsH Dec 01 '10 at 20:37
  • Yeah, C++ breaks this since you can overload a[10] with operator[] but not 10[a] – plaisthos Dec 26 '10 at 01:45
  • 2
    This is perfect stuff for **code obfuscation**. Let's change all array references now. ;) I can see a bunch of baffled faces staring at these... – Robert Koritnik Mar 02 '11 at 17:01
  • I use it in `lengthof` macro to quit the need for extra parentheses: `#define lengthof(x) (sizeof(x) / sizeof 0[x])`. Very bad, I know. – unkulunkulu Aug 29 '11 at 11:06
  • That's about as sensible as the 6502 instruction set, where the offset went into the register rather than the base address. And people built things with it! Thanks for giving me a heck of a smile, this never came to my enfeebled attention before. – holdenweb Dec 15 '11 at 22:46
1290

In JavaScript:

 '5' + 3 gives '53'

Whereas

 '5' - 3 gives 2
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dipstick
  • 9,854
  • 2
  • 30
  • 30
  • 81
    I remember when I first started using javascript using this sort of technique to add numbers in strings: "111" - -"222" gives 333 whereas "111" + "222" gives "111222". – Callum Rogers Jan 03 '10 at 16:03
  • 112
    `+` for string concatenation is horrible – Matteo Riva Jan 03 '10 at 16:42
  • 416
    + for concat isn't the problem. Weak typing is. – FogleBird Jan 03 '10 at 21:18
  • 270
    @FogleBird Neither one is really the problem. It's just the **combination** of the two with inconsistent coercion rules. – TM. Jan 03 '10 at 21:29
  • 70
    So basically, + is concat when a string is involved. Why can't they code something like '123456' - 456 = '123'? That would be interesting. – Jimmie Lin Jan 04 '10 at 08:40
  • 16
    It's weird, but it does make sense. You trying to add a number to a string, so it goes with concatenation. In the second, you cannot subtract a number from a string, so it just casts the string to a number. – BigBeagle Jan 04 '10 at 20:27
  • 3
    That's one reason Perl uses completely different operators for addition (+) and concatenation (.). – David R Tribble Jan 05 '10 at 00:59
  • 3
    @Jimmie Lin Would that be a decatenation? – Jeff Davis Jan 05 '10 at 16:32
  • 2
    I'm not seeing the sense. None of my computer science theory courses or books used "+" to mean concatenation. Where did that come from, anyway? – Ken Jan 05 '10 at 17:01
  • 3
    If you think about what concatenation actually means, it makes perfect sense. When you concatenate "abc" and "def", you're adding "def" to the end of "abc". It isn't mathematical addition, but logically it's similar. Of course, that doesn't mean that it's a good idea to use + for concatenation. – Eric Jan 05 '10 at 17:24
  • 3
    @Eric: I don't have a problem with `+` for concat. It's just a symbol. (It's how it behaves with mixed types I don't like). But I find string concatenation a very different operation from mathematical addition, beginning with the fact it's not commutative. – R. Martinho Fernandes Jan 05 '10 at 17:36
  • 1
    Eric: Nope, still not making "perfect sense" to me. I thought about "add" and "append" and "concatenate", and they're all different words with subtilely different meanings, so it makes sense to me that they'd be different programming language functions. In other languages which use different names, I've never once wished they used the same name, and I still think that there's probably a reason none of my books or profs ever used "+" for concatenation. – Ken Jan 06 '10 at 06:36
  • 2
    This is exactly why I hate implicit string -> number conversion, and any language that allows it. VB.Net will allow this as well, iirc – gillonba Jan 06 '10 at 22:46
  • There's no problem with implicit string -> number conversion because of the fact that it was a *really* poor choice to not have a dedicated concatenation operator. If that was fixed then it wouldn't be bad. – RCIX Jan 06 '10 at 23:35
  • 1
    In mathematics `+` is not used for non-commutative operators (although I'm sure someone will give a counter-example). Even as a monoid(?) I'd prefer not to use `*` as it would cause the same confusion. – Tom Hawtin - tackline Jan 07 '10 at 04:37
  • 2
    @Tom Hawtin - tackline: The operator * may be non-commutative in math. In matrix multiplication, A*B may be possible and B*A impossible, for instance. I can't think of any examples for +, but I'm pretty sure there will be. – luiscubal Jan 10 '10 at 16:57
  • 9
    + for concatenation isn't the issue, Python's implementation works great. It just refuses to add int and str without conversion. Javascript should throw an exception in this case. – crgwbr Jan 11 '10 at 17:19
  • 1
    Weak typing isn't really the problem, but Javascript's strange implementation of it – Chris S Jan 15 '10 at 22:33
  • WTF... isn't '5' string in the two ways??!! – jjj Jan 17 '10 at 05:18
  • That tripped me up so bad when I was first learning javascript. The inconsistent behavior made the bug extremely hard to find, especially since I didn't have a line-by-line debugger where I could watch variable values. – Chris Dutrow Feb 02 '10 at 04:27
  • So you have to remember that most variables in JavaScript are converted into strings in a heartbeat. To convert to numbers, use expressions like `x - 0`. – David R Tribble Feb 02 '10 at 21:16
  • 13
    "foo" + + "bar" => "fooNaN" – tlrobinson Feb 12 '10 at 21:25
  • 1
    What's worse... `'a'+2+3+5+7` is `'a2347'`. Now tell me what `'a'+2+3-5+7` will be. Wisest syntax lawyers get baffled. – SF. Feb 26 '10 at 13:47
  • 2
    @SF: `alert('a'+2+3-5+7)`. You need to meet some wiser language lawyers. –  Mar 16 '10 at 10:19
  • 12
    Neither `+` for concat nor weak typing is the problem. Programmers who are unaware of the language semantics are the problem. I mean: If you think it's a good idea to subtract an int form a string, it's all your own fault. And if you're even not aware what type your variables belong to -- so much the worse. – wnrph May 27 '10 at 10:35
  • 1
    @TM: Also not the combination is the problem. The problem is automatic casting or allowing such operations on objects of different types. – Albert Aug 13 '10 at 17:56
  • 2
    Weak typing can hardly be the problem, as JavaScript is not weakly typed. It is strongly typed: there is never any doubt about what will happen according to the language definition. It happens to be dynamically typed, but that doesn't make it weak. The exact opposite would be C, which is weakly statically-typed: types can be declared at compile time, but the declarations are allowed to be wrong (due to casting) and so some programs have undefined behaviour. The problem (if any) is implicit conversion. – Daniel Earwicker Sep 14 '10 at 12:22
870

In JavaScript, the following construct

return
{
    id : 1234,
    title : 'Tony the Pony'
};

returns undefined is a syntax error due to the sneaky implicit semicolon insertion on the newline after return. The following works as you would expect though:

return {
    id : 1234,
    title : 'Tony the Pony'
};

Even worse, this one works as well (in Chrome, at least):

return /*
*/{
    id : 1234,
    title : 'Tony the Pony'
};

Here's a variant of the same issue that does not yield a syntax error, just silently fails:

return
    2 + 2;
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Tamas Czinege
  • 118,853
  • 40
  • 150
  • 176
  • 226
    Semicolon insertion is one of the most evil parts of JavaScript. –  Jan 05 '10 at 01:17
  • 231
    You always run into problems when you design language features around the assumption that your users will mostly be idiots. – Rob Van Dam Jan 05 '10 at 06:38
  • 8
    I actually had that problem, being c# developer myself, I put the brace in new line. Took me hours to realize what was the problem. Even when I've solved the issue I didn't know what was the problem until I read your answer! – Fedor Hajdu Jan 05 '10 at 16:30
  • 1
    I think this answer is bogus. Both the first and the last are SyntaxErrors, at least in Firefox. – Jason Orendorff Jan 05 '10 at 22:25
  • 2
    Jason Orendorff: You're right it actually yields a syntax error due to the unexpected JSON. I corrected it and provided an example that does actually return undefined silently. The third example indeed doesn't work on Firefox but it most definitely works on Chrome. This is a well known artefact, not bogus at all unfortunately. – Tamas Czinege Jan 06 '10 at 00:05
  • 2
    These are so called bad parts of JS, to avoid these every javascript developer should read the good parts of Douglas Crockford. – Sinan Jan 07 '10 at 19:03
  • 5
    "Feature"? I think this item belongs on "strangest language *bugs*". – Ryan Lundy Jan 08 '10 at 17:35
  • 1
    Kyralessa: Implicit semicolon insertion is supposed to be a feature that makes working with javascript easier for non-programmers. – Tamas Czinege Jan 08 '10 at 17:37
  • 2
    It's not a bug, it's a feature! Really! – gillonba Jan 08 '10 at 21:35
  • 6
    Why are people voting for this? This will happen in any language with significant newlines, like Ruby and Python for example. Why would anyone produce this code knowing newlines are significant? – Nick Retallack Jan 10 '10 at 10:00
  • 24
    Nick Retallack: Because, due to JavaScript's C-like curly brackets & semicolons syntax, it's not apparent at all that newlines are significant. – Tamas Czinege Jan 10 '10 at 15:27
  • 4
    That sounds like more of a cultural problem than a language problem. If people didn't think they were supposed to use semicolons, they wouldn't be confused to find their statements are also delimited by newlines where possible. I never end lines with semicolons (except empty for-loops, which expect a statement) because two statement delimiters is redundant. Might as well complain about parenthesis in lisp or indentation in haskell or python - it's part of the syntax, and it's there by design. – Nick Retallack Jan 11 '10 at 21:31
  • 6
    I cannot understand how this could ever achieve the up-votes it has. It can only surprise people who try to use C-style when programming in Javascript. I wish people would give up on the very concept of "preferred" style and use the style natural to the language/project they are programming in. – Daniel C. Sobral Jan 12 '10 at 11:15
  • 3
    I agree with the last couple of comments. You shouldn't be opening curly braces at the start of a line anyway (in any language), and if you know that semicolons at the end of a line are optional, then this behaviour becomes incredibly obvious. – mcv Jan 12 '10 at 14:31
  • 19
    If you're not supposed to use C style when programming in JavaScript, then it was rather perverse of the JavaScript language designers to choose a C-style syntax. – Ryan Lundy Jan 22 '10 at 14:55
  • 2
    @Nick Retallack, @mcv: I think what makes it confusing is that only *some* newlines are treated like semicolons, and others aren't. For instance `a = myFunc[newline](1)` is not the same as `a = myFunc;(1)`. In the first case a equals the value returned by `myFunc(1)`, but in the second case a equals the *function* `myFunc`. – Tim Goodman Mar 25 '10 at 11:07
  • 4
    @mcv: Also, I disagree with you on not using opening braces at the start of a line in *any* language. This is a perfectly valid convention to use in most C-style languages, and (combined with tabbing) has the advantage of lining up each opening brace with the matching closing brace. Moreover, some college computer science departments require it. However, I agree that it's a bad idea for JavaScript in particular, because of semicolon insertion. – Tim Goodman Mar 25 '10 at 11:14
  • 4
    You may want to watch Dough Crockford's video about this, minute 32: http://goo.gl/zM5t – CMircea Apr 13 '10 at 15:43
  • 5
    Tight JavaScript syntax is not a style preference, it's good web development. C/C++/C#/Java are compiled. JavaScript is not. Every space is another byte (two for windows line breaks) for the user to download. Extend that to HTML/CSS, and it adds up. Some DotNetNuke pages have 20% page weight (not including images) from excess whitespace; they use 4-spaces where tabs should be. There's a growing population of mobile users surfing at modem-like speeds, prompting Google to add page weight/download time as criteria for search engine ranking this year - it's time to give a crap. – Matt Jul 02 '10 at 04:52
  • 4
    @Matt: Fair point, however I believe that these days, in production environment, you would only serve JavaScript that has been preprocessed by tools such as JsMin and Closure Tools anyway, so the original source code doesn't really resemble the actual JavaScript that has been served. – Tamas Czinege Jul 02 '10 at 08:51
  • This blasted feature really messes up things when you try to minify the code for a production environment (remove CR's and extra spaces, etc. to make it smaller). Sure you could try to "fix" your minify code, but WTF! – aDev Nov 04 '10 at 14:25
  • @mike: Only for naive minifiers. @tim: Yes that is the only situation I know of where it breaks. It is noted specifically in the ecmascript spec (last example in section 7.9.2). That should be the real wtf here. – Nick Retallack Jan 01 '11 at 21:37
793

JavaScript truth table:

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true

Source: Doug Crockford

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Chandra Patni
  • 17,347
  • 10
  • 55
  • 65
  • 237
    Good thing Javascript has the === operator, then. – Anonymous Jan 04 '10 at 10:16
  • 65
    So what purpose does `==` serve in the eyes of the language designer? – Chris S Jan 04 '10 at 15:20
  • 14
    @Chris S: I think it's supposed to do what people expect most of the time. – cdmckay Jan 04 '10 at 16:26
  • 1
    This is one of those examples where the Javascript designers where trying to outsmart the programmers. Which is okay to do for a language but they are not constant with doing this type of thing at all so you usually don't expect this kind of thing when it hits you. You are more likely to expect they type of thing that say Java or C would do. If this happened in say something like Ruby you'd be "ah..., okay..., i see...". In Javascript you usually curse. – aDev Jan 04 '10 at 16:58
  • 3
    Distinguishing the '==' operator (call it "looks like") from the '===' operator (call it "is identical to") only makes sense in a weakly-typed language. Everything has a defined string representation, for example, which can be handy but is a source of confusion when feeling out syntax for the first time. – Anonymous Jan 04 '10 at 18:48
  • 123
    It'd be nice if `==` had the meaning of `===`, and then there was another operator, something like `~=` that allowed type coercion. – TM. Jan 04 '10 at 22:39
  • 9
    The worst part is that == isn't even an equivalence relation since it's not reflexive: ''=='0' is false, but 0=='' is true. – Adam Crume Jan 06 '10 at 05:59
  • 5
    @Adam your example shows that it is not commutative. If it wasn't reflexive it would mean that 0==0 is false. – Otto Allmendinger Jan 06 '10 at 11:38
  • 18
    @Otto Actually, since we're geeking out, his example shows that == is not symmetric. At the moment, I don't seen how commutativity would be specified for a binary relation. – PeterAllenWebb Jan 06 '10 at 21:48
  • Yes, symmetric. But I don't think there is nothing wrong with commutative binary relations. Quick example: for booleans `(a != b) != c <=> a != (b != c)` (`!=` is exclusive-or for booleans). – Tom Hawtin - tackline Jan 07 '10 at 04:46
  • 5
    Another Javascript weirdness: 255 == { valueOf:function(){ return “0xFF”; } } // true – Laurie Cheers Jan 07 '10 at 17:41
  • 3
    This is the essential problem of a language designed by a committee and grown bit by bit organically. Consider English. – Lawrence Dol Jan 09 '10 at 10:05
  • 5
    If you think javacsript was designed by committee then you need to go back and read the history again. – Breton Jan 09 '10 at 12:29
  • I love javascript, but this scares me. Fortunately I rarely need to distinguish between my falsy values any way other than if(!value) or if(typeof value == 'undefined'). I will be using === more often from now on. – Nick Retallack Jan 11 '10 at 21:33
  • 1
    @TM I'm not sure that'd be as nice as you think. There's a lot of people that rely on `==` without realizing it when they do `getAttribute()` and get a string value but compare against an int value. – Nicole Mar 01 '10 at 20:36
  • 1
    @WTFITS: Don't forget about the `===` operator which does have sane semantics. Other than this and a couple other WTFs, JavaScript is actually a really cool language and definitely worth learning, in my opinion. – Joey Adams Apr 19 '10 at 19:39
  • 2
    This is more like a Truthiness table than a Truth table. – justin.m.chase Sep 07 '11 at 16:03
658

Trigraphs in C and C++.

int main() {
   printf("LOL??!");
}

This will print LOL|, because the trigraph ??! is converted to |.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Andreas Bonini
  • 44,018
  • 30
  • 122
  • 156
  • 71
    Quick! Tell all C /b/ programmers! – Esteban Küber Jan 03 '10 at 20:39
  • 235
    Trigraphs are amazing, because you can be sure nobody will -ever- find out what ??! will mean from Google without knowing the name already. – zaratustra Jan 04 '10 at 04:47
  • 3
    Are trigraphs changed to their equivalent character by the preprocessor? – dreamlax Jan 04 '10 at 20:23
  • No dreamlax, by the actual compiler I believe. As long as I know the preprocessor only touches lines that begin with a # – Andreas Bonini Jan 04 '10 at 20:40
  • @bytenik: macros still work in C++. Somehow I think it has a preprocessor... No to mention, oh, *preprocessor directives*! – R. Martinho Fernandes Jan 04 '10 at 20:50
  • 56
    Trigraphs are disabled by default in GCC. – sastanin Jan 04 '10 at 21:12
  • I don't particularly see the point of trigraphs, although I knew they existed. Are they just there to increase compilation time and help programmers who don't have | in their keyboards(do those keyboards even exist?) – luiscubal Jan 04 '10 at 21:37
  • 360
    These let you use the "WTF operator": (foo() != ERROR)??!??! cerr << "Error occurred" << endl; – user168715 Jan 04 '10 at 21:39
  • 6
    dreamlax & Andreas: Trigraphs replacement *is* performed by the preprocessor. See http://en.wikipedia.org/wiki/C_preprocessor – Laurence Gonsalves Jan 05 '10 at 00:12
  • 57
    Trigraphs were a necessary evil when they were introduced. Some platforms just did not include certain characters key to the language, so it was either "trigraphs" or "you can't have a C compiler period-end-of-statement so go use assembler". Check out Stroustrup's description in "The C++ Programming Language". – Euro Micelli Jan 05 '10 at 03:31
  • 5
    Couldn't it be a feature of the editor, rather than buil tinto the language? – Martin Beckett Jan 05 '10 at 16:19
  • 11
    I used to program in C on an IBM mainframe using a 3270 terminal in EBCDIC. Some of the characters needed by C (possibly including the "|" character) weren't on the keyboard and there was no such feature as ^Q 7 C on a block-mode terminal. Oddly, there was a "¦" (U+00A6, "Broken Bar") character. Even more oddly, most modern US PC keyboards have the "¦" character drawn on the key but the PC turns it into "|" – Adrian Pronk Jan 05 '10 at 22:28
  • 7
    @Adrian Pronk: When I was growing up I always thought it was very strange that the key had a broken bar but when I typed it, the bar was solid. I passed it off as one of those "it is because it is" things. – dreamlax Jan 07 '10 at 02:44
  • voyager, I don't think C /b/ (difficult to google) supports trigraphs. (I guess they are included and defined to cause compilation errors.) – Tom Hawtin - tackline Jan 07 '10 at 04:39
  • @Adrian- You were the other guy doing that? I interned at IBM one summer and they ran out of stuff to do so I proposed a project which the head nerd thought would be great until I said, but if you want me to finish it I have to do it in a language I know really well: C. And so I did. And they loved it. But I had to learn trigraphs. – jmucchiello Jan 07 '10 at 17:42
  • gcc disallow (or at least warns about) trigraphs by default. – Elazar Leibovich Jan 09 '10 at 23:01
  • Having read the Wikipedia digraphs and trigraphs page, it's interesting that the <% and %> are replaced with { and }. I wonder if that's ancestral to their use in asp asp.net php etc. – Andrew M Jan 18 '10 at 23:31
  • 3
    @dreamlax - that's because the PC keyboard was designed in the 80's for DOS and (IBM/PC flavored) ASCII. If you launch a console window you will see that the 'broken bar' key still output a 'broken-looking bar' there. The bar is 'broken' so it can be composed with `-` and `+` to produce _very primitive_ graphical boxes. In Unicode, I believe that the 'broken bar' was introduced elsewhere (0xA6) for compatibility, just so that such graphics can still be drawn. – Euro Micelli Jan 19 '10 at 19:23
  • 22
    `| ¦ |` was for drawing roads in ascii games – Scoregraphic Jan 22 '10 at 08:59
  • 1
    Why did they choose weird ??! over just inventing more \e scape \c haracters? – Chris Burt-Brown Mar 05 '10 at 17:39
  • 8
    @Chris because they are not escape characters. The example shows the use inside a string, but, get this, you can use them everywhere! Like this: `if(foo ??!??! bar)` instead of `if(foo || bar)`. – R. Martinho Fernandes Apr 02 '10 at 14:32
  • 1
    @Euro Micelli: some kind of escaping for Finnish programmers was probably necessary (although lots of Finnish programmers just resigned themselves to programming with operators like ä), but trigraphs are a particularly bad kind of escaping. GCC offers a much more readable set of two-character escapes instead. – Kragen Javier Sitaker Aug 14 '10 at 07:11
  • I'm not sure I get why this is a WTF. Trigraphs were necessary for some systems at one time. EBCDIC 3270s did not have consistant (or sometimes any) [] characters. Other chars were sometimes problematic too. But since trigraphs disabled by default seems to be the default behavior of most C compilers for decades... – Joe Zitzelberger Mar 23 '11 at 17:12
  • @EuroMicelli "_Trigraphs were a necessary evil when they were introduced._" When they were standardised, trigraphs were already of historical interest only. – curiousguy Dec 16 '11 at 19:04
573

Fun with auto boxing and the integer cache in Java:

Integer foo = 1000;
Integer bar = 1000;

foo <= bar; // true
foo >= bar; // true
foo == bar; // false

//However, if the values of foo and bar are between 127 and -128 (inclusive)
//the behaviour changes:

Integer foo = 42;
Integer bar = 42;

foo <= bar; // true
foo >= bar; // true
foo == bar; // true

Explanation

A quick peek at the Java source code will turn up the following:

/**
 * Returns a <tt>Integer</tt> instance representing the specified
 * <tt>int</tt> value.
 * If a new <tt>Integer</tt> instance is not required, this method
 * should generally be used in preference to the constructor
 * {@link #Integer(int)}, as this method is likely to yield
 * significantly better space and time performance by caching
 * frequently requested values.
 *
 * @param  i an <code>int</code> value.
 * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
 * @since  1.5
 */
public static Integer valueOf(int i) {
    if (i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

Note: IntegerCache.high defaults to 127 unless set by a property.

What happens with auto boxing is that both foo and bar the same integer object retrieved from the cache unless explicitly created: e.g. foo = new Integer(42), thus when comparing reference equality, they will be true rather than false. The proper way of comparing Integer value is using .equals;

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
z -
  • 7,130
  • 3
  • 40
  • 68
  • 31
    Took me a couple of seconds to see why... java must keep a pool of Integer instances for values between -128 and 128, otherwise it allocs a new Integer, right? – Mike Akers Jan 04 '10 at 20:25
  • 18
    however keep in mind that if you specify new Integer(42) it will not be using the instance from the pool so foo == bar will evaluate to false – z - Jan 04 '10 at 20:58
  • 10
    I always use ints instead of Integers if possible, but if I had to use Integers for some reason, should I just use .equals() instead of == ? – Tyler Jan 05 '10 at 05:12
  • 2
    @MatrixFrog: yes, they are objects. – jackrabbit Jan 05 '10 at 08:00
  • @Mike Akers: Highly unlikely. – Gaurav Jan 05 '10 at 10:12
  • 4
    What's more puzzling, is that Java is able to break the laws of mathematics by making 1000 both greater and less than itself! – RCIX Jan 05 '10 at 12:53
  • 1
    @Gaurav: Actually that's exactly what happens (except 128 is not required to be pooled). And you can always implement it yourself: http://thedailywtf.com/Articles/The-Integer-Cache.aspx – R. Martinho Fernandes Jan 05 '10 at 13:31
  • 1
    @Gaurav, see the java api if you don't believe it: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Integer.html#valueOf%28int%29 or go into Integer.java and take a look at the source code – z - Jan 05 '10 at 13:36
  • 5
    Best of all, you can use reflection to make 42 equal to whatever you want! – Adam Jaskiewicz Jan 05 '10 at 22:12
  • 1
    Can someone explain why you need a pool of integers? – graham.reeds Jan 06 '10 at 01:11
  • 3
    Can someone explain why you would make a pool of integers for a subset of integers only!? – johnc Jan 06 '10 at 01:26
  • 10
    I find it more interesting that the programmers of JAVA decided to use an - assumably - modifiable value dubbed `IntegerCache.high`, but only 1 line ahead, they decide it's better to hardcode the 128 (instead of using IntegerCache.high+1). – monokrome Jan 06 '10 at 01:59
  • 2
    @graham.reeds & johnc, the idea is to save a little bit of memory by caching the most often used integers instead of having a few million Integer objects containing the value 0, for instance (0 is probably most commonly used such as for default values). – z - Jan 06 '10 at 03:10
  • 3
    @all - yes auto(un)boxing is one of the dodgier things in Java - Introduced in Java1.5 because people still hadn't gotten over their obsession with primitives. @mono - because the offset is based on the low value. If anything they need a new IC.low variable. – CurtainDog Jan 06 '10 at 06:00
  • 6
    @monokrome: That `128` is there to rebase the array so the pooled instance of -128 is at index 0, -127 at index 1, 0 at index 128, and so forth. Writing `IntegerCache.high+1` would be a *bug*. – R. Martinho Fernandes Jan 06 '10 at 20:47
  • monokrome: The flexible cache size was initially introduced in performance releases. The max cached value is important in certain macrobenchmarks (database IDs I guess). Avoiding changing the offset allows for smaller code changes, and simpler code. – Tom Hawtin - tackline Jan 07 '10 at 04:54
  • 87
    @Will: C# has some very similar gotchas. See http://blogs.msdn.com/jmstall/archive/2005/03/06/386064.aspx – spookylukey Jan 07 '10 at 11:08
  • 5
    @spookylukey: The big difference is that in C# you don't need to box integers all the time, while in Java you have to do it as soon as you start using generics, which is... lots of times. – R. Martinho Fernandes Jan 07 '10 at 18:19
  • 5
    Strange feature, ya, problem, no, anyone comparing Objects with such operators have more to worry about than inconsistent results. – Pool Jan 10 '10 at 18:26
  • 6
    What's worst about this, and my primary complaint against this feature, is that if you refactor from primitives to Integers, and your tests don't explicitely try values outside of the cached range, you'll have a series of bugs that only show up in production. Not cool. – Jason May 13 '10 at 22:59
  • 1
    Java wasn't designed for bad programmers, or lazy ones that use a class without bothering reading its documentation. – Pierre Gardin Jul 28 '10 at 10:54
  • 2
    Thats the result of premature optimization. – Joschua Sep 03 '10 at 15:43
  • 1
    The big problem given Java's goals is that the range 127 and -128 is just a minimum. The spec allows an implementation to cache a bigger range if it wishes. This would make the above test code behave differently on different implementations. So much for write-once, run-anywhere. – Daniel Earwicker Sep 14 '10 at 13:06
  • @spookylukey - all those C# examples use an integer variable `x` and it is not necessary to know what range the value of `x` is within to predict the result. – Daniel Earwicker Sep 14 '10 at 13:07
  • @jae: Python does this, too. Check it out: `a = 127; b = 127, a is b` will return `True`. :) – mipadi Nov 12 '10 at 17:32
  • 1
    @spookylukey: Another big difference being, of course, that C#'s boxed integers aren't called Integer - they're called objects, and when you see object comparison you don't expect integer comparison. – configurator Jan 03 '11 at 21:33
372

Quoting Neil Fraser (look at the end of that page),

try {
    return true;
} finally {
    return false;
}

(in Java, but behaviour is apparently the same in JavaScript and Python). The result is left as an exercise to the reader.

EDITED: As long as we are on the subject consider also this:

try {
    throw new AssertionError();
} finally {
    return false;
}
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
lorenzog
  • 3,483
  • 4
  • 29
  • 50
  • 153
    Thankfully C# doesn't allow such madness... `Control cannot leave the body of a finally clause` – Richard Ev Jan 05 '10 at 16:40
  • 64
    This returns, false, does it? It may look like a WTF (and possibly it is one), but I live by the rule: Finally always wins, unless you crash the Machine before. – Michael Stum Jan 05 '10 at 19:01
  • 1
    @Richard E - even when an unchecked exception is thrown? – kdgregory Jan 05 '10 at 19:49
  • 1
    @michael: yes, it does return false. To my dismay when I first met this.. here I was, thinking that once you `return` the stack is "discarded". But you're right, finally always wins. I wonder if you can insert some clever trick here, like fooling the compiler and yet executing other code. – lorenzog Jan 05 '10 at 23:32
  • 28
    To be fair, I blame TDWTF's nice explanation for remembering that finally always wins unless you yank the power cord: http://thedailywtf.com/Articles/My-Tales.aspx – Michael Stum Jan 06 '10 at 02:10
  • @kdgregory - yes, even when an exception is thrown as the purpose of the finally is to clean up memory and other resources (i.e. call dispose, unlock things, or do something that must always be done regardless, maybe set a static variable), and then because an exception is thrown, no value needs to be returned as the function earlier in the callstack won't get the result (exception will either be caught, or that function will be exited out of as well due to the exception) – Grant Peters Jan 06 '10 at 14:59
  • I'm not sure I get you, Grant. Are you saying that the return in the finally clause will get executed in the sense that it puts a return value onto the stack, but this return value is then discarded when the stack continues to unwind upon exiting the finally block? – Nate C-K Jan 06 '10 at 17:26
  • 22
    I'm not sure what the code should return in this case. But I'm absolutely sure that you must not put `return` in `finally` clause. – jfs Jan 06 '10 at 20:31
  • @J.F. Sebastian: I totally agree. I can't think of a single valid use for `return` in a `finally`. Well, i'll predicate that with saying that it depends on what the language tells you about what happens when you `return` or `throw` or any other thing. – SingleNegationElimination Jan 08 '10 at 04:08
  • 1
    Hmm... After thinking about this for a bit, I actually understand it. when the return statement has completed, the function is no longer active. Since the `finally` clause has to run, it follows that the `return true` statement *has not executed* when `return false` is encountered. The function returns at that point. A compiler might notice that a `return` statement cannot raise an exception, so it is safe to rewrite it to put it after the `finally` clause. – SingleNegationElimination Jan 08 '10 at 04:12
  • 11
    Even if you can't return in a `finally` what would the following code do: `bool x = true; try { return x; } finally { x = false; }` – Chris Lutz Jan 11 '10 at 06:08
  • 6
    @Chris Just tested this in LINQPad (for C#) and it returns true. On the other hand if you change the code to `TestClass x = new TestClass(); x.Value = true; try { return x; } finally { x.Value = false; }` where TestClass is a reference class then the Value property will be set to false before control returns to the calling method. So it would appear that the value is copied to the stack when the return is hit, but the finally block is still called (as you'd expect). – Martin Harris Jan 18 '10 at 16:00
  • @Martin - The same thing happens for the equivalent situations in Python. This seems rather odd that a minor implementation detail can affect how the results of a `try / finally` block work. – Chris Lutz Jan 19 '10 at 05:00
  • 6
    Just remember that `finally` does exactly what it says. – David R Tribble Feb 02 '10 at 21:18
  • 1
    if `halt;` doesnt stop the madness, maybe `exit;` will.. :) – Talvi Watia Jun 11 '10 at 03:31
  • FYI, Its a compile time error in C#. Control cannot leave the body of a finally clause – Amit Wadhwa Aug 13 '10 at 17:29
  • 3
    It is NOT true that control cannot leave the body of a finally clause in C#. See section 8.10: "If an exception is thrown during execution of a finally block, and is not caught within the same finally block, the exception is propagated to the next enclosing try statement. If another exception was in the process of being propagated, that exception is lost." (Checking for "return" statically is just a special case.) Java, Common Lisp, Python, et. al. all behave this way. – Dan Weinreb Aug 30 '10 at 02:25
  • 4
    This is not a WTF. Its just logical, because finally, will always execute it's code and so it overwrites everything, that's in its way. – Joschua Sep 03 '10 at 15:45
  • Just tried the equivalent in Delphi, and it won't compile - same as C# ([Error] Unit1.pas(26): Cannot BREAK, CONTINUE or EXIT out of a FINALLY clause) – Gerry Coll Oct 07 '10 at 19:59
  • 3
    C++ avoids this issue by using RAII instead of finally. – Joseph Garvin Nov 13 '10 at 07:03
  • 5
    The intuitive behavior here would be fork() with control branching out into two parallel timelines. – SF. Jan 17 '11 at 13:41
  • @Joseph Garvin - *"C++ avoids this issue by using RAII instead of finally."* Not really - as Dan Weinreb pointed out, exceptions can leave a *finally* block, and unfortunately they can also leave a destructor in C++. If this happens during stack unwinding caused by a previous exception, the program simply terminates. And hence in C++ the expert advice is to take every step you can to ensure that exceptions do not leave a destructor. – Daniel Earwicker Sep 12 '11 at 12:54
324

APL (other than ALL of it), the ability to write any program in just one line.

e.g. Conway's Game of Life in one line in APL:

alt text http://catpad.net/michael/APLLife.gif

If that line isn't WTF, then nothing is!

And here is a video

Community
  • 1
  • 1
lkessler
  • 19,819
  • 36
  • 132
  • 203
321

The weird things C++ templates can be used for, best demonstrated by "Multi-Dimensional Analog Literals" which uses templates to compute the area of "drawn" shapes. The following code is valid C++ for a 3x3 rectangle

#include"analogliterals.hpp"
using namespace analog_literals::symbols;

          unsigned int c = ( o-----o
                             |     !
                             !     !
                             !     !
                             o-----o ).area;

Or, another example with a 3D cube:

  assert( ( o-------------o
            |L             \
            | L             \
            |  L             \
            |   o-------------o
            |   !             !
            !   !             !
            o   |             !
             L  |             !
              L |             !
               L|             !
                o-------------o ).volume == ( o-------------o
                                              |             !
                                              !             !
                                              !             !
                                              o-------------o ).area * int(I-------------I) );
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
josefx
  • 15,506
  • 6
  • 38
  • 63
  • 18
    While Eelis' analog literals are great, are they a strange language *feature*, or just a strange way to *use* a feature? –  Jan 10 '10 at 09:02
  • 85
    The real WTF will be the compiler error generated by one of those that is malformed. – Andrew McGregor Jan 20 '10 at 12:10
  • PHP = expanded debug. Reminds me of windows = `assert(blue-screen-of-death)` LOL – Talvi Watia Jun 11 '10 at 02:07
  • 6
    How sick is that..wake me up again when there is a version of AnalogLiterals that supports turning the literal around the X, Y and Z axis in Eclipse...now that would give "visual programming" a new real meaning. – TheBlastOne Aug 17 '10 at 14:23
  • 2
    Do the ordering of the o's and L's and |'s matter? – Ming-Tang Sep 04 '10 at 17:47
  • 4
    The ordering matters, since the templates make creative use of operator overloading.( Don't do this with real code, misusing operators makes code hard to read) – josefx Jan 14 '11 at 23:31
  • See: http://potential-lang.org/2010/07/02/quasi-quoting-ascii-art-to-define-data-structures/ -- Template Haskell beats C++, hands down. – Lambda Fairy Jan 04 '12 at 03:18
291

Perl’s many built-in variables:

  • $#not a comment!
  • $0, $$, and $? — just like the shell variables by the same name
  • , $&, and $' — weird matching variables
  • $" and $, — weird variables for list- and output-field-separators
  • $! — like errno as a number but strerror(errno) as a string
  • $_the stealth variable, always used and never seen
  • $#_ — index number of the last subroutine argument... maybe
  • @_ — the (non)names of the current function... maybe
  • $@ — the last-raised exception
  • %:: — the symbol table
  • $:, $^, $~, $-, and $= — something to do with output formats
  • $. and $% — input line number, output page number
  • $/ and $\ — input and output record separators
  • $| — output buffering controller
  • $[ — change your array base from 0-based to 1-based to 42-based: WHEEE!
  • $}nothing at all, oddly enough!
  • $<, $>, $(, $) — real and effective UIDs and GIDs
  • @ISA — names of current package’s direct superclasses
  • $^T — script start-up time in epoch seconds
  • $^O — current operating system name
  • $^V — what version of Perl this is

There’s a lot more where those came from. Read the complete list here.

jrockway
  • 42,082
  • 9
  • 61
  • 86
Chris S
  • 64,770
  • 52
  • 221
  • 239
  • 83
    The `$[` variable is the most evil of them all. – Brad Gilbert Jan 04 '10 at 04:34
  • 24
    Would definitely appreciate it if Perl 6 was something I could code in without having to check `perldoc perlvar` every five seconds. (Though I confess that half the time I check it thinking "I know there's a special variable that can do this for me, I just don't remember which one..." =P ) – Chris Lutz Jan 04 '10 at 07:26
  • 17
    The problem with `use English;` is that it affects RegExp performance. I am not making this up. http://perldoc.perl.org/English.html#PERFORMANCE – David Webb Jan 04 '10 at 13:06
  • 3
    $_ is my favorite variable. Having to write foreach($a as $v) in php makes my hair hurt. – Erik Jan 04 '10 at 21:07
  • I think the worst ones are $@ and @$. Both work and I still have no idea what the 2nd one does (the first one is an eval error). I was debugging some code that was supposed to use $@ but the original coder wrote @$ and it evaded me for hours. – Artem Russakovskii Jan 05 '10 at 01:17
  • 13
    @Dave: it's not a problem because of the -no_match_vars option in the page you linked. @Brad: $[ is SO evil. The intention behind it is evil, yes, but it also doesn't even work! @Artem: from perlvar "Perl identifiers that begin with digits, control characters, or punctuation characters are exempt from the effects of the package declaration and are always forced to be in package main ; they are also exempt from strict 'vars' errors." So that means @$ would be created and assigned to without an error even under stricture. Ugh! – rjh Jan 05 '10 at 03:03
  • 1
    Ruby has stuff like this too. Quite annoying. – Tyler Jan 05 '10 at 05:11
  • @rjh: re: use English -> but then you would have to use the non-English vars for regex. – R. Martinho Fernandes Jan 05 '10 at 17:23
  • 1
    I felt like the topic of this post was the names of the variables, rather than the function of them so I created a new answer specifically for the function of $[: http://stackoverflow.com/questions/1995113/strangest-language-feature/2008240#2008240 – Evan Carroll Jan 05 '10 at 18:49
  • 1
    I hate `use English;`. I hate mixedCaseCode unconditionally as it is, but ALL_CAPS_CODE is a whole new level of loathing. – Chris Lutz Jan 05 '10 at 21:13
  • They're nice for one liners, though. {local $/=undef;$_=<>} – niXar Jan 07 '10 at 13:07
  • 1
    I am by no means a Perl veteran and I LOVE these special characters. You just have to be aware that Perl has these special characters and know what they mean. It's like learning any new language ... you have to learn the syntax in order to understand how to write and read the code. – Brian T Hannan Jan 11 '10 at 22:14
  • (Plain) Python doesn't have this . Guess why I prefer it? ;-) – Jürgen A. Erhard Jan 12 '10 at 01:16
  • `$$` is more evil than Brad's one, I'd never seen that before. – Chris S Jan 12 '10 at 23:51
  • So doesn't $[ always have the value 0? – Leo Jweda Jan 16 '10 at 11:44
  • If you subscribed to that school of thought, you wouldn't use Perl! – asmeurer Jan 17 '10 at 02:24
  • 4
    @Brian: How do you propose to learn the syntax when the official documentation itself states that there are circumstances where the Perl interpreter *heuristically guesses* what a sequence of characters means? E.g. in `/$foo[bar]/`, is the `[bar]` part a character class or a subscript to the array `@foo`? Grep perldata for the terrifying answer. – j_random_hacker Jan 31 '10 at 08:19
  • 1
    That column of special vars is clearly a man with a hat riding a segway. They HAD to it this way. – Francisco Aquino Mar 01 '10 at 20:46
  • 1
    This is valid PHP... ` $__='([^/]+)@i\',$__,$___';$_=preg_match('@^(?:,)?([^/]+)@i',$__,$___); echo $_; echo $__; print_r($___); ?>` – Talvi Watia Jun 12 '10 at 06:33
  • 1
    By the way, one other slight problem with these variables: They're ungooglable! – malvim Aug 13 '10 at 21:48
  • 1
    @malvim: Luckily you can find everything about these variables from the command line, for eg. `perldoc -v $.` Also see `perldoc perlvar` for complete list (also online: http://perldoc.perl.org/perlvar.html) – draegtun Aug 14 '10 at 19:00
  • @Chris Perl 6 has only 4 special variables left, of which you'll need three (`$_` as the topic, `$!` for errors and `$/` for match results). None of them are global anymore. – moritz Dec 06 '10 at 07:16
  • 1
    a lot of those are there in ruby too – johannes Oct 28 '11 at 14:18
289

PHP's handling of numeric values in strings. See this previous answer to a different question for full details but, in short:

"01a4" != "001a4"

If you have two strings that contain a different number of characters, they can’t be considered equal. The leading zeros are important because these are strings not numbers.

"01e4" == "001e4"

PHP doesn’t like strings. It’s looking for any excuse it can find to treat your values as numbers. Change the hexadecimal characters in those strings slightly and suddenly PHP decides that these aren’t strings any more, they are numbers in scientific notation (PHP doesn’t care that you used quotes) and they are equivalent because leading zeros are ignored for numbers. To reinforce this point you will find that PHP also evaluates "01e4" == "10000" as true because these are numbers with equivalent values. This is documented behaviour, it’s just not very sensible.

Community
  • 1
  • 1
Dan Dyer
  • 53,737
  • 19
  • 129
  • 165
  • 56
    Just use === and !==. Which should be used anyway unless a loose type comparison is needed. – Dykam Jan 03 '10 at 16:52
  • 14
    @Dykam, if you follow the link to the fuller answer you'll see that I've addressed the use of the === operator. – Dan Dyer Jan 03 '10 at 17:17
  • 18
    Weak typing strikes again! – gillonba Jan 06 '10 at 22:50
  • 43
    I always knew PHP was a sin. Up until now I didn't realize it was an unforgivable sin :D – Thomas Eding Feb 13 '10 at 12:08
  • This is heinous! But I'm confused: are you saying that "01a4" != "001a4" in PHP? If so, I don't get it. How can "01e4" == "001e4" if "01a4" != "001a4"? They're all valid hex values. – Igby Largeman Apr 20 '10 at 16:19
  • PHP `intval()` is recommended for integer comparisons using `==` when in non-integer variable form. – Talvi Watia Jun 11 '10 at 04:37
  • 2
    They should tech people to use === in any programming book or tutorial. Added note: On a badly written PHP app I was able to supply as my password anything that was parsed as the same number. – Pepijn Jul 21 '10 at 16:06
  • I've hit issues in PHP where I used a very large number (a Facebook API key) and didn't quote it when declaring it; PHP silently converted it to floating point in scientific notation when I displayed it and screwed up the API call. – Michael Louis Thaler Aug 13 '10 at 15:26
  • How come PHP is not first in the wtf list? – Roman Plášil Aug 13 '10 at 17:09
  • 1
    I knew the was a reason I distruted weakly typed languages. If a well designed langauge there should be no need for abominations like === and !==. As string is a string. An number is number. If I want to convert one to the other **I** will SAY SO – Gerry Coll Oct 07 '10 at 20:03
  • @Talvi: it's not even that straight-forward... intval() doesn't even give you the proper value.. var_dump("01e4") => "01e4", var_dump("01e4" == "001e4") => true, var_dump(001e4) => float(10000) ... BUT: var_dump(intval("01e4")) => 1, and var_dump((int)"01e4") => 1. YET: var_dump("01e4" == 1e4) => true, AND: var_dump("01e4" == 10000) => true as well ;) – Joe Jan 04 '11 at 01:22
  • @joe the problem is you are containing the value in quotes. (causing it to be interpreted as a string.) try no quotes and it works fine. also, if you know you are using hex, you can use `intval(01e4,16);` see: http://us2.php.net/manual/en/function.intval.php – Talvi Watia Jan 30 '11 at 22:18
  • @Talvi: I understand that, but the original response explicitly uses quotes :) hence further exploring the inconsistencies, both with and without quotes. If "01e4" == "001e4", then it's clearly doing an internal conversion to a number. Yet intval (or int-cast) does not see it as that number. – Joe Feb 01 '11 at 17:49
281

The JavaScript octal conversion 'feature' is a good one to know about:

parseInt('06') // 6
parseInt('07') // 7
parseInt('08') // 0
parseInt('09') // 0
parseInt('10') // 10

More details here.

Community
  • 1
  • 1
Brian Deterling
  • 13,556
  • 4
  • 55
  • 59
281

Let's have a vote for all languages (such as PL/I) that tried to do away with reserved words.

Where else could you legally write such amusing expressions as:

IF IF THEN THEN = ELSE ELSE ELSE = THEN

(IF, THEN, ELSE are variable names)

or

IF IF THEN THEN ELSE ELSE

(IF is a variable, THEN and ELSE are subroutines)

badp
  • 11,409
  • 3
  • 61
  • 89
MZB
  • 2,071
  • 3
  • 21
  • 38
  • 28
    @RoadieRich one group of buffaloes is not explicitly from Buffalo, they are just nondescript buffalo. – Jürgen A. Erhard Jan 12 '10 at 02:24
  • 1
    Or FORTRAN, in which there were not only no reserved words, but whitespace was not significant (the END statement was defined as a card with 'E', 'N', and 'D', in that order, and spaces everywhere else). Parsing an IF statement was tricky, since `IF(` could mean either the start of one of the varieties of IF, or an assignment to the IF array. – David Thornley Feb 18 '10 at 18:36
213

Duff's device in C!

In C one can interlace a do/while with a switch statement. Here an example of a memcpy using this method:

void duff_memcpy( char* to, char* from, size_t count ) {
    size_t n = (count+7)/8;
    switch( count%8 ) {
    case 0: do{ *to++ = *from++;
    case 7:     *to++ = *from++;
    case 6:     *to++ = *from++;
    case 5:     *to++ = *from++;
    case 4:     *to++ = *from++;
    case 3:     *to++ = *from++;
    case 2:     *to++ = *from++;
    case 1:     *to++ = *from++;
            }while(--n>0);
    }
}
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Frunsi
  • 7,099
  • 5
  • 36
  • 42
  • 9
    Duff's device is probably a good reason for the switch statement not having a break by default ;-) However, I did not yet see any other good use of interlaced switch and loop - but probably there is one. Oh wait, yes, there is another use: coroutines and protothreads. – Frunsi Jan 07 '10 at 19:14
  • It's part of the hacker's test, in fact. :-) – Daniel C. Sobral Jan 12 '10 at 11:09
  • This is so wrong. You jump from outside the loop straight to the middle of the loop, right? You never actually come across the do{ . So what would happen if you put the while() behind case 0: ? Does it still loop? Or is that exactly why the while needs to be at the end? C suddenly feels like a interpreted language to me. – mcv Jan 12 '10 at 15:02
  • 16
    @frunsi: "Duff's device is probably a good reason for the switch statement not having a break by default" - Always make the common case the default. I would not exactly say this is the common case.. – BlueRaja - Danny Pflughoeft Jan 19 '10 at 20:14
  • 6
    @mcv probably easiest if you try to read it as assembly code, i.e. the `while` at the end is a (conditional) `JMP` back to the `do`, which explains why you can skip the `do` and still end up in the loop. – wds Jan 22 '10 at 09:01
  • 14
    Do keep in mind that Duff's Device generally produces WORSE code than the normal looping statement for modern compilers, which know how to (better) loop unrolling than you can do by hand. – Billy ONeal Feb 08 '10 at 17:54
  • 37
    @frunsi: Duff himself, publishing it, claimed something like this: "This definitely provides an argument in the discussion whether switch should fall through by default, but I'm not sure if the argument is for or against it." – SF. Feb 26 '10 at 13:58
  • @SF.: yes true, in a no-default-fall-through world, duff's device could probably also work (with a `fallthrough` or `continue` keyword). and in that world most other code using a switch statement would be shorter. however, it is too late to change that for C and C-like languages (everyone except newbies expect the default-fall-through nowadays). – Frunsi Feb 26 '10 at 14:48
  • 2
    This technique can also be used to implement stackless threads in C, as in the Contiki operating system: http://www.sics.se/~adam/pt/ – Oskar N. Sep 06 '10 at 21:21
204

Algol pass by name (illustrated using C syntax):

int a[3] = { 1, 2, 3 };
int i = 1;

void f(int j)
{
    int k;
    k = j;  // k = 2
    i = 0;
    k = j;  // k = 1 (!?!)    
}

int main()
{
    f(a[i]);
}
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Richard Pennington
  • 19,673
  • 4
  • 43
  • 72
  • Interesting, what PHP calls a reference is more like a shallow version of an Algol call-by-name than like a pointer in C. It's useful to find out it has an intellectual heritage. –  Jan 03 '10 at 17:46
  • 3
    It's possible in Scala though (`def f(j : => int)`) – Dario Jan 03 '10 at 20:49
  • Nice that you use C for illustrating that - I have always thought that C preprocessor macros are the closest equivalent to "pass by name" that any language that is in wide use has. – nd. Jan 04 '10 at 07:59
  • 10
    So this is something like `... template struct by_name { virtual operator T&() = 0; }; void f(by_name j) { ... } int main() { f(struct : by_name { operator int&() { return a[i]; } }); }`? – Simon Buchan Jan 05 '10 at 10:38
  • Amazing, though I'm wondering how you would implement this feature. – Paggas Jan 07 '10 at 13:01
  • 2
    It's actually pretty straight-forward: You generate a small piece of code (usually called a "thunk", hence my pun above) that calculates the address resulting from the expression, in this case &a[i]. A pointer to this function is passed to the called function, which then uses it to calculate the current address every time the parameter is accessed. – Richard Pennington Jan 07 '10 at 15:55
  • But your thunk accesses the scope from where it is used, which is insane and not at all like a closure. – Tobu Jan 07 '10 at 16:13
  • No, the Algol thunk (not mine!) accesses the scope from where it is defined. So it would have to work like a closure. – Richard Pennington Jan 07 '10 at 16:23
  • 1
    The traditional thing to do is to pass the array index as an argument as well, instead of making it a global variable, so you can say `x = dotproduct(a[i], b[i], i)`. – Kragen Javier Sitaker Jan 07 '10 at 22:12
  • The problem is that it's not clear that you are passing by reference. In C/C++ syntax it looks like you are passing by value and not reference. This feature is very standard, but one must know that Algol passes by reference in this case I guess? – Brian T Hannan Jan 11 '10 at 22:18
  • D version: auto a = [1, 2, 3], i = 1; void f(lazy int j) { writefln(j); /* 2 */ i = 0; writefln(j); /* 1! */ } void main() { f(a[i]); } – FeepingCreature Feb 07 '10 at 15:32
  • This is an Algol bug, not a feature, eh? – TheBlastOne Jun 18 '10 at 11:57
  • In Smalltalk you can have similar fun with `become:`, it swaps any two objects in place, for example `true become: false`. – starblue Aug 12 '10 at 12:35
  • This looks kind of like lazy evaluation mixed with imperative programming. :) – Albert Aug 13 '10 at 18:15
  • 2
    This was originally done for things like integration and derivaties. It's indeed poor man's closure. No matter how complex is the expression you pass in, it's reevaluated every time it shows up in the function's text. Think of the fun with side effects! And, if I remember correctly, it was the default method for passing parameters, too. In Algol 68 it was called _proceduring_ and was not default any more, as far as I can recall. –  Aug 20 '10 at 20:26
  • call by name is an special form of lazy evaluation. Scala can do this. – Ismael May 13 '11 at 17:20
  • In C#, the function `f` would take a parameter `Func`, the test call would be `f(() => a[i]);` and references to `j` inside `f` would say `j()`. This makes the recalculation more obvious. – Daniel Earwicker Sep 12 '11 at 13:03
189

In Python:

>>> x=5
>>> 1<x<10
True
>>> 1<x<3
False

Not a WTF, but a useful feature.

MAK
  • 26,140
  • 11
  • 55
  • 86
188

In Java:

int[] numbers() {
  return null;
}

Can be written as:

int numbers() [] {
  return null;
}
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Chandra Patni
  • 17,347
  • 10
  • 55
  • 65
  • 29
    I hate to say this but the WTF one is a consistent extension of the C type system. If C functions were allowed to return arrays then that's what it would look like. The nicer one is a consistency violation to make it more readable. Much like "const char * var" vs "char const * var". – Gordon Wrigley Jan 04 '10 at 22:38
  • 15
    @Adam - It actually makes sense when you consider that variable declaration similarly allows both "int stuff[]" and "int[] stuff". They just let the same rules work for method declaration. – Brandon Yarbrough Jan 05 '10 at 00:06
  • @tolomea: I might misunderstand what you are trying to say, but your given example of consting either the pointer of the content of the pointer is actually a syntactical difference, not only some kind of violation to make it more readable. – lImbus Jan 05 '10 at 00:45
  • 2
    @lImbus: Actually, `const T*` and `T const*` are equivalent, it's `T* const` that consts the pointer. Also, I hate sans fonts. – Simon Buchan Jan 05 '10 at 10:42
  • 1
    I agree, this isn't that strange if you are a C programmer. – Brian T Hannan Jan 11 '10 at 22:22
  • 3
    After all, `numbers()[2]` is a legal statement. – badp Feb 09 '10 at 16:53
  • 1
    Even better with multi-dimensional arrays:`int[] numbers() [] { return new int[1][1];}` – Bas Leijdekkers Dec 15 '11 at 19:23
184

INTERCAL is probably the best compendium of strangest language features. My personal favourite is the COMEFROM statement which is (almost) the opposite of GOTO.

COMEFROM is roughly the opposite of GOTO in that it can take the execution state from any arbitrary point in code to a COMEFROM statement. The point in code where the state transfer happens is usually given as a parameter to COMEFROM. Whether the transfer happens before or after the instruction at the specified transfer point depends on the language used. Depending on the language used, multiple COMEFROMs referencing the same departure point may be invalid, be non-deterministic, be executed in some sort of defined priority, or even induce parallel or otherwise concurrent execution as seen in Threaded Intercal. A simple example of a "COMEFROM x" statement is a label x (which does not need to be physically located anywhere near its corresponding COMEFROM) that acts as a "trap door". When code execution reaches the label, control gets passed to the statement following the COMEFROM. The effect of this is primarily to make debugging (and understanding the control flow of the program) extremely difficult, since there is no indication near the label that control will mysteriously jump to another point of the program.

Jeff Foster
  • 43,770
  • 11
  • 86
  • 103
  • 16
    Quite evil -- turns labels into GOTOs. Sounds like a language feature hackers would beg for... – RCIX Jan 03 '10 at 15:52
  • 1
    Yes it is quite eval -- but when you think about it you will see its just a primitive implimetation of "Aspect Oriented Programing" or "Dependency Injection" expect its not kool and AOP is. – James Anderson Jan 04 '10 at 01:43
  • 114
    Ok, but INTERCAL is supposed to be funny - this is not really a surprising "gotcha". INTERCAL compiler can actually refuse to compile the program if you don't use the `PLEASE` modifier often enough! – vgru Jan 04 '10 at 10:54
  • 1
    Don't forget that defining multiple COME FROMs allows multithreading. – alex strange Jan 04 '10 at 20:16
  • 2
    @alex: that's just in the Threaded-INTERCAL implementation. It's not part of the INTERCAL spec. (I can't help but laugh when I say "INTERCAL spec") – R. Martinho Fernandes Jan 04 '10 at 20:53
  • 6
    What amazes me most is that in system requirement analysis in the "World of Commercial T. I." , COMEFROMs are actually used in text files describing Use Cases. (seriously: some analysts here delayed a corporate wide migration to OpenOffice instead of MS's Office because the former could not properly reference a "comefrom" with the required granularity in a link) – jsbueno Jan 06 '10 at 17:50
  • 5
    Groo: It's worse. Use PLEASE too frequently and it refuses to compile your program because you're grovelling (C-INTERCAL requires between 33% and 66% of statements to have PLEASE modifiers). – Vatine Jan 07 '10 at 12:21
  • 2
    COMEFROM statement considered harmful – Chad Braun-Duin Jan 07 '10 at 18:25
  • 2
    But the real beauty of this is that you can have *multiple* statements that come from the same line... Yup, intercal has multi-threading! – Kevin Wright Jan 07 '10 at 19:11
  • 2
    Is it just me, or does this actually sound a lot like plain ol' events in .NET? – Dan Tao Aug 13 '10 at 21:28
160

Not really a language feature, but an implementation flaw: Some early Fortran compilers implemented constants by using a constant pool. All parameters were passed by reference. If you called a function, e.g.

f(1)

The compiler would pass the address of the constant 1 in the constant pool to the function. If you assigned a value to the parameter in the function, you would change the value (in this case the value of 1) globally in the program. Caused some head scratching.

Richard Pennington
  • 19,673
  • 4
  • 43
  • 72
  • 124
    Ooh. Then `2+2` *can* equal `5` (for very large values of `2` of course!). – Alok Singhal Jan 03 '10 at 21:14
  • 12
    um, what value of 2 would make "2+2" == "5"? I don't know any integer value 2 can take on for that to be true. – Aaron Jan 04 '10 at 21:07
  • @Aaron, I'm guesing `2` is defined as a constant, and as such could be sent by reference to a function making the constant `2` be any abritrary value in the actual machine code. – Earlz Jan 04 '10 at 21:35
  • 36
    @earlz: I suspect that it would wind up as an integral value, of whatever bit pattern. On the other hand, you could probably set 5 to 4 that way (so `2+2` would equal `5` for small values of `5`). – David Thornley Jan 04 '10 at 22:17
  • 2
    Maybe we can change the quote to "2+2=5 for very small values of 5". http://www.thinkgeek.com/tshirts-apparel/unisex/generic/60f5/ – Alok Singhal Jan 05 '10 at 05:27
  • 18
    Excuse me, Alok, but this is early FORTRAN we're talking about. It won't be true that `2 + 2 = 5`; that'll be a syntax error. What will be true is `2 + 2 .EQ. 5`. – David Thornley Jan 06 '10 at 15:57
  • @Thomas: `2 + 2 .EQ. 5` is possible. Just read the other comments. Or if you don't want to, just make 5 be 4. – R. Martinho Fernandes Jan 07 '10 at 02:31
  • 3
    In Haskell the following snippet evaluates to 5: "let 2+2=5 in 2+2" :) – Tirpen Jan 07 '10 at 13:32
  • 1
    Ahhh, my favorite bug. I spent *days* debugging that one once. I ultimately found it very fascinating to discover the constant 1 had the value zero after a certain point in our program. That was eye opening. – Bryan Oakley Jan 07 '10 at 22:37
  • This isn't necessarily strange - in C, arrays are always passed as a reference, which can be really handy! – Jamie Rumbelow Jan 10 '10 at 12:22
  • 1
    2 = 100 5 = 200 2 + 2 .EQ. 5. There. 2 + 2 is 5 for very large values of 2. – luiscubal Jan 10 '10 at 17:01
  • 1
    Almost like pythons shared-mutable-default-args, but global. – Macke Jan 11 '10 at 16:43
  • 1
    Interesting. If C had had a similar history, the old "if (1 == x)" trick (in place of the (IMHO) more readable "if (x == 1)") might never have been created... or would at least have been as bad as the problem it was invented to avoid. – Jürgen A. Erhard Jan 12 '10 at 01:46
  • This was true up through FORTRAN 66. Later versions of F77 corrected it. Been There Done That! – Dave Mar 24 '10 at 22:31
  • A long time ago, a programmer (designing a TRS-80 game, IIRC) did this accidentally, passing 1 as a parameter to a function that passed that parameter to another function which altered the value of 1. He declared a variable I, assigned 1 to it, and passed it in, so nothing untoward changed. This demonstrates one of Murphy's laws: "Constants aren't, and variables don't." – David Thornley Apr 23 '10 at 21:57
  • I had been wondering about that question in [The HACKER test](http://www.hungry.com/~jamie/hacker-test.html) "Ever change the value of 4?" – Ken Bloom Jul 11 '10 at 21:24
  • @Alok: How? If `x` is an integer, shouldn't `x+x` at least always be an even number? Or can you even make the integer constant `2` point to `2.5`? – Albert Aug 13 '10 at 18:26
  • 1
    @Albert, who is to say that 5 is actually 5? If the value of 2 can change, so can the value of 5 (so 5 could be changed to 6 for example)! – Alok Singhal Aug 13 '10 at 19:11
  • Fortran was the first real programming language ever invented. That was 1953 to 1954. At the outset, it wasn't clear that such a thing was even possible. It's hardly fair to criticize from the perspective of 58 years of intensive further development. – SeaDrive Apr 11 '11 at 15:17
  • Okay, so if `int foo(a) {return ++a + 2;}` then `foo(2)` returns `6`? – Robert Jul 07 '11 at 13:18
153

Don't know if it can be considered a language feature, but, in C++ almost any compiler error related to templates delivers a fair amount of WTF to many C++ programmers around the world on daily basis :)

Dmitry
  • 6,590
  • 2
  • 26
  • 19
  • 1
    Depends on the compiler. MSVC++ is much worse in this regard compared to GCC. – Daniel Sloof Jan 04 '10 at 07:33
  • 15
    That's okay, most code related to templates already creates plenty of WTFs around the world. – Joris Timmermans Jan 04 '10 at 13:31
  • 43
    Oh come now. undefined reference to `std::basic_ostream >& std::operator<< >(std::basic_ostream >&, char const*)' Is perfectly readable! – Matt Greer Jan 04 '10 at 20:48
  • 1
    @Khelben: However, Matt Greer's example is about something like `cout << "Hello, World!"`, which many people don't realize involves templates. (Using a string instead of a quoted string would have been even more verbose.) – David Thornley Jan 04 '10 at 22:32
  • 1
    @Khelben templates are about the only reason to use C++ rather than an object oriented language or C + GObject – Pete Kirkham Jan 05 '10 at 10:28
  • 10
    I once had a template-related compiler error that was five lines, the shortest of which was seventeen thousand characters (the classic 'no match for x' error, in a deeply templated program). That's the WTF, not the feature in the first place, templates are wonderful. – Andrew McGregor Jan 05 '10 at 11:26
  • 111
    Even if there's no error, try finding which functions take the longest with your profiler. Oh look, it's `std::vector, std::allocator > >::vector< std::vector, std::allocator > >::iterator>(std::vector, std::allocator > >::iterator, std::vector, std::allocator > >::iterator, std::allocator >)` – rlbond Jan 05 '10 at 17:24
  • 12
    I think this fits here: Check out STLFilt at http://www.bdsoft.com/tools/stlfilt.html to make the output readable. – foraidt Jan 06 '10 at 09:58
  • Depends on the compiler. clang has fixed it mostly (for example leave away default template parameters and more). And I think GCC is following (or is planning to). – Albert Aug 13 '10 at 18:33
150

The many name spaces of C:

typedef int i;

void foo()
{
    struct i {i i;} i;
    i: i.i = 3;
    printf( "%i\n", i.i);
}

Or with characters:

typedef char c;

void foo()
{
    struct c {c c;} c;
    c: c.c = 'c';
    printf( "%c\n", c.c);
}
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Victor Hurdugaci
  • 28,177
  • 5
  • 87
  • 103
149

I would say the whole whitespace thing of Python is my greatest WTF feature. True, you more-or-less get used to it after a while and modern editors make it easy to deal with, but even after mostly full time python development for the past year I'm still convinced it was a Bad Idea. I've read all the reasoning behind it but honestly, it gets in the way of my productivity. Not by much, but it's still a burr under the saddle.

edit: judging by the comments, some people seem to think I don't like to indent my code. That is an incorrect assessment. I've always indented my code no matter what the language and whether I'm forced to or not. What I don't like is that it is the indentation that defines what block a line of code is in. I prefer explicit delimiters for that. Among other reasons, I find explicit delimiters makes it easier to cut and paste code.

For example, if I have a block indented 4 spaces and paste it at the end of a block that is indented 8 spaces, my editor (all editors?) have no idea if the pasted code belongs to the 8-space block or the outer block. OTOH, if I have explicit delimiters it's obvious which block the code belongs to and how it should be (re-)indented -- it does so by intelligently looking for block delimiters.

edit 2: some people who provide comments seem to think this is a feature I hate or that I think makes python a poor language. Again, not true. While I don't like it all that much, that's beside the point. The question is about the strangest language feature, and I think this is strange, by virtue of it being something very, very few (but >0) languages use.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • 63
    if it gets in the way of your productivity then your non-python code can't be very readable... – Tor Valamo Jan 03 '10 at 15:36
  • 27
    What language did you use before Python? How were you able to work with other people and not indent that language? How could anyone put up with non-indented code in *any* language? Did you work in a room full of geniuses who didn't need visual cues in the source code? – S.Lott Jan 03 '10 at 16:21
  • 53
    +1 Couldn't agree more, if my editor (Emacs) can't indent my code based on something distinct (like braces/begin, end/you name it) automatically, it's seriously silly. Pretty much any refactoring you'd do on a "bigger" function can be a really bad experience. – Dmitry Jan 03 '10 at 16:43
  • @S.Lott: Of course he did, he's from the future where all programming is done via brain-machine interface – RCIX Jan 03 '10 at 16:48
  • 9
    Did he ever say that he does not like to indent at all? But being forced to at all prices, and having to deal with strange space-vs-tab issues may be painful. (I hope I didn't tell rubbish, because I never really did Python) – Lena Schimmel Jan 03 '10 at 20:22
  • 3
    You're the first person I've seen claim that it was still a "problem" even after working with it for any extended period of time. – FogleBird Jan 03 '10 at 21:22
  • All the places I have worked, none have used Python. **BUT** consistent was still required, not by the language, but by the people on the dev team. As for 'spaces vs tabs'... this is something that you solve in about 2 seconds with a simple editor command. – TM. Jan 03 '10 at 21:35
  • 83
    Here's the deal - with any other language, I can highlight a block of code and have it indented properly by any editor. But because whitespace IS by definition the proper indenting, you lose that ability in Python. So it's harder to move code around or refactor things. And for the person who claims the OP is the "first person to claim it was a problem", well I had to maintain some python code for a while and I will now use any language over python for this very reason. – Kendall Helmstetter Gelner Jan 03 '10 at 21:39
  • 6
    It does get in hte way of productivity!! There is not way for an editor to work out what the indentation of pasted code should be, vi's "%" command does not work any more, and if you make a mistake in indentation there is no "{" or similar which might highlight this mistake to anyone reading the code on complex statements which go over more than one screen its a pig to match the end of the block with the matching 'if', 'for' or whatever. Still its a small price to pay for the most elegant programming syntax yet devised. – James Anderson Jan 04 '10 at 01:52
  • 2
    Another thing is that it means that every user of the language must use the same format, which is IMHO a good thing. – RCIX Jan 04 '10 at 08:14
  • 4
    @RCIX: that sounds good in theory. In practice people are still free to choose the amount of indentation to use so you still have to rely on standards within a group. Just within the last month I had to re-indent a bunch of code checked in by a new team member, so Python is really no better nor worse than any other language in this regard. – Bryan Oakley Jan 04 '10 at 11:57
  • There's always problems like that when you copy/paste code with a different format. I've copied code in C++ with different indentation and you end up correcting it, just for having a consistent style, which is always useful. Of course, the indentation can be a little messy sometimes, but, to me,it's one of the BEST ideas of Python. I love that feature, and yes, it forces you to use ALWAYS 4 spaces to indent, which it's not bad at all... – Khelben Jan 04 '10 at 12:55
  • 4
    @Khelben: ALWAYS 4 spaces? Are you sure?... The difference with C++ (or any other bracy language) is that *you* don't need to correct things. You can ask the editor to do it for you. – R. Martinho Fernandes Jan 04 '10 at 14:09
  • 38
    I don't mind the whitespace in Python. The WTF is that it's not enforced consistently. You can mix indent levels and tabs, so long as they're consistent with their siblings. So the first indent level can be one space, and the second can be two TABs, and this is not a syntax error. – ieure Jan 04 '10 at 20:51
  • 3
    "if python's mode of defining blocks with whitespace is so superior, why is it virtually the only language past or present to do it?" -> Other examples: boo (well, it's based on the python syntax), Haskell. – R. Martinho Fernandes Jan 04 '10 at 21:41
  • 9
    Let me get this straight: You rearrange code blocks so often that a few keystrokes to realign them is a drag on your productivity. – phkahler Jan 04 '10 at 21:58
  • 5
    Indented block is one of my most favourite features of Python (and The Layout, correspondigly, of Haskell). Yes, it makes copy-pasting less “productive” and more likely to produce broken code, but it makes _reading_ of written code easier. And yes, it forces the programmer to layout his code manually. Think of typeset books (Python) vs text markup (C-like). BTW, braces are a pain to enter with Italian keyboard layout... (I don't use it normally, but when I have to, it's a pain). – sastanin Jan 04 '10 at 22:00
  • but honestly, it gets in the way of my productivity How so ? [Begin Block : Tab vs {-Enter-Tab], [End Block : Backspace vs }-Enter], [Find End of Block : Visually vs Goto Block Begin + Some keystroke] – Dhananjay Nene Jan 04 '10 at 22:01
  • 8
    Wow, this is the first argument against significant whitespace in Python that makes sense to me. I've run into the "I've moved this block of code and now have to manually fix the indent" problem many, many times. – Schof Jan 04 '10 at 22:19
  • 1
    @Martinho don't forget F#. Note that in both Haskell and F#, the whitespace-as-syntax is optional syntax sugar; one is perfectly free to use the more cumbersome desugared syntax with braces and semicolons. – yfeldblum Jan 05 '10 at 01:52
  • 8
    If you're using Vim, look up the `]p` and `]P` commands, which help paste code into new locations while automatically using the correct indent. – Greg Hewgill Jan 05 '10 at 02:21
  • 1
    @Greg: how does it know what the correct indent is? If you paste between two blocks with differing indent which one does it choose? It can't possibly know. – Bryan Oakley Jan 05 '10 at 02:31
  • 4
    @Bryan: Have a look at the docs, or try it. Vim adjusts the indent of the pasted block so that the first line of the paste aligns with the line the cursor is on. The difference between `]p` and `]P` is whether the pasted text is inserted below or above the current line. – Greg Hewgill Jan 05 '10 at 03:22
  • 5
    I wonder how many folks are unaware of the block indentation feature of many editors. i.e. Highlight a block of text (several lines) and press TAB to push the entire block in, and SHIFT-TAB to move it out. It's "obvious" if you know about it, but until then realignment is a lot of work. – phkahler Jan 05 '10 at 14:40
  • 2
    Kendall: Your editor can't do it for you because it's part of the syntax. (I'm not sure how it makes refactoring harder; every editor I've used in the past decade made it stupid-easy to in/dedent.) That's like a Lisp programmer complaining that in C you can't just highlight a block of code and have your editor properly capitalize it -- capitalization is part of the C language, so obviously the editor can't do it for you. But it's not a problem because I can recognize that caps are significant in C so any refactoring must *include* that, just as it does indenting in Python. – Ken Jan 05 '10 at 18:56
  • Your editor argument has merit, however in my editor of choice (vim) it's only 3 keystrokes to indent it appropriately, also Guido himself mentions in the docs that any piece of code with 8 levels of indentation needs refactoring ;) – richo Jan 06 '10 at 03:23
  • Looking at a representative sample of my own code, I think Guido is too generous. I don't have anything past five, and not very many blocks with four levels beyond the left margin. – Bryan Oakley Jan 06 '10 at 03:51
  • 1
    @Richo: The difference (as already stated tons of times) is that in a language with explicit block delimiters, it's only **0** keystrokes to indent it appropriately. – R. Martinho Fernandes Jan 06 '10 at 21:01
  • 6
    You can always do: from __future__ import braces and use braces :) – mauro.dec Jan 07 '10 at 14:21
  • 1
    It's a matter of taste, so why bother ? You don't like it ? Use Ruby, it's as good as Python. I love white spaces, it makes the code simple and elegant. My productivity is much better when I don't have to think about where this "}" is supposed to be aligned. See ? Really a matter of taste. – Bite code Jan 07 '10 at 23:06
  • 3
    @e-satis, I actually like ruby better than python (and maybe groovy better than ruby) but at my job we use python. I don't understand your comment though. Remember, the question isn't "what do you hate about a language" but what was weird, surprising, or WTF. I think it's safe to say that since python is one of only a very, very small handful of languages that use whatspace in this way, it meets the definition of "surprising or weird". There are a lot of other things about python that outweigh this feature. Python is a fine language, but it's use of whitespace is IMO, "weird, strange or WTF". – Bryan Oakley Jan 08 '10 at 00:46
  • I see both sides: for one, Emacs' python-mode has the ctrl-c > for indenting (one level, prefix for more), and ctrl-c < for dedenting the region (and a pasted block is the current region). But you can't just mark-whole-buffer and then indent-region. – Jürgen A. Erhard Jan 12 '10 at 02:37
  • Another language that used whitespace was Occam. – Jürgen A. Erhard Jan 12 '10 at 02:37
  • 5
    @presario don't you believe others can have opinions that differ from your own? – Bryan Oakley Jan 20 '10 at 00:23
  • The problem is that editors aren't smart enough yet. I still think whitespace indentation is one of pythons greatest features. – AnnanFay Mar 05 '10 at 11:12
  • 2
    What's scary to me is how many programmers find copy/paste essential (and how many do it vs. writing a throw-away function). – xcramps May 24 '10 at 16:01
  • 2
    @xcramps: copy/paste is essential for refactoring. When I move a block of code out of or into a function or class definition I use copy/paste. Sometimes the move requires that the level of indentation changes. In my experience, having explicit block delimiters makes that easier. – Bryan Oakley May 24 '10 at 20:21
  • 5
    What I find surprising is the number of people saying they like Python's indenting misfeature because it enforces the nice indenting based on structure. As if, when they write in C or other languages, they don't bother to indent their code. I've never seen a professionally written C program that did not use proper indentation. This Python thing fixes a problem that doesn't exist in the real World. And where you do see badly formatted code, your modern text editor has a function to beautify it at the touch of a button. – JeremyP Aug 10 '10 at 10:03
  • 2
    Copy & Paste is useful but not essential. Cut & Paste is essential for refactoring. On moving blocks of code and editors - No matter how easy it is to move blocks of lines, in Python I have to THINK about what the right placement is. In any other language the editors auto-indent is a sanity check - if the indentation looks wrong after a large reformat, I know I have got a block delimiter wrong. You cannot perform that kind of check in Python because the editor cannot override your formatting. All my code is well formatted because my editor does it for me, constantly. – Kendall Helmstetter Gelner Aug 14 '10 at 06:25
  • Maybe I haven't studied this well enough, but I also find that docstrings seem to be inconsistent with python indentation. – Andrej Panjkov Aug 14 '10 at 06:25
  • @Kendall “in Python I have to THINK about what the right placement is” – I hope you actually think about the placement in *any* language.. And then it's not a problem at all to realize what indentation level you need.. – poke Aug 14 '10 at 13:14
  • 1
    @poke - why SHOULD I think about placement? Why should I have to bother? I know it's in a block, so why should I care where I type or copy the code - when with a single keystroke all of it is formatted correctly? With whitespace-based block definition, you are just adding busywork to the process of coding and increasing the chance that code goes in the wrong block. – Kendall Helmstetter Gelner Aug 15 '10 at 20:52
  • 3
    +1 this is totally true. While I agree that using whitespace reduces the noise and might help the readability, it has caused me headaches lots of times. Since code is not just prose text, I believe it is better to use explicit delimiters for structuring. – galaktor Oct 27 '10 at 19:18
  • 1
    This is an awful language "feature" if you have to move between platforms. Text based transfers of source code where whitespace is significent can cause issues going EBCDIC to ASCII and or some of the various double byte character sets. – Joe Zitzelberger Dec 14 '10 at 16:18
  • 1
    You can really abuse the feature to write strangely intented code by mixing tab with spaces. A tab counts for seven spaces... so a tab and one space is on the same level as 8 spaces. – plaisthos Dec 26 '10 at 01:56
  • I like any language that uses indentation for code structure, because humans understand code structure from indentation much more easily than from delimiters. That's **why** we indent code. If the machine also uses the same information to determine code structure, the two senses cannot get out of sync accidentally. – Ben Apr 07 '11 at 07:26
  • 1
    @ben: that might be a good argument except for tne fact humans don't perceive whitespace very well. We can't distinguish between one tab or eight spaces, and its fairly hard to distinguish between 7 spaces and eight spaces if they are separated by a blank line or two. So, what we perceive can easily be different from what a computer sees. – Bryan Oakley Jun 16 '11 at 12:44
  • 1
    @Bryan Oakley: Would you indent C/Java/PHP/etc code with a mixture of tabs and spaces? Or use 7 spaces and 8 spaces as different indent-levels? It's a bad idea in brace-delimited languages for the same reason it's a bad idea in indented languages: it confuses human readers. So in brace-delimited languages, we have to keep indentation straight (to keep human readers happy) and keep the braces matched (to keep the compiler happy) *and* keep those two structural senses in sync. Why not have the compiler read the code the same way the humans do, and toss out the braces? – Ben Jun 16 '11 at 23:21
  • 1
    @Ben: no, I would not intentionally use a mix of tabs and spaces, and that's part of the problem. If i accidentally did that my program might look OK to me but have different runtime behavior. The problem is, the computer does *not* read the whitespace the same as humans do -- the computer takes it quite literally, the human, not so much. Humans think both a tab and eight spaces to be the same, python doesn't. If there's a brace, there is no ambiguity. In practice it works ok most of the time, but I still believe it's a strange feature. – Bryan Oakley Jun 17 '11 at 10:57
  • @Bryan Oakley: Actually, Python 2.7 does read the tab as if you had tabstops of 8 spaces, and Python 3 raises an exception if you mix tabs and spaces in a way that makes the meaning of the program dependent on tab width. My point though, was that you can make this same error in a brace-delimited language because we cannot do without indentation, and it is actually *worse* in that context because your code contains no syntax error but may look at a quick reading like it does something else. (This is also why using tabs in code is a terrible idea IMHO, but that's a different flamewar ;) ) – Ben Jun 19 '11 at 23:32
  • I don't mind the language feature, but the copy / paste scenario does KILL me sometimes. especially in TextMate on OS X - where it pastes empty lines with *no spaces* in, just to break your scope (oh, the pain.) – tehwalrus Dec 15 '11 at 16:37
137

I struggled a bit about this:

1;

In perl, modules need to return something true.

miku
  • 181,842
  • 47
  • 306
  • 310
  • 29
    Some modules may return values based on runtime operations. If you always return true, you still don't have to be uncreative about it: http://returnvalues.useperl.at/ – Anonymous Jan 04 '10 at 10:06
  • 8
    If my Perl memory serves me correctly, returning true from a module indicated that the module loaded successfully. Returning a false value meant that something went wrong and would prevent the program from running (if not caught). – Barry Brown Jan 05 '10 at 00:28
  • This is a valid C statement as well, only nothing is returned. – sigjuice Jan 06 '10 at 12:53
  • 24
    Mark Dominus wrote, "I have very rarely used `'Cogito ergo sum';` which as everyone knows is self-evidently true in all possible universes. This ensures maximum portability." – Greg Bacon Jan 27 '10 at 03:50
  • PHP `=1;?>` returns 1. `=true;?>` returns 1. `=false;?>` returns null. – Talvi Watia Jun 11 '10 at 04:39
134

I always wondered why the simplest program was:

class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

Whereas it could be:

print "Hello World!"

Maybe this is to frighten computer science students in the first place ...

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Didier Trosset
  • 36,376
  • 13
  • 83
  • 122
  • In witch language? What about arguments? What about programs with 2 files? What about functions? – Ignacio Soler Garcia Jan 04 '10 at 16:57
  • 34
    In some languages, "Hello World!" is a valid program. – David Thornley Jan 04 '10 at 20:16
  • 31
    @SoMoS: in most dynamic languages such as Python, Ruby, or Perl print "Hello World!" or some minor variation (e.g. puts instead of print) is a valid and complete program. – Dave Kirby Jan 04 '10 at 20:44
  • 2
    Makes sense if you have used Java for any amount of time. – Kevin Jan 04 '10 at 21:05
  • Since every method and variable must be a member of some class in Java, which class would the "improved" one-line statement belong to? – David R Tribble Jan 05 '10 at 01:02
  • Oh yeah forgot to mention, Groovy is a derivative of Java. Both code snippets you posted would work. I haven't used it yet but it looks really cool. – Kevin Jan 05 '10 at 01:21
  • 36
    @Loadmaster: the implication was that "all code belongs in a class" or "all code belongs in a function" are unnecessary constraints – Jimmy Jan 05 '10 at 01:22
  • 5
    This is a piece of crap.. no, OOP is not your average structured/unstructured type of programming. – Andrei Rînea Jan 05 '10 at 07:49
  • 4
    BlueRaja: The code in the answer is not strict OOP. To be strictly OO, you'd need to instantiate an object and call a method to ask it to do something. –  Jan 05 '10 at 12:51
  • 19
    Just because a language enforces the use of objects, does not mean it is being used for proper object-oriented programming. It is perfectly possible to program procedurally in Java or C#. That's what static methods are for. – jdmichal Jan 05 '10 at 15:28
  • What the OP is saying is, there should be an implied class and parameterless method, like there is in the Perl example. – spoulson Jan 05 '10 at 19:53
  • 68
    I love people who think OOP means that everything should be an object. – Tor Valamo Jan 06 '10 at 13:58
  • 4
    @BlueRaja: in .NET everything all code has to be inside a class/struct methods as well. That doesn't stop boo (a .NET language) from having `print "Hello World!"` as its hello world program. – R. Martinho Fernandes Jan 06 '10 at 20:55
  • In JSP (and other languages) a Hello World program can be written as `Hello World!`. – Tom Hawtin - tackline Jan 07 '10 at 05:03
  • 9
    Hey, in APL `'Hello World!'` is how the program would go. Must be much easier to use than this "Java" thing! – Tikhon Jelvis Mar 17 '10 at 05:54
  • Used to frighten and also to prepare learners for understanding what the particular language is all about: Java->OO, C->low level/procedural, PHP->scripting/create html, etc. Technically, PHP's program is also simply `Hello World!`. Just as bad sometimes for those picking up a second language are those examples that use a generic `print 'Hello World!'` and lead you to believe "Oh good, it's exactly the same, this'll be easy." – bob-the-destroyer Jun 16 '10 at 17:44
  • 5
    I've seen worse... Like the Win32 C version of "Hello World" :P http://www.paulgriffiths.net/program/c/srcs/winhellosrc.html – rsenna Oct 16 '10 at 17:29
  • 3
    Why not just `h`? It is valid in Jon Skeet's Hello World language. :) –  Feb 07 '11 at 16:55
  • 1
    @Radek S: Ever heard of *HQ9+*? – fuz Feb 17 '11 at 16:32
  • @FUZxxl I have, but the Hello World language is more fun. It's even the only valid program. –  Feb 17 '11 at 17:23
  • @Radek S: Phhh... The hello world language is too restricted in my mind. *HQ9+* is more useful. In can print Hello World, 99 bootles of beer, a quine AND it can increment a pointer. – fuz Feb 17 '11 at 17:54
  • You can use `print "Hello World!"` exactly in PHP. No need for this `public static void main(String[] args)` nonsense! – Kevin Ji Dec 06 '11 at 23:58
134

I'm surprised that no one has mentioned Visual Basic's 7 loop constructs.

For i As Integer = 1 to 10 ... Next
While True ... End While
Do While True ... Loop
Do Until True ... Loop
Do ... Loop While True
Do ... Loop Until True
While True ... Wend

Because sticking an ! in front of your conditional is way too complicated!

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Brian Postow
  • 11,709
  • 17
  • 81
  • 125
  • 47
    They should have made it "`While` and `Whend`", since there are some people who do pronounce the word "while" with the voiceless labialised velar approximant. And of course it lines up nicer, and code that lines up is nice. – dreamlax Jan 04 '10 at 21:06
  • 61
    ! isn't not in VB, it's "Not". Or is it? Yes, not is not !, but Not. – brianary Jan 05 '10 at 00:29
  • 7
    Yes, "Wend" is an English word, meaning to go or proceed along some course or way (http://www.google.com/search?q=define%3A+wend). I'm not sure if that helps or hurts. – Michael Myers Jan 05 '10 at 15:44
  • 3
    @mmyers: "wend" in VB and "wend" in English have two very different definitions. VB's "wend" means "repeat" or "go again", but "wend" in English doesn't include any sort of repetition at all. If anything, I think `Wend` should have been a replacement for `goto`. `On Error Wend FixIt` – dreamlax Jan 06 '10 at 03:05
  • BBC Basic had Repeat Until, While Wend and For Next. Wend is BASIC for "End While" from an era when the parser couldn't cope with two-word statements. – Richard Gadsden Jan 15 '10 at 15:39
  • I found the line `Do: Loop` breaks the debugger. – Robert Jul 07 '11 at 13:44
133

For those who don't know, bc is an "arbitrary precision calculator language", and I use it quite often for quick calculations, particularly when the numbers involved are large ($ is the prompt):

$ bc -lq
12^345
20774466823273785598434446955827049735727869127052322369317059031795\
19704325276892191015329301807037794598378537132233994613616420526484\
93077727371807711237016056649272805971389591721704273857856298577322\
13812114239610682963085721433938547031679267799296826048444696211521\
30457090778409728703018428147734622401526422774317612081074841839507\
864189781700150115308454681772032

bc has been a standard Unix command for a long time.

Now for the "WTF feature". This is from man bc (emphasis mine):

quit: When the quit statement is read, the bc processor is terminated, regardless of where the quit statement is found. For example, "if (0 == 1) quit" will cause bc to terminate.

halt: The halt statement (an extension) is an executed statement that causes the bc processor to quit only when it is executed. For example, "if (0 == 1) halt" will not cause bc to terminate because the halt is not executed.

Alok Singhal
  • 93,253
  • 21
  • 125
  • 158
  • quit should be renamed to exit, and then this makes sense. I feel like language features were added ad-hoc, and then to keep backward compatibility, names weren't changed. – Stefan Kendall Jan 12 '10 at 05:00
132

JavaScript is object oriented, right? So running methods on literal strings and numbers should work. Like "hello".toUpperCase() and 3.toString(). Turns out that second one is a syntax error, why? Because the parser expects a number followed by a dot to be a floating point literal. That's not the WTF, the WTF is that you only have to add another dot to make it work:

3..toString()

The reason is that the literal 3. is interpreted as 3.0, and 3.0.toString() works fine.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Theo
  • 131,503
  • 21
  • 160
  • 205
129

In JavaScript:

2 == [2]

// Even stranger
2 == [[[2]]]

// And down-right nutty
var a = { "abc" : 1 };
a[[[["abc"]]]] === a["abc"]; // this is also true

Luckily the kind folks at stackoverflow.com explained the whole thing to me: Why does 2 == [2] in JavaScript?

Community
  • 1
  • 1
Xavi
  • 20,111
  • 14
  • 72
  • 63
  • 6
    That’s why you should use `===` instead. – Gumbo Jan 04 '10 at 21:00
  • 10
    This is useful btw, if you have a function that returns a number and you want to return some additional metadata with it, you can return [number] with some additional fields added. Simple code will never know it is not a real number, and other code can get the required metadata. – Andrey Shchekin Jan 05 '10 at 00:28
  • 36
    @Andrey except that if I ever have to maintain code that does what you suggest, I would very soon wish death upon its author. – Breton Jan 05 '10 at 06:45
  • @Andrey, that's a great idea! You can also use `Number(n)` to do something similar. Unfortunately in both of our solutions `===` breaks =(. – Xavi Jan 05 '10 at 14:50
  • @Breton unfortunately there was once a use for that, when two Array wrappers wanted to pass information between each other while staying within Array contract when only one was applied. – Andrey Shchekin Jan 07 '10 at 11:27
  • This is because `[2]` is casted to a string, and `[[["abc"]]]` is casted to a string, too. It still shows poor design, IMO... – strager Mar 23 '10 at 09:50
126

My biggest most hated feature is any configuration file syntax which includes conditional logic. This sort of thing is rife in the Java world (Ant, Maven, etc. You know who you are!).

You just end up programming in a c**p language, with limited debugging and limited editor support.

If you need logic in your configuration the "Pythonic" approach of coding the configuration in a real language is much much better.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
James Anderson
  • 27,109
  • 7
  • 50
  • 78
  • What is this "Pythonic approach" you speak of? Is it writing the config file in python and doing "import MyConfigFile" ? – phkahler Jan 05 '10 at 14:49
  • phkahler -- The usual way is to "eval" the config file. – James Anderson Jan 06 '10 at 01:46
  • 24
    Tcl re-invented that long before Python was born and Lisp invented it before that. So let's not call it Pythonic, let's call it Emacs-ish. – slebetman Jan 07 '10 at 01:55
  • 30
    AMEN. If your configuration or build language is turing complete, you're doing it wrong. I'm looking at you CMake / autotools. – Joseph Garvin Jan 07 '10 at 15:40
  • 16
    This is exactly what Lua was designed for, originally – Cogwheel Jan 18 '10 at 23:00
  • 1
    Well, if your code is in Python, then having your configuration file be a Python file is a great idea, because you then just import the file and read the attributes of the module. And you get the 100% Turing Complete power of Python in your config file. – asmeurer Jan 14 '11 at 04:20
  • Maven POM files are purely descriptive (That's the point of Maven) and shouldn't contain any logic. Don't touch my Maven ;) – Nico Jun 26 '11 at 09:12
113

powerbasic (www.powerbasic.com) includes the compiler directive:

# BLOAT {bloatsize}

this increases the size of the compiled executable by <bloatsize> bytes. this was put in the compiler in case people creating the executable don't like the small size of the generated executable. it makes the EXE seem bigger to compete with bloated programming languages:)

mercator
  • 28,290
  • 8
  • 63
  • 72
Don Dickinson
  • 6,200
  • 3
  • 35
  • 30
  • 9
    Haha yuk. I've heard about developers deliberately slowing down some operations (e.g. a search) because it helps people believe that it is really doing something. Similar thing I guess. – David Jan 07 '10 at 04:49
  • 42
    This reminds me of something I read recently. They were testing an FPS and decided to increase the number of hit points the bad guys had. Then they asked the testers how they AI was, and they swore it was much smarter. But the AI hadn't changed, just the hit points. People have a certain narrative about the world in their heads, and if you understand and match their expectations they will just assume it validates their narrative. – Nate C-K Jan 07 '10 at 17:42
  • 3
    Back in school we had 80286 machines and I actually had to write some screen output routines in assembly to get a reasonable speed (i.e. not crawling). – berkus Nov 18 '10 at 13:36
  • 7
    @Nate C-K, if the AI lives long enough to show off its AI, it *may* actually *be* smarter, whereas before it may have died too quickly to prove it. – zzzzBov Feb 03 '11 at 20:38
97

In PHP function names are not case sensitive. This might lead you to think that all identifiers in php are not case sensitive. Guess again. Variables ARE case sensitive. WTF.

function add($a, $b)
{
    return $a + $b;
}

$foo = add(1, 2);
$Foo = Add(3, 4);

echo "foo is $foo"; // outputs foo is 3
echo "Foo is $Foo"; // outputs Foo is 7
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Doug T.
  • 64,223
  • 27
  • 138
  • 202
95

I've always been a huge fan of the PHP error thrown when using two colons in a row out of context:

Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in /path/to/file/error.php on line 3

The first time I encountered this I was absolutely befuddled.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Jesse
  • 10,370
  • 10
  • 62
  • 81
90

In C

a[i++] = i;

It compiles, but it rarely does what you think it ought to do. An optimization change leads to producing wildly different results. And it runs differently on different platforms.

Yet, the compiler's perfectly happy with it.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • 87
    .. but the language is not. More than one reference to something in an expression that is modified in the expression is undefined behaviour. – Richard Jan 03 '10 at 15:40
  • 5
    @Richard. Why would undefined behavior compile and run? That's my point. That's the strangest feature of the C language. And this particular block of code is what I use to summarize that strange feature in a tangible way. It sometimes leads to arguments with C n00bs who claim that is has a clear meaning. – S.Lott Jan 03 '10 at 16:18
  • 20
    "Why would undefined behavior compile and run?". In general because some things which cause UB in C cannot be detected at compile time, and detecting them at run time (or defining the behaviour) would significantly impact performance. In this particular case, I do think it's a bit feeble that compilers generally don't detect the error. It would certainly end a lot of those arguments. But equally I'm not about to submit a patch to gcc to issue a warning. Presumably your compiler's authors are working on other things, which would get pushed back if the C language mandated an error for this code. – Steve Jessop Jan 03 '10 at 17:34
  • 5
    "Undefined behavior" means the compiler can get away with not handling this code correctly and/or issuing any warning or error whatsoever. That's why it is important, especially in the case of C, to be aware of any undefined or unspecified behavior of the language (as specified in Annexes of the ANSI-C standard). Compilers (or their manufacturers) generally assume you are aware. – cschol Jan 03 '10 at 17:38
  • 13
    @cschol: "Compilers (or their manufacturers) generally assume you are aware" That's precisely the WTF of C. – S.Lott Jan 03 '10 at 17:41
  • 29
    It's an inevitable consequence of the fact that C permits low-level programming, but CPUs do different things in response to low-level errors. If C had defined all behaviours, then C on x86 would be slow, because it would be attempting to emulate edge-cases from a PDP-7. If you don't like it, you either write in assembly for a particular architecture with fully defined behaviour, or you don't write low-level code. Seems a bit weird though to say in effect, "C's wtf is that it's a portable low-level language". That should not be surprising, since that is its purpose. – Steve Jessop Jan 03 '10 at 17:56
  • 6
    `a[i++] = i` is obviously UB, otoh `a[(*p)++] = *q` is UB depending on whether p and q point to the same object; you can't tell which until you run the thing, and so the compiler can't actually do anything in the general case. another example: division is UB if the denominator is zero, but what do you expect the compiler to do with `x / foo(69)`? – Nietzche-jou Jan 03 '10 at 18:08
  • 1
    In any case, the question was odd features about a language, not a language implementation. As far as I know, undefined behavior is fairly common for languages, and how an implementation treats a case of UB is not a language issue. There may be a catch here that qualifies, but I don't see it offhand. – David Thornley Jan 04 '10 at 16:31
  • 2
    "undefined behavior is fairly common for languages" Not really. I've worked with a lot of languages; C has this problem in the worst possible way, leading to endless WTF's. Some modern languages like Java don't have this "UB" concept at all. Things are either defined or forbidden or it's a bug waiting to be fixed. – S.Lott Jan 04 '10 at 17:01
  • 1
    Forgive my C "n00bness," but why is it that this line compiles to something other than a[i] = i; i++; ? – tzenes Jan 04 '10 at 20:18
  • @tzenes: it's unclear where -- precisely -- `i` gets incremented. It could be (as you hope) after the statement as a whole. Or it could be after evaluating the LHS of the assignment. And it's unclear if RHS or LHS is evaluated first. So there are at least four alternatives. – S.Lott Jan 04 '10 at 20:26
  • 4
    Undefined behaviour is just that, it's undefined. It doesn't mean that it is illegal, just that you can't expect the same *defined* behaviour from all implementations. – dreamlax Jan 04 '10 at 20:30
  • It was my understanding that C requires assignment operators to be evaluated RHS first [ie. a=b=c compiles to a = (b = c)] . Based on the postfix increment that should compile to: temp = i; temp_p = &(a[i]); i++; *temp_p = temp; But now I'm going to have to dig through the C standard to see if that's true. Edit: apparently I was wrong – tzenes Jan 04 '10 at 20:38
  • 1
    "you can't expect the same defined behaviour from all implementations". Best of all? No warning from most compilers. Just code that behaves "oddly" when you change something. That's the WTF moment. – S.Lott Jan 04 '10 at 21:06
  • 1
    @S. Lott: Over the past sixty-plus years, we've learned a lot about specifying language behavior, but we're not perfect, so there's still undefined behavior in many modern languages. Moreover, languages like C are going to underspecify behavior to allow performance. C is probably still the poster child for UB, though. – David Thornley Jan 04 '10 at 22:22
  • 1
    @tzenes: It gets complicated. Operations are performed in a more or less defined order to evaluate the value of expressions, but there's a lot less restrictions on applying side effects. The standard specifies "sequence points" at which all side effects have been applied, but there's no sequence point inside that expression. It's an illegal expression, but it isn't obviously so, and similar expressions are well-defined. – David Thornley Jan 04 '10 at 22:27
  • 20
    with the the `-Wall` flag, gcc warns about this `warning: operation on 'i' may be undefined` – Hasturkun Jan 05 '10 at 11:24
  • In C# at least, it (shouldn't) be undefined: we get i and store it in a variable. increment i, access the array with the temp variable, and set the value. AFAIK, that's how it works... – RCIX Jan 06 '10 at 23:42
  • 1
    -1: Undefined behavior is undefined behavior, not illegal behavior. – Thomas Eding Feb 13 '10 at 17:37
  • @trinithis: You're missing the point. The mere presence of "undefined behavior" which compiles without error and produces code is what's wrong with this. – S.Lott Feb 13 '10 at 18:53
  • 2
    @S.Lott: Except that it's deeper than that. As sgm pointed out, it's easy to write code that might create undefined behavior that the compiler can't possibly catch, unless we want to have defined behavior for `x/0`, which will seriously slow down division on some computers, whatever the definition. We both know that C has a lot of UB issues, but we seem to miss the root cause. – David Thornley Feb 18 '10 at 18:49
  • I'm fine with run-time errors like `x/0`. I'm not fine with something that compiles error-free and ambiguously. It's the ambiguity that kills me. – S.Lott Feb 18 '10 at 19:03
  • Clang gives a warning when you are setting the same variable multiple times in one statement, like in this case. –  Feb 17 '11 at 17:26
  • @Radek S: You're not setting a variable multiple times. You're setting two different values, and the value of one is undefined. – S.Lott Feb 17 '11 at 18:18
80

Python 2.x

>>>True = False
>>>True
False

You can really make someone become crazy with this one.

Gab Royer
  • 9,587
  • 8
  • 40
  • 58
  • 9
    You can't do this in Python 3.x anymore. It gives a syntax error. – Reshure Jan 07 '10 at 17:52
  • 3
    Hmm. I think this might be the answer to questions like "Why should I use Python 3?" (eg http://stackoverflow.com/questions/1921742/python-should-one-start-a-new-project-directly-in-python-3-x) – Ewan Todd Jan 09 '10 at 20:12
  • 7
    That's messed up, and hilarious. For twice the fun, `True,False = False,True`. What makes it doubly awful is that `1==1` afterwards still returns True. It wouldn't be such a big deal if True and False were simply consistent (global) labels – kibibu Mar 23 '10 at 03:43
  • In C: `#define true false` but only if stdbool.h is used. –  Feb 17 '11 at 17:33
  • This is one more reason to never use do `if test() == True:`, but just do `if test():`, which is suggested in Python (same of course for `if not test():` instead of `if test() == False:`) – Colin Emonds Sep 13 '11 at 17:11
72

Oracle has a couple of SQL WTF issues.

  1. Oracle's treatment of empty strings as null.

  2. Treatment of null values in a "<>" comparison.

    create table wtf (key number primary key, animal varchar2(10));    
    insert into wtf values (1,'dog');
    insert into wtf values (2,'');
    insert into wtf values (3,'cat');    
    select * from wtf where animal <> 'cat';
    

The only row returned is the (1,'dog') row.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
rayd09
  • 1,837
  • 17
  • 20
  • 6
    I *wish* SQL Server treated empty strings as NULLs. After all, what is a practical difference between the two? My DB is full of CHECK (Name <> ''). – Andrey Shchekin Jan 04 '10 at 12:24
  • The problem is that treating NULL as different from '' is also a WTF. Perhaps the solution would be to never have NULL strings but always empty, but I bet that would be a WTF, too. It's probably a problem with no good solution. – erikkallen Jan 04 '10 at 13:45
  • 109
    The practical difference between the two is that '' is a value. NULL is not. – recursive Jan 04 '10 at 20:13
  • 6
    Andrey Shchekin: What is the meaning of the life? – Tamas Czinege Jan 05 '10 at 00:16
  • 6
    A value is a known quantity, amount, or measured value, numeric or otherwise. For example a "special instructions" field could be '' if there are no special instructions, and NULL if that field has not yet been filled. – recursive Jan 05 '10 at 00:17
  • 64
    The string `''` should no more be treated as NULL than should the integer `0`. – Ben Blank Jan 05 '10 at 00:31
  • Andrey Shchekin, try this: `NULLIF(field, '')`. It assigns `NULL` if the value `''` is found. It's like a brother to `ISNULL(field, '')` which assigns a value `''` if `NULL` is found. – Scoregraphic Jan 05 '10 at 14:49
  • 1
    +1 for treating '' as Null, -1 for null values in '<>' comparisons. You can not determine if a 'unknown' value is not equal to an unknown value. "comparisons with Null can never result in either True or False, but always in a third logical result, Unknown" - http://en.wikipedia.org/wiki/Null_(SQL)#Three-valued_logic_.283VL.29 – Mark Roddy Jan 05 '10 at 18:34
  • 2
    @Mark Roddy: Just use `SELECT * FROM wtf WHERE ISNULL(animal, '') <> 'cat'`, the same way that is done in any RDBMS. – Esteban Küber Jan 06 '10 at 02:26
  • @Ben Blank -- Did you #undef NULL or something? – Robert Fraser Jan 07 '10 at 06:54
  • 4
    _The string '' should no more be treated as NULL than should the integer 0_ I have seen more cases when 0 is logically different from NULL than cases when '' is. Actually, I have yet to see a single business case when '' is a valid value for a nullable string field and is different from null. – Andrey Shchekin Jan 07 '10 at 11:47
  • Even on the language level it makes sense for the empty sequence to be the same as null value. There are cases when these two carry different meaning, but I do not think these cases are good API and good practice. – Andrey Shchekin Jan 07 '10 at 11:53
  • 1
    @Andrey: NULL has special properties in SQL. SELECT * FROM t1,t2 WHERE t1.c1=t2.c2 will not match lines where c1 and c2 are NULL, even though they are the same. It means something more like "unknown." If you don't know the age of two persons (p1.age=NULL and p2.age=NULL), it doesn't follow that they have the same age. – niXar Jan 07 '10 at 13:17
  • Oracle is funny about empty strings and NULL values. For some comparisons, an empty string is null. For others, it is not. The thing is very inconsistent. This is one of the things that causes me the most grief when writing things that work on multiple DB's. – Grant Johnson Jan 07 '10 at 16:09
  • @niXar well, but what is the actual in-life situation when you do know when value of something is ''? I know NULL has strange comparison rules, but what could be c1 and c2 so that it made sense for two '' to be equal? – Andrey Shchekin Jan 07 '10 at 21:18
  • 1
    @Andrey Shchekin: *recursive* mentioned above a use case for differentiating between an empty string and `NULL`. In any scenario, `NULL` means no value has been supplied, whereas an empty string is a value of zero length. Just like in many imperative languages, an array reference could be `null` or a reference to an array of zero elements. This difference can sometimes be important. **If a data member has zero length, then its length and content are known. If it is `NULL`, its length and content are unknown until it is retrieved/calculated/prompted for/whatever.** – P Daddy Jan 09 '10 at 01:20
  • 4
    @Andrey Shchekin: Real world example: Middle name. NULL - Middle name is unknown. Empty string - Person has no middle name. – Grant Johnson Feb 01 '10 at 20:22
  • 3
    Where text is concerned, NULL means "we don't know this value yet." The empty string means "we know this doesn't have a value." If you have a list of cars, it's valuable to know which ones don't have license plates and which ones haven't had their license numbers entered yet. It's also valid to assert that two cars whose license numbers you don't know yet don't have the same number on their license plate, but that two cars without license plates do. – Robert Rossney Feb 08 '10 at 08:27
  • Back before SQL Server 7, empty strings were stored as a single space so as to avoid this problem. Of course this just changes which two values are confused, but a string containing a single space is much less common compared to NULL. – Gabe Jun 09 '10 at 07:39
  • create table wtf (key number primary key, animal varchar2(10)); insert into wtf values (1,'dog'); insert into wtf values (2,''); insert into wtf values (3,'cat'); select * from wtf where animal || 'x' <> 'cat' || 'x'; – EvilTeach Aug 13 '10 at 00:04
  • in oracle you cannot do regular operations on null. The only way to op on null is the "is" operator. An empty string is considered to be identical to null. The <> and != and = and whatever boolean operations you want to do will always return false when hitting null. Null cannot be compared. The needed where clause is animal != 'cat' or animal is null. This was a big topic in the oracle book from Oreily I read when starting out with oracle. – Dmitriy Likhten Dec 15 '11 at 18:27
70

Java has a whole freakin book about them.

book http://www.javapuzzlers.com/lg-puzzlers-cropped.jpg

Java Puzzlers

brianegge
  • 29,240
  • 13
  • 74
  • 99
  • 1
    To be fair, the same topic in C would make for a much larger book. If you do like that kind of book, I'd recommend Deep C Secrets (http://my.safaribooksonline.com/book/programming/c/0131774298). Written before C99, but still a useful and entertaining read. – NeedTungsten Jan 18 '11 at 05:20
70

In JavaScript, void is not a keyword, it is not a type declaration, nor is it a variable name, and it is also not a function, nor is it an object. void is a prefix operator, similar to -, --, ++, and !. You can prefix it to any expression, and that expression will evaluate to undefined.

It is frequently used in bookmarklets, and inline event handlers, as in this somewhat frequent example:

<a href="javascript:void(0)">do nothing</a>

The way it's used in that example makes it look like a function invocation, when really it's just an overly clever way of getting the primitive undefined value. Most people don't really understand the true nature of void in JavaScript, and that can lead to a lot of nasty bugs and weird unexpected things happening.

Unfortunately, I think the void operator is the only truly guaranteed way to get the undefined value in JavaScript, since undefined, as pointed out in another answer, is a variable name that can be reassigned, and {}.a can be messed up by Object.prototype.a = 'foo'

Update: I thought of another way to generate undefined:

(function(){}())

Eh, a bit verbose though, and it's even less clear that returning "undefined" is its purpose.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Breton
  • 15,401
  • 3
  • 59
  • 76
  • 1
    I usually create normal divs/spans with an onclick event and a css style of `cursor:pointer` (or something like that) – hasen Jan 20 '10 at 03:50
  • 2
    I just use href="#somemeaningfulfragmentid", and when I assign a click handler I get it to return false. I can often encode some useful things in the fragment id that I can retrieve in the click handler. Then if javascript is disabled, the link can still do something useful if there's an element with a cooresponding id- The browser can scroll to it. Alternatively, the link points to a regular page that reproduces as best as possible the javascript functionality. – Breton Jan 20 '10 at 04:34
  • I thought it was normally done like this: `(function(){})()`, with the parentheses in different places – Eric May 20 '10 at 12:28
  • @Eric I invite you to look at the edit history for my answer. – Breton May 21 '10 at 01:46
  • @Eric "There are some people who would put the golden paren around the function, and not around the whole invocation. That doesn't make sense to me, because what we're trying to tell the user is: look at the whole thing. Putting parentheses around just part of it is, I think, counter productive. I think the whole thing needs to be wrapped in parens." -Douglas Crockford. – Breton May 28 '10 at 03:05
  • also `do nothing` same thing, and why would you need it? – Talvi Watia Jun 11 '10 at 03:18
  • 3
    @hasen j: add `tabindex=0` to those elements, otherwise they won't be keyboard-accessible. – Kornel Jul 21 '10 at 12:34
  • @Talvi Watia that onclick handler shouldn't make any difference. – Breton Jul 21 '10 at 13:44
  • The jQuery library does it this way: `(function($, undefined){})(jQuery);` – Adam Lassek Aug 14 '10 at 00:32
  • @Adam Lassek yeah! I discovered that a while back! strangely, jslint complains about that pattern. – Breton Aug 14 '10 at 02:51
  • @Breton Well, Crockford has been pretty clear that jslint is merely his opinion about javascript code. I think it's perfectly safe to ignore if you understand exactly why you're doing it. – Adam Lassek Aug 14 '10 at 06:58
  • 3
    Why not just use a variable, like this? `var foo;` Variables are assigned the default value of `undefined`, regardless of what the variable "undefined" is. The same goes for function arguments, as already noted. – Pauan Oct 25 '10 at 12:15
  • @Pauan depends on what you're doing, and whether you need an expression. – Breton Nov 21 '10 at 06:26
  • Yeah, my preferred tactic is something along the lines of `(function(){var v; return v})()`. – ELLIOTTCABLE Dec 14 '10 at 01:52
69

Perl has the yada yada operator (...).

The so called “yada yada” operator of Perl 6 heritage is a shortcut to mark unimplemented code:

if ($condition) { ... }

is the same as

if ($condition) { die "not yet implemented" }
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Motti
  • 110,860
  • 49
  • 189
  • 262
68

In fortran (77 for sure, maybe in 95 as well), undeclared variables and arguments beginning with I through N (the "in" group) will be INTEGER, and all other undeclared variables and arguments will be REAL (source). This, combined with "whitespace optional in certain cases" resulted in one of the most famous bugs.

As told by Fred Webb in alt.folklore.computers in 1990:

I worked at Nasa during the summer of 1963. The group I was working in was doing preliminary work on the Mission Control Center computer systems and programs. My office mate had the job of testing out an orbit computation program which had been used during the Mercury flights. Running some test data with known answers through it, he was getting answers that were close, but not accurate enough. So, he started looking for numerical problems in the algorithm, checking to make sure his tests data was really correct, etc.

After a couple of weeks with no results, he came across a DO statement, in the form:

DO 10 I=1.10

This statement was interpreted by the compiler (correctly) as:

DO10I = 1.10

The programmer had clearly intended:

DO 10 I = 1, 10

After changing the . to a , the program results were correct to the desired accuracy. Apparently, the program's answers had been "good enough" for the sub-orbital Mercury flights, so no one suspected a bug until they tried to get greater accuracy, in anticipation of later orbital and moon flights. As far as I know, this particular bug was never blamed for any actual failure of a space flight, but the other details here seem close enough that I'm sure this incident is the source of the DO story.

I think it's a big WTF if DO 10 I is taken as DO10I, and that in turn, because of implicit declarations is taken to be of type REAL. And it's a great story.

Alok Singhal
  • 93,253
  • 21
  • 125
  • 158
  • 7
    F90+ has this "feature" as well, but you can suppress it with the `IMPLICIT NONE` statement. Also, the implicit typing applies to function names as well; I spent a particularly unpleasant evening trying to figure out why an `INTEGRATE` function I had written for a numerical methods course would always return 0. – Pillsy Jan 05 '10 at 14:39
  • `implicit none` is backported to a number of fortran 77 compilers too. – SingleNegationElimination Jan 08 '10 at 04:29
  • 1
    This made me shudder -- the ability to rename alphanumeric variable names without changing program semantics is just so ingrained in me. This makes about as much sense to me as having undeclared variables be INTEGER or not depending on whether the current line number is divisible by 7. – j_random_hacker Jan 31 '10 at 05:47
  • Yeah, we've come a long way since then in terms of programming languages. Although I've known people who like programming in Fortran: it's still very common in scientific programming circles. – Alok Singhal Jan 31 '10 at 05:51
  • Fortran is, I believe, the oldest language in general use today, predating Algol (still around in renamed descendants like Pascal), Lisp, and COBOL. Later versions have tried to reduce the number of oddities, but it's hard when you want backward compatibility. – David Thornley Feb 18 '10 at 18:52
  • FORTRAN, The first compiled language which is still in use today, has always predefined the variables by the first character. D is double precision REAL*8, i,j,k,l,m,n are INTEGER (*2 or *4), and the rest of them are REAL*4 – Dave Mar 24 '10 at 22:44
  • @Dave: yes. The problem happens when implicit declarations and concatenation of tokens end up in hiding a bug. – Alok Singhal Mar 25 '10 at 03:16
  • 3
    Fortran ignores *all* whitespace! `DO10I=1.10` and `D O 1 0 I = 1 . 1 0` are treated the same! – Kevin Panko May 02 '10 at 16:28
  • 1
    I think you and the compiler better agree on what the code should do when you're dealing with (expensive) space missions :-) – Andre Holzner Aug 14 '10 at 07:20
  • @Dave: which compiler implicitly made variables beginning with D double precision? This is not in any Fortran standard. I suspect it was a compiler non-standard extension. – Andrej Panjkov Dec 16 '11 at 02:11
  • agreed - definitely non-standard, but since I've worked on more than 20 different platforms with multiple versions of FORTRAN on some, I don't remember. Most of my work was on DEC PDP-11s which stayed very close to the standards. – Dave Dec 16 '11 at 20:16
63

My favorite little C++ syntax trick is that you can put URL's (with some restrictions) directly into the code:

int main( int argc, char *argv[] )
{
    int i=10;

    http://www.stackoverflow.com
    return 1;
}

This compiles just fine.

Syntax highlighting kind of spoils the joke, but it's still fun.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
joeld
  • 31,046
  • 3
  • 27
  • 22
58

I would not dare to claim that XML is a programming language, but isn't it close to our heart? :-)

The strangest feature, to my mind, in XML is that the following is a well-formed document:

<_....>
</_....>

Here is the the lexical definition of NT-Name that allows consecutive dots.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
xcut
  • 6,219
  • 1
  • 33
  • 27
  • What is the reasoning and value of this really? It seems like some joke from the xml designers. – Dykam Jan 04 '10 at 07:28
  • 95
    If I read the spec right, I could also have `<:-D>..` as tag. Great, I'm going to abuse this immediately! – Esko Jan 04 '10 at 08:23
  • 7
    Esko: that won't quite work, because the namespaces spec prevents you from having a colon with no prefix before it :) You will have to put at least one valid start character before the colon. XML does not need the navigation programming languages like Java do (e.g. foo.bar); why they did not restrict the lexical definition further, I don't know. Laziness? Or they just did not care. – xcut Jan 04 '10 at 09:49
  • 15
    So by giving a hat *(`C`)* to the smiley face it should be valid? `OMG` is directly valid tho' – Esko Jan 04 '10 at 14:54
  • XMI, the interchange format for UML, uses plenty of dotted names. – Pete Kirkham Jan 05 '10 at 10:31
  • It's very far away from my heart! – kirk.burleson Sep 11 '10 at 22:41
  • 1
    @Talvi, as @xcut pointed out, the namespaces spec prevents you from having a colon with no prefix before it (but parsers must accept those colons anyway). Also, the 3rd `<` (which I assume is supposed to be text content) is illegal. How about `<_><_·.>:/:>_.·` – LarsH Dec 01 '10 at 22:04
  • 3
    If you don't keep XML far away from your heart, it _will_ cut you and you _will_ bleed. Death of a thousand angle brackets. – Kelly S. French Dec 15 '10 at 14:19
  • @KellyF We can put some parenthesis bandages on them, though. – Mark C Dec 15 '11 at 17:39
57

Inheriting from random class in Ruby:

class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].sample
   ...
end

(first seen at Hidden features of Ruby)

Community
  • 1
  • 1
Andrey Shchekin
  • 21,101
  • 19
  • 94
  • 162
55

I was taken by surprise that you can change a class's inheritance chain in Perl by modifying its @ISA array.

package Employee;
our @ISA = qw(Person);
# somwhere far far away in a package long ago
@Employee::ISA = qw(Shape); 
# Now all Employee objects no longer inherit from 'Person' but from 'Shape'
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Motti
  • 110,860
  • 49
  • 189
  • 262
  • 5
    Argh. That's true? Really weird!! :) – Ignacio Soler Garcia Jan 04 '10 at 14:34
  • 3
    This is also possible in Objective-C too, if I remember correctly. I think KVO in Cocoa/GNUstep works by dynamically subclassing the observed object at runtime to intercept accessor methods. The object's `isa` / `class_pointer` is changed to the newly created subclass. – dreamlax Jan 04 '10 at 20:38
  • 3
    In some respects, it's no odder than changing the index variable inside a `for` loop. Of course, most languages don't expose the object-oriented aspects quite as much (see the Common Lisp Meta-Object Protocol). – David Thornley Jan 04 '10 at 22:29
  • 6
    @David: yeah, that's because most languages don't have object-oriented aspects grafted on to the language as an afterthought. – R. Martinho Fernandes Jan 06 '10 at 14:00
  • 7
    It's called meta-programming. Being able to change classes (by adding parents, methods, etc) as part of the program. Very useful for things like debugging (like adding a Logger parent class to any existing class) and extending. – mpeters Jan 07 '10 at 17:06
  • 8
    I'm failing to see what's weird -- it's merely a dynamic language doing what it was told to do. And it enables lots of useful things like Class::MOP. – hobbs Jan 09 '10 at 01:53
54

I love the fact that this sort of thing is fine in JavaScript:

var futureDate = new Date(2010,77,154);
alert(futureDate);

and results in a date 77 months and 154 days from the 0th day of 0th month of 2010 i.e. Nov 1st 2016

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Gordon Mackie JoanMiro
  • 3,499
  • 3
  • 34
  • 42
  • 13
    Oh my gosh, that's horrible. Before the computer calculates the date for me, I have to calculate the date for it! – Nathan Long Jan 04 '10 at 21:04
  • 15
    And something's supposed to be wrong here? It's just auto-normalizing dates. While it doesn't really make much sense used this way when the numbers are the result of math it can be useful. – Loren Pechtel Jan 05 '10 at 04:32
  • 3
    one program that I once worked on had this "feature" on the timestamp class, but only for hours/minutes/seconds. Days/months/years were confined to their normal ranges. It caused me a lot of grief when people would enter times like "25:70:99" and it would convert them into something on the next day instead of throwing an error like I expected. I agree that this feature can be useful, but it should be opt-in. – rmeador Jan 06 '10 at 17:53
45

In ruby/python/c, you can concatenate strings just like this:

a = "foo" "bar"
print a # => "foobar"
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
miku
  • 181,842
  • 47
  • 306
  • 310
  • 82
    THat's not WTF --- that's awesomeness – Kris Walker Jan 03 '10 at 15:36
  • 12
    @redder: as long as they're constant strings - yes. – Asaf R Jan 03 '10 at 16:50
  • 18
    Oh yeah. That's fun if you have a variadic function in C and forget the comma between two symbolic constants. All params offset by one, and crashes galore. But is nice in e.g. ObjC, where you can use @"" __FILE__ to get an NSString with the file name. – uliwitness Jan 03 '10 at 18:22
  • Still a better string concatenation syntax than + (see chrisharris.'s above), except that it's only good with constants. – Mike D. Jan 04 '10 at 03:31
  • 3
    As a side note in Obj-C, when you use it with NSString constants (`@""`), you don't need any extra @s. For example, `@"foo" "bar"`. This can be really useful for breaking strings across lines... – jtbandes Jan 05 '10 at 02:46
  • 2
    Pfft, sh has been doing this for decades. – rjh Jan 05 '10 at 03:13
  • 2
    String **constants**. Doing `"foo" bar` where bar is a variable containing a string won't work. – Juliano Jan 05 '10 at 16:04
  • 1
    In Core Foundation, the `CFSTR` macro that builds compile-time static `CFStringRef` instances ensures that it is only used with constant strings by being defined like this: `#define CFSTR(x) __some_magic_builtin_that_i_cant_remember("" x "")` – dreamlax Jan 06 '10 at 03:09
  • 6
    In Python this is not "string concatenation" - it is part of the parsing of the code. it is one ot the few thigns taht happen at parse ("compile") time, instead of runtime. So, print "a" + "b" and print "a" "b" Yield the same result, but are fundamentally different things - the later should only be used for splitting large string constants over multiple lines of code, (where you can't afford the triple quote - """ bla """ style due to the \n's, that is) – jsbueno Jan 06 '10 at 18:18
  • 2
    I would just call it a string constant syntax, not concatenation. – hmp Jan 07 '10 at 10:42
  • In Python that only works for string literals so it's always obvious what's going to happen – DasIch Jun 26 '10 at 19:25
45

In JavaScript, undefined is a global variable whose default value is the primitive value undefined. You can change the value of undefined:

var a = {};
a.b === undefined; // true because property b is not set
undefined = 42;
a.b === undefined; // false

Due to the mutability of undefined, it is generally a better idea to check for undefined-ness through typeof:

var a = {};
typeof a.b == "undefined"; // always true
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Ates Goral
  • 137,716
  • 26
  • 137
  • 190
  • omfg. how did I not know about this? the wheels in my head that think evil obfuscation thoughts are spinning very fast right now... – rmeador Jan 06 '10 at 20:47
  • void(0) is a more reliable way of getting the undefined value. However, read my answer to see why this is a bad idea as well. (in short, void(0) isn't doing what it looks like it's doing). – Breton Jan 06 '10 at 23:26
  • 23
    "undefined" is not a reserved words. It's a variable name, which happens to be undefined. Being undefined is a type, shown by typeof. – niXar Jan 07 '10 at 14:07
  • 4
    This also goes for Infinity and NaN. This will be changed in Firefox 3.7, by the way: http://whereswalden.com/2010/01/12/more-es5-backwards-incompatible-changes-the-global-properties-undefined-nan-and-infinity-are-now-immutable/ – Erik Hesselink Feb 07 '10 at 19:56
  • 2
    That's why most libraries define their local scope like `(function (undefined) { ... })();`. This way you have a guaranteed undefined value in your scope (since omitted parameters are undefined always). And it's compressed better than typeof checks. – Sedat Kapanoglu Feb 05 '11 at 16:59
43

In Forth, anything that does not contains spaces can be an identifier (things that contain spaces take a bit of work). The parser first checks if the thing is defined, in which case it is called a word, and, if not, checks if it is a number. There are no keywords.

At any rate, this means that one can redefine a number to mean something else:

: 0 1 ;

Which creates the word 0, composed of 1, whatever that was at the time this was executed. In turn, it can result in the following:

0 0 + .
2 Ok

On the other hand, a definition can take over the parser itself -- something which is done by the comment words. That means a Forth program can actually become a program in a completely different language midway. And, in fact, that's the recommended way of programming in Forth: first you write the language you want to solve the problem in, then you solve the problem.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • 2
    Wow. That's pretty crazy. Is it useful? or is it just a pain? – Paul Nathan Jan 05 '10 at 00:51
  • 4
    Well, I never encountered any programs redefining numbers themselves -- just because it is possible doesn't mean it is a good idea, after all. There are words starting with numbers, though, such as `0BRANCH`. As for taking over the parser, that's pretty common, as the language is pretty much geared towards building DSLs. – Daniel C. Sobral Jan 05 '10 at 16:07
  • 2
    I was trying to think back to the mid-80s when I used Forth. You nailed it with the definition taking over the language. Since it was right around the place and time of the Homebrew Computer Club, there were some real characters messing around with Forth and the kit computers like the Z80 S100-bus. Later Forth was an alternative to 6502 assember on Atari 2600 and Commodore 64 -- darn kids nowadays have NO IDEA that TOTAL ADDRESSABLE RAM was 64k. That's it! – reechard Jan 10 '10 at 08:07
43

I added the "format" function to Lisp in about 1977, before "printf" even existed (I was copying from the same source as Unix did: Multics). It started off innocently enough, but got laden with feature after feature. Things got out of hand when Guy Steele put in iteration and associated features, which were accepted into the Common Lisp X3J13 ANSI standard. The following example can be found at Table 22-8 in section 22.3.3 of Common Lisp the Language, 2nd Edition:

(defun print-xapping (xapping stream depth)
  (declare (ignore depth))
  (format stream
      "~:[{~;[~]~:{~S~:[->~S~;~*~]~:^ ~}~:[~; ~]~ ~{~S->~^ ~}~:[~; ~]~[~*~;->~S~;->~*~]~:[}~;]~]"
      (xectorp xapping)
      (do ((vp (xectorp xapping))
           (sp (finite-part-is-xetp xapping))
           (d (xapping-domain xapping) (cdr d))
           (r (xapping-range xapping) (cdr r))
           (z '() (cons (list (if vp (car r) (car d)) (or vp sp) (car r)) z)))
          ((null d) (reverse z)))
      (and (xapping-domain xapping)
           (or (xapping-exceptions xapping)
           (xapping-infinite xapping)))
      (xapping-exceptions xapping)
      (and (xapping-exceptions xapping)
           (xapping-infinite xapping))
      (ecase (xapping-infinite xapping)
        ((nil) 0)
        (:constant 1)
        (:universal 2))
      (xapping-default xapping)
      (xectorp xapping)))
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Dan Weinreb
  • 533
  • 5
  • 7
  • 19
    +1 for a guy who was there. This answer is refreshing considering the plethora of off-the-cuff answers where somebody is surprised C# doesn't work like C++, etc. – John K Aug 30 '10 at 03:02
  • 1
    @Biosci3c -- It made me a little surprised and pleased that I hadn't seen any Lisp entries yet. Perhaps that means it does not have much unexpected behavior. – Mark C Dec 15 '11 at 17:42
42

MUMPS. There are lots of WTF features, I've picked one, the if statement. (Note that I'm using a rather verbose coding style below in order to accomodate those who don't know the language; real MUMPS code is usually more inscrutable to the uninitiated.)

if x>10 do myTag(x)    ; in MUMPS "tag" means procedure/function
else  do otherTag(x)

This is similar to saying in Java:

if (x > 10) {
  myMethod(x);
} else {
  otherMethod(x);
}

Except that in MUMPS, the else statement isn't syntactically part of the if block, it is a separate statement that works by examining the built-in variable $TEST. Every time you execute an if statement it sets $TEST to the result of the if statement. The else statement actually means "execute the rest of line if $TEST is false, otherwise skip to the next line".

This means that if x was greater than 10 and thus the first line called myTag, and myTag contains if statements, then the behavior of the else depends not on the if in the line above it but on the last if evaluated inside of myTag! Because of this "feature", MUMPS coders are generally taught write the above code like this to be safe:

if x>10 do myTag(x) if 1
else  do otherTag(x)

The if 1 at the end of the first line ensures that $TEST is set correctly before control proceeds to the next line. (BTW, the spacing here has to be just so, with two spaces after the else and one space in all the other places. The spacing is odd but at least it's very orthogonal once you understand the pattern.)

Nate C-K
  • 5,744
  • 2
  • 29
  • 45
  • 28
    This is the most staggeringly bad piece of language design I have seen yet. My heart goes out to you and your fellow MUMPS programmers. – j_random_hacker Jan 31 '10 at 07:46
  • At least the irritation of those quirks is moderate somewhat by the small size of the language. TBH what really gets me is that MUMPS has a very powerful type abstraction -- efficient sorted n-ary trees -- but they are not first-class objects. There is no other aggregate data type. The language lacks reference or pointer types so you can't, e.g., build a tree from the bottom up. This makes some algorithms very awkward to implement. – Nate C-K Feb 04 '10 at 21:30
  • 1
    That's absurd! Absurd I tell you! – Igby Largeman Apr 23 '10 at 21:29
41

Tri-valued logic of nulls in ANSI SQL.

Chandra Patni
  • 17,347
  • 10
  • 55
  • 65
41

An amusing side effect of Python's everything-is-really-a-reference:

>>> a = [[1]] * 7
>>> a
[[1], [1], [1], [1], [1], [1], [1]]
>>> a[0][0] = 2
>>> a
[[2], [2], [2], [2], [2], [2], [2]]
NickZoic
  • 7,575
  • 3
  • 25
  • 18
  • 8
    you asked for 7times the same object not 7 times for a copy. I think this is normal, not WTF – Kugel Jan 07 '10 at 03:04
  • 8
    normal yes, but I know I've been bitten by this one a few times – cobbal Jan 07 '10 at 09:07
  • 5
    Not coming from a Python background, that really threw me off. +1 – Maulrus Jun 09 '10 at 03:54
  • 1
    Try def x(y, z=[]): z.append(y); print z – cthom06 Sep 10 '10 at 14:33
  • No, believe me, as someone who uses Python all the time, this is something that is definitely a WTF and has thrown me off more than once in the past. By the way, if you want a list with 7 *copies* of `a`, you could do `[a for i in range(7)]`. – asmeurer Jan 14 '11 at 04:40
  • 1
    No, believe me, as someone who uses Python all the time, this couldn't be more expected. By the way, your example doesn't work. Try [list() for i in range(7)]. – porgarmingduod Mar 16 '11 at 18:08
41

In JavaScript, you can use a double bitwise negation (~~n) as a replacement for Math.floor(n) (if n is a positive number) or parseInt(n, 10) (even if n is negative). n|n and n&n always yield the same results as ~~n.

var n = Math.PI;
n; // 3.141592653589793
Math.floor(n); // 3
parseInt(n, 10); // 3
~~n; // 3
n|n; // 3
n&n; // 3

// ~~n works as a replacement for parseInt() with negative numbers…
~~(-n); // -3
(-n)|(-n); // -3
(-n)&(-n); // -3
parseInt(-n, 10); // -3
// …although it doesn’t replace Math.floor() for negative numbers
Math.floor(-n); // -4

A single bitwise negation (~) calculates -(parseInt(n, 10) + 1), so two bitwise negations will return -(-(parseInt(n, 10) + 1) + 1).

Update: Here’s a jsPerf test case comparing the performance of these alternatives.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Mathias Bynens
  • 144,855
  • 52
  • 216
  • 248
  • This is very interesting! Also note that, for some reason, function `parseInt(x, 10)` is about 3 times slower than `Math.floor()`. – Harmen Jul 02 '10 at 15:42
  • 3
    Bitwise operators will truncate their inputs to signed 32 bit values. Math.floor(4294967295.1) == 4294967295; parseInt("4294967295.1") == 4294967295; (4294967295.1 | 4294967295.1) == -1; – rpetrich Aug 15 '10 at 00:16
  • That’s right, @rpetrich. I should’ve mentioned that. I updated the answer with a link to [the performance test case on jsPerf](http://jsperf.com/rounding-numbers-down/4). – Mathias Bynens Aug 15 '10 at 07:46
  • How does something like this even get discovered? – kirk.burleson Sep 11 '10 at 22:42
39

Not so much a weird feature, but one that's really irritating from a type-safety point of view: array covariance in C#.

class Foo { }
class Bar : Foo { }
class Baz : Foo { }

Foo[] foo = new Bar[1];
foo[0] = new Baz(); // Oh snap!

This was inherited (pun intentional) from Java, I believe.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Will Vousden
  • 32,488
  • 9
  • 84
  • 95
  • 1
    Assigning an instance of Baz to foo will result in a runtime error, since foo is actually an array of Bar, from which Baz does not derive. This means that if – for example – you have a method that takes an array of Foo, you can't be sure whether you'll actually be able to modify it without causing an exception. – Will Vousden Jan 03 '10 at 17:07
  • Well to be fair, when you say 'Foo[] foo =', you tell the compiler that `foo` is an array containing `Foo` objects... Why should it complain when you add a foo object? It seems like this is rational behavior to me. – TM. Jan 03 '10 at 21:42
  • 26
    The point isn't that it should prevent me from adding `new Baz()` to `foo`; rather, it shouldn't have let me coerce the array into type `Foo[]` in the first place. An array of `Foo` makes two guarantees: 1) that any element retrieved from it will have type `Foo`, and 2) that any object of type `Foo` may be assigned to the array. This obviously isn't the case if the underlying type of the array is actually `Bar`. – Will Vousden Jan 04 '10 at 00:13
  • 11
    Eric Lippert wrote a good series of articles on type variance, the second of which illustrates the problems with array covariance: http://blogs.msdn.com/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx – Will Vousden Jan 04 '10 at 00:18
  • This *is* the case. This is the **whole point on inheritance and polymorphism**. You do something similar every time you use an interface! – Kobi Jan 04 '10 at 06:05
  • 7
    In Programming Scala, this behaviour is talked about on page 391: "When asked [why Java has covariant arrays], James Gosling, the principal inventor [of Java], answered that they wanted to have a simple means to treat arrays generically. For instance, they wanted to be able to write a method to sort all elements of an array, using a signature like the following that takes an array of `Object`: `void sort(Object[] a, Comparator cmp) { ... }`. Covariance of arrays was needed so that arrays of arbitrary reference types could be passed to this `sort` method." – cdmckay Jan 04 '10 at 07:41
  • 8
    @Kobi: I don't follow. `Bar[]` is not a subtype of `Foo[]`, so what do inheritance and polymorphism have to do with it? The reason that this kind of type variance shouldn't be allowed is that an array allows both read and write operations on its underlying type. A read-only type may be type covariant, while a write-only type may be type contravariant, but a read/write type may not be type variant at all. – Will Vousden Jan 04 '10 at 10:58
  • @cdmckay: This could easily have been achieved by way of generics. I realize that this may have been before they were added to Java, but it's still an incorrect form of type variance (and it's possible to achieve this in C# without array covariance or generics by using the `Array` type). – Will Vousden Jan 04 '10 at 11:08
  • @Inquisitor: Oh I know, I was just giving some context as to why Java has covariant arrays. – cdmckay Jan 04 '10 at 16:22
  • @Inquisitor: A nit-pick here: Java doesn't have generics. Java has templates, which are much less powerful than generics. See C# for a good example of real generics implemented in a C-like syntax. – Ray Burns Jan 05 '10 at 21:24
  • 4
    No, Java does not have templates. Templates generate new code for every type that uses the template. C++ templates do this, Java generics do not. Java generics are more similar to C# generics; the difference is that C# retains information about type parameters in the bytecode whereas Java discards this information after using it for type-checking at compile time. – Nate C-K Jan 07 '10 at 17:52
  • This behaviour is totally intended. you should be able to assign an array of bar to an array of foo as they are the same base type. However Baz and Foo are on different branches of the tree so you cant instantiate an element of Bar as a BAz ... you could add an element of baz to an array of foo though. – John Nicholas Sep 01 '10 at 11:35
  • The proper way of handling the situation would be to have separate array types for Readable, ReadAndSwap, and Writable arrays (a ReadAndSwap array would support swapping two items, but both would have to be members of the same array). The first two types could be safely covariant; the third could not. – supercat Dec 22 '10 at 23:21
39

My favorite weirdness in C is 5["Hello World"], but since that was already posted, my next-favorite weirdness is the Windows versioned-structure initialization hack:

void someWindowsFunction() {
    BITMAPINFOHEADER header = {sizeof header};

    /* do stuff with header */
}

That one, subtle line accomplishes the following:

  1. Declares a BITMAPINFOHEADER structure
  2. Concisely sets the "size" member of the structure, without hardcoding a size constant (since many Window structures, including BITMAPINFOHEADER, follow the convention of specifying the size of the structure as the first member}
  3. Declares the version of the structure (since many Windows structures, including BITMAPINFOHEADER, identify their version by the declared size, following the convention that structures definitions are append-only)
  4. Clears all other members of the structure (a C standard behavior when a structure is incompletely initialized).
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Tim Lesher
  • 6,341
  • 2
  • 28
  • 42
  • 13
    Actually, I find this to be an elegant solution, not a WTF at all. – Frank Szczerba Jan 05 '10 at 14:59
  • 6
    At what point did I say it was a WTF? The original question asked for "surprising, weird, strange or really 'WTF'". The surprising thing to me was how expressive one line can be when it combines a little-used but well-defined language behavior with a simple coding convention. – Tim Lesher Jan 05 '10 at 23:01
38

Java; making all object instances be mutexes.

Viktor
  • 3,295
  • 2
  • 25
  • 26
  • Well, to be fair, the `synchronized` statement would be a lot harder to use if that wasn't the case. – David R Tribble Jan 05 '10 at 01:03
  • 6
    What is the problem with shipping a mutex class with the JVM that could then be used in every synchronized statement? What would be more difficult then? – codymanix Jan 05 '10 at 01:35
  • 5
    Maybe he hates multi core/cpu systems. – mP. Jan 05 '10 at 04:35
  • 11
    Uh, maybe he hates adding overhead to *every single object you allocate*, or is observing that if you're locking on a per object basis you're almost certainly doing it wrong, or that it could've been accomplished with a generics library instead of burdening the core language syntax or ... – Joseph Garvin Jan 07 '10 at 15:44
  • 3
    Since 1.5 there has been a dedicated class: `java.util.concurrent.locks.ReentrantLock` but it could have been a separate class from the beginning. Most objects don't need built-in locks, especially immutable objects. – finnw Feb 01 '10 at 05:20
  • @finnw - that makes no difference. Java still allows any object to be used as a mutex, and it is impossible for the JIT to determine that an object can never be used as mutexes. Therefore, the runtime system **must** reserve space on every object for representing the mutex. – Stephen C Jun 11 '10 at 03:12
  • In any real-world multithreaded Java code I've ever seen or written, synchronized blocks always acted on either a java.util.concurrent.locks lock (so that reader and writer locks can be managed properly) or an Object which does nothing but act as a lock. Given that, I see absolutely nothing wrong with shipping a mutex class and avoiding the needless overhead to every other object. Anyway, having a Lock/Mutex class makes intent much clearer when you look at the variable declarations and clearer intent is, IMHO, much more important than the little convenience added by making all objects mutexes. –  Jan 08 '11 at 16:04
37

In PHP one can do:

System.out.print("hello");
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
  • WTF?! Is this documented anywhere? – PureForm Nov 08 '10 at 22:02
  • 4
    Didn't want to believe it. But is actually works, ask e.g. codepad.org. http://www.jansch.nl/2007/03/09/systemoutprint-in-php/ explains why it works, but it's still weird (TRWTF is how PHP swallows references to undefined variables and treats `UndefinedConstant` as `"UndefinedConstant"`) –  Nov 08 '10 at 22:13
  • holly s**t. this is a real WTF – gion_13 Nov 22 '11 at 08:26
  • I don't understand what's so weird about this. Could you explain what it's actually doing? – Nick Retallack Dec 06 '11 at 21:05
  • @NickRetallack String coercion is what PHP does... well, not best, but everywhere and with vigor. Unknown constants? Make 'em strings! What you end up with is the same as if you said ``"System" . "Out" . print("hello");``, which concatenates those strings with the output of print (whatever it is), and then does nothing with it. Meanwhile, the "print" function sends whatever you passed it to the output. – Adam Bard Dec 15 '11 at 23:04
36

In JavaScript:

alert(111111111111111111111) // alerts 111111111111111110000

This was quite damaging to some 64bit keys I passed back and forth in JSON.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Andrey Shchekin
  • 21,101
  • 19
  • 94
  • 162
35

else in Python's for loops.

From the Python documentation:

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print n, 'equals', x, '*', n/x
            break
    else:
        # loop fell through without finding a factor
        print n, 'is a prime number'

Output:

2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
tom_pl
  • 425
  • 2
  • 9
  • 16
  • 3
    @Daniel: I believe the `else` is only executed if the `for` loop does **not** exit because of a `break` statement. – Adam Paynter Sep 11 '10 at 13:05
  • 1
    a quick example code snippet would be nice here for those not familiar with python – scunliffe Sep 11 '10 at 13:56
  • There's an else for while and try too. – Plumenator Sep 13 '10 at 06:08
  • 3
    try: else: works just like you would expect (gets executed when no exception is raised); for/white: else: doesn't match the intuition of ~50% of programmers. I expected it to be executed only if the main body of the for/while loop was never executed, but that's not the case -- the else clause is executed only if no break statement inside the for/while loop is executed. Confused yet? – Marius Gedminas Sep 25 '10 at 01:36
  • 1
    This is used if there are two ways of exiting a loop. Say you are searching a list. You exit the loop when you find what you want, or you hit the end of the list without finding it. In other languages, I set flags "itemFound = False" and test the value of the flag after the loop. The else is kind of like the post loop test, but you don't need a flag. Only thing is, if there are three or more ways to exit the loop (e.g. found, not found, too many occurrences, bad items), you still need flags. So I tried using for-else once, then dropped it. – Andrej Panjkov Dec 16 '11 at 02:22
33

Some early dynamic languages (including, if I remember correctly, early versions of Perl) hadn't figured out what was good dynamism and what was bad dynamism. So some of them allowed this:

1 = 2;

After that statement, the following would be true:

if(1 + 1 == 4)
Imagist
  • 18,086
  • 12
  • 58
  • 77
  • 14
    or perhaps: `2 = 2.5;` then `if(2 + 2 == 5)` – GameFreak Feb 07 '10 at 19:41
  • 2
    What would 2=1; 5=2; 5+2=? Is it 3? Or 2? – Yahel Oct 23 '10 at 20:39
  • @yahelc that'd be 2. This issue crops up in languages that just assume any lvalue is a valid identifier, and will allow you to shadow literals like 1 with variables of the same name. Rename 2 and 5 to x and y and you'll see what this looks like. x=1; y=x; x+y -> 2. – Nick Retallack Dec 06 '11 at 21:01
30

In Python, the "compile time" (or declaration time) evaluation of function arguments can be confusing:

def append(v, l = []):
    l.append(v)
    return l


print append(1)
print append(2)

>>> [1]
>>> [1,2]

The intention might have been:

def append(v, l = None):
    if l is None:
        l = []
    l.append(v)
    return l

print append(1)
print append(2)

>>> [1]
>>> [2]

This behavior is useful for things like caching, but it can be dangerous.

A bonus feature: tuples with mutable contents:

a = (1,2,[3])
a[2][:] = [4] # OK
a[2] = [2] # crashes
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
wisty
  • 6,981
  • 1
  • 30
  • 29
  • 1
    To be a major WTF it'd have to be something that commonly causes problems. –  Jan 05 '10 at 12:35
  • 5
    @Roger Pate: Every single Python programmer gets bitten by this at some point, after which they have to constantly keep it in the back of their mind. That is exactly what constitutes a language-gotcha ( http://www.ferg.org/projects/python_gotchas.html#contents_item_6 ). – BlueRaja - Danny Pflughoeft Jan 06 '10 at 03:21
  • 2
    You can't `return l.append(1)`. You have to `l.append(1); return l` because `list.append` returns nothing. – Chris Lutz Jan 06 '10 at 05:45
  • fwiw, you can't hash `a`. Every element of a tuple has to be hashable in order for you to hash it. I mention this because hashability is the main reason for immutable types like tuples. – asmeurer Jan 14 '11 at 04:53
29

In PHP, a string is as good as a function pointer:

$x = "foo";
function foo(){ echo "wtf"; }
$x(); # "wtf"

Unfortunately, this doesn't work:

"foo"();
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Nick Retallack
  • 18,986
  • 17
  • 92
  • 114
29

In Scala, there are no operators, just methods. So a + b - c is actually the same as a.+(b).-(c). In this, it is equal to Smalltalk. However, unlike Smalltalk, precedence is taken into account. The rules are based on the first character, so an hypothetical method called *+ would have precedence over one called +*. An exception is made so that any method ending in = will have the same precedence as == -- meaning !! and != (non-hypothetical methods) have different precedence.

All ASCII letters have the lowest precedence, but all non-ASCII (unicode) characters have the highest precedence. So if you wrote a method is comparing two ints, then 2 + 2 is 1 + 3 would compile and be true. Were you to write it in portuguese, é, then 2 + 2 é 1 + 3 would result in error, as it would see that as 2 + (2 é 1) + 3.

And, just to top off the WTF of operators in Scala, all methods ending in : are right-associative instead of left-associative. That means that 1 :: 2 :: Nil is equivalent to Nil.::(2).::(1) instead of 1.::(2).::(Nil).

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
29

In JavaScript the result of a method can depend upon the style braces are placed. This is the K&R style, where braces are placed right after the method signature and after a return statement:

var foo = function() {
  return {
    key: 'value'
  };
}

foo() // returns an object here

Now, if I format this code to the Allman style, where braces are always placed on a new line, the result is different:

var foo = function()
{
  return
  {
    key: 'value'
  };
}

foo() // returns undefined here

How come? In JavaScript the language places automatically semicolons at the end of each line if you won't do it yourself. So what really happened in the last code fragment was this:

var foo = function()
{
  return; // here's actually a semicolon, automatically set by JavaScript!
  {
    key: 'value'
  };
}

So if you'd call foo(), the first statement in the method would be a return statement, which would return undefined and would not execute other following statements.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
  • 2
    +1 for a good explanation, though this has already been mentioned earlier (http://stackoverflow.com/questions/1995113/strangest-language-feature/2003277#2003277). – Helen Feb 08 '10 at 19:32
  • 1
    Uh, I think styles like K&R and Allman apply to brackets used for flow control. Brackets used to implicitly create an object are a different animal. – fenomas May 12 '10 at 10:18
28

Other weird things:

In C++ overriding a virtual method hides all other overloads of that method. In Java this does not happen. This is very annoying. Example: http://codepad.org/uhvl1nJp

In C++ if a base class has a public virtual method foo() and a subclass has a private method foo(), this private method overrides the other one! This way you can call what is a private method outside of the class just by casting the subclass object pointer to a superclass object pointer. This shouldn't be possible: it's a violation of encapsulation. The new method should not be treated as an override of the old one. Example: http://codepad.org/LUGSNPdh

In PHP you can define functions to accept typed parameters (e.g. objects that are subclasses of a certain interface/class), the annoying thing is that this way you cannot use NULL as the actual parameter value in this case. Example: http://codepad.org/FphVRZ3S

P Daddy
  • 28,912
  • 9
  • 68
  • 92
Andrea Zilio
  • 4,444
  • 3
  • 29
  • 34
  • 1
    Ah yeah! That really annoys me about PHP not allowing null..! – nickf Jan 04 '10 at 08:11
  • 16
    Actually, if you provide the type-hinted parameter the default value of `null`, then it means that the value can be either `null` or an instance of the specified class. – Ignas R Jan 04 '10 at 15:01
  • point two is better explained in this same thread: http://stackoverflow.com/questions/1995113/strangest-language-feature/1995315#1995315 – Evan Carroll Jan 05 '10 at 18:21
  • @EvanCarroll The other answer you've linked shows another different problem. What's explained here is completely different ;) – Andrea Zilio Jan 06 '10 at 12:52
  • 2
    Re: private foo() overriding public foo(), this is by design and A Good Thing. Otherwise changing access qualifiers could silently change which methods are called. That it can be subverted in the way described is unfortunate, but the lesser of two evils. – tragomaskhalos Jan 07 '10 at 10:19
  • @Talvi Watia, I'm not sure what you mean in this context. – Andrea Zilio Jun 11 '10 at 12:45
  • `NULL` in an object means empty, and unknown if undefined. A child element normally should not exist. In the example at `http://codepad.org/FphVRZ3S`, there is a child element being called from `$obj`... `return $obj->eat();` ... below when you call `foo(null);`, you should actually instead call `foo();`, rather `foo($var_obj);` by creating it first. Inserting `NULL` as the function parameter just won't work because it doesn't exist (yet). see: `http://php.net/manual/en/language.types.object.php` *If the value was `NULL`, the new instance will be empty.* – Talvi Watia Jun 12 '10 at 06:01
  • 1
    Regarding PHP: you constrained what type the argument should be (implements Eatable). You gave it a value that does not satisfy the constraint (NULL). What, other than throw an exception do you want it to do in this case? – Zak Aug 14 '10 at 14:21
  • @Zak I want it to as behave similarly to all the other languages where parameters are constrained to types. For example Java which allow you to pass null values. – Andrea Zilio Aug 14 '10 at 14:51
  • 1
    @Andrea Zilio - what advantage does that get you? Actually trying to call null->eat() will throw an exception as well, and moves the error farther from the incorrect code (imagine the call to $obj->eat() buried a couple function calls deep). I'm not up to date on PHP, but typed parameters appear to exist to simplify debugging in the event of runtime type errors; allowing arbitrary nulls would reduce its effectiveness for that purpose. – Zak Aug 14 '10 at 19:07
  • @Zak Typed parameters has two advantages in my opinion: by using them you have a form of implicit documentation (the function is more self-explanatory on its usage), moreover the type checking you usually have to do manually becomes automatic. Since there are cases where it is needed to pass null values to certain arguments, making null values not acceptable in combination with typed parameters exclude those functions or methods to the aforementioned benefits that typed parameters usually provide. Allowing null values only when `null` is set as the default value may be an acceptable trade off. – Andrea Zilio Aug 15 '10 at 00:17
  • @Andrea Zilio It seems a bit strange to me that PHP, a language known for being very liberal with types is so strict in this situation. It is not, however the only language that won't allow values of arbitrary types to also be null. For example, values can only be null in OCaml, Haskell, F# and Scala using an Option or Maybe type, though it can sneak in through .NET/Java interop in the latter two. It actually seems very strange to me that languages with static typing would allow nulls without an explicit declaration, but I'm getting off-topic now. – Zak Aug 15 '10 at 00:26
  • @Zak I agree that an explicit declaration to allow null values would be great even in Java, c++ or other languages... PHP included :) – Andrea Zilio Aug 15 '10 at 00:52
  • @Andrea Zilio In PHP, I believe you can explicitly declare it to accept null values by using `function foo(Eatable $obj=null)` as your function declaration. – Aether Jan 19 '11 at 13:54
27

One of my favorites in C++ is the "public abstract concrete inline destructor":

class AbstractBase {
public:
    virtual ~AbstractBase() = 0 {}; // PACID!

    virtual void someFunc() = 0;
    virtual void anotherFunc() = 0;
};

I stole this from Scott Meyers in Effective C++. It looks a bit weird to see a method that's both pure virtual (which generally means "abstract") and implemented inline, but it's the best and most concise way I've found to ensure that an object is polymorphically destructed.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Tim Lesher
  • 6,341
  • 2
  • 28
  • 42
  • It may be implemented inline but it's probably not really going to be inlined because it is virtual. – shoosh Jan 05 '10 at 00:00
  • That's correct--it's strictly a matter of conciseness and clarity. – Tim Lesher Jan 05 '10 at 23:04
  • 1
    @shoosh: ...unless the compiler can actually know from the context the real type of the object being destroyed. AFAIK only GCC knows how to do this optimization, though. – slacker Mar 26 '10 at 02:26
27

Some 20 years ago, when I last dabbled in MUMPS, the implementations had some curious limitations. While hosts MUMPS was becoming ever more popular, MUMPS was traditionally a self-hosted language: computer language, operating system and database in a single package.

MUMPS was essentially about its database. Essentially, a huge multidimensional hash table, supported by a B* tree that made for very fast access. There wasn't any barrier between the language and the database either: if you wanted something to be stored there, you just prefixed the variable with a symbol indicating it was to be persisted to the backing store.

On the other hand, a filesystem was almost non-existent, and support for it even less so. About the only thing one could do was to load a program into memory from a file, and send whatever was in memory back to a file. And one had better clear the buffer before loading, otherwise it would get mixed with whatever was there first.

So, considering its self-hosting nature and the extremely hostile file system, one could wonder how these programs were edited. The editors, as a matter of fact, were written in MUMPS itself -- so how could the editor store the program in memory without written over itself?

Well, the trick was the ability to execute the contents of a variable as source code. An editor, then, loaded itself into variables, executed itself in them, cleared the memory, and then loaded, saved and edited files in memory, all the time executing from variables.

Add to that the fact that all commands could be shortened to their first letters (except the Z commands, shortened to two letters, that mostly handled the filesystem), and curiosities like the fact that IF (I) set a variable which was then consulted by ELSE (E) -- and, of course, could be overridden by any intervening I, or by the program itself. On second thought, I think the whole language was a WTF. And, yet, it had a strange attraction.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • 1
    MUMPS is famous on The Daily WTF. I think the question is more about weird *features* instead of the ways languages which make a freakishly demented hash of things, though.... ;) –  Jan 05 '10 at 01:06
  • 1
    Read 'A Case of the MUMPS' on thedailywtf.com: http://thedailywtf.com/Articles/A_Case_of_the_MUMPS.aspx – An̲̳̳drew Jan 07 '10 at 03:10
  • Luckily modern implementations are much better than this. – Nate C-K Jan 07 '10 at 05:40
  • BTW, I'm familiar with that Daily WTF article and it's quite out of date (perhaps 10+ years old) and also, IMO, not entirely truthful. – Nate C-K Jan 07 '10 at 05:50
  • 2
    Just to make it clear, I *like* MUMPS. But I have also seen the worse of it. Or, rather, seen something bad enough to have felt pity for those who _have_ endured the worse of it -- maintaining badly written, single-letter commands, legacy MUMPS code. – Daniel C. Sobral Jan 07 '10 at 12:31
  • 1
    It's actually oddly high level for such an early language. If it just had better structured programming features (Intersystems is trying at least) then it could be a pretty good language. RE the `if`-`else`, they've proposed adding a `then` statement that would preserve the value of $TEST and restore it at the beginning of the next line, thus protecting you from the hazard of having it change on you; but I don't even know if the proposed future standard will ever happen. – Nate C-K Jan 07 '10 at 17:27
  • And IMO, single-letter commands aren't so bad. There are only a few commands anyway, it's not that hard to remember them. Single-letter *variables* are bad, though. And tag interfaces that pass around information in arbitrarily named variables rather than explicit parameter passing. Those practices are (no longer) allowed where I work. – Nate C-K Jan 07 '10 at 17:33
  • But the best thing about MUMPS is not having to scrap and rewrite your code every 10 years because your language of choice is no longer supported. The language has had phenomenal longevity. – Nate C-K Jan 07 '10 at 17:35
  • Ok, I'll grant the one letter commands. It's just that whenever I see one letter commands, everything else is also one letter. – Daniel C. Sobral Jan 07 '10 at 18:53
  • My most un-favorite variable name is probably `%`. – Nate C-K Jan 07 '10 at 22:11
27

In Ruby, 0 evaluates as true in conditional expressions.

Duncan
  • 2,056
  • 13
  • 11
  • 9
    +1 because it can be a WTF, even though I think it's a good thing. – Chris Lutz Jan 11 '10 at 06:30
  • 1
    Please do explain how `0 == true` is a good thing. I'm not trolling - actually interested... Does any integer evaluate as false? – nickf Jan 13 '10 at 12:46
  • 12
    In Ruby only `false` and `nil` are false. I suppose it avoids using a magic number for false, if for instance 0 is a valid result for a function it could still return `nil` on a error and be used in an if statement. – Scott Wales Jan 14 '10 at 03:41
  • 12
    I think coercing numbers to booleans is a WTF - 0 should not be evaluatable as a boolean, it should be a type mismatch. – Richard Gadsden Jan 15 '10 at 16:31
  • In scheme nil 0 and #f are disjoint and only #f is false. – Justin Smith Jan 18 '10 at 17:36
  • @Richard, it's not just numbers. In languages like Ruby and Python, everything can be interpreted as a boolean. In Ruby, as Scott said, everything is true, except false and nil. In Python there are other false things, like (,) and [], but everything can be treated as a boolean. It's not just numbers. – Tyler Feb 09 '10 at 15:41
  • @MatrixFrog, Python and Ruby are dynamically typed languages, so it's not great surprise you can coerce anything into a boolean. I was thinking more of a statically-typed language like C (++/#/Obj), Java or even VB. – Richard Gadsden Feb 11 '10 at 10:19
  • @Richard: At least in C# (and I think Java too), it _already is_ a type mismatch. – Allon Guralnek Aug 24 '10 at 11:04
  • That's a WTF for people (like me) coming from the C languages world to Ruby/python; but for anyone coming from the lisp family that's perfectly natural: in common lisp only the empty list (which is aliased as `nil`) is "false" and everything else is true. – lfborjas Dec 06 '10 at 01:23
  • @Scott I agree that avoiding magic numbers is a good thing. But the negation is still there. So in a typo or bug, you can get true and false for this confusing. For example !0 is false. In short, just use the keyword true/false. – squarism Dec 06 '11 at 15:12
  • 1
    It's good feature while any search return position in string or `nil`/`false` if not found so you can simply write `puts "Found" if "abba".find "ab"` instead `puts "Found" unless "abba".find("ab") == nil` – Hauleth Mar 03 '12 at 19:30
27

The absolute worst WTF has got to be Cobol's ALTERED GOTO.

The syntax is pretty straight forward: "ALTER label1 TO GOTO label2", but the results of debugging run-time spaghetti are mind-boggling.

Joe Zitzelberger
  • 4,238
  • 2
  • 28
  • 42
  • 5
    It represents accurately the business model of some stakeholders, when they say something but REALLY MEAN some other thing. What a feature! ;D – Chubas Jun 20 '10 at 20:01
  • 3
    And this was one of those things that if I ever saw it, I'd pull out a shotgun. – Russ Aug 12 '10 at 13:25
  • 1
    Sounds useful for static initializers that only need to run once `Label:` `` `ALTER Label TO GOTO InitializedLabel` `InitializedLabel:` ``. – configurator Feb 20 '11 at 02:30
  • I agree with @configurator, I think the Real WTF here is just GOTO. – Justin Morgan - On strike Mar 23 '11 at 15:17
  • @configurator -- altered goto still allow a fall-through to the original path, only a goto label would proceed to InitializedLabel. Besides, Cobol has a better meme for a static initializer that is used by many preprocessors -- set a hard goto to the end of the initialization with a conditional jump into the initialization immediately before it, thus preventing the fall through execution risk. – Joe Zitzelberger Mar 23 '11 at 16:24
  • Oh, one other thing -- the altered goto makes automatic optimazation of code by the compiler or 3rd party optimizers nearly impossible, so using it for that would have some unintended side effects. – Joe Zitzelberger Mar 23 '11 at 16:26
26

In C-like languages (including C itself), you can use the "goes down to" operator:

for (x = 20; x --> 0;) {
    print x;
}

This will print the numbers from 19 to 0.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Chris Eidhof
  • 1,514
  • 1
  • 12
  • 15
26

"Piet is an esoteric programming language designed by David Morgan-Mar, whose programs are bitmaps that look like abstract art."

Piet program that prints Piet

Piet program that prints Piet

Tony Morris
  • 3,045
  • 2
  • 29
  • 17
26

Well, this one's also my all-time-favorite hard to find bug... treating integers beginning with a zero as octal numbers. This led to a bug that would only show between 8 and 10 in the morning:

Once, I helped building an automated regression test to be executed via cron at night. It worked nearly for everyone in a 20 person team - expect one developper complained every once in a while the automatic test had failed, but when run manually, everything worked fine. Not even once this could be reproduced manually.

Well, the reason was, we did some calculation (in bash) for statistics based on the output of the date command, and this failed only from 8:00 till 9:59 in the morning because we'd read the hour value as "08" (which is an illegal octal value, whereas "01" - "07" are valid octal values, and from "10" onwards everything is treated as decimal again)...

Axel
  • 13,939
  • 5
  • 50
  • 79
  • And new programming languages continue to support octal numbers. Who use them, except for Unix file rights? – PhiLho May 12 '11 at 13:00
  • I think they are still used to confuse undergraduate computer science students. ;) – Axel May 13 '11 at 06:40
25

JavaScript dates are full of WTF.

var d = new Date("1/1/2001");

var wtfyear = d.getYear(); // 101 (the year - 1900)
// to get the *actual* year, use d.getFullYear()

var wtfmonth = d.getMonth(); // 0
// months are 0-based!
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Civil Disobedient
  • 1,527
  • 11
  • 5
  • 5
    Ever heard of Java's Date API? Same thing. – R. Martinho Fernandes Jan 07 '10 at 19:10
  • Have to love backwards compatibility and 2 digit years. :-) – devstuff Jan 08 '10 at 05:20
  • 1
    Yeah, the people who wrote Java's Date and Calendar classes need to be shot. Joda time is a lot better, but still not quite where it needs to be. Beter use(TimeCategory) in Groovy. It fixes the Date class and adds cool stuff to Integer. – mcv Jan 12 '10 at 15:47
  • 3
    new String[] { "jan", "feb", ... }[date.getMonth()]... might be an explanation for the behavior. But then, DAY_OF_WEEK is 1-based... I'd love to hear the reasoning for months being 0-based and days of week, 1-based. – alex Jan 16 '10 at 00:35
23

As an NHibernate enthusiast, I was thrilled when I heard about become from Smalltalk... e.g.

a become: b

it literally changes the a object into b, which makes it trivial to write lazy-initialized proxies because all references to a will now reference b. Pretty neat!

I think it qualifies as a strange language feature in that no other language has this ability to my knowledge.

mookid8000
  • 18,258
  • 2
  • 39
  • 63
  • 31
    Whenever somebody says "no other language has this", I tend to mentally append "... except Common Lisp": http://www.lispworks.com/documentation/HyperSpec/Body/f_chg_cl.htm :-) – Ken Jan 04 '10 at 16:55
  • Wow! As a C# guy, I am baffled by language features like that! Think of the hoops we jump through with dynamic subclassing and whatnot to imitate this behavior :) – mookid8000 Jan 04 '10 at 19:20
  • 2
    You can do this in Objective-C, see NSProxy (http://developer.apple.com/mac/library/documentation/cocoa/reference/Foundation/Classes/NSProxy_Class/Reference/Reference.html) – Mike Akers Jan 04 '10 at 20:18
  • One *can* do this in C#, but not without some weird code. An implementation of this behavior would require quite a few hundreds lines of code...(for it to be usable, I mean). – luiscubal Jan 04 '10 at 21:52
  • 2
    @mookid: it's a shame that someone didn't think of features like this 20 years before C# existed... oh wait... – D.Shawley Jan 04 '10 at 23:24
  • `become:` for Python: http://wargle.blogspot.com/2009/07/smalltalks-become-in-python.html – outis Jan 05 '10 at 14:01
  • 2
    This worked in 'traditional' smalltalk implementations because everything was doubly indirected through an object table. I do recall reading somewhere that become: on some ST implementations is pretty inefficient. In practice writing a 'generic' proxy mechanism that traps #NotImplemented tends to be more useful for persistence or other mechanisms that require this type of proxy arrangement. – ConcernedOfTunbridgeWells Jan 07 '10 at 17:38
  • Ruby strings have a method #replace that does this, but that's only for strings. – Ollie Saunders Mar 23 '10 at 01:43
23

In FoxPro, if I remember correctly, every command can be abbreviated to 4 characters and everything else is ignored, so READ, READY, READINESS is all the same - whatever is after the first 4 characters is ignored. The guy who explained it to me liked that feature, but I thought it was creepy.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Ravi Wallau
  • 10,416
  • 2
  • 25
  • 34
  • 4
    Early Infocom games (text adventures) used to have a similar limitation. So if you tried to reference an object the game didn't expect, sometimes you'd get a hint about an item that would surface later in the game. As in: > STEAL THE JACKET > You can't see a powerful looking jackhammer here! – fenomas May 12 '10 at 09:54
22

Common Lisp's format function has an option to print numbers as Roman numerals.

In INTERCAL that is the only form of output you'll ever get.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
David Thornley
  • 56,304
  • 9
  • 91
  • 158
  • 43
    This is a vicious slander on CL's `FORMAT`, which has **two** options for printing numbers as Roman numerals: one prints 4 as `IV`; the other prints 4 as `IIII`. – Pillsy Jan 05 '10 at 14:43
  • 2
    Format also has the option to display numbers in English, or to specify looping through a format argument through usage of format characters. – Justin Smith Jan 18 '10 at 17:29
  • 2
    IIII is not "incorrect", it was in use as late as 1390, it just doesn't comform to modern ideas of "proper Roman numerals". So, essentially, a variant rather than an error. – Vatine May 11 '10 at 10:26
22

In C, the sizeof operator does not evaluate its argument. This allows one to write code that looks wrong but is correct. For example, an idiomatic way to call malloc(), given a type T is:

#include <stdlib.h>

T *data = NULL;
data = malloc(sizeof *data);

Here, *data is not evaluated when in the sizeof operator (data is NULL, so if it were evaluated, Bad Things would happen!).

This allows one to write surprising code, to newcomers anyway. Note that no one in their right minds would actually do this:

#include <stdio.h>

int main()
{   
    int x = 1;
    size_t sz = sizeof(x++);
    printf("%d\n", x);
    return 0;
}   

This prints 1, not 2, because x never gets incremented.

For some real fun/confusion with sizeof:

#include <stdio.h>
int main(void)
{
    char a[] = "Hello";
    size_t s1 = sizeof a;
    size_t s2 = sizeof ("Hi", a);
    printf("%zu %zu\n", s1, s2);
    return 0;
}

(The confusion is only if one is confused about arrays, pointers, and operators.)

Alok Singhal
  • 93,253
  • 21
  • 125
  • 158
  • also used a lot in c++ for SFINAE stuff in templates – jk. Jan 08 '10 at 10:52
  • 1
    Doesn't this just boil down to the fact that sizeof is a compile time operator? – Dykam Jan 10 '10 at 13:07
  • @Dykam, yes it does, and you are absolutely right. Given that, the answer is obvious, but it still "seems" strange, particularly because the operator, unlike other operators, is a word, and almost looks like a function call. – Alok Singhal Jan 10 '10 at 15:42
  • Rather than casting to `int`, you should use `%zu` to print out `size_t` types. – Chris Lutz Jan 11 '10 at 06:21
  • 1
    @Chris: I was being lazy: I know that `s1` and `s2` are small enough to fit in `int`. I did the cast because `%zu` is C99 only. – Alok Singhal Jan 11 '10 at 14:03
  • 2
    One benefit of sizeof() not evaluating its innards is that it allows you to create a macro expanding to an array followed by its count: #define STRING_ARRAY(...) ( (const char *[]){__VA_ARGS__} ), (sizeof( (const char *[]){__VA_ARGS__} ) / sizeof(const char *)) – Joey Adams Feb 01 '10 at 05:22
22

Might have already been said (and maybe this isn't so strange to some) but I thought this was pretty cool:

In Javascript, declaring the parameters a function accepts is only a convenience to the programmer. All variables passed through the function call are accessible by the keyword "arguments". So the following would alert "world":

<script type="text/javascript">

function blah(){
alert(arguments[1]);
}

blah("hello", "world");

</script> 

Note, that while it may seem like these arguments are stored in an array (since you can access object properties in much the same way as array elements), they are not. arguments is an Object, not an Array (so, they are Object properties stored with numeric indices), as the following example illustrates (typeOf function taken from Crockford's remedial JavaScript page):

argumentsExample = function(){
    console.log(typeOf(arguments));

    anArray = [];
    console.log(typeOf(anArray));

    anObject = {};
    console.log(typeOf(anObject));
}

function typeOf(value) {
    var s = typeof value;
    if (s === 'object') {
        if (value) {
            if (typeof value.length === 'number' &&
                    !(value.propertyIsEnumerable('length')) &&
                    typeof value.splice === 'function') {
                s = 'array';
            }
        } else {
            s = 'null';
        }
    }
    return s;
}

argumentsExample("a", "b");
cmcculloh
  • 47,596
  • 40
  • 105
  • 130
  • 1
    cmcculloh, it's a documented feature, nothing strange ;) – Lyubomyr Shaydariv Jan 10 '10 at 12:09
  • 2
    Yep, I assumed a lot of these were documented... Maybe not. It's still a strange language feature imo. – cmcculloh Jan 10 '10 at 19:50
  • 18
    The real WTF here is that arguments are not an Array. – Andrey Shchekin Jan 11 '10 at 10:54
  • 1
    Seems typical for allowing variable length arguments. Sort of like PHP's `func_get_args()` function, except you'd actually have to type out `$arguments = func_get_args();`. And if you really don't like cluttering up function declarations with parameters and leaving everyone who reuses your code hating you, you can do this: `function do_something() {list($var1, $var2, $var3) = func_get_args();}` – bob-the-destroyer Jun 16 '10 at 18:50
  • @cmcculloh: Hopefully all of these are documented somewhere, at least in the official language spec. – asmeurer Jan 14 '11 at 06:18
  • @Andrey Shchekin: I'm not sure what you are saying is a WTF here. The arguments passed into the function are stored behind the scenes in an array. This is fine since, in JavaScript, an array is just a numeric indicied collection of items (doesn't matter what their type is, they can all be different types if you want). The array "arguments" just holds references to each of the arguments passed in, in the order passed. It's actually brilliant and makes perfect sense. This does not preclude you from declaring parameters your function will accept, but is instead just another tool for your toolbox. – cmcculloh Jun 11 '11 at 02:05
  • 1
    @cmcculloh I mean that arguments do not use Array prototype (so they do not have any of the built-in or extension methods available to Arrays). – Andrey Shchekin Jun 13 '11 at 06:40
  • @Andrey Shchekin: Aha! I was wrong. They are not stored behind the scenes as an array, they are just a plain vanilla Object. Edited the answer to reflect this. I never would have realized this, and yes, that is odd that they made arguments a numeric indiced object instead of a full-blown array... Thanks for pointing that out! – cmcculloh Jun 13 '11 at 17:24
22

Java caches Integer object instances in the range from -128 to 127. If you don't know this the following might be somewhat unexpected.

Integer.valueOf(127) == Integer.valueOf(127); // true, same instance
Integer.valueOf(128) == Integer.valueOf(128); // false, two different instances
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Thomas
  • 759
  • 8
  • 15
21

Being able to cast out of range ints to enums in C# is quite weird in my opinion. Imagine this enum:

enum Colour
{
    Red = 1,
    Green = 2,
    Blue = 3
}

Now, if you write:

Colour eco;
eco = (Colour)17;

The compiler thinks that’s fine. And the runtime, too.

See here for more details.

Community
  • 1
  • 1
CesarGon
  • 15,099
  • 6
  • 57
  • 85
  • C# doesn't hide the fact Enums are just integers, or whatever you set it too. Int is just the default type. If they would require you to explicitly give enums a underlying type, would it look less strange? – Dykam Jan 03 '10 at 17:19
  • 2
    @Dykam: I don't think that enums in C# are *just* integers; if they were *just* integers, we would be using variables of type Int32 to use them, and we are not. Instead, we use a purposefully-created mechanism, the Enum type, that adds *some* type safety to finite lists of named constants. From a semantic point of view, the interesting things about enums is that they represent a domain of values, not that they are integers. – CesarGon Jan 03 '10 at 20:40
  • If you look at it like that it can be weird. But if you are afraid the casting will make the code error prone, don't use them... I don't use them either but am happy that the possibility is exposed. – Dykam Jan 04 '10 at 07:24
  • Might be because adding checks to make sure that bitfield enums are valid would be expensive? – Roger Lipscombe Jan 04 '10 at 16:37
  • 3
    @Dykam, @Roger: I don't disagree with either of you. Some time ago I suggested that it might be nice that enums (i.e. finite lists of named constants) and bitfields could be implemented through different syntactic mechanisms in the language rather than the same one. .NET uses the "enum" construct to implement *both* enums and bitfields (perhaps inheriting the C++ tradition) but, from a semantic perspective, a list of named constants (a proper enum) and a list of combinable 1-bit values in an integer (a bitfield) are quite different things. Different things need different language constructs. – CesarGon Jan 04 '10 at 18:50
  • Agreed, they are a different beast. Though the current way does simplify some stuff greatly. – Dykam Jan 04 '10 at 21:44
  • ill ask you, why should the compiler care if the enum fits? Most of the assignment of enums are late binding, making it impossible to know it the assignment is legal. yes they could add a small feature, for beginners. – none Nov 14 '10 at 15:33
20

I'm surprised no one mentioned the REALLY ugly switch-case implementation in most C-like languages

switch (someInt) {
    case 1:
    case 2: System.out.println("Forgot a break, idiot!");
    case 3: System.out.println("Now you're doing the wrong thing and maybe need hours to find the missing break muahahahaha");
            break;
    default: System.out.println("This should never happen -,-");        
}

The good thing is newer languages got it implemented right.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Trollhorn
  • 11
  • 3
  • 4
    I like Delphi's handling of the case statement. A single line breaks automatically, a begin starts a block of text that breaks automatically after the end. – Tom A Jan 05 '10 at 00:32
  • 10
    +1 OH GOD YES - when will they learn, it's always best to make the common case the default (no pun intended)? It would make much more sense (without breaking ANY optimizations) to leave the break out, and have a "continue" keyword for the RARE occasions that we want to actually continue onto the next case. – BlueRaja - Danny Pflughoeft Jan 05 '10 at 05:32
  • 2
    Oh, I really hate that newer languages have changed the behavior. Now when I mix loops and switch in them and put `break` there out of habit I get the bug I could never find looking at the code. – vava Jan 05 '10 at 11:18
  • 1
    @BlueRaja: `continue` has useful behaviour inside a `switch` (as does `break`), so overloading either of those words to mean either "fall through" or "leave the `switch`" is, in my opinion, a bad idea. – C. K. Young Jan 05 '10 at 18:39
  • I would actually say the *bad* thing is that newer C-based languages (C# and Java) did *not* do it right. They kept the same bad C-style `switch` statement, with a few improvements (fall-through disallowed) but still using that horrible syntax. The one thing I prefer about VB.NET over C# is its superior `Select Case` statement where each case block is a true block of code, not just the span of lines between a label and a `break` statement. – Nate C-K Jan 07 '10 at 05:31
  • @Chris: Yes I know; they could use any keyword they wanted. The point is that there should be *some* keyword needed for fallthrough, not for escaping. Since fallthrough is not allowed anyways in Java/C#, I don't see why they don't just make the 'break' statement optional (they can't disallow it due to backwards compatibility). – BlueRaja - Danny Pflughoeft Jan 09 '10 at 18:05
  • 1
    Fallthrough is actually allowed in Java. – Matthew Flaschen Mar 01 '10 at 21:57
  • Its always bugged me that `{statement;statement;}` was never enough and `break` was needed.. – Talvi Watia Jun 11 '10 at 03:58
  • Complete disagree. Newer languages have it wrong. It was right, and not at all ugly, in the earlier form. – Brian Knoblauch Mar 01 '11 at 21:05
20

x = x + 1

This was very difficult to digest when I was a beginner and now functional languages don't use it, which is even more difficult!

If you don't see how this is strange: Consider the equals sign as a statement of assertion instead of an assignment action, as you used to do in basic algebra, then this is the equivalent of saying "zero equals one".

Pratik Deoghare
  • 35,497
  • 30
  • 100
  • 146
  • 8
    Did you come from a math background prior to programming? – Erik Forbes Jan 05 '10 at 16:43
  • You can write `x = x + 1` in a functional language if you wish. http://codepad.org/7n69C5KC – Josh Lee Jan 12 '10 at 06:54
  • @jleedve But its still gives impression that 0 = 1 :) – Pratik Deoghare Jan 12 '10 at 07:58
  • 1
    I found this odd before I started programming, several years ago... Now I got used to it, and I actually like it. – luiscubal Jan 16 '10 at 00:17
  • 13
    One interpretation is that this is really x'' = x' + 1, but time is implicit in programming (bottom to top of source code), while it must be made explicit in math. – Justin Smith Jan 18 '10 at 17:57
  • 3
    Does anyone know if this is why Wirth made := the assignment operator in Pascal? – GreenMatt Jan 22 '10 at 19:49
  • 1
    @GreenMatt: Wirth probably took it from ALGOL, which might well have had := to avoid the above. – David Thornley Apr 23 '10 at 22:10
  • 1
    +1 I never had a strong math background, so this wasn't too hard for me to get used to, but I can see how it would be. – Maulrus Jun 09 '10 at 04:04
  • ...and all the variants... like `$x++;` or `$x.=1;` in PHP. (not `$x.='1'` BTW, completely different statement!) – Talvi Watia Jun 11 '10 at 03:28
  • 1
    Yes, I strongly prefer := for assignment and = for equality checking. – Andreas Rejbrand Jul 06 '10 at 12:50
  • @David, @GreenMatt - Algol used :=, as apparently did BCPL. For whatever reason Thompson and/or Ritchie decided to use = and == for B, and then C. Also note that old line number BASICs you needed to use `LET X=X+1` – Gerry Coll Oct 07 '10 at 20:40
  • As per above, maybe ':' was hard/impossible to type on the PDP7 and 11 keyboards! – Gerry Coll Oct 07 '10 at 20:48
  • 1
    Yeah, I picked up programming before algebra even, and I totally agree that this syntactic tradition is a pedagogical problem. F# (and I think OCaml) uses `<-` for assignment and `=` for constant declarations and equality, which I think is much more clear. Pascal's `:=` irked me at first too, until I tried teaching C# to beginners and discovered that the `=` not being equality was extremely frustrating to them. – Rei Miyasaka Oct 11 '10 at 20:48
  • Hmmm, never struck me as odd at all, but then I was programming before I had Algebra... Actually might explain why I had such a terrible time with Algebra I (passing by the skin of my teeth!) even though I was otherwise always really good in math... – Brian Knoblauch Mar 01 '11 at 21:03
20

Perl:

It's possible to write a program consisting entirely of punctuation.

How does this even work?!

dan04
  • 87,747
  • 23
  • 163
  • 198
  • http://infoozapps.files.wordpress.com/2011/09/zz186191f0.jpg <--- works with Lua as well, even though not entirely in punctuation. – polemon Dec 18 '11 at 16:51
19

Ok, since question will be in intermittent mode, I'll join to the "fun"

Go ( aka Issue9 ) use of upper case for visibility:

  • If you name something with uppercase it will have public access.

  • If you use lower case it will be package-protected:

Visible outside the package:

func Print(v ...) { 
}

Not visible outside the package

func print( v ... ) {
}

You can find more in this original answer.

Community
  • 1
  • 1
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
18

Here's a good bunch of strange C features: http://www.steike.com/code/useless/evil-c/

TheMagician
  • 1,846
  • 7
  • 20
  • 26
18

In Perl you can do:

my $test = "Hello World";
substr($test, 0, 5) = "Goodbye";

print $test;

Is this possible in other languages?

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
zedoo
  • 10,562
  • 12
  • 44
  • 55
  • 6
    Wow, I really want to learn Perl now after reading all these cool tips. – Kevin Jan 05 '10 at 01:23
  • So what does it print? `Goodbye World` I assume? – Tyler Jan 05 '10 at 05:39
  • Ruby: `test[0,5] = 'Goodbye'`. You could roll your own in C++ (and presumably many other languages supporting OOP). – outis Jan 05 '10 at 14:19
  • It's possible in VB6: `Mid(test, 0, 5) = "Goodbye"` – SLaks Jan 05 '10 at 16:43
  • 1
    This is called lvalue sub syntax; but for simplicity and great justice, you can also use the three argument version substr() and eliminate the equalities. There are some other wierdnesses though with the core library. my $foo = "foobar"; my @args=(0,3); substr( $foo, @args ) = "bar"; what will $foo be here, is it the same ass substr( $foo, 0, 3 )... Enjoy! – Evan Carroll Jan 05 '10 at 18:42
  • Ancient (for common internet definitions of) BASIC dialects had this already (and that's pretty much where VB* has it from). – Jürgen A. Erhard Jan 12 '10 at 04:54
  • The Idea behind is that you do a direct replacement of literals. Think of it as using the backspace or delete key to erase the characters in question, and then fill them with your replacement text. – polemon Sep 01 '10 at 20:13
  • I like to think about it like a regexp replacement: `test =~ s/^...../Goodbye/;` I know the comparison is kinda moot, but in essence, this would yield the same result, although using a completely different approach and technique. I use Regexp before any other replacement methods. – polemon Dec 18 '11 at 16:57
18

In JavaScript, seeing !!a for the first time (as a way to convert to boolean).

Andrey Shchekin
  • 21,101
  • 19
  • 94
  • 162
18

I like sneaking-in octal values in C:

int values[8] = { 123, 154, 103, 310, 046, 806, 002, 970 };
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
polemon
  • 4,722
  • 3
  • 37
  • 48
  • 1
    I've actually seen this 'in the wild', self-proclaimed hackers tend to like this oddity to obfuscate code. – polemon Aug 19 '10 at 00:46
  • 1
    What does this pattern actually mean? :-/ – letsc Dec 10 '11 at 10:23
  • @letsc The compiler automatically parses the numbers into integer literal values, but 046 and 002 are interpreted as octal numbers. Octal 2 and decimal 2 are identical so that doesn't cause an issue. But octal 046 is decimal 38. The C convention is to interpret any number beginning with a leading 0 as octal. This somewhat outdated convention can catch coders off guard. – Wedge Dec 15 '11 at 19:55
18

The C++ templating mechanism is Turing-complete: As long as you don't need input at run time, you can do arbitrary calculations at compile time. Arbitrary. Or you can easily write a C++ program that never compiles - but is syntactically correct.

Mitro
  • 1,576
  • 1
  • 13
  • 11
17

This is one of my favorites, you can do a println in Java without main().

This will compile and run, giving the println, but also an exception (java.lang.NoSuchMethodError: main)

class Test {
    static {
        System.out.println("I'm printing in Java without main()");
    }
}
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
RussellW
  • 255
  • 5
  • 8
  • 2
    So is it strange? Completely predictable behaviour. The class loader invokes the class construcor itself when it loads a class before looking-up for any method. No matter is it main(String[]), or is it any other method. Moreover, the entire application may have not the main(String[]) method - it depends to the application infrastructure. – Lyubomyr Shaydariv Jul 02 '10 at 07:50
  • @Lyubomyr: You are correct on your comment, but you used the wrong terms. It is the *free floating static block* what gets executed when the class is loaded. The class is loaded to determine whether or not a main method exists. The class loader never invokes the class constructor. – OscarRyz Jul 05 '10 at 18:19
  • @OscarRyz: Oh, I see. I'm not very familiar with Java, 'cause it's somewhat new for me. Thank you for clarification, Oscar. Now I know more. :) – Lyubomyr Shaydariv Jul 06 '10 at 20:22
  • @Lyubomyr: It is also strange because this will print out to the screen while also throwing an exception: java.lang.NoSuchMethodError: main. – RussellW Jul 07 '10 at 21:55
  • 6
    @Luybomyr Shaydariv: Yes, it is strange. The fact that it is predictable does not cure strangeness. Most of the "strange" language features listed under this question are completely predictable. – Tom Jul 08 '10 at 08:44
  • @RussellW: As far as I understand Java and JVM, it depends just a way you load the class, so if you run it as a single application, it requires `main(String[] args)` - that's why it's definitely clear why it fails with `NoSuchMethodError`. This is very similar to Turbo C++ programming techniques that allowed to specify some _before-main_ priority using some special `#pragma` directives, if I'm not wrong. – Lyubomyr Shaydariv Sep 15 '10 at 20:25
  • 2
    adding System.exit(0); to end will help you to get rid of NoSuchMethodError – asela38 Nov 11 '10 at 05:39
17

This may have been already mentioned, but --

PHP's handling of octal values:

$a = 07; // 7 (as it should be)
$b = 08; // 0 (would be an error in any sensible language)
$c = 018; // 1 (again, should have been an error)
$d = 0A; // error (as it should be)

See here: http://bugs.php.net/bug.php?id=29676

Also note the comments on the bug - Derick calls it a feature (as shown by quoting "fix"), not a bug and he claims it would "slow down PHP dramatically in all cases where numbers are used inside scripts" - but then, why does PHP raise an error for 0A?

I think one could make a whole book about the weirdness of PHP...

Tim Čas
  • 10,501
  • 3
  • 26
  • 32
17

In Java you might expect

byte b = 0;
b++;

to be equal to

byte b = 0;
b = b + 1;

But it is not. In fact you get a compiler error, as the result of the addition is of type int and therefore not assignable to the byte variable b. When using the compound operator ++ The compiler automatically inserts a cast here. So

b++;

becomes

b = (byte) b + 1;
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Thomas
  • 759
  • 8
  • 15
16

VBScript's date/time literals (why is this still so rare?):

mydate = #1/2/2010 5:23 PM#

If mydate > #1/1/2010 17:00# Then ' ...

Edit: Date literals are relative (are they technically literals, then?):

mydate = #Jan 3# ' Jan 3 of the current year

VB.NET, since it is compiled, does not support relative date literals. Date only or time only literals are supported, but the missing time or date are assumed to be zero.

Edit[2]: Of course, there are some bizarre corner cases that come up with relative dates...

mydate = #Feb 29# ' executed on 2010-01-05, yields 2/1/2029
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
brianary
  • 8,996
  • 2
  • 35
  • 29
  • Scala has XML literal notation. def xmlString = foo bar baz –  Jan 05 '10 at 01:00
  • _why is this still so rare?_ because literal date is not needed often -- time span literals would be more useful. – Andrey Shchekin Jan 05 '10 at 01:52
  • 3
    My issue with DateTime Literals is that they can be ambiguous - mydate = #10/9/2009 18:35# - October 9 or September 10? Nowadays I'm guessing it's always mm/dd/yyyy, but for non-US users it's always very odd to have a date not in dd/mm/yyyy format. In languages that have a Date constructor, you at least can always refer to the signature, but I guess it's not that different from just looking it up in the help or memorizing it. On the other hand: A whole language construct for Dates seems very "heavy". I can understand why Visual Basic has it (Office VBA), but I wouldn't see much use i.e. in C# – Michael Stum Jan 05 '10 at 03:18
  • @fennec: So does VB.NET 9, now that you mention it. – brianary Jan 05 '10 at 16:13
  • @Andrey Shchekin: I don't know, I tend to use them often enough for it to be worthwhile. Keep in mind VBScript uses relative time literals, so #Jan 5# is 2010-01-05 today. Timespan literals (beyond simple count of seconds) would be nice, too, though. – brianary Jan 05 '10 at 16:16
  • 2
    @Michael Stum: Agreed. ISO 8601 should probably be used, just to keep things clear. I guess the relative weight of language features depends a great deal on how it impacts the programmer personally. – brianary Jan 05 '10 at 16:18
  • Don't know about VB, but in FoxPro, date literals were interpreted at compile time based on the current user DATE setting, which could be changed with SET DATE DMY, SET DATE MYD etc. – Gerry Coll Oct 07 '10 at 20:54
  • @Gerry: VBScript seems unaffected by the computer's Regional settings. The US date format MM/dd/yyyy seems to be preferred when there is ambiguity, though yyyy-MM-dd HH:mm:ss works too (ISO8601 minus the 'T'). – brianary Nov 01 '10 at 18:19
16

Why does C#'s List<T>.AddRange() not let me Add elements of a subtype of T? List<T>.Add() does!
All it would take would be ONE extra line of code on Microsoft's part:

public void AddRange<S>(
    IEnumerable<S> collection
) where S : T
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
  • 4
    Not really a language feature insomuch as it is a framework feature. Pedantic, I know... – Erik Forbes Jan 05 '10 at 16:48
  • I would call it a framework design oversight - but it's definitely a WTF – BlueRaja - Danny Pflughoeft Jan 06 '10 at 02:25
  • 3
    It works with C# 4.0 due to new co- and contravariance features. – Michael Damatov Jan 06 '10 at 09:17
  • Because Interface variance and co-variance did not appear before framework 4, and it did NOT take 1 line of code. And yes, it feels like it should work, but if you think about it it makes perfect sense that it does not by default. – Denis Troller Jan 06 '10 at 22:58
  • 2
    @Denis: Try it yourself. That single line of code *does* solve *this* particular example because it is basically mimicking covariance (or contravariance, I never know which one is which). – R. Martinho Fernandes Jan 07 '10 at 02:39
  • Microsoft didn't do it back in .NET 2.0 because it would require you to specify the generic parameter S every time you used `AddRange()`. Only with the introduction of type inference (alongside .NET 3.5) were you able to omit the type parameter and so the syntactic baggage was no longer a consideration. But by then it was too late. A neat trick nonetheless. – Allon Guralnek Aug 24 '10 at 10:50
  • 1
    @Allon: no, that doesn’t use type inference and hence already worked pre-3.5. – Konrad Rudolph Oct 01 '10 at 14:10
16

In C#, this should at least generate a compiler warning, but it doesn't:

public int Something
{
    get { return Something; }
    set { Something = value; }
}

When called, it causes your app to crash, and you don't get a good stack trace, since it's a StackOverflowException.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Eric Z Beard
  • 37,669
  • 27
  • 100
  • 145
  • 33
    It's simple recursion, and one could write a perfectly valid recursively evaluated property. While the compiler could potentially be hard coded to catch some very simple cases of infinite recursion, to enforce it as a *rule* in the language would require a solution to the Halting Problem. Are you a bad enough dude to solve the Halting Problem? – David Jan 06 '10 at 13:24
  • 1
    This particular case is simple, though. If the property does nothing but get or set itself (you'd need more than that for a valid use of a recursive property), generate a warning. I've seen too many developers and even whole teams stuck on a "mysterious crash" because of this issue, which is very hard to spot in a large code base. – Eric Z Beard Jan 07 '10 at 11:45
  • 4
    I think this issue is considered fixed in the current version of the language. You should be using auto properties if your property is trivial. – Mehrdad Afshari Jan 07 '10 at 13:01
  • Mehrdad: Since auto properties can't have an initial value, the typical solution is to implement the property yourself. – Gabe Jun 09 '10 at 16:05
  • VB .NET will raise an ERROR in this case. – Joshua Aug 13 '10 at 20:43
  • @Gabe auto-implemented properties can have an initial value, you just assign them in the class constructor. – Dan Diplo Aug 20 '10 at 20:08
  • Dan Diplo: You mean assign them in *all* the class constructors (or make sure you chain them all with `:this()`). – Gabe Aug 20 '10 at 20:30
16

Variable/function declarations in Javascript:

var x = 1;
function weird(){
  return x;
  var x = 2;
}

weird() returns undefined... x is 'taken' even though the assignment never happened.

Similarly, but not so unexpectedly

function weird2(){
   var x;
   return x();
   function x(){ return 2 };
}

returns 2.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
  • this happens because of `hoisting` of the variable & function declarations – gion_13 Nov 22 '11 at 08:36
  • This is simply an example of hoisting. [Adequately Good](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting) gives a very in-depth article about hoisting. – Kevin Ji Dec 07 '11 at 02:17
15

I've written a programming language for a client (used for experimentally driving custom hardware) with some custom types (Curl, Circuit, ...) that each have only 2 values. They are implicitly convertible to boolean, but (at the request of the client) the exact boolean value of a constant of such a type can be changed at runtime.

E.g.: The type Curl has 2 possible values: CW and CCW (clockwise and counterclockwise). At runtime, you could change the boolean value by a simple assignment statement:

ccw := true

So you could change the boolean meaning of all values of those types.

Tommy Carlier
  • 7,951
  • 3
  • 26
  • 43
  • This would seem like a good idea to me (it allows things like `ccw` to be defined based on what is in actual data), but only if all such assignments are the same. Differences should be flagged as conflicts, unless there's some awesome way for the compiler to translate between modules. It does seem pretty out there at first glance, I'll agree, but it's a neat idea if you're dealing with input data whose sense you have no control over. – Mike D. Jan 04 '10 at 03:37
15

ActionScript 3:

When an object is used by its interface, the compiler doesn't recognize the methods inherited from Object, hence:

IInterface interface = getInterface();
interface.toString();

gives a compilation error. The workaround is casting to Object

Object(interface).toString();

PHP:

. and + operators. It has its reasonable explanation, but still "a" + "5" = 5 seems awkward.

Java (and any implementation of IEEE754):

System.out.println(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1);

Outputs 0.9999999999999999

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • It also means PHP has to use `->` for qualifying objects instead of the prettier `.`. – cdmckay Jan 04 '10 at 07:45
  • 3
    It's great that PHP didn't do what Javascript did with overloading the `+` operator for both string concatenation as well as addition. In PHP, if you see `+` you know you're talking about adding numbers. *...(unless you've got arrays...)* – nickf Jan 04 '10 at 08:08
  • 8
    The first one isn't a WTF - it's a gotcha that catches most people sooner or later regarding the finite-precision floating point representation on computers. – Joris Timmermans Jan 04 '10 at 13:28
  • well, the first time you see it, it's definitely a wtf :) – Bozho Jan 04 '10 at 13:33
  • 9
    And it's not a Java WTF, it's WTF for any correct(!) implementation of IEEE754. – R. Martinho Fernandes Jan 04 '10 at 14:14
  • @nickf: you know you're talking about adding numbers, even though you're actually adding strings. – R. Martinho Fernandes Jan 04 '10 at 14:15
  • @Gumbo: sure, but 0.9999999999999999 does not equal 0.999... nor 1. IEEE754 values do not have infinite precision – R. Martinho Fernandes Jan 04 '10 at 21:27
  • 1
    That's because in C# the default type for a number with a floating point is Double. Having 0.1f instead of 0.1 would give the same result. – Allon Guralnek Jan 07 '10 at 15:29
  • @nickf no, overloading is perfectly fine. Allowing "addition" with the operands being strings, that's just 100% wrong. If you convert "a" to an int, you should get an exception. And not silently 0. – Jürgen A. Erhard Jan 12 '10 at 06:34
  • Correction to my previous comment: executing Debug.WriteLine(0.1f + 0.1f + 0.1f ...) will print 1.0 because the compiler converts that expression to a constant (and when calculating it, it must be using a double). But if you use a loop to add 0.1f ten times, you will get 0.999999... – Allon Guralnek Feb 03 '10 at 14:20
  • @cdmckay actually `'a'.'5'.'...'` looks pretty in my editor because of the markup colors... `->` gets so annoying because it *appears* similar to HTML tags. Which is why `::` seems to work better for that. – Talvi Watia Jun 11 '10 at 04:54
15

Perl is full of odd but neat features.

if may be used before or after the statement like this:

print "Hello World" if $a > 1;    
if ($a > 1) { print "Hello World"; }

The same is true for foreach:

print "Hello $_!\n" foreach qw(world Dolly nurse);
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Christian V
  • 2,010
  • 17
  • 26
  • 8
    Ruby allows the same if-structures. It's one of my favourites from that language. – Matt Grande Jan 04 '10 at 18:06
  • Ruby allows this, but personally I think that consistently putting the "if" first makes code easier to read. It's just as grammatically pleasing, anyway, and you don't have to reorder if you need to add an else. – Nathan Long Jan 04 '10 at 21:03
  • 7
    I actually like the `if` modifier as it makes the programs more expressive and readable. it lets you place the more important part of the statement (the condition or the action) before the other so it is prominent. Like any feature, it is useful if used judiciously and not abused. – Prakash K Jan 05 '10 at 14:22
  • fyi, this is called mutator syntax, and is syntactically awesome: `last unless defined $row` – Evan Carroll Jan 05 '10 at 18:24
  • Good thing I can control myself, or I would start to rant on Perl... odd, sure. Neat? Not by a... okay, I shut up. – Jürgen A. Erhard Jan 14 '10 at 03:34
  • I miss that 'reverse if' syntax in other languages (c/c++). – hlynur Aug 16 '10 at 05:29
  • This syntax is taken from functional programming. Perl tries to be as multi-paradigm as possible, and with this allows for a number of functional programming bits. This is one of them. Having a good deal of experience in functional programming, I don't really see it as a strange feature, but as a nice addition from a different paradigm section. – polemon Aug 27 '10 at 11:14
  • Perl takes its postfix statement from BASIC-PLUS if you know what that is unless you want more than one of them while typing for example. – tchrist Apr 07 '11 at 21:26
15

When I was in college, I did a little bit of work in a language called SNOBOL. The entire language, while cool, is one big WTF.

It has the weirdest syntax I've ever seen. Instead of GoTo, you use :(label). And who needs if's when you have :S(label) (goto label on success/true) and :F(label) (goto label on failure/false) and you use those functions on the line checking some condition or reading a file. So the statement:

H = INPUT :F(end)

will read the next line from a file or the console and will go to the label "end" if the read fails (because EOF is reached or any other reason).

Then there is the $ sign operator. That will use the value in a variable as a variable name. So:

ANIMAL = 'DOG'
DOG = 'BARK'
output = $ANIMAL

will put the value 'BARK' on teh console. And because that isn't weird enough:

$DOG = 'SOUND'

will create variable named BARK (see the value assigned to DOG above) and give it a value of 'SOUND'.

The more you look at it, the worse it gets. The best statement I ever found about SNOBOL (from link text) is "the power of the language and its rather idiomatic control flow features make SNOBOL4 code almost impossible to read and understand after writing it. "

Jeff Siver
  • 7,434
  • 30
  • 32
  • 6
    PHP allows that aswell, $animal = "dog"; $dog = "bark"; echo $$animal; – Kristoffer Sall-Storgaard Jan 05 '10 at 13:38
  • 2
    I should've also mentioned that my university didn't have a SNOBOL compiler. Instead, we had a SPITBOL compiler. – Jeff Siver Jan 05 '10 at 14:40
  • 3
    The one time I wrote a class assignment in SNOBOL, it wasn't any fun at all. That language desperately needs better control structures, and that's far more important than having only one sort of statement (including label, main variable/value, pattern matching part or all of the former, equal sign, value to assign, and labels to jump to). – David Thornley Jan 06 '10 at 16:12
  • @Kris It would be more useful as an array `$animal[$dog][$bark]=$sound;` or class `$animal->dog->bark=$sound;` – Talvi Watia Jun 11 '10 at 03:40
  • 1
    I heard a SNOBOL anecdote of smartass programmers who used to bring their stacks of SNOBOL cards to the card reader, make a show of dropping them all on the floor, picking them up in a random pile, and drop the whole lot into the reader. SNOBOL would happily run their program as intended with no problem, while the other languages on the machine would invite the programmer to spend the evening manually sorting cards. – sarnold Jul 11 '10 at 07:14
  • Before anybody goes hating on SNOBOL, you have to remember that it dates from 1962, roughly corresponding to Fortran IV; long before structured programming was invented. If you want structured SNOBOL, I'd recommend Icon (created by the same team that created SNOBOL). – Eric Brown Aug 13 '10 at 20:50
15

In PHP "true", "false" and "null" are constants which normally cannot be overridden. However, with the introduction of namespaces in PHP >=5.3, one can now redefine these constants within any namespace but the global namespace. Which can lead to the following behaviour :

namespace {
    define('test\true', 42);
    define('test\false', 42);
    define('test\null', 42);
}

namespace test {
    var_dump(true === false && false === null); // is (bool) true
}

Of course if you want your trues to be true, you can always import true from the global namespace

namespace test {
    var_dump(\true === \false); // is (bool) false
}
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Mike
  • 31
  • 4
  • If it was global, `define("TRUE",false,false);define("true",true,false);` would be `echo(TRUE==false);//echos true` and `echo(true==false);//echos false`... `TRUE` would then mean not really true, unless its lowercase. – Talvi Watia Jun 11 '10 at 02:39
15

In Haskell:

let 2 + 2 = 5 in 2 + 2

yields 5.

user954298
  • 41
  • 1
  • 3
  • Can I get an explanation to this? – Bobby Aug 17 '10 at 10:17
  • 2
    The reason is very straightforward: In haskell, (like in most other languages) you can simply redefine a function locally (haskell treats operators in the exact same way as "normal" functions), this lets the outer operator be hidden. After this, he just pattern matches against the values 2 and 2, like it's common in haskell. For instance, `let 2 + 2 = 5 in 2 + 3` would yield a pattern matching failure. – fuz Aug 17 '10 at 10:54
  • 4
    this is the same as `let (+) = \2 2 -> 5 in (+) 2 2` – user954298 Aug 17 '10 at 12:14
14

In PHP:

echo 'foo' == 0;    // echos '1'
echo 'foo' == true; // echos '1'
echo 0 == true;     // echos '0'
$foo = 'foo';
echo $foo['bar']    // echos 'f'

PHP has some of the most annoying type coercion...

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
pib
  • 3,293
  • 18
  • 15
  • If it's not clear above, true and false are equal to 1 and 0, respectively (and their names aren't case sensitive. TRUE or FALSE or True or False also work.) – pib Jan 16 '10 at 20:04
14

LOLCODE!

The whole language itself. While not exactly a WTF thing, I've never come across a language which plays out in my head in a squeeky cartoony voice. Nor have I ever looked at code before and want to exclaim "aaaawwww cuuute!"

This program displays the numbers 1–10 and terminates

HAI
CAN HAS STDIO?
IM IN YR LOOP UPPIN YR VAR TIL BOTHSAEM VAR AN 10
    VISIBLE SUM OF VAR AN 1
IM OUTTA YR LOOP
KTHXBYE
Fahd
  • 256
  • 6
  • 15
  • Well, the language is ment as a joke, just as INTERCAL. I don't see such a great "weird feature in there"... – polemon Aug 29 '10 at 17:32
13

In C or C++ you can have a lot of fun with Macros. Such as

#define FOO(a,b) (a+b)/(1-a)

if FOO(bar++,4) is passed in it'll increment a twice.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
wheaties
  • 35,646
  • 15
  • 94
  • 131
  • 9
    `#define while if` (who needs loops?) `#define void int` ("Why is the compiler complaining about no explicit return from my `void` functions?") `#define main(argv, argc) (main)(argc, argv)` (switch argv and argc for no apparent reason) – Chris Lutz Jan 04 '10 at 07:24
  • 3
    While there are dumb things you can do with #define, there ARE perfectly valid reasons for defining it the way it was defined. As opposed to some of the other entries here... – Brian Postow Jan 04 '10 at 20:49
  • I agree with Brian, but maybe a warning indicating that you're redefining keywords wouldn't hurt anyone... – Khelben Jan 04 '10 at 21:48
  • 11
    I've seen someone on stackoverflow mention `#define private public`. – luiscubal Jan 04 '10 at 21:50
  • @Brian, yes there are very smart things you can do with define but they asked for strange things. Being able to `#define void int` is quite odd. – wheaties Jan 04 '10 at 21:55
  • 3
    @wheaties: A long time ago, in a computer lab far away, some people came up with the C language. And C was without `void` at first; `void` only really appeared with standard C. That meant there were a heck of a lot of people with old compilers who wanted to run modern C code, and `#define void int` worked well enough to run some C90 code in K&R compilers. – David Thornley Jan 04 '10 at 22:37
  • This is in the Unix Haters Handbook. – Evan Carroll Jan 05 '10 at 18:14
  • #define InterlockedIncrement(x) (x)++ http://stackoverflow.com/questions/652788/what-is-the-worst-real-world-macros-pre-processor-abuse-youve-ever-come-across – vobject Jan 08 '10 at 02:23
  • 1
    I've heard that this is actually undefined because having the decrement/increment operator(s) occur more than once in a statement apparently isn't defined. Unconfirmed. – bambams Jan 11 '10 at 21:49
13

Perl filehandle-style operator calls.

In the beginning, there was

print "foo", "bar", "baz"; # to stdout
print STDERR "foo", "bar", "baz";

Notice the ostentatious lack of a comma so that you know that's a filehandle to print-to, not a filehandle to print in a stringified manner. It's a dirty hack.

Language upgrade rolls around, they make proper OO filehandles and turn x FOO y, z, abc into FOO->x(y, z, abc). Kinda cute. The same print statement effectively runs

STDERR->print("foo", "bar", "baz");

Mostly you notice this when you miss a comma, or try to run something like hashof $a, $b, $c (subroutine call without parentheses) and forget to import the hashof function into your namespace from its utility package, and you get a weird error message about "Can't call method 'hashof' via package 'contents of string $a'".

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
  • 3
    Dealing with filehandles in Perl is inconceivably awkward. They are not scalar values or objects, but a 3rd category that lacks decent syntactical support. So, a bunch of Perl modules like `IO::Handle` were created to make them more sensible -- except these objects don't work everywhere a real filehandle would. *It's a good thing programmers don't need to work with files much.* – j_random_hacker Jan 31 '10 at 07:42
12

In Python:

>>> a[0] = "hello"
NameError: name 'a' is not defined
>>> a[0:] = "hello"
NameError: name 'a' is not defined
>>> a = []
>>> a[0] = "hello"
IndexError: list assignment index out of range
>>> a[0:] = "hello"
>>> a
['h', 'e', 'l', 'l', 'o']

These slice assignments also give the same results:

a[:] = "hello"
a[42:] = "hello"
a[:33] = "hello"
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • I agree that the a[0:] and a[42:] should raise an IndexError - but both the a[:] and a[:33] style make sense and can be usefull. – jsbueno Jan 07 '10 at 12:51
  • If a[:33] can be useful, why not a[42:]? Don't see the big difference. (And a[:] is of course incredibly useful) – Jürgen A. Erhard Jan 12 '10 at 06:35
12

Easy pickins, Erlang is full of them. For example, 3 forms of punctuation,

a_function(SomeVariable) ->
  statements_end_with_commas(),
  case PatternMatching of
    0 -> now_we_end_with_semicolon;
    true -> except_the_last_one
  end.

%%  Function definitions end with periods!
pablo.meier
  • 2,339
  • 4
  • 21
  • 29
  • I guess I should add that this isn't a language feature, per se, more of an odd choice in syntax. If I had to pick an odd language feature of Erlang, it would be the representation of strings as lists of integers. Meaning [80,97,117,108]. => "Paul". I wonder what implications this had for Facebook Chat, if any? – pablo.meier Jan 06 '10 at 21:26
  • A C string is also just a list of integers, sort of. – Tor Valamo Jan 10 '10 at 19:55
12

In JavaScript (and Java I think) you can escape funny characters like this:

var mystring = "hello \"world\"";

If you want to put a carriage return into a string though, that's not possible. You have to use \n like so:

var mystring = "hello, \nworld";

That's all normal and expected- for a programming language anyway. The weird part is that you can also escape an actual carriage return like this:

var mystring = "hello, \
world";
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Breton
  • 15,401
  • 3
  • 59
  • 76
  • 2
    The same as good old C syntax. But remember that standard HTML expects CR+LF (`"\r\n"`) newlines. – David R Tribble Jan 07 '10 at 03:28
  • 10
    @Loadmaster: sure you didn't mean HTTP? afaik HTML is line-separator-agnostic – Christoph Jan 10 '10 at 14:01
  • It's quite handy, actually, when you need to define a veeeeery long string without messing with string concatenation operators. – Helen Feb 08 '10 at 19:26
  • @Helen except that it kind of breaks down if you want to minify or do any other sort of automated whitespace manipulation. – Breton Feb 08 '10 at 21:57
  • Beware, that while this works in many browsers, it is not part of the ECMAScript standard. See: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml#Multiline_string_literals – martineno Dec 15 '11 at 19:13
  • Actually it /is/ part of ecmascript 5. That doesn't mean you should use it (you shouldn't), but what you say is incorrect @martineno – Breton Dec 16 '11 at 00:46
  • @abahgat maybe they had the sense to remove it. I found that it works in C as well. – Breton Dec 16 '11 at 00:49
  • @Breton you are absolutely correct. I went and read the standard docs. It wasn't in ECMAScript 3, but has been with us since ESMAScript 5, which was published in Dec. 2009. I wonder which older browsers reliably support this notation. – martineno Dec 16 '11 at 04:52
  • Its always been in most/all browsers. The difference now is that it's documented in the standard. – Breton Dec 17 '11 at 03:53
12

More of a platform feature than a language feature: on the iPhone, create an infinite loop with a few computations inside and run your program. Your phone will heat up and you can use it as a hand-warmer when it's cold outside.

Imagist
  • 18,086
  • 12
  • 58
  • 77
12

In C or C++, parentheses are optional for the argument to sizeof ... provided the argument isn't a type:

void foo() {
  int int_inst;

  // usual style - brackets ...
  size_t a = sizeof(int);
  size_t b = sizeof(int_inst);
  size_t c = sizeof(99);

  // but ...
  size_t d = sizeof int_inst; // this is ok
  // size_t e = sizeof int; // this is NOT ok
  size_t f = sizeof 99; // this is also ok
}

I've never understood why this is!

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
tragomaskhalos
  • 2,733
  • 2
  • 17
  • 10
12

Bracket identifiers in VBScript

VBScript has so-called bracket identifiers, which are identifiers defined enclosed in square backets, like this:

[Foo]

They're quite handy, actually, as they allow you to name variables and routines after reserved words, call methods of third-party objects whose names are reserved words and also use almost any Unicode characters (including whitespace and special characters) in identifiers. But this also means that you can have some fun with them:

[2*2] = 5

[Здравствуй, мир!] = [Hello, world!]

[] = "Looks like my name is an empty string, isn't that cool?"

For[For[i=0]=[0]To[To[To[0]
  [Next[To]([For[i=0])=[For[i=0]
Next

On the other hand, bracket identifiers can be a gotcha in case you forget the quotes in a statement like this:

If MyString = "[Something]" Then

because If MyString = [Something] Then is a perfectly legal syntax. (And that's why an IDE with syntax highlighting is a must!)


More info on bracket identifiers in Eric Lippert's blog:

Community
  • 1
  • 1
Helen
  • 87,344
  • 17
  • 243
  • 314
  • Hm... In pure mathematics, [x] is sometimes used to denote a very "formal" interpretation of x, as in [0/0] and [∞/∞] (two interesting cases of limits of fractions). Although I am aware of no precise definition of [], I would say something like "I mean exactly what I write, but do not try to interpret it literally". Related? – Andreas Rejbrand Jul 06 '10 at 13:46
12

C/C++:

The Fast Inverse Square Root algorithm takes advantage of the IEEE floating-point representation (code copied from Wikipedia):

float InvSqrt(float x)
{
    union {
        float f;
        int i;
    } tmp;
    tmp.f = x;
    tmp.i = 0x5f3759df - (tmp.i >> 1);
    float y = tmp.f;
    return y * (1.5f - 0.5f * x * y * y);
}
Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Jaime Soto
  • 3,168
  • 1
  • 21
  • 19
11

In earlier version of Visual Basic, functions without a "Return" statement just "Return None", without any kind of compiler warning (or error).

This lead to the most crazy debugging sessions back when I had to deal with this language on a daily basis.

Adrian Kosmaczewski
  • 7,956
  • 4
  • 33
  • 59
  • 3
    Oh *man* this sucked. I was so glad they pulled that out in later versions of VB.NET. They really should have just created VB.Sharp and left the compatibility argument on the table. – Jeff Atwood Jan 04 '10 at 20:21
  • I'd say the return statement that lets you return a value is one of my favorite improvements of VB.NET over VB6. (My #1 favorite is exceptions vs. On Error Goto.) – Nate C-K Jan 07 '10 at 05:35
  • This is also one of python's features. In a strongly typed language it wouldn't be so bad, and one could actually argue that it's good because it makes things more uniform (all functions have a return value), but with dynamic typing it always causes me headache. – Joseph Garvin Jan 07 '10 at 15:47
11

in PHP the strings letters cannot be used like in C, you need to use ord() and chr() in order to convert from number to char and vica versa: "a" != 97, but ord("a") == 97.

Although, there is one exception:

for ($i = 'a'; $i < 'z'; $i++) {
    print "$i ";
}

will print letters a to y. just like you would expect as if it was C style datatypes.

however if the test condition is changed to <= it will not print a to z as you would think, but a to yz! (total 676 items printed)

also if you change the 'z' to 'aa' which came out next after 'z' in the 676 items list, and change test condition to < again, you will see only "a" being printed out! not a to z as you would expect.

And if you change the incrementor to $i+=2 it will print only "a" again! only way to do that is to use $i++, $i++ in sequence, and now it works like expected.

Nevertheless, this is a nice way in PHP to output combinations of letters a-z, although its very hard to actually use it.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
11

String math in Perl is pretty weird.

$ perl -E '$string = "a"; $string++; say $string'
b

$ perl -E '$string = "abc"; $string++; say $string'
abd

$ perl -E '$string = "money"; $string++; say $string'
monez

$ perl -E '$string = "money"; $string--; say $string'
-1
Nathan
  • 3,842
  • 1
  • 26
  • 31
11

In PowerShell, you can rename variables:

> $a = "some value"
> $b = "a"
> $c = "d"
> Rename-Item variable:$b $c
> $d
some value

Indirect indirection! Take that, PHP!

Literals work, too:

> Rename-Item variable:d e
> $e
some value
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • Yeah, PowerShell drives me mad. I wrote to them about the syntax one time. They responded, somewhat evasively: http://blogs.msdn.com/b/powershell/archive/2006/07/23/issues-with-windows-powershell-syntax.aspx – Rei Miyasaka Nov 20 '10 at 00:20
  • The worse part is that, despite the WTFs, PowerShell looks clean when compared to other shells (sh, bash, csh, tcsh, comd.exe, etc.) and Perl. Ever tried to understand Bash's $(()), $(), [[]], etc.? – marcus Jun 13 '11 at 20:48
  • @marcus: Yes, see my answers [here](http://stackoverflow.com/questions/3869072/test-for-non-zero-length-string-in-bash-n-var-or-var/3870055#3870055) and [here](http://stackoverflow.com/questions/2188199/bash-double-or-single-bracket-parentheses-curly-braces/2188369#2188369) for examples. – Dennis Williamson Jun 15 '11 at 11:25
10

The bigest collection (today 1313) of decent and weird programming languages I know, you will find here: http://99-bottles-of-beer.net/ be prepared to see real weird stuff ;-) Everybody should make his one choice

stacker
  • 68,052
  • 28
  • 140
  • 210
10

Ruby

Time.parse often pretends that the parsing did not fail, returns now instead

require 'time'

Time.parse '2000-01-01 12:00:00'
# -> 2000-01-01 12:00:00 +0100

Time.parse '2000-99-01 00:00:00'
# -> ArgumentError: argument out of range ...

Time.parse 'now'
# -> 2010-08-13 21:26:13 +0200

Time.parse 'yesterday'
# -> 2010-08-13 21:26:18 +0200

Time.parse 'billion years ago'
# -> 2010-08-13 21:26:37 +0200
asmeurer
  • 86,894
  • 26
  • 169
  • 240
mykhal
  • 19,175
  • 11
  • 72
  • 80
10

Early FORTRAN where whitespace was not significant. (The anti-Python!)

DO 20 I = 1, 10

Meaning: loop from here to line 20 varying I from 1 to 10.

DO 20 I = 1. 10

Meaning: Assign 1.10 to the variable named DO20I.

Rumors are that this bug crashed a space probe.

Darron
  • 21,309
  • 5
  • 49
  • 53
9

In my opinion this should not be allowed in C++:

class A {
public:
  virtual string foo(){return "A::foo";}
};

class B : public A {
public:
  virtual string foo(){return "B::foo";}
};

int main () {
  B* b = new B();
  // In my opinion the following should not be allowed
  cout << b->A::foo() << endl;  // Will print "A::foo"
}

This may seem right, but this means that you cannot override a method without allowing users of the subclass to call the original method instead of the new one.

Just think about a subclass of a collection where you want to increment the number of elements when adding an element to the collection itself.

A logical solution would be to override the add() method to increase the counter before adding the element, but a user of the new collection could add an element to it using the old method so bypassing your increment and resulting in your elements-counter disagree with the actual number of elements of the collection.

This is not possible in Java.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Andrea Zilio
  • 4,444
  • 3
  • 29
  • 34
  • 6
    I think who ever downvoted this two times should give some reasons why he did - I can't see anything wrong. – Lena Schimmel Jan 03 '10 at 20:29
  • 17
    Just more examples of trying to make object-orientation do things it's not supposed to be doing. The syntax makes it very clear that you are purposely calling the *base* function. If you really don't want that to happen, the two classes are most likely not Liskov-Substitutable, and you should be using protected or private inheritance which disallows this construction, or even aggregating the "A" inside a completely new object so that A is not available from the outside. – Joris Timmermans Jan 04 '10 at 13:39
  • @MadKeithV I don't agree with you :) I think that in fact the two classes should be obviously subtypes by the point of view of OOP and so substitutable. You're right that making an Adapter (by aggregating A) or with implementation-inheritance you have control over the situation, but this way you loose the useful subtype relation and this only because of this, in my opinion wrong, behavior of C++. In Java or other OOP languages this problem does not exist because you can call, from the outside, only the newest method. – Andrea Zilio Jan 04 '10 at 14:55
  • 16
    You seem to be taking an attitude opposite Stroustrup's. Stroustrup didn't worry about features having the potential for misuse, provided they were sufficiently useful. C++ is full of abusable features. – David Thornley Jan 04 '10 at 22:39
  • 1
    @David You are right. Every choice made by language designers make sense from their point of view: here I'm just saying that in this specific case I have a different opinion and that I don't agree with the language designer. I really think that this is violation of the way it was intended to work in general OOP and the fact that Stroustrup decided to allow this make me feel a bit unconfortable. Don't you have fear of the fact a user of your class can call a LESS specific version of a method you've overrided? Because in some cases I do :) – Andrea Zilio Jan 05 '10 at 02:42
  • mentioned http://stackoverflow.com/questions/1995113/strangest-language-feature/1996486#1996486 – Evan Carroll Jan 05 '10 at 18:21
  • @EvanCarroll No: this one is a different problem ;) – Andrea Zilio Jan 06 '10 at 12:53
  • 1
    @Andrea Zilio: Personally, it doesn't bother me, because to get this weird behavior the programmer had to write something obviously weird. Anybody can write bad code in any language; the benefits languages provide in this case are to make writing better code easier and to make worse code more obvious. – David Thornley Jan 06 '10 at 16:07
  • 1
    I agree with David, the C++ design philosophy is not to restrict what the programmer can do just because their decisions might be dangerous or wrong. While I personally wouldn't follow this philosophy myself and am not a fan of C++, the language's success over the years certain vindicates this as useful way of doing things, if perhaps not the ideal way. – Nate C-K Jan 07 '10 at 05:19
  • 4
    There's a simple solution for this: make `foo()` protected in the base class (and rename it `foo_core()` or something). Then define a public non-virtual `foo()` in the base class that calls the protected virtual one. – munificent Jan 07 '10 at 16:17
  • 2
    munificent is right -- you should try to avoid making virtual methods public. This makes it easier for the base class to enforce constraints on derived classes (e.g. via the Template Method pattern). Guru Herb Sutter explains: http://www.gotw.ca/publications/mill18.htm – j_random_hacker Jan 31 '10 at 07:12
  • 1
    I don't think this is a strange language feature. – kirk.burleson Sep 11 '10 at 16:27
9

Java's access modifiers are a recent WTF to me (as I had to learn a bit of it).

Apparently packages are more intimate than class hierarchies. I can't define methods and attributes that are visible to sub-classes but not to other classes in the package. And why would I want to share the insides of a class to other classes?

But I can define attributes and methods that are visible to every class inside the package, but not to subclasses outside the package.

No matter how hard I think about this, I still can't see the logic. Switch over the access modifiers and make protected act like it works in C++ and keep the package private modifier as it is and it would make sense. Now it doesn't.

Makis
  • 12,468
  • 10
  • 62
  • 71
  • 11
    The logic is pretty obvious to me: not a class, but a package is a unit of maintenance. Hiding members from subclasses effectively reserves the right for the maintainer to remove or rename them without breaking code in subclasses, which is pretty useful if those subclasses are in a different package, and were probably written by completely different people at a completely different time and place. The package maintainers may not even know the subclass exists at all. – reinierpost Jan 04 '10 at 09:18
  • So only one person can update a package? Considering how large even some Java base packages are, that's a tall order. – Makis Jan 04 '10 at 10:49
  • @Makis: "the maintainer" is the group that's responsible for the package (perhaps it should have been "the maintainers"). Programmers writing subclasses outside this group shouldn't have to worry about package internals. – outis Jan 05 '10 at 14:11
  • 1
    Well, I still don't understand why that is better. Unless we keep packages really small, the problem is the same as in any application development: what you want to use OO for is exactly what this is countering. – Makis Jan 05 '10 at 18:53
  • I always considered this strange too. The only reason I could thought up is the strict order of modifiers: public > protected > package > private – user57697 Jan 07 '10 at 11:10
  • @joppux: protected is not strictly > than package. Package allows access from places protected doesn't and vice-versa. – R. Martinho Fernandes Jan 07 '10 at 18:55
9

In C:

warning C4013: 'myfunc' undefined; assuming extern returning int

I remember for some reason not seeing warnings (too much of them in some legacy code?) and puzzling over why conversion from int causes compiler error where non int-returning function is used.

Compiler assuming such stuff was quite unexpected.

Andrey Shchekin
  • 21,101
  • 19
  • 94
  • 162
  • The compiler has to assume *something* about undefined symbols in order to continue parsing. The most reasonable guess for an undeclared function is one returning int taking unspecified parameters. – David R Tribble Jan 07 '10 at 03:31
  • I am ok with parser assuming that while parsing, but later, when all symbols are being resolved, it should cause an error instead of being propagated through the full compilation pipeline. – Andrey Shchekin Jan 07 '10 at 11:23
  • Ah, the "later" part is where it gets fun -- the original C compiler was a single-pass program. See code, output assembly. This is why all functions are assumed to take whatever arguments are used and return an int in K&R C unless the compiler has been told otherwise. Needless to say, ISO C prototypes were a vast reliability improvement at the cost of forcing compilers to be much smarter and assume less. – sarnold Jul 11 '10 at 07:17
9

Reading a line from a text file in Java.

BufferedReader in = null;
try {
   in = new BufferedReader(new FileReader("filename"));
   String str;
   str = in.readLine();
   if (str != null) {
      ...
   } 
} catch (IOException e) {
   ...
} finally {
   try {
      if (in != null) {
         in.close();
      }
   } catch (IOException e) {}
}

Ugh. Although I admit it is not strange...just evil. :-)

A shorter, more idiomatic version:

try {
   BufferedReader in = new BufferedReader(new FileReader("filename"));
   try {
       String str = in.readLine();
       while (str != null) {
          str = in.readLine();
       } 
    } finally {
        in.close();
    }
} catch (IOException e) {
    e.printStackTrace();
}
wds
  • 31,873
  • 11
  • 59
  • 84
Tomas Brambora
  • 1,056
  • 8
  • 17
  • 1
    So much code and you still got it wrong. ;) The close() call would better be inside a finally section to make sure the file handle gets released also in case of an exception is thrown. – x4u Jan 06 '10 at 23:16
  • Fair enough, fixed. Hopefully. :-) – Tomas Brambora Jan 07 '10 at 10:31
  • 1
    Now it does not compile because 'in' can be uninitialized; so you have additionally to initialize it to null and check it in finally (3 more lines!). More than that, close() errors should be handled too! – user57697 Jan 07 '10 at 11:21
  • Don't initialise it to null, take the resource acquisition out of the try-finally. – Tom Hawtin - tackline Jan 09 '10 at 04:01
  • I added how I would write it. I left the other version in though, cause that it is so hard to get right is exactly the point. – wds Jan 22 '10 at 08:53
  • 3
    Perl's while(<>){print;} never looked better. – sarnold Jul 11 '10 at 07:40
9

For me it's definitely the PLEASE modifier in INTERCAL. If PLEASE does not appear often enough, the program is considered insufficiently polite, and the error message says this; if too often, the program could be rejected as excessively polite.

Doc Snuggles
  • 241
  • 1
  • 3
  • 15
9

PHP as an entire language is mostly WTF.

The langauge definition is defined,(see www.php.org) not by a grammar, or a standard, but by a bunch of "you can write this example" sections (can you write anything else, sure, just guess at the generalization), with honest-to-god user contributions saying "but it does this wacko thing ...".

I periodically encounter glitches with a PHP parser we built. Here's the latest:

 "abc$A[define]def"

Now, PHP is a (truly bad) copy of PERL, and so it allows strings to be constructed with implicit substition of variables. $X in the string says "plug the value of $X into the string", equivalent to "abc" . $X . "def" where "." is PHP's string-concatenate operator.

$A[7] in a string says, "plug the value of the seventh slot of array $A into the string",equivalent to "abc" . $A[7] . "def".

Now, the language (website) clearly says "define" is a keyword, and you can't use it whereever you'd find an expression. So the above gem containing "define" does what? Throw a syntax error? Nah, that would make sense.

No, what it actually means is:

 "abc" . $A["define"] . "def"

It does this ONLY if you write an thing that looks like an identifier (keyword or not!) in an simple array access in a string. Nowhere else in the language does this behaviour occur. What, writing "abc$A["define"]def" was unreasonable so the PHP inventors had to throw this in? Give me a break. (To compound the felony, there's "complex array access in a string" and of course it works differently. Check out "abc{$A[define]}def"; that is illegal according to the PHP website.

(Turns out PHP arrays are associate hashes, so looking up an array (well, hash table) member by name isn't a terrible idea).

The language is full of gotchas like this. If you like "gee, look what squirmy thing I found under my subroutine today", you should switch to PHP.

Ira Baxter
  • 93,541
  • 22
  • 172
  • 341
  • 3
    That makes sense considering $a['test'] and "$a[test]" are also equivalent. But one does wonder why PHP has so many "features" that don't add any real benefit but just lead to unexpected or unpredictable behavior... – Kevin Mar 17 '10 at 05:25
  • It does? No it doesn't. The distributive law does not apply logically to quote marks, regardless of the fact that your example is valid in PHP. I agree, it is also full of useless junk. (In 5.x, they actually added 'goto'! What, the language didn't work before that? Have you seen the new, kewl, NOWDOC strings? What a waste of time. ) – Ira Baxter Mar 17 '10 at 05:44
  • `define` isn't a keyword in PHP, it's a function. Sure, it's an incomprisable primitive too but it's still a function. – Ollie Saunders Mar 23 '10 at 03:27
  • I normally pretty careful. I'll swear I looked at this page http://www.php.net/manual/en/reserved.keywords.php when I wrote my diatribe and 'define' was in the list. Maybe I was on drugs, because it isn't there now. However, if you replace 'define' in my example by any of the official keywords listed, you get the same problem. – Ira Baxter Mar 23 '10 at 14:51
  • I prefer my PHP with no `define`. I just keep a `globals.php` file. Keep it `$variables`! – Talvi Watia Jun 11 '10 at 01:34
  • I started disliking PHP the time I wrote a calendar. I left the $ off of a variable in my `isLeapYear()` function. Rather than being an error, it made the function always return true. – dan04 Jun 11 '10 at 07:20
9

Found while learning PowerShell:

Try to guess what the resulted array look like:

$a = 1, 2
$b = 1, 2+3
$c = 1, 2*3

Answers:

1, 2
1, 2, 3
1, 2, 1, 2, 1, 2

Ouch! It shakes my faith in PowerShell and people behind it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Codism
  • 5,928
  • 6
  • 28
  • 29
  • 1
    That's just the comma operator binding more tightly than the arithmetic operators. e.g. `$b = 1, 2+3` is the same as `$b = (1, 2)+3`. You were possibly expecting: `$b = 1, (2+3)` – Eclipse May 28 '10 at 20:08
  • 9
    I understood why it's working that way. But didn't understand why it was designed in that way. – Codism May 28 '10 at 21:11
  • 1
    Wow, this is totally mind-boggling! It's like they were trying to redefine the opposite of intuitive. They've done it, too! – Michael Foukarakis Jul 21 '10 at 15:27
9

In JavaScript this:

var something = 12;

function nicelyCraftedFunction()
{
  something = 13;
  // ... some other code
  // ... and in Galaxy far, far away this:
  if( false ) // so the block never executes:
  { 
    var something; 
  }
}
nicelyCraftedFunction(); // call of the function

Normally you would expect that something variable will get value of 13. But not in JavaScript - variables there have function scope so later declaration affects everything up-stream.

In languages that use C/C++/Java notation (like JS) you would expect variables having block scope, not like this ...

So dead block of code that compiler can even remove from final generated bytecode still have side effects in the rest of code that executes normally.

Therefore something will be still 12 - not change after invocation of the function.

c-smile
  • 26,734
  • 7
  • 59
  • 86
  • 1
    Your original answer doesn't state what `something` actually gets, leaving the reader to wonder what is the strange result of this language feature. – John K Aug 15 '10 at 22:06
  • 2
    Outer variable 'something' will not change after execution of the function. So 'something = 13;' does nothing in this sample. As soon JS sees 'var something' *anywhere* in function body it will think that it is a local (for the function) variable. – c-smile Aug 16 '10 at 04:32
8

Unary operators in INTERCAL (AND, OR and XOR).

river
  • 1,508
  • 1
  • 12
  • 17
  • 1
    Since when are AND, OR, XOR unary operators? They need at least two operands which also could be given implicitly, which might be the case in intercal – codymanix Jan 05 '10 at 02:27
  • 13
    From http://en.wikipedia.org/wiki/INTERCAL#Operators: "Contrary to most other languages, AND, OR, and XOR are unary operators, which work on consecutive bits of their argument; the most significant bit of the result is the operator applied to the most significant and least significant bits of the input, the second-most-significant bit of the result is the operator applied to the most and second-most significant bits... and so on." That said, all of INTERCAL is an intentional WTF. – Frank Szczerba Jan 05 '10 at 14:55
8

In MUMPS you can have a GOTO with offset. If you have (my MUMPS is rusty...)

some_label if x=1 do_something
           else  do_something_else

Then the code

           goto some_label+1

Will jump to the ELSE statement...

8

I'm fond of the lack of operator precedence in Smalltalk

2 * 3 + 4 * 5 = 6 + 4 * 5 = 10 * 5 = 50

instead of

2 * 3 + 4 * 5 = 6 + 4 * 5 = 6 + 20 = 26

This is due to the object nature of smalltalk and the fact that messages are passed left to right. If the message * is sent to the 2 with the number 3 as a parameter, the response of that message is 6. Pretty awesome, you can even monkey patch it if you're feeling evil.

dvincelli
  • 148
  • 2
  • 6
8

In SQL

NULL is not equal to NULL

So you can't do:

WHERE myValue == NULL

This will always return false.

NULL != NULL
Stephane Grenier
  • 15,527
  • 38
  • 117
  • 192
  • 9
    It makes perfect sense. I have should have two values but I don't know what they are. Are they the same value? I DO NOT KNOW. – Tom Hawtin - tackline Jan 09 '10 at 03:05
  • @Tom: but Null is a defined value: the absence of anything else. There should be another value for this. – RCIX Jan 10 '10 at 10:09
  • 3
    @Tom if you don't know what it is, then what's it doing in the database? – Breton Jan 10 '10 at 23:09
  • NULL should be denoted by 0/0 – Kamil Szot Jan 11 '10 at 23:35
  • 1
    No, NULL is NULL. And it's not equal to NULL, because it's not really a value. And it doesn't mean "I don't know" it just means "There is no value for this column in this row". – Jürgen A. Erhard Jan 12 '10 at 06:56
  • Really, SQL uses three-valued logic. So the result of a comparison can be true, false or NULL. The result of myValue = NULL is always NULL, and so is the result of myValue != NULL. – Derek Ledbetter Jan 12 '10 at 22:23
  • The problem is there's more than one sensible way to define the meaning of NULL (as shown by the above comments) and those different meanings imply different semantics for things like equality tests. There is no way to satisfy all interpretations at once. – j_random_hacker Jan 31 '10 at 07:23
  • 2
    The real WTF is using `==` in SQL. – Talvi Watia Jun 11 '10 at 02:21
  • Comparisons to `NULL` make sense if `NULL` is interpreted as unknown. But SQL isn't consistent about that. (If it were, `SUM` would return `NULL` if any summed value is `NULL`.) – dan04 Jul 16 '10 at 10:07
  • The real WTF is that fact that it is valid sql, that returns nothing. It ought to be at least a warning. – EvilTeach Aug 13 '10 at 00:14
  • 1
    Use IS and IS NOT for comparing NULLs. – signine Aug 17 '10 at 13:01
8

Forth has some strange things about its control structures. First, because it is a reverse polish notation language, the condition precedes the IF, as in:

x 0 = IF

Now, to close the conditional block, one uses the keyword THEN:

x 0 = IF ." Equals zero!" THEN

Now the real WTF begins. What IF does is compile a conditional forward jump, and place on a stack the address of the jump offset. When THEN is found, it pops that address from the stack, computes the actual offset, and then compile that. The ELSE, on the other hand, compiles an inconditional forward jump, pops an address from the stack, pushes a new address on the stack, computes the offset for the popped address, and then compiles that offset. Meaning the syntax is this:

x 0 = IF ." Equals zero!" ELSE ." Not equal to zero!" THEN

The first and second statements are compiled like this:

x LITERAL 0 = (0BRANCH) LITERAL offset SLITERAL" Equals zero!" (DOTQ)
x LITERAL 0 = (0BRANCH) LITERAL offset SLITERAL" Equals zero!" (DOTQ) BRANCH LITERAL offset SLITERAL" Not equal to zero!" (DOTQ)

To compound the weirdness, that behavior is not hidden. It is part of the ANSI specification of the language, and can be freely be taken advantage of, either by constructing custom flow control structures or by combining them in interesting ways. For example, take Forth's WHILE loop:

BEGIN x 10 < WHILE x 1+ to x REPEAT

The part between BEGIN and WHILE is arbitrary code, so you can actually have code execute before and after the conditional test in a single control structure. That's by design, but the following, though allowed, is not:

BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN 

Which takes advantage of how each control flow word works to combine two WHILE statements, and, to boot, add a different post-loop code for each exit. And just to show I'm not kidding, I just copied that small snippet from a code on the Internet, with minor modifications to simplify it.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
8

In MAXScript, all operators are treated equal. So, a = b + c sets a equal to b, then calculates the sum a+c, and discards the result.

eduffy
  • 39,140
  • 13
  • 95
  • 92
8

Inform 7. An example of a valid program:

    Chomsky is a room. 
    A thought is a kind of thing. 
    Color is a kind of value. 
    The colors are red, green and blue. 
    A thought has a color. It is usually Green. 
    A thought can be colorful or colorless. It is usually colorless. 
    An idea is a thought in Chomsky with description "Colorless green ideas sleep furiously." 
    A manner is a kind of thing. 
    Furiously is a manner. 
    Sleeping relates one thought to one manner. 
    The verb to sleep (he sleeps, they sleep, he slept, it is slept, he is sleeping) implies the sleeping relation. 
    Colorless green ideas sleep furiously. 

Other silliness like this Turing machine simulator can be found.

Igby Largeman
  • 16,495
  • 3
  • 60
  • 86
sehugg
  • 3,615
  • 5
  • 43
  • 60
8

C++1x Lambda's:

[] (int x) { std::cout << x << std::endl; } ();

These can be abused for some odd syntax:

[](){}();[]{[]{}();}();

This is completely valid C++1x.

Joe D
  • 2,855
  • 2
  • 31
  • 25
  • 1
    I'm assuming that example does nothing? Bonus points if you can write a fork bomb out of that syntax a la BASH `:(){ :|:& };:` – new123456 Dec 19 '10 at 03:49
8

By far the strangest feature I've ever encountered was a "RETURN n" statement in a dialect of BASIC (don't remember which one, this was about 28 years ago). "n" was optional and defaulted to 1. It could be a positive or negative number that indicated which line relative to the invoking GOSUB is the next to get executed.

For example the following would output "30":

10 GOSUB 200
20 PRINT "20"
30 PRINT "30"
100 END
200 RETURN +2

I encountered this when I had to translate a program written in this bizarre BASIC to FORTRAN. The BASIC program used this feature quite a bit to return to different statements based on various conditions and it took me a while to understand the logic flow. Once I understood it, I was able to write a much simpler version of the program. Needless to say, the simpler FORTRAN version had fewer bugs than the original BASIC program.

joast
  • 3,048
  • 2
  • 24
  • 16
8

In PHP:

for ($s="a";$s<="z";$s++) echo $s.' ';

This will write:

a b c d e .. .w x y z aa ab ac ad .. ay az ba bb bc ... by bz ca cb ... yz za zb ... zx zy zz
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
poiuyttr
  • 110
  • 1
  • 4
  • because PHP follows perl' convention dealing with increments on a string variables. so, $s = 'z'; echo ++$s; will return 'aa'. but strings are compared as strings, so 'aa' is less than 'z'. – poiuyttr Aug 15 '10 at 10:29
8

The designers of VB.NET did several really dumb things to maintain backwards compatibility with Visual Basic 6.0. Of course, not enough that it actually was compatible, just enough to make things more counter-intuitive. But the worst of them was the fact that you don't have to initialize variables because they already are, except on those rare occasions when they are not.

    For i As Integer = 1 To 3
        Try
            Dim k As Integer
            k += 1
            MsgBox(k)
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    Next

This will print 1 2 3.

Having a feature you can't trust 100% of the time is not a feature, it's a bug. Saying it's as designed just makes it a design bug, not an implementation bug.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dwidel
  • 1,264
  • 1
  • 12
  • 22
  • 3
    The reason is the lifetime of a variable is per function, it's not the same as the scope. I knew that before, it's true in all .NET, I think. The part that wasn't obvious to me is why it would automatically reuse the same variable and not initialize it. The scary thing is no one I've met seems to know about this behavior, and I have seen this bug in production code. – dwidel Dec 30 '10 at 20:24
7

I once wrote a programming language that had a "strfry" operator:

"hello world"?
# => "wdo rlholle"

Useful, eh?

Bob Aman
  • 32,839
  • 9
  • 71
  • 95
7

Another C-ism.

int i= 0;
while( i != 12 ) {
    /* Some comment 
    i += 1;
    /* Another comment */
}

Why doesn't it work? Lint will tell you. The C compiler, however, usually passes over this blithely. As did I.

That was a real WTF moment when I figured out what was wrong.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • 1
    This problem is easy to detect with a good IDE, but it can be difficult in legacy systems... – Khelben Jan 04 '10 at 21:53
  • 1
    I don't get what is odd about it? – Dykam Jan 04 '10 at 21:54
  • @Dykam: run it through lint. @Erik: The multi-line comment as a feature of C is not unique. However, some languages (like Python) don't support multiline comments to avoid this problem stemming from the feature. – S.Lott Jan 04 '10 at 22:32
  • Can someone explain what the problem is? Naturally I would assume that i += 1 is not executed as it's in a Multi-Line comment (Which isn't a strange concept to me), but I also vaguely remember some rules about not allowing nested comments. But the Syntax Highlighting on SO is exactly how I would perceive it - are Multiline Comments really such a big "WTF?" to people? – Michael Stum Jan 05 '10 at 01:13
  • 3
    @Michael Stum: Yes, multi-line comments that are incorrectly terminated are a total WTF. Syntax highlighting, BTW, is very new technology. And it does help. However, many of us have been programming for decades prior to the invention of syntax highlighting. – S.Lott Jan 05 '10 at 01:48
  • 4
    @BlueRaja: When I learned C, IDE's hadn't been invented. Seriously. When I learned COBOL the word-processor hadn't been invented. It's nice to say that "tools fix this problem". They don't fix the problem. They expose the problem a little more clearly. The problem still exists, and related problems in languages like Java still cause WTF moments when helping n00bs. – S.Lott Jan 05 '10 at 11:00
  • 8
    I like that the code highlighting here on SO makes the problem quite clear! – Michael H. Jan 05 '10 at 18:05
  • What I used to rely on was a compiler or lint message (can't remember which at the time) that would flag a `/*` inside a comment as a warning. It was a good warning to pay attention to. – David Thornley Jan 06 '10 at 16:15
  • @David Thornley: Nice if you have such a warning. Epic WTF when I didn't have such a warning. – S.Lott Jan 06 '10 at 16:54
  • uhh.. I don't get it, is it that when viewed without syntax highlighting the programmer *thinks* it was already closed or what? – OscarRyz Jun 11 '10 at 02:36
  • @Support - multilanguage SO. Try it in a non-syntax highlighting editor. Tell me what you see. – S.Lott Jun 11 '10 at 02:53
  • my editor will show WTF if I try `// comment... */` instead of `*/` being on its own line, as the close-comment can skip if its commented. another nice-to-have. – Talvi Watia Jun 11 '10 at 04:03
  • @S.Lott, that's what I thought, :) – OscarRyz Jun 11 '10 at 14:58
7

This is a lack of a feature which is weird: Python has no switch statement (although workarounds exist).

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • 25
    The really weird part: somehow you never miss it. – Andrew McGregor Jan 05 '10 at 13:27
  • Perl too. There are workarounds, but they are all more verbose and less clear. – Frank Szczerba Jan 05 '10 at 15:03
  • 1
    Actually Perl does come with `switch` (http://perldoc.perl.org/Switch.html). However this was a "source filter" and with 5.10 the new given/when (borrowed from Perl6) were added (http://perldoc.perl.org/5.10.0/perlsyn.html#Switch-statements) – draegtun Jan 08 '10 at 12:36
  • You could have a condition dictionary: each key is a literal, each value is a lambda, and if an input value is equal to a key, execute its lambda and break. – new123456 Oct 27 '10 at 00:08
7

In javaScript, NaN is a global variable.

Paul Butcher
  • 6,902
  • 28
  • 39
7

The most weird feature I know of is from C++ world : SFINAE.

The worst is that it happens to actually be very usefull, extensive use of SFINAE in BOOST is proof enough for me.

Community
  • 1
  • 1
kriss
  • 23,497
  • 17
  • 97
  • 116
7

Java Generics Are a WTF:

List<String> ls = new ArrayList<String>(); //1
List<Object> lo = ls; //2

2: Is illegal (???) this is puzzling but you have to think what could happen next:

lo.add(new Object());
String s = ls.get(0);

We would be assigning an Object to a String reference, oh noes! And like this there a lots of gotchas around them.

Dana the Sane
  • 14,762
  • 8
  • 58
  • 80
migsho
  • 31
  • 4
  • the same is true of templates in C++ and generics in C#, although I believe the next (maybe now current?) version of C# allows this. it's not a WTF, it's a consequence of the compiler not knowing if the template/generic parameter is covariant or contravariant – rmeador Jan 07 '10 at 20:55
  • 8
    I think Java screwed up a whole generation of programmers by making its arrays covariant. – cdmckay Jan 08 '10 at 05:44
  • 5
    the real wtf with java generics is type erasure – jk. Jan 08 '10 at 10:44
  • 6
    The worst part about java generics is that they didn't want to bother to extend the JVM so they just coded it all into the compiler... That in my opinion results in most of the generics problems in java. – RCIX Jan 10 '10 at 10:06
  • 1
    @rmeador: yes, C# 4 will have covariance and contravariance in interface type parameters. But `IList` won't be one of the changes, because of the problem migsho showed. But `IEnumerable foo = new List()` will be legal, yes. – R. Martinho Fernandes Apr 02 '10 at 15:33
  • How is this at all strange? First you say that 2 is illegal, and then you go on to show that it is also unsafe. Well... good job Java! – Mankarse Jun 10 '11 at 16:26
7

About 20 years ago I worked with a compiler for a language called Coral which allowed me to declare writeonly variables!

It made sense, though, as they were global and used as a signalling mechanism. One process would write a value and another would read it.

Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551
  • 12
    but if they're writeonly variables how does the other one read it? – RCIX Jan 22 '10 at 02:38
  • hmm, why two down votes? Don't you think that is a strange language feature? It seemed to me. RCIX. The variable was `writeonly` for the process which declared it so - just an annotation for the compiler to check it. It could be read-only or read/write for others. And, of course, it was a global variable, shared between compilation units. – Mawg says reinstate Monica Jan 23 '10 at 13:45
7

The following C# code throws NullReferenceException rather than print 1:

    static void SomeMethod(string format, params object[] args)
    {
        Console.WriteLine(args.Length);
    }

    static void Main(string[] args)
    {
        SomeMethod("blabla", null, "Ok here"); // print 2
        SomeMethod("blabla", null); // exception
    }
Dudu
  • 1,264
  • 13
  • 14
7

PHP

From the online doc:
string implode ( string $glue , array $pieces ) — Join array elements with a string
Note: implode() can, for historical reasons, accept its parameters in either order.

So this works: implode($someArray, $glue)

Hope they kill these historical quirks in PHP 6.

scunliffe
  • 62,582
  • 25
  • 126
  • 161
Vili
  • 1,599
  • 15
  • 40
6

In Java,

int x = 010;

This assigns x to have the value 8.

Any integer preceded with a zero in Java is presumed octal.

  • 11
    Should have stated: "In many programming language..." because it's the same in C/C++, Perl, PHP, Tcl, Javascript, Ruby, Python ... I say it's C's fault. – slebetman Jan 07 '10 at 02:22
  • 2
    This is the n-th dupe of "In [insert-favorite-or-hated-language-with-octal-literals-here] 010 is 8". Please delete and improved the original answer. – R. Martinho Fernandes Jan 07 '10 at 02:58
  • 2
    What Martinho said. @slebetman Though I *do* have to mention that Python 3.x removed it. Yes, it doesn't interpret a leading 0 as octal (you can use the "0o" prefix for that, similar to "0x"). In fact, a number with a leading zero is an error. – Jürgen A. Erhard Jan 14 '10 at 03:30
6

In PHP, you can reference variables using a sigil and a string literal or variable containing the name of the variable, for example:

${'foo'} = 'test';
echo $foo;

This will print "test". The strange thing about this behavior is that you can also use non-strings as variable names, for example:

${array()} = 'test';
echo ${array()};
${NULL} = 'test';
echo ${NULL};

Now we have variables named array() and even NULL! All containing the string "test".

codysoyland
  • 633
  • 1
  • 5
  • 7
  • 3
    `${array()}` actually becomes `$Array` (because converting an array to string always returns `Array`). So you cannot use actual arrays here. – user1686 Feb 23 '10 at 13:42
  • If only this worked in `.js`, `${===}='==';`, then `==` would finally be correct. – Talvi Watia Jun 11 '10 at 02:52
6

C++:

void f(int bitand i){ //WTF
    i++;
}
int main(){
    int i = 0;
    f(i);
    cout << i << endl; //1
    return 0;
}
smerlin
  • 6,446
  • 3
  • 35
  • 58
  • But does anybody ever actually use the iso646 stuff? – criddell Jan 07 '10 at 14:47
  • 1
    well maybe some people would use it when they knew about these features... but these are mentioned nearly nowhere. But surely everybody has to learn to read and use the "normal" operators anyway, so its quite understandable they arent mentioned that often. The main intention behind these macros is (according to wikipedia): that some of the standard operators sometimes cannot be quickly or easily typed with some international keyboard layouts. So these macros were introduced .. – smerlin Jan 07 '10 at 18:03
  • They're not macros, but keywords. In C, they're macro's from . And that header name tells you the real reason for their introduction: One ISO standard (646) specified a standard spelling, and at least two others (ISO C and ISO C++) build on that. – MSalters Jan 08 '10 at 11:19
  • Also at http://stackoverflow.com/questions/1995113/strangest-language-feature/2022131#2022131 –  Jan 10 '10 at 14:26
  • ISO 646 was an early standard for national character sets, most of which didn't include all the characters needed by C. – dan04 Jul 16 '10 at 10:20
6

In Java, if the value of x is NaN then x == x returns false and x != x returns true.

Oak
  • 26,231
  • 8
  • 93
  • 152
  • 14
    This is in the definition of NaN, it should be true in any language which uses IEE floating point. If the value is not a number it cannot be equal to anything. – Scott Wales Jan 08 '10 at 03:08
  • Regardless of the reasoning behind it, when I see `if (x!=x) ...` my first thought is "WTF", so I'd say it qualifies for this topic :) By the way, the Eclipse compiler agrees this is a WTF - it generates a warning for it. – Oak Jan 08 '10 at 09:35
  • Definitely an odd value and WTF worthy – Pyrolistical Jan 14 '10 at 00:07
6

javascript:

parseInt('06'); // 6
parseInt('08'); // 0
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 6
    Numbers prefixed with 0 are octals. – BalusC Feb 18 '10 at 20:33
  • yes, I'm aware of that, but it still seems strange :) and since most of the answers here are explainable anyway.. – Bozho Feb 18 '10 at 20:39
  • 1
    @Bozho What is strange about it? 8 is not a valid number in octal so it just wraps back around to 0. Remember that octal is 0 to 7. – Cromulent May 14 '10 at 17:11
  • 5
    It's counter-intuitive, since when parsing Int you would expect it to do it in decimal notation and strip leading zeros. This has lead to alot of annoying bugs... who needs to ever parse octal numbers anyway? Other languages (more intuitively) default to decimal which can be overriden with radix parameter. – Mavrik May 24 '10 at 08:46
  • Octals are represented with a leading zero since at least '78. – Michael Foukarakis Jul 21 '10 at 15:29
  • In integer context I think representation with a leading 0 is perfectly normal. However, a explicit casting function that expects string representation in octal, and int is supremely weird to accept two different bases. ` perl -E'my $foo = "05"; say int($foo)'` `python -c 'a = "05"; b = int(a); print b';` `ruby -e'a='05'; puts a.to_i'` .. All return 5. – Evan Carroll Apr 08 '11 at 06:03
6

The entirety of the Malbolge programming language: http://en.wikipedia.org/wiki/Malbolge

Russ
  • 4,091
  • 21
  • 32
6

Commodore BASIC's command shortcuts. Basically most commands had an abbreviated form which was usually the first letter + (shift+2nd letter). But because the character set on a C64 was by default in all uppercase, these commands would look like bizarre symbols. Here's a short hello world example:

Commodore BASIC screenshot

Maybe someone has a better example actually with more meat to it, but for long programs this looked completely ridiculous.

Here is a list of abbreviations: http://www.c64-wiki.com/index.php/BASIC_keyword_abbreviation

Chris Frederick
  • 5,482
  • 3
  • 36
  • 44
tenfour
  • 36,141
  • 15
  • 83
  • 142
  • the abbreviation translated to memory savings, and with 3,583 bytes and 38,991 on the c64, every byte counted. – Sky Sanders Aug 14 '10 at 06:34
  • 1
    i also remember that you didn't need to put space after the command, so `FORI=1TO15` is valid. Shouldn't take too much imagination to come up with more interesting examples. The one everyone experienced though is that if you put the cursor on the `READY.` line and hit ENTER, the BASIC parser interprets it the same as `READ Y`. – tenfour Aug 14 '10 at 20:58
  • A rougly similar approach was used in Sinclair Basic at ZX-Spectrum (at least 48K) where each BASIC keyword had its own character code that's above 0x7F. So anyone who tried reviewing the BASIC program dump (and not its listing using `LIST` command) was surprised for the first time. – Lyubomyr Shaydariv Sep 15 '10 at 20:32
6

Looking for a function? Why not a language?

I love PHP but it always seems to be built like this "Oh s***t! I forgot this! Let's just add another argument to the function" which result in this :

str_replace($search, $replace, $subject, ...)
strstr($subject, $search, ...)

Notice the extra underscore and the different order for the arguments.

Here is something else

$a = array( 'a', 'b', 'c', 'd');

print_r($a); //Prints array( 0 => 'a', 1 => 'b',    2 => 'c', 3 => 'd');
unset($a[2]); //Destroys the element 2 of the list
print_r($a); //Prints array( 0 => 'a', 1 => 'b',    3 => 'd');
user420041
  • 1
  • 1
  • 1
  • 1
    `strstr` is like that to copy its behaviour in C. And php's arrays are stored associative. If you don't want indexes to break, don't use `unset` but actual array functions like `array_splice`. – poke Aug 14 '10 at 16:21
6

In Perl (without "use strict" or "use warnings"):

if(true==undef)
{
    print "True\n";
}
else{
    print "False\n";
}
if(undef)
{
    print "True\n";
}
else{
    print "False\n";
}
if(true)
{
    print "True\n";
}
else{
    print "False\n";
}

Prints:

True
False
True
Alexandr Ciornii
  • 7,346
  • 1
  • 25
  • 29
D__
  • 210
  • 2
  • 4
  • 1
    It prints True False True - implying that the automatic undef -> boolean typecasting behaves differently if it's being compared with the == operator. – Iiridayn Aug 23 '10 at 19:03
  • You do realise you can edit an answer, especially CW answers? – Joe D Sep 10 '10 at 14:28
6

In JavaScript:

1 / 0; // Infinity
1 / -0; // -Infinity
viam0Zah
  • 25,949
  • 8
  • 77
  • 100
  • 7
    This behavior is defined by IEEE754 -> http://grouper.ieee.org/groups/754/ Other curiosities of this specification is positive and negative NaN:s, +0, 0 and -0. – Esko Sep 10 '10 at 10:35
  • 6
    so what? it's just the 1/epsilon limit for epsilon \downto 0 and \epsilon \upto -0 – Tobias Kienzler Sep 10 '10 at 11:02
  • Most languages I know raise some kind of division by zero error. This behavior was a surprise for me. – viam0Zah Sep 10 '10 at 14:05
  • 3
    Ironically, the answers it provides mathematically *are* correct. – Talvi Watia Sep 14 '10 at 03:57
  • @Talvi - I would hardly agree. if 1 / 0 = infinity => infinity * 0 = 1, which definitively is not true. I know that @Tobias is right, though. – Ralph M. Rickenbach Sep 17 '10 at 10:23
  • 1
    @Ralph your counter-example is flawed per infinity is not (necessarily) commutative. see: http://en.wikipedia.org/wiki/Commutative – Talvi Watia Sep 17 '10 at 12:43
6

C#'s default inheritance model wins my vote:

public class Animal
{
    public string Speak() { return "unknown sound" ; }
}

public class Dog : Animal
{
    public string Speak() { return "Woof!" ; }
}

class Program
{
    static void Main( string[] args )
    {
        Dog aDog = new Dog() ;
        Animal anAnimal = (Animal) aDog ;

        Console.WriteLine( "Dog sez '{0}'" , aDog.Speak() ) ;
        Console.WriteLine( "Animal sez '{0}'" , anAnimal.Speak() ) ;

        return ;
    }
}

Running the program give the following as a result:

Dog says 'Woof!' Animal says 'unknown sound'

Getting that sort of behavior should require the programmer to go out of the programmer's way. The subclass instance doesn't stop being what it is because it's been upcast to its supertype. Instead you have to explicitly request the expected (and almost always desired) result:

public class Animal
{
    public virtual string Speak() { return "unknown sound" ; }
}

public class Dog : Animal
{
    public override string Speak() { return "Woof!" ; }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • 5
    This was very much deliberate on the part of the C# designers, and with good reason. Anders Hejlsberg explains why here: http://www.artima.com/intv/nonvirtual.html – Will Vousden Dec 02 '10 at 21:24
  • 4
    Hmmm, that's pretty rad. I'm so deep in C#, I didn't even realize that was unusual. – CodexArcanum Dec 03 '10 at 00:28
  • 1
    Yes, I know Hejlsberg did it that way for a reason. Doesn't change the fact that the default behavior is opposite what any reasonable person would expect -- that the behavioral differences implemented by a subtype would, when upcast to its supertype, would still manifest themselves. – Nicholas Carey Dec 03 '10 at 18:04
  • 3
    Isn't it the same model for C++ ? – bltxd Dec 06 '10 at 11:15
  • 1
    Isn't that what it should be? If you choose to override, then it is override. If you choose not, it is not. If you don't specify, just as your example, the compiler gives warnings. – Dudu Jan 18 '11 at 03:36
6

C++'s most vexing parse:

struct S
{
    S() {} //default constructor
};

int main() {

    S s(); // this is not a default construction, it declares a function named s that takes no arguments and returns S.
}
Esko
  • 29,022
  • 11
  • 55
  • 82
tadaaaaa
  • 1
  • 1
  • 1
6

PL/SQL allows to declare variables and function names that are keywords. The following is compilable PL/SQL:

create or replace 
  function function 
  return number  as
  return number;
begin 
  function.return := 4;
  return   return;
end function;
/

This created a function named function. Later:

SQL> select function from dual;

  FUNCTION
----------
         4
René Nyffenegger
  • 39,402
  • 33
  • 158
  • 293
5

One unexpected feature was the trailing commas in enum def lists and array initialization lists in C, C#, Ruby, etc.

string[] foods = { "tofu", "grits", "cabbage", }

public enum ArtPeriod {
  Modern,
  Romantic,
  Dada,
}
jjnguy
  • 136,852
  • 53
  • 295
  • 323
msp
  • 141
  • 3
  • 1
    I agree that it's useful. It was strange to me because it was unexpected and given the years and years of syntax errors in my coding history, I never would've expected those to be valid. – msp Jan 04 '10 at 21:11
  • I don't know whether to up-vote you for pointing this out or down-vote you for adding something that is not strange. – ChaosPandion Jan 05 '10 at 00:35
  • 2
    I always use the trailing comma. That way someone can add/remove/comment one more enum value in the middle or end easily. – softveda Jan 05 '10 at 02:05
  • 3
    Very useful when generating a list using a script. It removes the need to bother removing the trailing comma. – 3Doubloons Jan 05 '10 at 04:33
  • 4
    Not strange. Strange would be Internet Explorer's insistence for generating errors or outright crashing when it encounters trailing commas (all other javascript interpreters are tolerant towards trailing commas). – slebetman Jan 06 '10 at 02:18
  • re: ChaosPandion I guess my comment would be, "How many years did you code in one of the above languages and never know that the trailing comma feature existed?" For me, mere mortal, it was easily like 15 years. I think using something for 15 years and suddenly finding a new feature you might have never dreamed was syntactically valid qualifies as "surprising". – msp Jan 06 '10 at 23:11
  • I agree, ruiml, I didn't know this, and I find it surprising. – Matt Ellen Jan 07 '10 at 09:07
5

In Javascript, I believe the following are equivalent:

a['title'] = "Syntactic sugar is good for yr teeth.";
a.title = "Syntactic sugar is good for yr teeth.";
jjnguy
  • 136,852
  • 53
  • 295
  • 323
msp
  • 141
  • 3
  • 22
    It is not a WTF, it is very useful (and logical as well). – Andrey Shchekin Jan 05 '10 at 00:09
  • 2
    Useful maybe, logical hardly imo. – richo Jan 05 '10 at 01:01
  • 2
    why? because it's not exactly like C or PHP? – Breton Jan 05 '10 at 22:53
  • 1
    I thought it was neat. But it was a surprise. Seriously, I had been coding in Javascript for 6 years before I learned about that. That's why I posted it. It was a surprise. – msp Jan 06 '10 at 23:05
  • 3
    It makes the syntax a bit nicer if you know at design time what data member you're asking for but still allowing dynamic access with the array syntax. – Michael Mior Mar 12 '10 at 20:39
  • The really weird thing is that you can use array syntax for keywords, but not dot notation: `a["if"]` works, but `a.if` doesn't. This is fixed in ECMAScript 5. Also, you can do things like this: `a["foo.bar.qux"]` which is not the same as `a.foo.bar.qux`. In fact, object keys can be anything that's a valid string: `a["_%foo@@*(bar)"]` – Pauan Dec 25 '10 at 17:56
5

VBScript's With blocks:

With xml.appendChild(xml.createElement("category"))
  .setAttribute("id",id)
  .setAttribute("keywords",keywords)
  With .appendChild(xml.createElement("item"))
    .setAttribute("count",count)
    .setAttribute("tip",tip)
    .appendChild(xml.createTextNode(text))
  End With
End With
brianary
  • 8,996
  • 2
  • 35
  • 29
  • 1
    How is the With block a strange feature? Useful for setting many properties on data classes. – Josh Smeaton Jan 07 '10 at 10:16
  • I agree, it's handy. I guess I just meant "strange" in the sense that it is unique. JavaScript has a with() { } block, but it doesn't really work the same (or well). – brianary Jan 07 '10 at 15:38
  • 2
    A unique feature is not necessarily strange.... I wish C# and other languages had this feature as well. – Jeroen Huinink Jan 10 '10 at 18:42
5

Dozens of things in Javascript can make your eyes water.

The scoping of local variables, as just one simple example:

function foo(obj)
{
  for (var n = 0; n < 10; n++)
  {
    var t;        // Here is a 't'
    ...
  }
  t = "okay";     // And here's the same 't'
}
David R Tribble
  • 11,918
  • 5
  • 42
  • 52
  • Am I going mad here? Am I the only one who expects this "t" variable to be in scope as it was defined in this function??! I don't expect "t" to be global or accessible from any other function, but in the same function?! Yes! – Maltrap Jan 05 '10 at 03:09
  • 12
    @Maltrap: t is defined in an inner block, as delimited by { and }. In pretty much every other modern language, stuff defined inside a block stays inside that block. Likewise I could argue that t is defined in the global/window object and should be accessible globally. JavaScripts behavior is very odd as it applies scope to some {}-Blocks and not to others. – Michael Stum Jan 05 '10 at 03:20
  • what you need is something like (for(...)(function(){ var t; ... })();), if you want scoping doing well – Dennis C Jan 05 '10 at 14:17
  • Function scoping rather than block scoping. Meh. – outis Jan 05 '10 at 14:55
  • 1
    @Maltrap: I also expect this to work the way it does since my other favourite language also does this. – slebetman Jan 06 '10 at 01:59
  • @Cheung: That makes my eyes water. – David R Tribble Jan 08 '10 at 01:25
  • 1
    In good Javascript, you should have only one `var` statement per function, usually at the top of the function. Only functions create a new "scope" in Javascript, and not things like for loops and if statements or `{}`'s. – strager Mar 23 '10 at 22:31
  • @strager: Yes. Thus "good" Javascript is not conceptually compatible with almost every other block-scope language. – David R Tribble Apr 01 '10 at 17:02
  • @Loadmaster: Indeed. The problem is that JavaScript behaves similarly to Scheme (closures, lambdas, etc.) but uses C syntax... this is confusing when people see the C syntax and expect it to behave like C, but it doesn't. – Pauan Dec 25 '10 at 18:01
5

MySQL enums, specifically their ability to confuse the living hell out of unprepared coworkers.

CREATE TABLE foo (
    ....
    dispatched ENUM('0','1') NOT NULL DEFAULT '0',
)

Then:

UPDATE TABLE foo SET ..., dispatched = 1;

Oops, dispatched was set to ZERO instead, because the 1 wasn't quoted. This really annoyed someone who worked on my code; I use plain old INTs now.

On a related note, even if you add an empty string option to your enum, e.g.

blah ENUM('','A','B') NOT NULL,

If you assign an invalid value to blah, MySQL will use a secret hidden empty string value to represent the invalid value, which will be difficult to distinguish from the one you added yourself. Yay!

rjh
  • 49,276
  • 4
  • 56
  • 63
  • 1
    How about `TINYINT(1)`, `BIT` or (perhaps best of all) `BOOLEAN` rather than `ENUM('0','1')`? – outis Jan 05 '10 at 14:58
  • Indeed, I used TINYINT(1) -- MySQL doesn't yet have a BOOLEAN type. – rjh Jan 05 '10 at 15:50
  • It has a type BOOL which is an alias for TINYINT(1). – cdmckay Jan 08 '10 at 05:40
  • You don't even need to declare the empty string in the list of possible values. From the doc "if you insert an invalid value into an ENUM (that is, a string not present in the list of permitted values), the empty string is inserted instead as a special error value." i mean wtf, you explicitly list the set of possible values, specifically BECAUSE you want any other value to be an error.. – Adrian Smith Oct 22 '10 at 16:02
  • Yes, but crucially the 'error' empty string is different to the empty string in your ENUM - their numerical representations are different. – rjh Dec 03 '10 at 16:07
5

in X++ (Microsoft Dynamics AX):

1) the need of a semi-colon (;) on a separate line to separate variable declaration from statements (at least up to version 4.0)

    int i;
    int myArray[5];
    ;
    i = 1;


2) array indexes are 1-based, so you are not allowed to read from an array using index 0 (zero) like in

    int myArray[5];
    ;
    print myArray[0];    // runtime error

this is not strange, but you are allowed to use the zero index on the left hand side of an assigment, like in

    int myArray[5];
    ;
    myArray[2] = 102;
    myArray[0] = 100;    // this is strange
    print myArray[2];    // expcting 102?

what happens? The array gets initialized to it's default value, no matter what value was used in the assignment. The above code outputs 0 (zero)!

user85421
  • 28,957
  • 10
  • 64
  • 87
5

In c#

Math.Round(2.5)==2
AareP
  • 2,355
  • 3
  • 21
  • 28
  • 8
    That's called "banker's rounding" and is pretty much standard and expected. You can always use Math.Round() method overload with additional parameter to specify other ways of rounding. – Dejan Stanič Jan 05 '10 at 23:18
  • 9
    "Standard and expected" depends on audience. Programmers are rarely bankers, but good to point out what is happening. –  Jan 06 '10 at 01:38
  • I think there is an overload to Math.Round that allows you to specify if you want MidpointRounding or AwayFromZero. – Michael Stum Jan 06 '10 at 02:14
  • 4
    It's called "banker's rounding", but it's not just for bankers. If you've ever done any statistics (or banking for that matter) you know how useful this form of rounding can be. – R. Martinho Fernandes Jan 06 '10 at 21:31
5

In MATLAB (interactive array-oriented language, currently TIOBE 20) there is a keyword end to denote the last element of array (it corresponds to NumPy -1). So this is a well known MATLAB syntax:

myVar = myArray(end)

To get an element from the middle of array one would usually write:

myVar = myArray( ceil( length(myArray)/2 ) )

Surprisingly the keyword end is not a keyword at all but is a kind of variable:

myVar = myArray( ceil( end/2 ) )
Mikhail Poda
  • 5,742
  • 3
  • 39
  • 52
5

Variable assignment in JavaScript can create global variables. If a variable is a assigned a value within a function and it is not declared as var in the same scope it is implicitly declared global.

function foo() {
  x = "juhu";  // creates a global variable x!
  var y = "kinners"
}

foo();
alert(x); // alerts "juhu"
alert(y); // alerts undefined

Note that the var statement can also be used after a value has been assigned to the variable:

function foo() {
  x = 12;
  var x; // x is now local
  return x;
}

alert(foo()); // will alert 12;
alert(x); // will alert undefined
Fabian Jakobs
  • 28,815
  • 8
  • 42
  • 39
5

In Matlab, the following may be surprising, especially if you are used to Python:

>> not true

ans =

     0     0     0     0
>> not false

ans =

     0     0     0     0     0

There are two weird features here. The first one is that a b is interpreted as a('b'), so not true is interpreted as not('true'). The second weird feature is that not of any character returns 0 (presumably because there is no false or true in matlab, only 0 or 1).

Olivier Verdier
  • 46,998
  • 29
  • 98
  • 90
5

Atari BASIC:

You can fill a string with a character without writing a loop:

10 DIM A$(100)
20 A$(1)=" ":A$(100)=" ":A$(2)=A$
dan04
  • 87,747
  • 23
  • 163
  • 198
  • As far as I can remember ':' means what ';' means in Java/C. It's a old Basic thing, not specific to Atari's – pedrofurla Oct 25 '10 at 17:39
  • 2
    @pedrofurla: I'm pretty sure he's saying that after those three assignments, A$(3) through A$(99) will now contain spaces as well. I bet the underlying string implementation looks __scary__. – Jander Oct 27 '10 at 06:24
  • @Jander: yeah, now I am reinterpreting the line. It's a kind of unbelievable feature. The A$(2)=A$ portion is pretty weird, can't really wonder what's behind it. – pedrofurla Oct 27 '10 at 15:54
5

NSIS (the Nullsoft Scriptable Install System) has the StrCmp instruction:

StrCmp str1 str2 jump_if_equal [jump_if_not_equal]

Compares (case insensitively) str1 to str2. If str1 and str2 are equal, Gotos jump_if_equal, otherwise Gotos jump_if_not_equal.

StrCmp $0 "a string" 0 +3
 DetailPrint '$$0 == "a string"'
 Goto +2
 DetailPrint '$$0 != "a string"'

The icing on the cake: jump_if_equal and jump_if_not_equal can be negative, too. But I guess you already figured that out from the + symbol in front of positive numbers. I don't remember whether it's mandatory, or just a horrible convention.

This basically combines the worst of BASIC and the worst of Assembler.

jqno
  • 15,133
  • 7
  • 57
  • 84
5

In Java,

String s = null;
System.out.println(s + "hello");

This outputs "nullhello".

extraeee
  • 3,096
  • 5
  • 27
  • 28
  • I would have expected a Null Reference Exception. – John K Aug 13 '10 at 17:06
  • 1
    @jdk: NullReferenceException is C#'s thing. This is because all the `+` operations are automatically compiled to `StringBuilder` flows so that `a+b+c` (where all variables are `Strings`) becomes `new StringBuilder().append(a).append(b).append(c).toString()` and as we can see from `StringBuilder.append(Object o)`'s javadoc, nulls are handled by printing `null` instead of throwing an exception. **Tl;dr:** Compiler magic with syntactic sugar. – Esko Aug 13 '10 at 18:00
  • @Esko: And here I thought Microsoft copied Sun verbatim :) – John K Aug 13 '10 at 19:41
  • @jdk: Most of C# is syntactic sugar anyways :) But yeah, compiler magic related to concatenating Strings with `+` is really a whole issue on its own. – Esko Aug 13 '10 at 20:28
5

Python 2.x demonstrates a poor list comprehension realization:

z = 4
s = [z*z for z in range(255)]
print z

This code returns 254. The list comprehension's variable collides with an upper defined.

Python 3.x had disposed of this feature, but closures are still using dynamic linking for external variables and brings many WTFs in the functional style python programmer

def mapper(x):
    return x*x
continuations = [lambda: mapper(x) for x in range(5)]
print( [c() for c in continuations])

This code returns obviously [16,16,16,16,16].

sth
  • 222,467
  • 53
  • 283
  • 367
ayvango
  • 1
  • 1
  • 1
5

The following is similar to this answer which is about arrays.

In Powershell, like other dynamic languages, strings and numbers are somewhat interchangeable. However, Powershell can't make up its mind.

PS> $a = "4"    # string
PS> $a * 3      # Python can do this, too
444
PS> 3 * $a      # Python doesn't do it this way, string repetition is commutative
12
PS> $a + 3      # Python gives a mismatched types error
43
PS> 3 + $a      # Python would give an error here, too
7

If the variable is an integer instead of a string, then the operations are commutative.

PS> $a = 4      # integer
PS> $a * 3
12
PS> 3 * $a
12
PS> $a + 3
7
PS> 3 + $a
7

When in doubt, do a cast:

PS> $a = "4"
PS> $b = 3
PS> [int] $a * [int] $b
12

You could also use [float].

Community
  • 1
  • 1
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • 4
    Let's see, Powershell has a well-defined and reasonable policy for mixing integers and strings with the `*` and `+` operators: the left operand defines the type of the operation. It happens to differ from Python. Note that there is no "official" requirement for string repetition being commutative, unlike there is for numeric addition. Then, numeric operations work as expected. If you cast everything to a single type, everything works as expected too. So, what's strange? – R. Martinho Fernandes Nov 20 '10 at 04:02
  • @Martinho: `$a = "4"; 0 + $a * 3` So the `*` has higher precedence than the `+` and since `$a` is a string, we get `0 + 444` which results in `444`. I call that a "gotcha" (aka "strange"). – Dennis Williamson Nov 20 '10 at 07:02
5

Not sure whether someone mentioned it.

In Java, in finally block it can return a value. It will stop the propagation of an exception and override the normal return statement.

LLS
  • 2,128
  • 2
  • 23
  • 36
4

In Visual Basic 7 and above I found the implementation of short-circuit logical evaluation to maintain compatibility with legacy Visual Basic <=6 code a bit of a WTF:

AndAlso (MSDN)
OrElse (MSDN)

Kev
  • 118,037
  • 53
  • 300
  • 385
4

Perl's $[ (deprecated), this was mentioned in another earlier post about generic perl variables, but it deserves specific mention with better explanation. Changes to $[ are limited to current scope. More information and a quick writeup of how you can use this and its implications ;) can be found in $[ is under respected at http://www.perlmonks.org/index.pl/?node_id=480333

Alexandr Ciornii
  • 7,346
  • 1
  • 25
  • 29
Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
  • 4
    Why not put that special mention in that question (it's CW!) or comment on that question? We don't need more duplicates. –  Jan 06 '10 at 01:39
  • 3
    Doesn't have to be global, just scope it properly: `{local $[=1; ...}` – slebetman Jan 06 '10 at 02:31
  • The `$]` is always implicitly lexically scoped. – tchrist Apr 07 '11 at 21:45
  • We're not talking about `$[`, and local doesn't lexically scope anything.. It simply stores the global value in a private register, and *restores it at the end of the lexical scope.* However, the variable is still global in nature. – Evan Carroll Apr 08 '11 at 05:35
4

Another vote for JavaScript:

parseInt('08') == 0

because anything with a leading 0 is interpreted as octal (weird), and invalid octal numbers evaluate to zero (BAD). I discovered this one August when code I hadn't touched in months broke on its own. It would have fixed itself in October, as it turns out.

Octal support has apparently been deprecated, so future generations of JavaScripters will not have this rite of passage.

4

In Perl, objects are just blessed refs, so changing the class of an object at run time is a piece of cake:

package Foo;
sub new { bless {}, $_[0] }
package Bar;
package main;
my $foo = Foo->new;
ref($foo); # => "Foo"
bless $foo, 'Bar';
ref($foo); # => "Bar"

I was surprised that other languages can't do this. What a useful feature!

Max A.
  • 4,842
  • 6
  • 29
  • 27
  • You can do something similar in C++ but using pointer hacks. Just cast a pointer to a class to `void*` and then cast it to a pointer to a different class. – R. Martinho Fernandes Jan 06 '10 at 21:43
  • 2
    My C++ is rusty but I don't think what you've described would have changed the class of the object itself; just of this particular pointer to the object. – Max A. Jan 07 '10 at 12:53
  • 2
    In Python you don't have to do bother doing this. Who cares what class an object is? haha – Michael Mior Mar 15 '10 at 13:55
  • 1
    None of what you guys commented is really equivalent to the perl thing, which is leaving the object entirely intact but changing the class of it. – ben Sep 06 '10 at 18:15
4

Digraphs and alternative tokens

C (ISO/IEC 9899:1999, 6.4.6/3) and C++ (ISO/IEC 14882:2003, 2.5) have a feature that is rarely used, called "digraphs" by C and "alternative tokens" by C++. These differ from trigraphs mainly because string literals containing them will never be interpreted differently.

%:include <stdio.h>

int main() <%
    int a<:10:> = <%0%>;
    printf("Here's the 5th element of 'a': %d\n", a<:4:>);
    puts("Evil, eh? %:>");
    return 0;
%>

C++ has many more, including and, or, and not which are required to behave as &&, ||, and !. C has these too, but requires that <iso646.h> be included to use them, treating them as macros rather than tokens. The C++ header <ciso646> is literally an empty file.

It's worth noting that GCC implements support for this weird language feature, but lots of other compilers choke and die when trying to compile the above segment of code.

  • 2
    this is essentially a dupe of this high-voted answer http://stackoverflow.com/questions/1995113/strangest-language-feature/1995134#1995134, since digraphs and trigraphs are very closely related. – rmeador Jan 07 '10 at 20:57
4

In C++ you can call static methods from null pointers - behold!

class Foo {
  public:
    static void bar() {
      std::cout << "WTF!?" << std::endl;
    }
};

int main(void) {
  Foo * foo = NULL;
  foo->bar(); //=> WTF!?
  return 0; // Ok!
}

That one caught me by surprise...

maerics
  • 151,642
  • 46
  • 269
  • 291
  • 8
    if you understand what a static method really is, this isn't a surprise – GogaRieger Jan 10 '10 at 02:34
  • 1
    @goga: true, but it's surprising to see what looks like a null pointer dereference (even though we know it's actually not). – maerics Jan 10 '10 at 21:24
  • 1
    Actually, it is dereferencing a null pointer, so the behavior is not defined. It just happens that it doesn't do anything with the results of dereferencing, so the program doesn't crash. Also, in general there's no guarantee that dereferencing null will crash the program. – Derek Ledbetter Jan 12 '10 at 22:04
  • 3
    The confusion is caused, in my opinion, by the fact that it is possible to refer to a static method with a pointer to an object and not only with the class name. – felix0322 Jan 14 '10 at 10:16
  • In some implementations, you can call a *non* static method on a null pointer, provided that the method *could* have been static (i.e., is non-virtual and doesn't access any instance member variables). – dan04 Jul 16 '10 at 10:24
4

PHP's list construct:

$array = array(0,1,2);
list (,,$x) = $array;
$x == 2; // true
  • You are listing the array field names as id? Useful, not WTF! Try: `$array = array('id','field','value');` and... `$x == 'value'; // true`. Great for queries! – Talvi Watia Jun 11 '10 at 01:53
4

Forth can change the base of the numbers at any time:

HEX 10 DECIMAL 16 - .
0 Ok

It need not be one pre-defined one either:

36 BASE ! 1Z DECIMAL .
71 Ok
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
4

Variables everywhere are taken as globals in Coldfusion, no matter where they are placed.

<cffunction name="one" returntype="void">
    <cfset var wtf="coldfusion">
    <cfinvoke method="second">
</cffunction>

<cffunction name="two" returntype="void">
    <cfoutput>#wtf#</cfoutput>
</cffunction>
Chris C
  • 2,003
  • 15
  • 18
4

In Python:

>>> x = 4
>>> y = 1000000
>>> x is 4
True
>>> y is 1000000
False
>>>

Just try it if you don´t believe me!

Manuel Araoz
  • 15,962
  • 24
  • 71
  • 95
  • 3
    That's because small numbers are predefined or cached objects. So `x = 4` actually is a reference to an already existing number, whereas y is simply to big to be stored by default, so both constants create new objects. – poke Feb 08 '10 at 17:40
  • 1
    @poke: doesn't matter why, still crazy – andyczerwonka Feb 03 '11 at 22:27
  • @articpenguin: Just don't compare such primitive values using `is` and you are fine. – poke Feb 03 '11 at 23:33
4

In php:

easter_date — Get Unix timestamp for midnight on Easter of a given year

int easter_date ([ int $year ] )

roydukkey
  • 3,149
  • 2
  • 27
  • 43
  • 2
    ahh yes. Good old easter_date(). Led to one of the first "hacks" in my career. Semester project, due next day. code is ready: deploy. Not working because Hosting provider has compiled php without this function. What do to? Solution: Hardcode for next 30 years! – Esben Skov Pedersen Dec 06 '10 at 19:40
4

In Java (Actually, I have wrote this on different SO post recently) :

    int x = 1 + + + + + + + + + + + + + 1;
    System.out.println(x);
monn
  • 717
  • 1
  • 5
  • 13
4

SQLite lets you declare columns with whatever data type you want. It looks for a few particular substrings ("INT", "REAL", "TEXT", etc.) to determine the affinity.

This makes it possible to lie in your type declarations:

CREATE TABLE Quirks (
   X    FLOATING POINT,  -- = INTEGER affinity because of the "INT"
   Y    STRING,          -- = NUMERIC affinity
);
dan04
  • 87,747
  • 23
  • 163
  • 198
  • 1
    Actually the actual storage type is completely dynamic, so even if you say column X is integer, you could still put a blob into it. – poke Jun 09 '10 at 05:40
  • 1
    True. Affinity is just the *preferred* type to coerce values to. – dan04 Jun 09 '10 at 05:45
4

This old PHP favorite isn't all that WTFish on its own, but a scope resolution error is one of those things that gets seen by so many developers that it's worth giving some WTF love:

$class = new StdClass();
$class::test();

PHP Parse error:  syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM on line 3
4

Fortran's special meaning of different columns. (Probably completely natural if you grew up with punchcards.)

One side effect of this is that e.g. variable names are truncated after column 72. Combined with IMPLICIT NONE this then silently introduces a new variable when such a variable name is started close to column 72.

You'll need

  1. to be aware of this

  2. an editor which highlights the comment part (after column 72) in a different color than the part before...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andre Holzner
  • 18,333
  • 6
  • 54
  • 63
  • This is especially true on IBM where columns 72 thru 80 are significant to the editor. – Dave Aug 16 '10 at 18:12
  • 1
    For Fortran, you're not supposed use an editor. You are supposed to write your program out on forms where the column utilization is marked by color. Then get it keypunched to cards by the intimidating women at the data entry dept. – SeaDrive Apr 08 '11 at 20:32
  • There is implicit typing too. Variables with names from i to o are implicitly integer. (You could be explicit. No one ever was.) – SeaDrive Apr 08 '11 at 20:33
  • I believe the high columns were usually used for a sequence number so that you could sort your program back into order if it ever got shuffled, i.e. by dropping the deck of cards. – SeaDrive Apr 11 '11 at 15:20
3

In two words: multiple inheritance. It makes no sense, and creates nothing but trouble.

Edit - I am referring to MI in C++, not mixins and the like in Java and other languages.

Nathan Osman
  • 71,149
  • 71
  • 256
  • 361
  • 15
    Personally I like multiple inheritance, as it promotes a mix-in style of programming. Something I always enjoyed, but can't do much anymore as I'm mainly working in .Net :( – cwap Jan 04 '10 at 12:50
  • 4
    Is it MI you hate, or a particular implementation of it? I've seen MI done really well, and I've seen MI done really poorly. – Ken Jan 04 '10 at 16:52
  • 3
    Okay, so what implementations of MI have you worked with? I assure you it works great in certain languages to develop text adventures in, and it's just fine in the Common Lisp Object System. – David Thornley Jan 04 '10 at 20:12
  • 2
    @jk - I have two parents, but nobody was depending on my having a specific eye color. – Nathan Long Jan 04 '10 at 20:59
  • 1
    I use C++ and find that it creates too much confusion. When classes derive from MI classes, member order is not guaranteed. Just too many better solutions exist. – Nathan Osman Jan 04 '10 at 21:01
  • 1
    @Dykam: I really like composition, I just miss some form of automatic interface delegation in C#... mainly to reduce boilerplate code. – R. Martinho Fernandes Jan 04 '10 at 21:42
  • To clarify what jk means: What happens if you apply that statement to yourself having stated you have more than one parent? – RCIX Jan 06 '10 at 23:32
  • 5
    -1! LOL. George Edison, another victim of the mind eating Java marketing machinery. Sorry, but please justify your statement. Why do you think so? – Frunsi Jan 07 '10 at 02:48
  • Like I said, member order is not guarenteed. Now, this is not necesarily a problem, but a potential pitfall if one is not careful. And as for Java, to say I hate mixins is far from the truth. I think Java has a much better implementation of MI. – Nathan Osman Jan 07 '10 at 03:39
  • 1
    George Edison: That would depend on HOW multiple inheritance is defined to work. It may not work in YOUR language; but done right, it's pretty sweet. – Vatine Jan 07 '10 at 14:14
  • I know. Some languages do, some don't. I should probably fix my question. – Nathan Osman Jan 07 '10 at 19:07
  • @jk how many species are you? Parent is a hasa unless you are a mutant – Justin Smith Jan 18 '10 at 17:50
  • 1
    @jk I have two parents. I also have many characteristics that neither of them had, and many from one parent that arbitrarily overrode the other parent's genes. Is this how we should model OO inheritance? Shall we leave it down to the whim of the compiler to decide how the inherited members should mutate between generations? Hell, maybe we could even invent a new paradigm driven by natural selection! – Will Vousden Jul 01 '10 at 22:25
  • Since when did Java have mix-in inheritance? Scala, yes. – flatline Aug 13 '10 at 17:46
  • 2
    Modern c++ design by Andrei Alexandrescu and you can see that MI has it's uses. I kind of like shallow MI over deep SI. Deep MI witb virtual inheritance is not recommended by your doctor. – Just another metaprogrammer Aug 13 '10 at 19:31
3

To alternate between things in many languages:

boolean b = true;
for(int i = 0; i < 10; i++)
  if(b = !b)
    print i;

on first glance: how can b really not be equal to itself!? This acctually would print odd numbers only

Xian Stannard
  • 376
  • 3
  • 13
  • 6
    You are using "=" instead of "==". So b will get the value non-b each time. It will print odd number (once every 2 number) just as you say – Victor Hurdugaci Jan 04 '10 at 16:48
  • 8
    If there's a += operator, why don't we have a != operator too?!? ...oh, wait. :) –  Jan 05 '10 at 00:42
  • @fennec I think you generally only have complex assignment with binary operators, but `++` and `--` are notable counterexamples. – Peter Olson Dec 19 '11 at 05:47
3

Variable variables in PHP

An odd feature in PHP which allows you to create and assign variables from the content of other variables (warning, untested code):

$a = 'Juliet';
$$a = 'awesome'; // assigns a variable named $Juliet with value 'awesome'

echo '$a';       // prints Juliet
echo '${$a}';    // prints awesome
echo '$Juliet';  // prints awesome

Alright, let's say we have something like this:

$bob = 'I\'m bob';
$joe = 'I\'m joe';
$someVarName = 'bob';
$$someVarName = 'Variable \'bob\' changed';

How about some fun with all kinds of indirection:

$juliet = 'Juliet is awesome!';
$func = 'getVarName'

echo '${$func()}'; // prints 'Juliet is awesome!'

function getVarName() { return 'juliet'; }
richo
  • 8,717
  • 3
  • 29
  • 47
Juliet
  • 80,494
  • 45
  • 196
  • 228
  • String references. Perl will do that too, but will issue a warning if you `use strict` (or specifically `use strict 'refs'`). But I prefer symbol table games: `$a = 1; *b = \$a; $b = 2;` Now guess what $a is? yep! (serves you right for using package globals!) –  Jan 05 '10 at 01:14
  • This is a feature I really like in PHP. – MDCore Jan 05 '10 at 12:57
  • @MDCore, really? Why, because you like to shuffle your brain matter? – Robert Harvey Jan 06 '10 at 00:15
  • Any shell language can do this, and many others can do this via some read operation that returns a symbol based on a string. It is useful for implementing reflective features in dynamic languages. – Justin Smith Jan 18 '10 at 17:53
3

Perl's sub not having a real parameter list, just the @_ array. Also, sub's auto-flattening the parameters that are passed into it.

I don't understand why this is a persistent feature; this reflects what I had to do as a kludge on my TI-86 BASIC years ago because the language wasn't featured enough.

Paul Nathan
  • 39,638
  • 28
  • 112
  • 212
  • http://search.cpan.org/dist/MooseX-Method-Signatures/lib/MooseX/Method/Signatures.pm Perl may be a bit dated, but at least you can bolt on named/positional arguments, type checking and constraints, and optional params with nothing but a few modules! – rjh Jan 05 '10 at 03:20
  • 4
    @rjh: Yes, but adding in modules to support what was a core element of quality languages in the *60s* seems quite silly. – Paul Nathan Jan 05 '10 at 15:46
  • 4
    @Paul: it also allowed Perl to do things like my %args = @_; or my ($foo, $bar, @rest) = @_; or in fact, handle arguments any way you like. It's the same for OO - mostly do it yourself, but very flexible. That's Perl for you. – rjh Jan 05 '10 at 15:55
  • +1 I've always thought this defeats self-documentation of code. – slebetman Jan 06 '10 at 02:19
  • @rjh As Paul said, quality languages in the 60s. And yes, it allowed Perl to do things... other (saner ;P) languages had absolutely no need for. ;) – Jürgen A. Erhard Jan 14 '10 at 03:26
3

C#, namespace reslove order

for example.

namespace foo.bar.xyz{
  public class Foo{
    Exception e;   // you'll get compile time error here....
  }
}

Because

namespace foo.bar.Exception{
  class HowDoMyWayException : ApplicationException {
   // because someone did this
  } 
}
Dennis C
  • 24,511
  • 12
  • 71
  • 99
  • Hmmm, I wouldn't exactly call this a feature. How is the compiler supposed to know the difference? – ChaosPandion Jan 05 '10 at 14:45
  • It don't have to know the difference. But it should be a warning, and error only if duplicated "CLASS / STRUCT" name. – Dennis C Jan 05 '10 at 14:48
3

In C++, you can do:

std::string my_str;
std::string my_str_concat = my_str + "foo";

But you can't do:

std::string my_str_concat = "foo" + my_str;

Operator overloading is generally subject to WTF.

Tomas Brambora
  • 1,056
  • 8
  • 17
  • Actually the Visual Studio 2008 compiler supports this just fine. Not sure how they do it though. – Randy Voet Jan 28 '10 at 07:46
  • 2
    You can have a `operator+(const char *, std::string)` function, which will allow `"foo" + my_str`. In an operator overload, you need at least one user-defined type (class, enum, etc.), but it needn't be the first one. Operator overloading is usually not a good idea, but it can be very useful on occasion. – David Thornley Feb 18 '10 at 20:18
  • 1
    This answer is plain wrong, you can indeed do what you claim you cannot. Operator overloading is generally sensible. – ben Sep 06 '10 at 18:09
  • `char* dir=...; std::ifstream in((std::string(dir) + "/" + file).c_str());` steals it though – Stefan Dragnev Aug 03 '11 at 12:42
3

In ColdFusion arrays start at 1.

Don
  • 1,570
  • 4
  • 22
  • 38
  • That's how most languages did it before C rose to such prominence that it began influencing all the other new languages. You can certainly argue that starting from 1 is more logical and intuitive. This may not be the real reason for the decision, but C's need to start from 0 seems to stem from the equivalence between array indexing and pointer arithmetic rather than any philosophical argument that counting from 0 is better. – Nate C-K Jan 06 '10 at 18:33
  • It works just as well either way -- we're just trained to start from 0 now. – RCIX Jan 06 '10 at 21:49
  • 9
    In Perl arrays start at `$[` -- default 0, but it's variable. – ephemient Jan 06 '10 at 21:59
  • 3
    It's also much easier to create multidimensional arrays if indices start at 0, 'a[i*n+j]' vs 'a[(i-1)*n+j]'. You see similar indexing in fortran. – Scott Wales Jan 07 '10 at 05:04
3

not that this is heavily used, but syntax of C++'s "return reference to static-size array" is weird:

struct SuperFoo {
  int (&getFoo() const)[10] {
    static int foo[10];
    return foo;
  }
}

ofc, in above case method can be declared as static const

GiM
  • 460
  • 4
  • 13
3

In Python:

abs((10+5j)-(25+-5j))

Returns ~18.03, which is the distance between the points (10,5) and (25,5) by the Pythagoras theorem. This fact happens because Python has native language support to complex numbers in the form of 2+2j for example. Since the absolute value of a complex number in form of a+bj = sqrt(a^2+b^2), we get the distance while subtracting one complex number from another and then apply the abs (absolute) function over it.

Tarantula
  • 19,031
  • 12
  • 54
  • 71
  • 4
    What is so strange about this? How else would you calculate the absolute value of complex numbers? – Debilski Jan 07 '10 at 16:26
  • 3
    The strange is, as I cited, the native language support to complex numbers, which brings some strange syntax constructions. – Tarantula Jan 07 '10 at 16:57
  • Apparently it follows engineering conventions rather than mathematical ones. In engineering, `i` was already taken, so they used `j` instead. I couldn't find the comp.lang.python postings, but see, for example, this [python-tutor thread](http://mail.python.org/pipermail/tutor/2002-August/016789.html). – beerbajay Nov 15 '11 at 14:10
3

Feature: Bash, the Korn shell (ksh93) and the Z shell each allow subscripting arrays with variables with or without a dollar sign:

array[index]=$value
array[$index]=$value

This, with the dollar sign, will produce the expected value of 10000:

unset array
for i in {1..10000}
do
    ((array[$RANDOM%6+1]++))
done
unset total
for count in ${array[@]}
do
    ((total += count))
done
echo $total

Strangeness: If you remove the dollar sign from RANDOM, the total will vary randomly, even to be greater than 10000.

Similarly, this produces 3 instead of 2:

a=1; ((r[a++]++)); echo $a

And you can't use a dollar sign there because it's an assignment (a is on the lhs), although you could do it if you were using indirection, but the double evaluation still occurs.

The Reason: With the dollar sign, the variable expansion is performed before the arithmetic evaluation so only gets done once. Without the dollar sign, it's performed twice, once to calculate the index for the lookup and again to calculate the index for the assignment (so, in effect, an assignment at one step in the loop might look like array[4] = $array[6] + 1 which totally scrambles the array).

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
3

In PHP

var_export('false' == 0);       // true

var_export('false' == true);    // true

var_export('false' == false);   // false

EDIT

As @Kobi mentioned, it could happen because language interpret any value as "TRUE" except "FALSE", but not in case of PHP, where things are even more strange than you thought!

This case is fully documented in chapter "String conversion to numbers" of a PHP manual, which says:

If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero).

Here is example:

print (int) 'zero';    // 0
print (int) 'false';   // 0
// but
print (int) '1 - one'; // 1

P.S. I see more harm than usefulness of such implicit type conversions.

Sergiy Sokolenko
  • 5,967
  • 35
  • 37
  • 2
    I don't know any PHP, but it makes sense if any value is true, besides `false` (some languages behave that way) - `0` is true, and `'any string'` is true. – Kobi Jul 21 '10 at 06:55
  • 1
    @Kobi: If the tests worked that way, `1 == 2` would also be true. The test isn't `('false' && 0)`, it's `('false' == 0)`. PHP is just crazy. – Nicholas Knight Jul 21 '10 at 07:10
  • Well, quoting me in the answer is just unfair `:P`, but the direction is right - show some more asserts and see if it makes sense, draw a whole picture. – Kobi Jul 21 '10 at 09:08
3

In Ruby, you can do some weird things with heredocs. Consider:

a = <<ONE
This is one. #{<<TWO}
This is two. #{<<THREE}
This is three.
THREE
TWO
ONE

p a # => "This is one. This is two. This is three.\n\n\n"
3

Ruby Flip-Flops. "..." and ".." in conditional statements are not always range operators:

(0..20).each do |x|
  if ((x%10) == 5)..((x%10) == 5)
    print "#{x} "
  end
end

(0..20).each do |x|
  if ((x%10) == 5)...((x%10) == 5)
    print "#{x} "
  end
end

This will output:

5 15
5 6 7 8 9 10 11 12 13 14 15

.. checks both statements on each pass, ... only checks the "on" or "off" statement in each pass (depending on the flip-flop state). They are stolen from awk and sed.

Matz writes in "The Ruby Programming Language": "Flip-flops are a fairly obscure feature of Ruby and probably best avoided..."

Skade
  • 1,406
  • 1
  • 11
  • 14
3

How about the neat system-dependent overflows causing year rollovers in (MRI/C) Ruby and MacRuby (but not in JRuby) followed by localtime errors for a larger number. Not a common issue, but it is strange:

$ ruby -version
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
$ irb
>> Time.at(67767976233550799)
=> Tue Dec 31 23:59:59 -0500 2147483647
>> Time.at(67767976233550800)
=> Wed Jan 01 00:00:00 -0500 -2147483648
>> Time.at(67768036191694799)
=> Wed Dec 31 23:59:59 -0500 -2147481749
>> Time.at(67768036191694800)
ArgumentError: localtime error
...
Maybe IRB bug!!

This may be specific to 64-bit environments, though.

Gary S. Weaver
  • 7,966
  • 4
  • 37
  • 61
3

Since I haven't seen anyone mention it... RPG 2 or 3 (Report Program Generator... aka Rocket Propelled Garbage) is by far the screwyest language I've ever used. It combines almost no control over program flow (Enter at the top of the file, Exit at the bottom) and programming statements are defined based on characters defined in specific columns using a fixed font (think PUNCH CARDS!!).

To be really FUBAR you have to attempt to program in DYL-280. It combined RPG flow and logic with COBOL syntax.

Look here for RPG: wikipedia.org /wiki/IBM_RPG

An example of DYL-280: http://99-bottles-of-beer.net/language-dyl-280-224.html

Bill
  • 1
  • 1
3

For those who didn't know, PostScript is actually a programming language. I've gotten a bit insane with it -- I wrote a PostScript program that computes a Mandelbrot fractal to a very high level of detail. It's really printable PostScript, though it will crash a lot of print drivers...

Anyway, where to start with PostScript... Here's one: You can actually create a variable whose identifier is.... nothing.

() cvn 5 def % Assign the number 5 to... nothing

PostScript is a stack-based language. () puts an empty string on the stack. cvn converts it to a name ("/" if you print it, because all names in PS are preceded by a slash). Then 5 def assigns the value 5 to it. (% is the comment character)

You can't directly get it back, e.g. if I say "/ print", this will not print the number 5. But you can get it back indirectly:

() cvn load print % this will print the number 5

What else... PostScript has dictionaries as a native type, and you can use an array reference as a key to the dictionary... but it is the REFERENCE that is the key, not the array. So:

/myDict 100 dict def

[0] dup myDict exch 42 put myDict exch get == % prints 42

myDict [1] 42 put myDict [1] get % throws an undefined error

Edit: Oh yeah, one more fun thing... Try the following at a Ghostscript prompt:

1 array dup dup 0 exch put ==

D'oh!

  • Yes, I've seen (well, at least heard of) PostScript documents that contained the value of pi in them where it used the printer itself to actually approximate that value of pi to a certain number of decimal digits for inclusion in the document. ;-) – peSHIr Aug 19 '10 at 11:39
3

Here's some messing around in the Perl debugger:

  DB<1> sub foo { +(1..20) } 
  DB<2> @bar = foo(); # list of 1, 2, 3, 4...20
  DB<3> x scalar @bar # size of list
0  20
  DB<4> x scalar foo();
0  ''

That's right. When you call the method like that, the scalar context from scalar propagates down into the subroutine call, turning the innocuous-looking .. into an entirely different operator. (That's the "flip-flop" operator, instead of the range operator).

3

One of my C++ favorites:

#include <iostream>
using namespace std;
int main()
{
    cout <<  3 << 5  << endl;
    cout << (3 << 5) << endl;
    return 0;
}

Of course, this is easily explainable, but it has beginning programming students scratching their heads!

pr1268
  • 1,176
  • 3
  • 9
  • 16
  • 2
    It's ok to provide the sample output for this. Those beginning programming students will still scratch their head. For the rest of us, it will be the clue that triggers the palm-to-forehead when we remember about the bit-shift operators. – Kelly S. French Nov 19 '10 at 16:04
  • First line: 35 Second line: 96 – pr1268 Nov 22 '10 at 20:27
3

PHP backticks

From http://www.php.net/manual/en/language.operators.execution.php

PHP supports one execution operator: backticks (``). Note that these are not single-quotes! PHP will attempt to execute the contents of the backticks as a shell command; the output will be returned (i.e., it won't simply be dumped to output; it can be assigned to a variable).

$output = `ls -al`;
echo "<pre>$output</pre>";

Well it's "quite easy" to spot ` instead of ' in the code.

This is funny, too:

After much trouble, I have concluded that the backtick operator (and shell_exec) have a limited buffer for the return. My problem was that I was grepping a file with over 500,000 lines, receiving a response with well over 100,000 lines. After a short pause, I was flooded with errors from grep about the pipe being closed.

Vili
  • 1,599
  • 15
  • 40
3

RSL programming language is used in one strange banking system. There is built-in class TArray for arrays. But if you inherit from it every instance variable become an element of the array.

class (TArray) DerivedArray
  var someField = 56;
end

var a = DerivedArray();
PrintLn(a.Size);     // => 1
PrintLn(a[0]);       // => 56 
2

FORTRAN isn't a really WTF moment but rather it's more a "Why do I need to type all this garbage moment"

IF(12 .gt. 11) THEN
 // Do some magic
ENDIF

The ".gt." threw me off when I was playing with the language for a bit until I realized it was the ">" symbol. Oh how I love not being a biology major and having to dabble in this crap day to day

WarmWaffles
  • 531
  • 5
  • 16
  • 4
    I personally like the fact that whitespace is not significant so `IF(12.GT.11)THEN` and `I F ( 1 2 . G T . 1 1 ) T H E N` are identical. – D.Shawley Jan 04 '10 at 23:34
  • @D. Shawley - That reminds me of Apple BASIC, where any sequence of letters that matched a keyword was interpreted as that keyword, and spaces were automatically added between tokens. This meant that you could write the entire line of code with no spaces at all and the editor (if I can call the BASIC command line an editor) would format it for you. – Nate C-K Jan 07 '10 at 05:10
  • 3
    FORTRAN predates both ASCII and EBCDIC, and was first implemented on a computer with a 6-bit character set. So you couldn't count on < and > being available, hence the need for substitutes. More recent versions of Fortran do support the < and > operators. – dan04 Jun 09 '10 at 06:08
  • 1
    @D.Shawley whats the real advantage, that whitespace is not significant? (there is none) – Joschua Oct 12 '10 at 09:17
  • Also FORTRAN was the first of it's kind. Why didn't the other languages follow it's lead? – Dave Dec 30 '10 at 19:37
2

In Bash, variables can appear to be both scalars and arrays:

$ a=3
$ echo $a
3
$ echo ${a[@]}    # treat it like an array
3
$ declare -p a    # but it's not
declare -- a="3"
$ a[1]=4          # treat it like an array
$ echo $a         # acts like it's scalar
3
$ echo ${a[@]}    # but it's not
3 4
$ declare -p a
declare -a a='([0]="3" [1]="4")'
$ a=5             # treat it like a scalar
$ echo $a         # acts like it's scalar
5
$ echo ${a[@]}    # but it's not
5 4
$ declare -p a
declare -a a='([0]="5" [1]="4")'

ksh does the same things, but uses typeset instead of declare.

When you do this in zsh, you get substring assignment instead of arrays:

$ a=3
$ a[2]=4          # zsh is one-indexed by default
$ echo $a
34
$ a[3]=567
$ echo $a
34567
$ a[3]=9
$ echo $a
34967
$ a[3]=123         # here it overwrites the first character, but inserts the others
$ echo $a
3412367
$ a=(1 2 3)
$ echo $a
1 2 3              # it's an array without needing to use ${a[@]} (but it will work)
$ a[2]=99          # what about assignments?
$ echo $a
1 99 3
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
2

In Common Lisp, arrays with zero dimensions are strange, and naturally, they have read syntax.

? (aref #0A5)
5
Brian
  • 1,810
  • 12
  • 9
2

A Fortran compiler that I used years ago had the interesting feature that: (a) Numbers were stored high-byte first; (b) Numbers were passed to subroutines by address; (c) There was no compile-time checking of length.

So you could write a program like this: (Excuse me if I mess up the syntax. It's been a long time since I've written Fortran.)

INTEGER*2 FUNCTION TIMESTWO (INTEGER*2 N)
RETURN N*2

... THEN CALL THIS SOMEWHERE WITH A LONG INTEGER ...

INTEGER*4 I, J

I=42
J=TIMESTWO(I)

The final value of J is ... zero !

Why? Because the passed in value is 4 bytes, but the called function looks at only the first two bytes. As the first two are zero, it doubles the zero and returns it. This return value is then converted back to four bytes.

This was very mysterious when I first encountered it. Almost every number I passed in to certain functions got interpreted as zero!

Jay
  • 26,876
  • 10
  • 61
  • 112
  • They didn't fix this until some compilers in FORTRAN 77 came out. Not all implementations of FORTRAN 77 had it right. – Dave Dec 30 '10 at 19:43
2

Perl's CORE::open and standard library having elements of object orientation masked with a procedural interface: open ( my $fh, '>', 'foobar' ); open is a constructor that operates on the reference returned by my(), and takes the arguments '>', and 'foobar'. Moreover, that being an object that is a blessed typeglob (meaning it can't hold state inside the object).

More information on my perlmonks post IO::File vs CORE::open here: http://www.perlmonks.org/?node_id=763565

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
2

I think this one isn't actually a "language feature" (C) and I'm quite possibly being widely ignorant in posting it, but I couldn't figure why this happens, so I'll ask. If it turns out to be related to some odd language feature.. well, it really made me "WTF", so it's worth this place.

int a = 0;
int *p = &a;

printf("%d, %d, %d.\n", *p, (*p)++, *p); // Outputs "1, 0, 0.\n" on MinGW's GCC 4.4.1

Why?

-- edit

Just got it, and it's not big deal. I can sense the C++ gurus laughing at me now. I guess the order in which function parameters are evaluated is unspecified, so compilers are free to call them as they wish (and I think I've read that one somewhere in boost's documentation). In this case, the argument statements were evaluated backwards, probably reflecting the calling convention of the function.

Gui Prá
  • 5,559
  • 4
  • 34
  • 59
2

In Lisp you can copy a list, and you can copy a vector, and you can copy a struct, and you can copy a CLOS object...

... but you cannot copy an array or a hash table.

2

JCL Conditional execution.

//STEP02 EXEC PGM=PROG02,COND=(4,GT,STEP01) .

This features allows you to run or not run a step depending on the return code from previous steps. Quite a nice feature really.

Except for a couple of small features which turn the logic inside out and backwards.

First the step does NOT run if the condition is true.

Secondly the 4,GT,STEP01 actually means "if the return code from STEP01 is greater than 4"

So the whole thing means "Do not run this step if the return code from STEP01 is greater than 4". Which is the almost but not quite the same as a naive interpretation "Run the step if 4 is greater than the return code from STEP01".

Given that only time you ever look at these things seriously is about 2.30 am with a frantic nightshift operator at the other end of the line this double ambiguity leads to serious headaches.

James Anderson
  • 27,109
  • 7
  • 50
  • 78
2

Reverse Polish Notation (RPN). That means the arguments precede the function. Or, in other words, you add two and two by writing 2 2 +.

Languages featuring that WTF include Forth, Postscript (yes, of laser printers) and Factor.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • HP made a microwave oven once that had no Start button. To reheat macaroni at half power for 3 minutes, you'd press 3 [Enter] .5 [y^x] – maxpolk Jan 20 '10 at 04:48
  • 1
    @David It is unusual, and completely different from standard convention. – Daniel C. Sobral Feb 18 '10 at 21:59
  • 1
    @Daniel: It isn't unusual where it's used, and a whole lot of things in computer languages are different from standard non-computer conventions. RPN has been used in some very popular calculators, so many people have some familiarity with it. Forth isn't exactly a mainstream language, but I don't see RPN as a WTF. – David Thornley Feb 18 '10 at 22:34
  • 1
    @David "where it's used" kind of defeats the whole point of unusual. Nothing is unusual where it's used. Now, suppose you went to the university nearest of you, and inquired graduating CS students. What percentage of them do you expect to have seen it before, much less used it? – Daniel C. Sobral Feb 19 '10 at 10:18
  • 2
    @Daniel: Less so than maybe ten years ago, when a whole lot of engineers used RPN calculators. Since then, HP is no longer run by engineers. Still, one of the early iPhone calculator apps worked with reverse Polish (I bought it, as I dislike doing complicated things with infix calculators). Moreover, anybody who's taken a compilers class will be familiar with it. I think it's more common than you think. – David Thornley Feb 19 '10 at 15:47
  • 1
    @David And each of those engineers probably thought "wtf?!" when they first saw it. – Daniel C. Sobral Feb 19 '10 at 16:40
  • RPN is different from what we're used to, but it's really easy to implement. – dan04 Jun 09 '10 at 06:10
  • 5
    It's not a WTF, it's a FTW (double entendre). – Erich Mirabal Jul 21 '10 at 17:33
2

Something bizarre -- VBScript having both a Null keyword and a Nothing keyword (Null is missing data and Nothing is a missing object). Why not just have one keyword...? Most other languages seem to do fine with one!

Visual Basic 6.0 and of course "Classic ASP" code (because it uses VBScript) have the same bizarrity. And in Visual Basic old and new we also have DBNull.

The situation is improving however, as in Visual Basic.NET Null has at last gone away so that Null is unused and only Nothing and DBNull are used.

martinr
  • 3,794
  • 2
  • 17
  • 15
  • VB.NET is still a pain in the arse. Character is a non-nullable data type (so it cannot be "Nothing") but it can be vbNullChar which is a not-null Object representing a Null Character value. Why not just let Character be nullable!? – David Jan 10 '10 at 22:53
2

A very tiny thing that annoyed me in COBOL was that there was no dedicated modulo operation. Instead you could do a division specifying that you only wanted whole number results and store the rest in a different variable. Since COBOL is very sensitive when it comes to variables that means that you ended up with a variable you didn't really need, i.e. the actual result of the division. This is the story of how I once named a variable "USELESS" - that was the most appropriate name I could think of.

Anne Schuessler
  • 1,692
  • 13
  • 25
  • 3
    I once wrote a PHP function which returned a reference, except when there was an error, it'd return `null`. Except you can't just `return null;` since that's not a reference to anything. This meant I had to define a variable, set it to null and return that. Of course, the variable was named `$thisIsAStupidFxxxingVariableIHadToDefineBecauseOtherwiseThisFunctionShitsItself`. *(yes these were early days in my PHP development career)* – nickf Jan 13 '10 at 12:44
  • you shouldn't have been passing null as an error, that's just ugly having your return value to both indicate error or valid results – hhafez Jan 15 '10 at 05:31
  • I suspect he understands that now – Carson Myers Mar 18 '10 at 05:16
  • 3
    In these kinds of situations, I name the variable "fcrt" for Fxxxing Compiler Requires This. – dan04 Jun 09 '10 at 06:11
2

I can't believe this one isn't on here yet: JSF property access.

In a JSF UI tag, you would put the value of a property from the server-side object into the interface by referencing it thusly:

<h:inputText value="#{myObject.property}></h:inputText>

The thing is that Java doesn't support properties, so you have to write methods starting with get and set in order to link the UI object to the "property" on the server.

public void setProperty(String property){...}
public String getProperty(){...}

This confused me when I first learned JSF and I still consider it WTF-worthy... even though there's really no other way to do it until Java implements support for C#-style properties.

iandisme
  • 6,346
  • 6
  • 44
  • 63
  • This is common practice nowadays in Java world and you will never see C# syntax sugar properties in Java anyway. – Esko Jan 16 '10 at 08:27
2

In SQL server (MS at least):

This will always evaluate to false:

IF @someint <> NULL

Given:

DECLARE @int INT

SET @int = 6

IF @int <> NULL
BEGIN
    Print '@int is not null'
END
ELSE
BEGIN
    Print '@int is evaluating to null'
END

The output will be:

@int is evaluating to null

It must be written:

IF @someint IS NOT NULL
BEGIN
END

Who put English majors on the SQL Team! :)

Fred
  • 1,292
  • 10
  • 24
2

in Ruby ...

i=true
while(i)
   i=false
   a=2
end
puts defined?(a) // returns true
Lucas
  • 3,059
  • 5
  • 33
  • 48
  • 2
    I don't even know the language and that's clear. Implicit declarations like that aren't "supposed" to be narrowly scoped in any language supporting them. – Potatoswatter Feb 18 '10 at 19:25
  • 2
    the "a" variable is defined inner of the while block and exists after the while block goes out – Lucas Feb 19 '10 at 16:01
  • 1
    I believe JavaScript does this too *unless* you put the `var` keyword before the declaration. Python also does this, and there's no way around it AFAIK... really screws you up when you *thought* you redefined the variable later in a different scope, but didn't, and its still using the same value from a previous loop...confusing as hell! – mpen Jul 26 '10 at 18:58
  • in JavaScript, Python and Ruby only functions create scope – Maxim Sloyko Aug 12 '10 at 07:55
2

This is not a strange feature, in fact it makes total sense if you think about it, but gave me a WTF moment nevertheless.

In C++(and in C#), subclasses of a base cannot access private and protected members on the instance of the base.

class Base {
protected:
 m_fooBar;
};

class Derived: public Base {
public:
 void Test(Base& baseInstance) {
  m_fooBar=1; //OK
  baseInstance.m_fooBar = 1; //Badness
  //This, however is OK:
  ((Derived&)baseInstance).m_fooBar = 1; //OK
 }
};
Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128
2

Subjunctive case in English.

Oh wait, did you mean programming languages? Then using (macro) in C to bypass the preprocessor #define of macro(). E.g., if someone has #define free(...), (free)(...) will not be the same as free(...).

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
MSN
  • 53,214
  • 7
  • 75
  • 105
  • "using (macro) in C to bypass the preprocessor #define of macro" -- it doesn't, it bypasses the preprocessor #define of macro(), but if the preprocessor #define of macro doesn't have an lparen then it doesn't get bypassed. – Windows programmer Feb 05 '10 at 03:56
  • Yes, well it's hard to type function macro vs. object macro on an iPhone. – MSN Feb 05 '10 at 06:22
  • What's strange about the subjunctive case (except the name)? – configurator Feb 20 '11 at 04:30
2

In PHP, the following:

<?php $foo = 'abc'; echo "{$foo";

is a syntax error.

If you actually wanted {, followed by the contents of $foo, you'd have to use .:

<?php $foo = 'abc'; echo '{' . $foo;
Ollie Saunders
  • 7,787
  • 3
  • 29
  • 37
2

Processing (processing.org) is a language based on Java. In simple terms, processing compiler is Java preprocessor that translates Processing-specific syntax into Java.

Due to the language's design, it has a few surprises:

Processing's class are compiled into Java inner class, this causes some annoyance, like private variables that isn't really private

class Foo {
  private int var = 0; // compiles fine
}

void setup() {
  Foo f = new Foo();
  print(f.var); // but does not causes compile error
}

also missing draw() function causes event handlers to not be called:

// void draw() {} // if you forgot to include this
void mousePressed() {
  print("this is never called");
}
Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
2

In C++, the ability to create a protected abstract virtual base pure virtual private destructor.

This is a pure virtual private destructor that is inherited from a protected abstract virtual base.

IOW, a destructor that can only be called by members or friends of the class (private), and which is assigned a 0 (pure virtual) in the base class (abstract base) that declares it, and which will be defined later/overriden in a derived class that shares the multiple-inherited base (virtual base) in a protected way.

HTTP 410
  • 17,300
  • 12
  • 76
  • 127
2

Not technically a language WTF, but an architecture one.

http://www.6502.org/tutorials/6502opcodes.html#JMP

6502 assembly, indirect JMP:

Note that there is no carry associated with the indirect jump so:

AN INDIRECT JUMP MUST NEVER USE A

VECTOR BEGINNING ON THE LAST BYTE

OF A PAGE

For example if address $3000 contains $40, $30FF contains $80, and $3100 contains $50, the result of JMP ($30FF) will be a transfer of control to $4080 rather than $5080 as you intended i.e. the 6502 took the low byte of the address from $30FF and the high byte from $3000.

So adding a single byte to your code could make your indirect jump go wildly off target.

Bob Montgomery
  • 360
  • 4
  • 8
2

Perl can automatically convert base 26 into base 10, if you can live with yourself in the morning...

$ perl -E "say lc (@a='a'..'asdf')"
30530
gamache
  • 1
  • 1
2

The rest of these have nothing on the astounding Ruby Flip-Flop Operator:

p = proc {|a,b| a..b ? "yes" : "no" }

p[false,false]    => "no"
p[true,false]     => "yes"
p[false,false]    => "yes"   # ???
p[false,true]     => "yes"
p[false,false]    => "no"

Yes, program state stored in the interpreter's parse tree. Things like this are why it takes forever to make a compliant Ruby implementation. But I forgive you, Ruby <3

jedediah
  • 1,179
  • 9
  • 20
2

s a="a=""a=""""a"""",@a=""""2N"""",a=""""c=""""_(""""22""""?@a),@a"",@a,a=""a"",a(c)=""S+""_c,e=$T(@@a@(c))",@a

this is a nice one-liner in COS (cache objectscript). The funny thing to note here are 5 different modes of code-indirection *G

2

COMEFROM anyone?

Gaurav
  • 227
  • 1
  • 3
  • 11
2

At Ohio State University they teach programming using a bastard C++ language called Resolve/C++. Resolve/C++ uses a design-by-contract methodology to everything. It requires you to mathematically model out components and methods within comments that get compiled so that it forces you to maintain a requires/ensures relationship between methods and objects.

It Grunt
  • 3,300
  • 3
  • 21
  • 35
  • 1
    That's actually sort of cool, although I don't see why they'd stick so adamantly to C++... there are plenty of other languages that have support for design by contract, some that enforce it strictly: http://en.wikipedia.org/wiki/Design_by_contract#Language_support . Maybe it's just me because I started off with C++, but I don't see it as being a very good language pedagogically. – Rei Miyasaka Nov 20 '10 at 00:26
1

In retrospect, FORTRAN's computed goto is pretty odd. Wikipedia tells me some BASICs outdo it.

Another famous favourite is Algol 60's call by name parameter passing.

reinierpost
  • 8,425
  • 1
  • 38
  • 70
1

I've always wondered about the purpose of this function in the Math class of the Java Core library:

static double expm1(double x);  // Returns e^x - 1.
Benno
  • 5,288
  • 5
  • 42
  • 60
  • e^x - 1 occurs a bit much in statistics. – Joshua Jan 04 '10 at 20:00
  • 2
    Maybe, but you could always use exp(x)-1 instead of expm1(x), it doesnt even have more letters. – Benno Jan 05 '10 at 00:22
  • 9
    You should try using this other cool feature called Javadoc. ;) "Note that for values of x near 0, the exact sum of expm1(x) + 1 is much closer to the true result of e^x than exp(x)." http://java.sun.com/javase/6/docs/api/java/lang/Math.html#expm1%28double%29 – Tyler Jan 05 '10 at 05:47
  • (2^32 - 1) might overflow a 32 bit unsigned with the intermediate value, but a function could be written to do the right thing in this case. – billpg Jan 05 '10 at 13:23
  • 20
    e^x-1 is a function which *very* often turns up in physics and engineering and also very often x is quite small. In that case the obvious Math.exp(x)-1.0 is very imprecise. For small x you get 1.0000000yyyyyy as result of Math.exp(x) with yyy... the desired result. As you see the leading 1.0 does nothing than wasting accuracy. – Thorsten S. Jan 06 '10 at 11:47
1

In C#, why is this not legal?

public class MyClass<T>
    where T: Enum
{

}

It'd be pretty cool to be able to add extension methods on Enum's along with Func<T> where the T would be the enum you're extending so that you can get type inference on that enum.

Re the comment: Yes, you can extend an actual enum, but here's the difference:

You CAN do this:

public static void DoSomethingWithEnum(this Enum e)
{
   //do whatever
}

but what if you want to take a Func with your method that would be the same type as your enum:

public static void DoSomethingWithEnum<T>(this T e, Func<T,bool> func )
   where T: Enum
{
   //do whatever
}

That way, you can call your method like so:

DayOfWeek today = DayOfWeek.Monday;
today.DoSomethingWithEnum(e => e != DayOfWeek.Sunday);

or something like that. You get the idea... THAT'S not possible, and I'm not sure why...

BFree
  • 102,548
  • 21
  • 159
  • 201
  • You can use *actual* extension methods to extend an enum. – Erik Forbes Jan 04 '10 at 22:03
  • For your specific example (DayOfWeek), I would extend the DayOfWeek enum explicitly (this DayOfWeek e) rather than the base Enum type. Then you wouldn't need the generic type (or the constraint) at all. Then you would specify a Func - and all would be well. – Erik Forbes Jan 04 '10 at 22:24
  • The example was just an example to prove my point. What if you want to create some method that can work for any enum? What then? – BFree Jan 04 '10 at 22:33
  • Heh, I'm not the only one :-p – BFree Jan 05 '10 at 19:54
  • 1
    @SLaks: be sure to read the comments in Eric's answer. He actually made a mistake in saying the CLR does not support it. It is in the spec and there is a working implementation of a library with such constraints (http://code.google.com/p/unconstrained-melody) – R. Martinho Fernandes Jan 06 '10 at 21:40
1

C# yield statement, not weird but pretty useful.

http://msdn.microsoft.com/en-us/library/9k7k7cf0(VS.80).aspx

senthil
  • 339
  • 3
  • 8
1

This is nothing strange or surprising, but it is something that made me always say WTF:

Case sensitivity in syntax, or in identifier names.

Most languages that have it just seem to have it because C has it. There is no good reason for it.

kes
  • 5,983
  • 8
  • 41
  • 69
  • 6
    It's especially scary for loosely-typed declaration-free languages like Python, which will silently create a new totalsum variable, when really you meant totalSum. – BlueRaja - Danny Pflughoeft Jan 05 '10 at 05:43
  • 15
    I used to think that way, but I've come around to the fact that forcing all instances of the same identifier to use the same casing avoids some problems with later readability/maintenance when someone decides they will add code using a different "spelling". The modern IDE (Intellisense) feature of typing only a few letters of each identifier to type it out helps a lot. However as said, in declaration-free languages case sensitivity is suicide. – David Jan 05 '10 at 14:23
  • 2
    Case sensitivity is not implemented in a language so you can use totalsum and totalSum for different variables. It's there so you don't use it for them both for the _same_ variable. It makes all references to a variable consistent which is a good thing. It's just a side-effect that you can use it for similar-but-different variable names. TRWTF is when people do use it for that purpose. – David Jan 05 '10 at 22:33
  • David: No one intentionally uses totalsum and totalSum as two separate variables. That's the point; it's painfully common to mistakenly use the wrong variable name, it's very tricky-to-debug, and is entirely the fault of the pointless case-sensitivity of the language. – BlueRaja - Danny Pflughoeft Jan 06 '10 at 03:17
  • 1
    @BlueRaja: You're right, in languages where a variable doesn't need to be declared before using it this problem becomes far more sinister. But I have seen variables with different cases but the same name being used in Java. In my perfect world I would have 2 constraints: (1) variable names are case-sensitive AND (2) variable names cannot be the same as other variable names (ignoring case). That way variables names always look exactly the same and cannot be confused with other variables. [For clarity: there are 2 Davids commenting here. Mine was the third comment.] – David Jan 06 '10 at 03:31
  • (First David here) The totalsum/totalSum problem is one that exposes a larger issue, that of consistent naming schemes. It's actually getting consistent naming in a case insensitive language that helped opened my eyes to the long term benefits case sensitivity has for enforcing good coding habbits (making the job of maintenance programming a lot easier). – David Jan 06 '10 at 13:40
  • 1
    In Common Lisp, variable names are case-sensitive (which is really the only way to do it that internationalizes well - case-folding in general is a real can of worms), but the standard reader will upper-case them. (Since CL is an ANSI standard, we don't have to worry about German "ss" or Hungarian "sz" or Turkish "i".) – David Thornley Jan 06 '10 at 16:18
  • 1
    @scrapdog: Jeez, what makes programmers so lazy these days? Hitting shift is complicated? Stressful? What? Because FORTRAN was case insensitive, this is the way to go? Or Basic? Good Lord. If you don't like case, type everything in lower (or upper) case. And deal with the un-readability of the resultant code. Or let future programmers deal with it. – xcramps May 24 '10 at 19:53
  • @xcramps: It has nothing to do with economy of keystrokes. And it has nothing to do with my preference of case. It has only to do with how identifiers are interpreted. Case sensitivity in identifiers affords the programmer the ability to use the same word, differentiated only by case, for two or more different variables. A benefit not worth the cost of the problems it causes. This adds to confusion, it doesn't ameliorate it, it introduces many more ways to shoot oneself in the foot, and it *detracts* from readability. – kes May 24 '10 at 21:02
  • Of course, a good compromise would be to enforce case-sensitivity, while allowing only one instance of a particular word to exist. In other words, once you define "myIdentifier", you can only refer to it as "myIdentifier", and furthermore, this would preclude "MyIdentifier" and "MYIDENTIFIER" from being defined. – kes May 24 '10 at 21:10
  • ...that uppercase and lowercase are two different sets of numbers in ASCII and UTF-8 is probably why... – Talvi Watia Jun 11 '10 at 03:48
1

In SQL Server you may end up with a nasty surprise if you use select * in your production code. Using select * is not considered as a good practice anyway but it is good to know of some of the interesting behaviour.

See question “select * from table” vs “select colA,colB,etc from table” interesting behaviour in SqlServer2005 for more details

Community
  • 1
  • 1
kristof
  • 52,923
  • 24
  • 87
  • 110
1

Haskell's use of Maybe and Just. Maybe a is a type constructor that returns a type of Just a, but Maybe Int won't accept just an Int, it requires it to be a Just Int or Nothing. So in essence in haskell parlance Just Int is about as much of an Int as an apple is an orange. The only connection is that Just 5 returns a type of Maybe Interger, which can be constructed with the function Just and an Integer argument. This makes sense but is about as hard to explain as it can theoretically be, which is the purpose of haskell right? So is Just really JustKindaLikeButNotAtAll yea sorta, and is Maybe really a KindaLooksLikeOrIsNothing, yea sorta again.

-- Create a function that returns a Maybe Int, and return a 5, which know is definitly Int'able
>  let x :: Maybe Int; x = 5;
<interactive>:1:24:
    No instance for (Num (Maybe Int))
      arising from the literal `5' at <interactive>:1:24
    Possible fix: add an instance declaration for (Num (Maybe Int))
    In the expression: 5
    In the definition of `x': x = 5

>  Just 5  
Just 5
it :: Maybe Integer

    -- Create a function x which takes an Int
>  let x :: Int -> Int; x _ = 0;
x :: Int -> Int
-- Try to give it a Just Int
>  x $ Just 5                   

<interactive>:1:4:
    Couldn't match expected type `Int' against inferred type `Maybe t'
    In the second argument of `($)', namely `Just 5'
    In the expression: x $ Just 5
    In the definition of `it': it = x $ Just 5

Good luck reading this, I hope its right.

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
  • 2
    It makes perfect sense in a statically typed language for a function expecting arguments of type `Foo` to refuse arguments of type `Bar`. `Just` is a function `a -> Maybe a`, `Nothing` is a `Maybe a`, `fromJust` is a function `Maybe a -> a`. Hope this helps. – R. Martinho Fernandes Jan 06 '10 at 22:03
  • This makes sense but is about as hard to explain as it can theoretically be. If it was called NotJust and NotJustOrNothing, I would think it would be massively easier to comprehend. – Evan Carroll Jan 07 '10 at 16:43
  • 6
    The only WTF is how you're totally missing the point. I don't know your background, but take String in Java, for example. It is actually a "Maybe" String, because it can be String or null. Unfortunately, the compiler does nothing to prevent you from using it as a String, which cause the dreaded null pointer exception. Well, Haskell doesn't have null. If you do something that may or may not return a result, such as getting the index of a character in a string, then you return Maybe Integer. The receiving code uses pattern match to distinguish between Just Integer and Nothing. – Daniel C. Sobral Jan 08 '10 at 02:12
1

What datatype is foo?

SELECT TOP 1
   NULL AS foo
INTO
   dbo.bar
FROM
   sys.columns --trivial

Why does everything go to zero?

SELECT CAST('' AS int), CAST('' AS datetime), CAST('' AS float)

...except this

SELECT CAST('' AS decimal)
gbn
  • 422,506
  • 82
  • 585
  • 676
1

In MySQL string comparisons are case-insensitive.

> SELECT * FROM blah WHERE foo = 'BAR';
> SELECT * FROM blah WHERE foo = 'Bar';
> SELECT * FROM blah WHERE foo = 'bAr';

Are all equivelent. Not only that they will match any value of foo that looks like 'bar' (e.g. if foo = 'bar' it will match for BAR, baR, bAR, etc.).

1

Not so long ago, when I first descoverd the C Language in my CS class, it was very strange to see the way pointers behaived. we just wrote programs and guess what it would do, until they get the right behavior

iChaib
  • 469
  • 4
  • 10
  • 17
1

The C preprocessor and its usages. Specifically preprocessor metaprogramming and using the preprocessor to generate portable code -- total mindfcuk.

Hassan Syed
  • 20,075
  • 11
  • 87
  • 171
1

Labeled break and continue statements in Java..

They allow you to break out of multiple control-blocks with a single break.

1

C# has a feature called "extension methods", which are roughly analogous to Ruby mix-ins - Essentially, you can add a method to any pre-existing class definition (for instance, you oould add "reverse()" to String if you were so inclined). That alone is fine- The "Weird" part is that you can add these extension methods, with a method body and everything, to an interface. On the one hand, this can be handy as a way to add a single method to a whole swath of classes which aren't part of the same inheritance tree. On the other, you're adding fleshed out methods to interfaces, essentially breaking the very definition of an interface.

callingshotgun
  • 763
  • 2
  • 8
  • 17
  • 3
    Unfortunately you cannot do everything you can with Ruby mixins, especially adding per-instance state (without doing crazy stuff with dictionaries...). Also, extension methods do not break the definition of an interface in any way. You are not breaking the contract. You are not adding *anything* to the interface. The ability to call it as if it was part of the interface is just syntax sugar. Extension methods are just like any other static helper method, with that fine sugar on top. – R. Martinho Fernandes Jan 07 '10 at 19:25
  • I think this is a pretty usefull feature. Although it doesn't fare well when ofuscating code. – David Brunelle Jan 07 '10 at 19:32
1

Try, except, else

try:     pass
except:  pass
else:    pass
finally: pass

If no exception was caught the else part is executed.

Makes sense, but at first I really hadn't any clue what it does.

Example:

def show_square(string):
  try:
    n = int(string, 10)
  except ValueError:
    print "I can't do that, Dave."
  else:
    print n * n
Community
  • 1
  • 1
Mene
  • 3,739
  • 21
  • 40
  • 5
    Since I've learned this feature in Python, I'm really missing it in other languages. – vit Jan 07 '10 at 21:28
  • It doesn't seem useful; it's equivalent to putting the `print n * n` after the `n = int(string, 10)` – RCIX Jan 10 '10 at 10:14
  • No it isn't. The `else` block is only executed if an exception is raised but isn't of type (in this case) `ValueError`. – Chinmay Kanchi Jan 11 '10 at 00:42
  • 1
    @Chinmay Kanchi: That's wrong too, else block is executed if no exection where raised at all. If error happens in else block it isn't caught (as opposed to print n*n being put after n=int(...)) and if exception is raised and processed in except clause, else block isn't executed (as opposed to print being put after all try..except structure) – ymv Jan 11 '10 at 14:50
  • I wouldn't really call this a "strange" feature.. its too useful in most languages. – Talvi Watia Jun 11 '10 at 02:26
1

Python's ternary operator

In Python, the C ternary operator (C++ example: bool isNegative = i < 0 ? true : false;) is available as syntactic sugar:

>>> i = 1
>>> "It is positive" if i >= 0 else "It is negative!"
'It is positive'
>>> i = -1
>>> "It is positive" if i >= 0 else "It is negative!"
'It is negative!'

It's not really strange but a feature. The odd thing is the changed order (A if CONDITION else B) in comparison to the (IMO more logical) order in C (CONDITION ? A : B).

AndiDog
  • 68,631
  • 21
  • 159
  • 205
  • IIRC it's justified by looking at first (True) value as primary and second value as fallback (like in x = int(x) if x is not None else 0). – ymv Jan 11 '10 at 14:39
1

In C, a[b][c] is exactly the same thing as c[b[a]].

1

In PHP, you have to explicitly reference globals and explicitly use this-> for class variables. Makes refactoring fun. You cannot promote a variable/argument to a global or a class member without finding all points of usage.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
1

Perl

my %h1 = map { $_ => 1 } qw/foo bar baz/;    // construct an 'is_member' type lookup table
my %h2 = map { "$_" => 1 } qw/foo bar baz/;

the second line is a syntax error even though to even an experienced perl programmer it looks like it would be identical. The downside to perl always trying to do what you mean, not what you said.

Rob Van Dam
  • 7,812
  • 3
  • 31
  • 34
1

this made me stunning

#define _ -F<00||--F-OO--;
int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
{
            _-_-_-_
       _-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
       _-_-_-_-_-_-_-_
           _-_-_-_
}
binaryguy
  • 1,167
  • 3
  • 12
  • 29
  • 2
    Note that the program relies on non-ANSI preprocessor feature, that `_-` is expanded to `--F`. In ANSI C, it is two separate tokens, so expands to `-` followed by `-F`. The output is therefore not the value of pi as the author intended. See http://stackoverflow.com/questions/841646/is-define-supposed-to-add-spaces-around-macros for more. – Alok Singhal Jan 08 '10 at 22:44
  • There's the International Obfuscated C Code Contest for that purpose exactly to come up with weird C code that does actually work... http://www.ioccc.org – t0mm13b Jan 10 '10 at 02:33
  • 7
    -1. This is, IIRC, an IOCCC entry to calculate PI. What is the strange language feature here? –  Jan 10 '10 at 08:59
  • but pi is not 0.267...compiled with gcc 4.3.2 – Kai Jan 11 '10 at 23:59
  • @Roger: The *C preprocessor* is the strange language feature here. – David R Tribble Feb 02 '10 at 21:27
  • @Kai, the code relies on old preprocessor "features", see my comment above (the first comment to this post) for more. – Alok Singhal Feb 19 '10 at 06:16
  • The center of area in an equilateral triangle to one point works better... ;) – Talvi Watia Jun 11 '10 at 01:56
1

Smalltalk:

Have a class method in a class Test, that returns a constant string:

method1
    ^ 'niko'

You should expect that this method constantly returns the string 'niko' whatever happens. But that is not the case.

s := Test method1 

(Set s to 'niko'.)

s at: 4 put: $i.

(Set s to 'niki'.)

s := Test method1

(Set s to 'niki' again.)

So, what happens is that the second line of code permanently changed method1 to return 'niki' rather than 'niko', even though the source code of the method was not updated.

nes1983
  • 15,209
  • 4
  • 44
  • 64
1

shift;

sometimes you see it in the very first line of a perl method to get read of self pointer

Nylon Smile
  • 8,990
  • 1
  • 25
  • 34
1

In ColdFusion

Struct (aka Java HashMap) is passed by reference.

You'd have thought other data type behaves like Java...

Array is passed by value, wtf!

List is just a plain old comma-separated string!

Henry
  • 32,689
  • 19
  • 120
  • 221
1

In Unity,

GameObject.Find("MyObject")

will return your object normally. However, if you do something like this:

GameObject.Find("MyObject").active = false;
//do other stuff
if (GameObject.Find("MyObject").active)
{
    //do stuff
}

Then you will get a null reference. In Unity iPhone, this code will often work fine in the editor but will cause a SIGBUS when running from the iPhone. The problem is that GameObject.Find() will only locate active objects, so even if you're just checking to see if it's active, you are effectively calling if (null.active) .

To make it work right, you've got to store it prior to making it inactive.

GameObject obj = GameObject.Find("MyObject");
obj.active = false;
//do other stuff
if (obj.active)
{
    //do stuff
}

Arguably that's better practice anyway, but the way Unity treats inactive objects in general is quite weird. It appears to unload a large portion of the inactive object (textures, etc.) but not all of it, so inactive objects can still eat up a lot of memory.

Eli
  • 4,874
  • 6
  • 41
  • 50
  • Don't know this "unity" but that sounds perfectly logical to me. How is it supposed to know what to unload from memory? It probably just makes guesses because you might want to reactivate them later... I'm sure you can delete them if you really want to free the memory. – mpen Jul 26 '10 at 19:05
  • Yes, you can delete them. That functionality is not what's weird. It's that there is no way to locate an inactive object in order to completely delete it unless you stored it otherwise. It just doesn't match they way they encourage people to use their scenegraph. – Eli Aug 13 '10 at 18:57
1

In J, most primitives (a.k.a. functions) are monadic (one argument) or dyadic (two arguments, one to the left, one to the right). But the amend primitive takes 3 (I think it's the only one, besides foreigns). It's understandable that it would take 3, but it just looks... wrong at first.

vector =: i. 10   NB. Vector will be 0 1 2 3 4 5 6 7 8 9
(10) (0) } vector NB. Will yield 10 1 2 3 4 5 6 7 8 9
MPelletier
  • 16,256
  • 15
  • 86
  • 137
1

In J, foreigns (!:) are various functions bunched together. The left argument is a category, where as the right are often (but not always) incremental values for different... stuff. For example:

    2!:55 NB. Close console
    9!:10 NB. Set print precision
    6!:0  NB. Actual time
    6!:2  NB. Execution time
    4!:3  NB. Loaded scripts

Of course, the smart thing is to wrap them, but some you just commit to memory. BTW, all of those are, come to think of it, triadic, with 2 arguments to the right and one to the left. None of the above will work unless you give them a final valid argument.

MPelletier
  • 16,256
  • 15
  • 86
  • 137
1

In awk, arrays start at index 1, which is confusing the least.

helpermethod
  • 59,493
  • 71
  • 188
  • 276
  • awk isn't the only language where arrays start at index 1, Lua does that do, and AFAIK perl as well. –  Feb 01 '11 at 19:54
1

In Python, at least for me, this was very wft! the first time I saw it:

>>> "ja " * 5
'ja ja ja ja ja '

You can multiply strings! WTF??

PS: I think this is because x * n means: n times x so, 5 times "ja " is "ja ""ja ""ja ""ja ""ja " and because you can concatenate strings like this:

>>> "ja ""ja ""ja ""ja ""ja "
'ja ja ja ja ja '

That two codes have the same result (and maybe are just the same)

Lucas Gabriel Sánchez
  • 40,116
  • 20
  • 56
  • 83
  • The "explanation" might make it easy for you to remember string multiplication, but note that `5 5 != 25`. In Python, two adjacent strings are combined to make a string - this is taken directly from C. – Alok Singhal Jan 19 '10 at 00:54
  • Yes.. that's what I mean. I've never say that "5" * "5" is "25" no.. I've said that "5" * 5 is "5""5""5""5""5" that, and "55555" is the same string.. – Lucas Gabriel Sánchez Jan 19 '10 at 03:53
  • The asterisk isn't anything special in python (besides that it's a built in symbol). It doesn't mean "multiply this". You can specify it to mean whatever you want, simply by altering the __mul__ method of your class. "myclassinstance * something" is just another way of saying "myclassinstance.__mul__(something)". – Tor Valamo Jan 22 '10 at 02:40
  • Ok. but for me it still very strange that stringinstance.__mul__(number) have that result (at least for me) – Lucas Gabriel Sánchez Jan 22 '10 at 15:35
  • Well, what *other* result would you expect from multiplying a string by a number? There really isn't any other logical output IMO. – mpen Jul 26 '10 at 19:00
1

The implict variables\constants and mutable constants in ruby

Lucas
  • 3,059
  • 5
  • 33
  • 48
1

In C#, the following code generates compiler error "Cannot convert from method group to Delegate". Though the logic behind is reasonable, it still feels strange to me.

control.BeginInvoke(delegate { DoSomething(); });
Dudu
  • 1,264
  • 13
  • 14
1

A Java source file can end with the character \u001a (control-Z).

An̲̳̳drew
  • 13,375
  • 13
  • 47
  • 46
  • In CP/M, a `\x1A` would mark "end of file"... I can't imagine it being used on a modern system though. Anyway, Python (v3 at least) also treats this as end of file. – user1686 Feb 23 '10 at 13:54
  • 1
    Quite a few C compilers still recognize this as well. – Joshua Aug 13 '10 at 21:11
  • Ctrl+Z as a text file terminator comes from all the way back in the days of CP/M, which was what MS-DOS was based on. Many apps still support this for some reason. – David R Tribble Sep 14 '10 at 14:22
1

In Java, there is some inconsistency as to how Strings handle the == operator depending on how it was constructed.

String a = "Hello";
String b = "Hello";
System.out.println(a == b ); // prints true.
String c = new String("Hello");
String d = new String("Hello"); 
System.out.println(c == d ); // prints false
Jacob Bellamy
  • 769
  • 2
  • 10
  • 16
  • 7
    The behavior is consistent, as it only compares the references, a and b reference the same interned string while c and d reference two different string objects. Only compare java objects with == if you want to check for the same instance, if you want to compare two objects use c.equals(d). Using == to compare strings just asks for trouble – josefx Feb 09 '10 at 13:57
  • Yep. You could do both, which might be slightly faster: `c == d || c.equals(d)`. But you must call `equals()`, or intern both strings, to get the right result. This differs from C# behavior, BTW. – David R Tribble Sep 14 '10 at 14:18
1

Here is one about python:

>>> print 07
7
>>> print 08
  File "<stdin>", line 1
    print 08
           ^
SyntaxError: invalid token

Ain't that a beauty?

Especially unthoughtful when you think of how human write dates, which has the following effect:

datetime.date(2010,02,07) # ok
datetime.date(2010,02,08) # error!

(the reason is that 0x is interpreted as octal, so print 010 prints 8!)

Olivier Verdier
  • 46,998
  • 29
  • 98
  • 90
1

In Scheme there are no reserved identifiers. So, the following expression evaluates to 1:

((lambda (lambda) lambda) (let ((let 1)) let))

Note that there is a restriction on definitions within a given scope: no definition may redefine an identifier used to define identifiers within that scope, so the following is a syntax error:

(begin (define define 1) define)
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • Or the Y-combinator: `((ƛ (ƛ) (ƛ ƛ)) (ƛ (ƛ) (ƛ ƛ)))` is the simple version that requires an applicative-order compiler, and `((ƛ (ƛ) (ƛ ƛ)) (ƛ (ƛƛ) (ƛ (ƛ) ((ƛƛ ƛƛ) ƛ))))` works on standard compilers IIRC. – configurator Feb 20 '11 at 05:15
1

Well the first thing that came to my mind was 'noop', my brain did the same thing when I first came across it!

MikeAinOz
  • 126
  • 1
  • 10
  • 24
1

I don't know if it's still true, but we discovered by accident that VS FORTRAN(66 or 77) will not support recursion. The recursion was accidental and our default F77 supported it beautifully, but when we took the source to an IBM - Whatta Mess.

Dave
  • 1,234
  • 13
  • 24
  • I recall being frustrated when I read somewhere in the texinfo files of g77 that the recursive keyword is not supported and that all recursion can be turned into loops. That's probably why we used a commercial compiler instead (which supported this as an extension to fortran 77). I guess this has to do with the fact that arguments seem to be passed as references to functions in FORTRAN. – Andre Holzner Aug 14 '10 at 07:39
  • FORTRAN did not support recursive subroutines for decades. It has nothing to do with pass-by-reference, but by the way the call stack is statically allocated. – David R Tribble Sep 14 '10 at 14:15
  • VS FORTRAN is / was the "flagship" FORTRAN for IBM for both VM and MVS. I suspect that they didn't support recursion because of their policy that old code is still linkable and runable on their newest machines and at that point they still were supporting FORTRAN-H and allowing the two to be linked. I also suspect that this is no longer true (having been over 10 years since I worked with big blue) – Dave Sep 14 '10 at 16:42
1

"dynamic" in C#.

Ruins the day for everyone who has to work together with a RAD or python victim because Intellisense, type safety and determinism die instantly with the first use of the "dynamic" keyword.

  • Didn't know they added that! That's sweet. Type safety is one of the things I love about C# and one of the reasons I want to switch my web development from Python over to C#... however, this could also come in handy. – mpen Jul 26 '10 at 18:30
  • With power comes responsibility! – Rei Miyasaka Sep 14 '10 at 18:44
1

In ColdFusion text values are converted to various data types automatically for various purposes. I hit an odd problem where "00A" and "000" were being return as equal. It turned out that ColdFusion was interpreting "00A" as a time, converting to some sort of numeric time format, and converting it to 0. "000" was being converted to 0. So they were both considered equivalent. That is when I learned about the compare function for strings.

Dan Roberts
  • 4,664
  • 3
  • 34
  • 43
1

I built a language with a BUT clause once, a long time ago.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • is that similar to an else or otherwise clause? – scunliffe Aug 14 '10 at 13:41
  • Do you have any examples of this but clause? – Joe D Aug 14 '10 at 18:12
  • It was a string processing language, something like scan a until 'x' but if not found do y. It was a bit of an in-joke, really, one of the participants had always wanted a language with a BUT modifier in it. – user207421 Aug 15 '10 at 01:04
  • This is similar to the syntax of several languages that string together expressions separated by logical operators, like `expr1 || expr2 || expr3`. The execution stops at the first expression that evaluates to true. – David R Tribble Sep 14 '10 at 14:06
1

And again Haskell:

In Haskell you can handle an arbitary size file, as if it is a simple String. The file will be only read, if the string is actually used. Because of the incredible laziness of Haskell, a program like this will run in constant space, regardless of the file's size:

main = interact (>>= \x -> if x == '\n' then "\r\n" else [x])

(This program convert's a file from stdin to stdout and replace LF by CRLF, the interact function input's the whole stdin to a function and moves the output to stdout.)

This laziness may also cause problems, because if you close a file handle, you cannot be completely shure, whether lazy Haskell has already parsed all the data from it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
fuz
  • 88,405
  • 25
  • 200
  • 352
1

I came across this one while trying to figure out a MACRO that made absolutely no sense but worked anyway. This is true for objective-c but might be also true for other flavors of C (or at least the gcc compiler)

NSString *oneString = @"This " @"is " @"just " @"one " @"normal " @" string";

equals

NSString *oneString = @"This is just one normal string";

It's also true for C style strings

char* str = "this " "also " "works";
Marius Gedminas
  • 11,010
  • 4
  • 41
  • 39
Ron Srebro
  • 6,663
  • 3
  • 27
  • 40
  • 1
    I miss this feature in C#. This is very useful if you have a long string that needs to be wrapped -- you don't need to remember to add explicit concatenation. – liori Oct 29 '10 at 17:56
  • 1
    Actually after I did something I did realise that I've been using this feature all the time for long strings, I just never tried it in the same line, and when it is in the same line, it just looks so strange. – Ron Srebro Oct 30 '10 at 14:25
1

Go's pseudo-constant Iota:

type ByteSize float64
const (
_ = iota;   // ignore first value by assigning to blank identifier
KB ByteSize = 1<<(10*iota); MB; GB; TB; PB; YB;
)   
mdm
  • 5,528
  • 5
  • 29
  • 28
1

Tcl's virtualize the sense of time hooks in the interpreter are pretty weird: http://www.tcl.tk/cgi-bin/tct/tip/233.html

Basically it allows you to make the interpreter use some other source of time data, e.g. to run hardware tests in a simulator first and than later just replace the timer functions and run the identical tests against the real thing.

schlenk
  • 7,002
  • 1
  • 25
  • 29
1

Call/cc. Call/cc passes a function representing the rest of the program to its body.

1

In JavaScript, 2.0 - 1.1 = 0.8999999999999999. This is a result of the implementation of floats in the specification, so it will always be like this.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Zeki
  • 5,107
  • 1
  • 20
  • 27
  • 13
    This is well-known behavior and is true in almost every single language. – SLaks Jan 06 '11 at 01:27
  • Not true, in java 2.0-1.1 == 0.9 is true. But in javascript 2.0-1.1==0.9 is false. – Zeki Jan 06 '11 at 02:55
  • 2
    @Zeki: If you use `float`, you get 0.9 while if you use `double` you get 0.8999999999999999. Since `double` is Java's default floating point type and float is rarely used in practice, it's pretty safe to say that this does occur in Java too. – Esko Jan 06 '11 at 08:42
  • @configurator: As opposed to what? Are there any languages that don't? – SLaks Feb 20 '11 at 12:00
  • @SLaks: Languages that use fixed-point decimals, or rational numbers. For example, SQL uses fixed-point, and some implementations of Lisp use rationals (and will reply with either `0.9` or `9/10` to this query). – configurator Feb 20 '11 at 17:21
0

Here's one I thought was weird:

In C/C++ you can have as many semicolons as you want at least in the MS C++:

int main(void)
{
 cout<<"Hello World";;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;
 return 0;;;;;;;;;;;;;;;;;;;;;;;
}
Daniel
  • 75
  • 1
  • 5
  • It s just closing a void statement :3. More languages support this. – Dykam Jan 04 '10 at 21:55
  • 28
    That's got nothing on `#define EVER ;;`. You know.... `for(EVER){ ... }`. *i run away and hides now* –  Jan 05 '10 at 01:16
  • It's the equivalent of asm's NOP function ("No Operation") which simply does... nothing. I would expect the compiler to optimize this away though. I've seen this used many many many years ago in a loop intended to cause a delay: "for(int i = 0; i < 2000000000; i++) ;" which basically does nothing but increment i. (Never do stuff like that though, it will hurt you later: http://www.merlyn.demon.co.uk/pas-r200.htm#R200) – Michael Stum Jan 05 '10 at 01:17
  • 5
    it's not the equivalent of nop - nop has side-effects such as skipping a cycle which might help the CPU to cool down a bit. C\S* languages simply don't generate any machine code for void statements. – Tamas Czinege Jan 05 '10 at 16:25
  • 8
    @fennec - I prefer `#define ever (;;)` so I can say `for ever { ... }`. I also like `#define forever while(1)` so I could make the same statement work as both `forever { ... }` and `do { ... } forever;` – Chris Lutz Jan 07 '10 at 06:14
0

In C++, I find it strange and distasteful that "virtual" MI (multiple inheritance) allows the "diamond-shape" class hierarchy to "work"

A : Base class, e.g. "Object"
B, C: both derive (virtually or not) from Object and 
D: derives from both B and C

Problem: "normal" inheritance causes D to be 2 ambiguous kinds of A. "virtual" MI collapses B's A and C's A to a single shared base A object.

So, even if your Wheel is an Object and your Left Front Wheel is a Wheel and your Car inherits four kinds of Wheel, your Car is still only one kind of Object with virtual MI. Otherwise, your Car is not an Object, but 4 Wheel-y Objects.

This is one language feature that rewards poor class design, punishes compiler writers, and leaves you wondering at run-time where the heck the Object really is - and if any virtual MI baggage was misplaced.

If you really need the diamond pattern in your class hierarchy, it can be accomplished with regular MI and an "AProxy" that delegates to the single A base.

 A : Base class, e.g. "Object"
AProxy: Base class, constructs with other A to bind to
B : derives from A
C : derives from AProxy
D : derives from both B and C (passing B's A to C's AProxy at construction)

This requires a little more work for those that really like diamond MI and leaves the rest of us in peace with a more tractable set of language features.

reechard
  • 861
  • 6
  • 22
  • 1
    The problem here is that you are making a car inherit from a wheel. Is a car a type of wheel? No. A car *contains* four wheels. Using inheritance at all in this case is unjustified. – Jeremy Salwen Feb 06 '10 at 03:03
0

in Java

String("aaa")==String("aaa") //false
//you need to use
String("aaa").equals(String("aaa")) // true
  • 5
    That's because java doesn't have operator overloading, with the exception of `+` for String types, coming from a C background this is completely expected behaviour. – Joe D Aug 17 '10 at 15:16
  • 1
    To be even more specific, if the first line would be true, the String class would differ even more from all other classes in java – Viktor Sehr Aug 17 '10 at 22:02
  • why is this down voted. Its very strange. The fact that there is an explanation for it doesnt make it less surprising or strange – pm100 Aug 20 '10 at 22:46
  • 1
    +1 because it's not obvious that '==' often fails when working with strings. If you have a variable 'myStr' equal to 'hello', writing myStr=="hello" does not always work (I could be wrong but think it would work if the compiler is able to inline "hello"). – Jon Onstott Sep 16 '10 at 16:16
  • 1
    I wouldn't call it a "strangest" language feature, just one of the "poorest" language features. – EMP Oct 18 '10 at 21:59
  • +1. I agree. It is a "strange" feature if you don't know Java and come from a C background – Shervin Asgari Nov 12 '10 at 13:08
  • @Shervin: you're saying that in C, `==` works on strings as the equality operator? Why is there `strcmp` then? – R. Martinho Fernandes Nov 20 '10 at 04:11
  • `C++` was what I meant` http://www.java2s.com/Tutorial/Cpp/0300__string/Stringequals.htm – Shervin Asgari Nov 20 '10 at 16:01
  • And aren't ther two "new"s missing? – Axel Dec 20 '10 at 10:27
  • You don't catch the difference between reference equality and the object equality. – Danubian Sailor Jan 07 '11 at 09:01
0

In C,

 int x = 1;
 int y = x++ + ++x;
 printf("%d", y);

Is ambiguous, what gets printed depends on the compiler. The compiler could store the new value of x++ before ++x is evaluated, or at the end of the statement.

TDJoe
  • 1,388
  • 1
  • 10
  • 15
  • 4
    it is undefined. You can't change a variable in different places in a statement, that is undefined; not ambiguous. – Özgür Aug 21 '10 at 01:50
  • However, I would not say it's ambiguous or undefined or whatever else, even FFJoe used a very old piece of code that many people are familiar with. It's more a C bug or something like those weird things. A programming language should always have the same behavior even for expressions, the most core part of a language. The expression that has been depictured above, I think, always should be deterministic since it always have some defined precedence rules. Sorry, cannot compose sentences in English together well. – Lyubomyr Shaydariv Sep 12 '10 at 17:05
  • The problem is that the C language allows operations to occur in any order between sequence points, in order to allow compilers to optimize expressions. The only sequence point in the 2nd line is at the assignment operator, so all of the other operations can take place in any order, according to what the compiler deems the most efficient. Dictating more constraining (more "deterministic") rules about execution order would inhibit optimizations. – David R Tribble Sep 14 '10 at 14:03
  • @Lyubomyr: it is undefined and has been discussed many times here on StackOverflow. [Prasoon Saurav](http://stackoverflow.com/users/165520/prasoon-saurav) summed it up nicely in [this answer](http://stackoverflow.com/q/4176328/238902) – default Nov 15 '10 at 07:43
0

Delphi don't care about typecast like "word" and will read outside of array arr[0..65535] where pos = 65535: arr[word(pos + 10)]

Vladimir
  • 1
  • 2
  • Indeed, it **does** care about the cast and will read **inside** the array: What you wrote is equivalent to arr[9] because the cast tells the compiler `I know what I do` and generates a wraparound. If you just had written arr[pos + 10] you would get the range error you probably expect. (Tested with D2007 and $RANGECHECKS ON.) – Uli Gerhardt Jun 06 '11 at 07:27
0

In PHP:

<?php
$o = new stdClass;
echo count($o);
?>

..prints 1. Never figured out why.

Robin
  • 4,242
  • 1
  • 20
  • 20
  • because it's one object? (just guessing) – Jeff LaFay Nov 12 '10 at 14:08
  • 1
    It's right in the docs - http://us.php.net/count. "If var is not an array or an object with implemented Countable interface, 1 will be returned. There is one exception, if var is NULL, 0 will be returned." – Nicole Nov 12 '10 at 16:56
0

PHP (again?)

First: (unset) type casting.

$a = 1;
$b = (unset)$a;
var_dump($a); // 1
var_dump($b); // NULL

Usage: http://www.php.net/manual/en/language.types.type-juggling.php#89637

Second: difference between = NULL and the unset() function.

$c = 10;
$d = &$c;
$c = NULL;
var_dump($c); // NULL
var_dump($d); // NULL


$e = 10;
$f = &$e;
unset($e);
var_dump($e); // NULL
var_dump($f); // 10 - WTF?
Vili
  • 1,599
  • 15
  • 40
  • Are your `var_dump` s on the first example backwards? Also, the difference between `= NULL` and `unset` is interesting would it makes sense. I woulnt say it's a WTF. – Nicole Nov 29 '10 at 08:56
  • No, that's just a type cast, it doesn't really unset $a. – Vili Nov 29 '10 at 09:01
  • On the second one: $d is referencing to the value of $c, thus if you set $c's value to NULL, $d will follow. Because they point to the same value. If you unset $e, $f will point to 10 anyways. That's because $f is not pointing to $e, but $e's value. It's written in the manual. But it's confusing. – Vili Nov 29 '10 at 09:09
  • Right, sorry. I just realized I had a typo, I meant *but* it makes sense. I think I was typing on my phone :) That `(unset)` cast really is completely useless. In the example you linked to, the only reason why it really saves one line is kind of a unique case anyway. – Nicole Nov 29 '10 at 20:34
0

This C program prints a different result on x86 vs. x86-64:

#include <stdio.h>
int main (void)
{
  long a = -1; 
  unsigned b = 1; 
  printf ("%d\n", a > b); 
  return 0;
}
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
0

For those who never worked with COBOL, this is a common line of code but it doesn't do what you might be thinking about

PIC XXX

The_Black_Smurf
  • 5,178
  • 14
  • 52
  • 78
  • 7
    Heh, I was stupid enough to google that literally (`pic xxx`), it turns out that COBOL is full of `XXX Pic`'s. – Joe D Dec 15 '10 at 18:34
0

С#:

var a = Double.Parse("10.0", CultureInfo.InvariantCulture); // returns 10
var b = Double.Parse("10,0", CultureInfo.InvariantCulture); // returns 100

In invariant culture comma is not decimal point symbol, but group separator.

As I know, it's common mistake for novice programmers from some locales.

Alex
  • 2,438
  • 23
  • 30
-1

PHP

PHP has inconsistent handling of overloading for instance variables and methods. Consider:

class Foo
{
    private $var = 'avalue';

    private function doStuff()
    {
        return "Stuff";
    }

    public function __get($var)
    {
        return $this->$var;
    }

    public function __call($func, array $args = array())
    {
        return call_user_func_array(array($this, $func), $args);
    }
}

$foo = new Foo;
var_dump($foo->var);
var_dump($foo->doStuff());

The dump of $var works. Even though $var is private, __get() is invoked for any member which doesn’t exist or is inaccessable, and it returns the correct value. This is not the case for doStuff(), which fails with:

Fatal error: Call to private method Foo::doStuff() from context ”.”

I think a lot of these work in C-style languages, but I’m not sure.

  1. Pass a here document as a function argument:

    function foo($message)
    {
        echo $message . "\n";
    }
    
    foo(<<<EOF
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc
        blandit sem eleifend libero rhoncus iaculis. Nullam eget nisi at
        purus vestibulum tristique eu sit amet lorem.
    EOF
        );
    
  2. You can assign a variable in an argument list.

    foo($message = "Hello");
    echo $message;
    

    This works because an assignment is an expression which returns the assigned value. It’s the cause of one of the most common C-style bugs, performing an assignment instead of a comparison.

Python

In Python, mutable default function arguments cause unexpected results:

def append(thing, collection=[]):
    collection.append(thing)
    return collection

print append("foo")
# -> ['foo']
print append("bar")
# -> ['foo', 'bar']
print append("baz", [])
# -> ['baz']
print append("quux")
# -> ['foo', 'bar', 'quux']

The empty list is initialized at function definition time, not call time, so any changes to it persist across function invocations.

MySQL Case Sensitivity

MySQL has really unusual case sensitivity rules: Tables are case sensitive, column names – and string values aren't:

mysql> CREATE TEMPORARY TABLE Foo (name varchar(128) NOT NULL);
DESCRIBE foo;
ERROR 1146 (42S02): Table 'foo' doesn't exist
mysql> DESCRIBE Foo;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| name  | varchar(128) | NO   |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.06 sec)
mysql> INSERT INTO Foo (`name`) VALUES ('bar'), ('baz');
Query OK, 2 row affected (0.05 sec)

mysql> SELECT * FROM Foo WHERE name = 'BAR';
+------+
| name |
+------+
| bar  |
+------+
1 row in set (0.12 sec)

mysql> SELECT * FROM Foo WHERE name = 'bAr';
+------+
| name |
+------+
| bar  |
+------+
1 row in set (0.05 sec)
ieure
  • 2,381
  • 1
  • 16
  • 16
-1

In C:

int main() {
  int i = 0;
  int array[] = {1,2};

  return (i[array] + 1 == array[i]);
}

This program will return 1 (true).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-2

Anything will autometic pluralizes or singularizes any class and member names.

Linq-to-Sql, for example

Dennis C
  • 24,511
  • 12
  • 71
  • 99
-2

Don't know if it is a feature or not. For some, yes, but for others it might be an annoying behavior. Anyway, I think it's worth mentioning.

In Python, the builtin function round() behaves a bit differently between Python 2x and Python 3x.

For Py 2x,

>>> round(0.4)
0.0
>>> round(0.5)
1.0
>>> round(0.51)
1.0
>>> round(1.5)
2.0

For Py 3x,

>>> round(0.4)
0
>>> round(0.5)
0
>>> round(0.51)
1
>>> round(1.5)
2

I'm just not familiar with the way round() in Py 3x works with 0.

Docs for round() in Py 2x and Py 3x.

user247468
  • 147
  • 6
  • There is more than one way of breaking rounding ties when you're halfway (i.e. X.*5*). Python 2's is rounding away from zero (http://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero). Python 3's one is called banker's rounding: http://en.wikipedia.org/wiki/Banker's_rounding. It has several advantages over the old one, and it is the default in IEEE754. – R. Martinho Fernandes Nov 20 '10 at 03:45
-2

In Python:

i = 1
++i
print i

prints '1'. The line '++i' evaluates to +(+i) (Python doesn't support increment operators)

Bill Zeller
  • 1,336
  • 1
  • 9
  • 13
-2

In C# you can use the new operator on an interface.

-3

Weak typing, in general.

C:

printf("%c\n", 'a' + 3);

PHP:

echo 5 + "3";

And far too many other languages.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 14
    -1 for begging to start a flame-war -- this is to highly debated to be called "strange" – RCIX Jan 03 '10 at 15:53
  • 2
    In C it is not weird for me. It would be if '3' + 3 was equal to 6. But you are right about PHP. – JCasso Jan 03 '10 at 15:58
  • 9
    In C any letter in single quotes giving us ascii number, if you know this, then 'a' + 3 is not "WTF", also as a['b'], and ('d' - 'a') / 4.. – Vitaly Dyatlov Jan 03 '10 at 17:26
  • 14
    -1 for incorrectly stating that the C example is weak typing. In C, the constants `'a'` and `3` are both `int`s with values of 97 and 3, respectively, and adding them produces an `int` of 100, which is passed to `printf()` for the argument `%c` (which takes an argument of type `char` which `int` is easily convertible to) which prints "d" (ASCII value 100). Any confusion is from a misunderstanding of the C language. If `"a" + 3` worked that way in C, it would be a valid complaint about typing, but that does something totally different. – Chris Lutz Jan 04 '10 at 07:35
  • PHP is a stateless language designed for the web, and all variables are passed from the browser as strings, which is why it makes sense for the language to handle a lot of the type-casting for you. – nickf Jan 04 '10 at 08:12
  • 1
    @jcasso: Actually '3' + 3 is equal to '6'. – R. Martinho Fernandes Jan 04 '10 at 14:23
  • 3
    @Chris Lutz: `printf()` is a variadic function, which means that nothing is passed as a `char or a `short` or a `float`. This means that `'a'` is an `int`, `3` is an `int`, `'a' + 3` is an `int`, and it's passed as an `int` to where `%c` expects an `int` and prints it out as a character value. There are no type conversions whatsoever in that example. – David Thornley Jan 04 '10 at 16:38
  • In C, `'a' + 3` may or may not be equal to `'d'`. – Alok Singhal Jan 04 '10 at 17:59
  • @David - My bad for not checking the manpage. `%c` converts an `int` to `unsigned char` for printing, but it is passed as an `int` (depending on your architecture, of course). @Alok - This is true, but from a practical perspective even in EBCDIC `'a' + 3 == 'd'` (you only get problems around `'l'` and `'m'` in EBCDIC). – Chris Lutz Jan 05 '10 at 19:48
-3

COMEFROM is the weirdest, and probably most useless, language feature I ever saw.

Runner-up would be the ternary operator, because it violates rule #1 of optimization. And it does more harm than it solves problems. It does more harm because it makes code less readable.

Not really a language feature, but interesting/awesome use of features is Duff's device.

elmuerte
  • 720
  • 5
  • 21
-3

Modula-2 doesn't have elseif or else if; it has elsif

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
-3

Java's Integer class's base-conversion static methods. :P Very few languages have this functionality built right in, it seems.

wakachamo
  • 1,723
  • 1
  • 12
  • 18
  • 1
    How does it differ from base conversion in C/C++, Python, or any other languages? –  Jan 06 '10 at 01:41
  • I'm not sure I understand but is this meaning autoboxing? – R. Martinho Fernandes Jan 06 '10 at 22:05
  • I meant simple base-conversion functions - such as Hexadecimal to Binary, or Binary to Decimal. Java has those right in the Integer class. PS. Nice to see someone from Portugal around here :D – wakachamo Jan 06 '10 at 22:23
-3

In all languages today:

TypeA a = (TypeA)some_operation_returning_TypeB(1,2,3); // TypeB is not inheriting TypeA

fails on runtime with "Cast to TypeA failed exception"-message (or similar). What this tells us is just how lazy programmers really are. There's no way for them to produce message "Failed to assign variable 'a' of TypeA with a value 'some_operation_returning_TypeB(1,2,3)' of TypeB". Noooo.. their motto is "thy who makes mistakes must suffer".

AareP
  • 2,355
  • 3
  • 21
  • 28
  • That may be because TypeA might not be easy to initialize. Maybe it's constructor takes a string that doesn't exist in TypeB? One could argue that implicit "casts" (=simple mappings between equally named fields) to a type with a parameterless constructor should be possible (in fact, the existence of tools like AutoMapper tell us that there is a need for that). Actually, official Mapping Support as part of a language would be quite cool. – Michael Stum Jan 06 '10 at 02:17
  • 1
    Oh wait, actually you were complaining about the message being too unspecific. Yes, that sucks too. – Michael Stum Jan 06 '10 at 02:19
  • Sorry, not all languages. Scala will say "type mismatch", follow with the type expected and the type wanted and indicate the exact point of the code where the incorrect type was found. If asked to, it will then show the decision tree it used to verify whether the types were compatible or not. So, go complain about specific languages. – Daniel C. Sobral Jan 07 '10 at 19:06
  • Also, it fails at compile time, unless you explicitly tell it to take a hike, and that you know what you are doing. – Daniel C. Sobral Jan 07 '10 at 19:07
  • 5
    Well, actually compile-time errors are the good ones. They are 100% reproducible. :) – AareP Jan 07 '10 at 22:28
  • Daniel: still sounds like too much work - reading the error, reading filename, reading line number, figuring out the character/column location of error.. All I need is the expression that is being casted incorrectly. So I can search all occurrences of it and ensure same error cannot happen anywhere in the program. – AareP Jan 07 '10 at 22:32
  • It shows the expression giving the error. That's what I meant by "the exact point of the code". If you have `a = b + c` and it's `c` that's causing the trouble, it will show that expression and point to `c`. – Daniel C. Sobral Jan 08 '10 at 02:04
  • The exception comes from the cast, not the assigning of object a. At the point of the exception, it really doesn't know it is ALSO trying to assign the value to a particular object. – Russ Aug 12 '10 at 13:09
  • Yes, especially .net-runtime doesn't seem to know anything about anything sometimes. Yesterday received an error "Object reference is not set to an intance". No line number, no file name, no function name, just a stupid text mocking you for your mistake. (Although it might be that this lack of information is caused by custom exception handling, will have to check.) – AareP Aug 14 '10 at 07:07
  • @AareP: If you don't have debug symbols (those .pdb files you might have seen around), either because you compiled without them (aka release mode) or simply deleted them, there's no way you can know line numbers or file names. As for method names, you can always see the stack track of an exception, unless you intentionally lose it with custom exception handling. "Object reference is not set to an instance" is the message of a `NullReferenceException`, which is probably the most embarassing an pointless exception you can have. – R. Martinho Fernandes Aug 29 '10 at 21:12
  • @Martinho Fernandes: I have .pdb files, compiling without optimization, using Debug-switch, fetching last Exception.InnerException, and my exception.StackTrace still ends at "Control.MarshalledInvoke". There is some filenames and line numbers, but not the ones responsible for the exception. Apparently things like Form.Invoke() screw up exception handling. – AareP Sep 01 '10 at 10:48
  • Also loading new assemblies (for example with Type.GetType) never shows you the real problem. Error message is always "Failed to find module." (not even saying which module it can't find), even though there are tens of reasons why dll-files wont load. There's a utility for troubleshooting loading problems "fuslogvw", but even that fails to show anything sometimes.. grrr... – AareP Sep 01 '10 at 10:52
-3

I find Javascript Date Object's love for the year 110 delightful.. Try it.

<Script language ="JavaScript">
<!--
var now = new Date()
var dia = now.getDay()
var mes = now.getMonth()
var fecha

//Day of the week
if(dia==0){
 fecha="Domingo, ";
}else if(dia==1){
 fecha="Lunes, ";
}else if(dia==2){
 fecha="Martes, ";
}else if(dia==3){
 fecha="Miércoles, ";
}else if(dia==4){
 fecha="Jueves, ";
}else if(dia==5){
 fecha="Viernes, ";
}else{
 fecha="Sábado, ";
}

fecha = fecha + now.getDate() + " de "
//Which month is it?
if(mes==0){
 fecha=fecha + "Enero"
}else if(mes==1){
 fecha=fecha + "Febrero"
}else if(mes==2){
 fecha=fecha + "Marzo"
}else if(mes==3){
 fecha=fecha + "Abril"
}else if(mes==4){
 fecha=fecha + "Mayo"
}else if(mes==5){
 fecha=fecha + "Junio"
}else if(mes==6){
 fecha=fecha + "Julio"
}else if(mes==7){
 fecha=fecha + "Agosto"
}else if(mes==8){
 fecha=fecha + "Septiembre"
}else if(mes==9){
 fecha=fecha + "Octubre"
}else if(mes==10){
 fecha=fecha + "Noviembre"
}else{
 fecha=fecha + "Diciembre"
}

//Year
fecha = fecha + " del " + now.getYear()

document.write(fecha);
//-->
</Script>

Script is in Spanish - sorry if you don't understand the code.. The idea is for you to see the year 110 result.

Hobhouse
  • 15,463
  • 12
  • 35
  • 43
cr0z3r
  • 711
  • 4
  • 9
  • 24
  • The getYear is getting the year since 1900. – kzh Jan 13 '10 at 13:17
  • @nickf: That would fix it. @kzh: I know, just trying to show a somehow 'funny' result. – Hobhouse Jan 13 '10 at 17:23
  • 3
    @Hobhouse: You didn't need the dozens of lines above then... `now.GetYear()` pretty much sums up your whole post. – mpen Jul 26 '10 at 19:03
  • That has been a problem since Unix/C (ca. 1972) based its time structure on an epoch of 1970-01-01. It has since spread to many other languages, libraries, databases, and spreadsheet apps. – David R Tribble Sep 14 '10 at 14:10
-3

In Python, every string contains the empty string.

answer = input("Enter 'Y[es] or N[o]:")
if answer in 'YyNn':        # verify input
    process(answer) 

Just hitting return at the above query will set answer to the null string, pass the if answer in ... test, and be processed as a correct answer. To put it more succinctly:

>>> "ABCDEFGHIJ".__contains__("")
True

As usual, Python's behavior here is mathematically and logically impeccable. As I recall from a long ago class in set theory: The empty set is a member of every set.

It's still surprising on the few occasions when I've been bitten by it, but I wouldn't have it any other way.

Don O'Donnell
  • 4,538
  • 3
  • 26
  • 27
-3

In MOD_REWRITE

RewriteRule ^([a-zA-Z0-9_-]+)\.php$ $1/ [R,NC]
RewriteRule ^([a-zA-Z0-9_-]+)/$ $1\.php [NC,L]

Will cause:

"file.php > file > file.php > file > file.php > file >  ..."

And finally:

Error 500 Too Many Redirects

(In general I find editing .htaccess files to be about as tedious as constructing a properly functioning regular expression.)

Talvi Watia
  • 1,070
  • 1
  • 14
  • 28
-3

PHP

$ php -r '::'
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM

WTF? http://en.wikipedia.org/wiki/Scope_resolution_operator

Why not say unexpected T_SCOPE_RESOLUTION_OPERATOR ?

animuson
  • 53,861
  • 28
  • 137
  • 147
CloudMarc
  • 381
  • 3
  • 2
  • 1
    It's an interesting case of an untranslated word in an error message but I wouldn't classify it as a language feature per se. – John K Aug 14 '10 at 16:17
  • @johnK I still don't get why error messages aren't language features. If error reporting wasn't a feature you would have the equivalent of `ERROR_REPORTING=OFF`, which BTW is also a feature... – Talvi Watia Sep 17 '10 at 18:04
  • @Talvi: I would draw the same line as you did between error messages as language features vs error reporting as a language feature: I don't consider messages as features even if the reporting system that contains them is a feature. Two different things. – John K Sep 17 '10 at 19:12
  • @johnK "its not a bug.. its a feature." <- that line – Talvi Watia Sep 17 '10 at 22:21
-3

In C#: a = cond ? b : c; If 'b' & 'c' are "assign incompatible", you'll never get result, even if 'a' is object. It's frequently used and most idiotically implemented operator from MS. For comparison see implementation in D language (note on type inference).

  • 4
    It should be noted that the C# implementation is quite sane in that it avoids a few hard problems quite elegantly. Read Eric Lippert’s explanation (somewhere on his blog) on why the conditional operator was designed the way it is. – Konrad Rudolph Oct 18 '10 at 16:10
  • 3
    You mean that it won't compile. Also, this is a sensible design decision. – SLaks Oct 18 '10 at 16:21
  • 2
    Eric Lippert's explanation: http://blogs.msdn.com/b/ericlippert/archive/2010/05/27/cast-operators-do-not-obey-the-distributive-law.aspx, also http://stackoverflow.com/questions/1171717/c-conditional-operator – Christian Oct 20 '10 at 09:31
-4

Perl.

print "Foo\n" unless $foo;

Thomas
  • 4,208
  • 2
  • 29
  • 31
-4

Best of show entry in the Perl Journal's Obfuscated Perl Contest in 2000:

#:: ::-| ::-| .-. :||-:: 0-| .-| ::||-| .:|-. :||
open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('-',$1)){$q=0;for(split){s/\|
/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";
#.: ::||-| .||-| :|||-| ::||-| ||-:: :|||-| .:|

Code fully explained by its author at http://mysite.verizon.net/les.peters/id2.html

maxpolk
  • 2,167
  • 1
  • 18
  • 24
-4

The fact that there is no encapsulation in C++ (or Java). Any object can violate the encapsulation of any other object, mess around with its private data, as long as it's the same type. For example:

#include <iostream>
using namespace std;

class X
{
  public:
    // Construct by passing internal value
    X (int i) : i (i) {}

    // This breaks encapsulation
    void violate (X & other)
    {
        other.i += i;
    }

    int get () { return i; }

  private:
    int i;
};

int main (int ac, char * av[])
{
    X a(1), b(2), c(3);

    a.violate (c);
    b.violate (c);
    cout << c.get() << endl;    // "6"
}
maxpolk
  • 2,167
  • 1
  • 18
  • 24
  • 2
    This is actually immensely useful in some cases. I think that if you code your class to access private data in a different instance you probably know what you are doing and you have to go out of your way to pass a reference to the other class. Cloning is one such operation where this is necessary. – Lawrence Dol Jan 21 '10 at 01:52
  • Also note that static functions can access instance members of the classes they belong in. – Rei Miyasaka Dec 07 '10 at 12:42
-4

Objective-C's use of @ for strings. Example: @"This is a string."

Alex
  • 1
  • 2
    C# does that too to disable \ being an escape character. What's wrong with it though? – Rei Miyasaka Nov 14 '10 at 04:07
  • 1
    @Rei it's used for all strings in Objective-C. However, this is awesome because otherwise the compiler would not know if we mean an array of characters terminated by a null-char or an NSString object. –  Jan 16 '11 at 17:10
  • Ah. Yeah, certain Windows frameworks in the past (I think MFC) used to use something like `T"string"` to distinguish between the library's string object and a null-terminated char array. I guess it's a common shorthand feature to C-based languages/libraries. – Rei Miyasaka Jan 16 '11 at 20:54
-4

in C.

int a;

(&a)[0] = 10; /* will assign value 10 to a */

(&a)[0] is equivalent to *(&a +0), which gives us *(&a), which is nothing but a.

Dawood
  • 1
-6

either in java (this is an if statement that results in assignment)

result = (Boolean condition) ? (if Boolean is true) : (if Boolean is false);

or

data Nat = Z|S Nat deriving Show
nattoInt Z = 0
nattoInt (S a) = 1 + nattoInt a

buildNat 0 = Z
buildNat a  =  S (buildNat (a - 1))

in Haskell... I still don't quite get how this defines the natural numbers (I understand the THEORY perfectly :-p)

Ritwik Bose
  • 5,889
  • 8
  • 32
  • 43
  • 10
    The first is the trinary if operator. Why is it a strange language feature? I use it in multiple languages a lot. – Dykam Jan 04 '10 at 07:35
  • 6
    Really? You understand the theory but you don't get a simple inductive definition of the natural numbers? – R. Martinho Fernandes Jan 04 '10 at 14:28
  • 2
    @Dykam: trinary is the language of the neo-fin dolphins. ;-) – Konrad Rudolph Jan 04 '10 at 21:19
  • @Martinho Fernandes no... I understand the THEORY. I have never paid enough attention to the SYNTAX to understand what each part of the statement means. – Ritwik Bose Jan 05 '10 at 01:54
  • 1
    @Mechko: I thought you knew Haskell. I'm sorry, then. The first line defines `Nat` as a type isomorphic with the natural numbers: it's the set of values that are either zero (`Z`) or the successor of a `Nat` (`S Nat`). For example 1 would be `S Z`, 2 `S (S Z)`, etc. The rest is just sugar to be able to print `Nat` values (`deriving Show`), and functions that convert actual numbers to `Nat` and `Nat` values to actual numbers, using recursion. Oh, by the way, ifs in Haskell work the same way as the *conditional operator* in Java: `result = if condition then 42 else 23`. – R. Martinho Fernandes Jan 06 '10 at 21:51
-7

I would definitely give Perl the honor of having multiple horrible examples:

if(!$#var)

or

if($mystring =~ m/(\d+)/) {
miku
  • 181,842
  • 47
  • 306
  • 310
Lars D
  • 8,483
  • 7
  • 34
  • 37
  • 2
    is second one regex? If so i cannot blame Perl. Regex looks weird at first. – JCasso Jan 03 '10 at 16:00
  • 14
    Sorry guys but all the "hated" features of perl turn out to be some of the most useful especially at 3am when you need a 3 line program to get everything up and running again. Except for regex syntax which predates perl itself you can (and should!) code all the perl shortcuts in longer and more explicit syntax to make it easier to read. – James Anderson Jan 04 '10 at 01:58
  • 5
    -1 this answer is complaining about a language's syntax rather than any actual behavior. – Chris Lutz Jan 04 '10 at 07:21
  • 4
    Forcing perl to calculate $#var's lvalue behavior can decrease performance unnecessarily. That should probably be "unless(@var)". – Anonymous Jan 04 '10 at 10:20
  • 10
    What's wrong with that second one? If the string matches the pattern, do the following. What's the big deal? – Matt Grande Jan 04 '10 at 18:02
  • I don't see what's wrong with _either_ example other than @Anonymous' point about the un-perl-ness (which can hardly be a language wtf). – rfunduk Aug 13 '10 at 19:18
  • @James - Lars D [not me] didn't say these features were not useful. He's answering a question about "the most surprising, weird, strange" language features. Also, they're only useful at 3am if you already know what they mean. If you're trying to modify somebody else's code at 3am and you're not a Perl programmer, these are highly anti-useful. That being said, I don't think these are the best examples of surprising (or obfuscated) Perl syntax. – LarsH Dec 01 '10 at 21:38
-7

In c++

const char* wtf()
{
    char buf[100];
    return buf;
}
string s = ... + wtf() + ...;

creates interesting values in s. Partly string, partly stack contents, mixed with zeroes so that s.length()!=strlen(s.c_str()). The strangest thing is that compiler has absolutely no problems with returning pointers to stack - compiler programmers's hand would probably fall off if he would have added a warning there.

AareP
  • 2,355
  • 3
  • 21
  • 28
  • TMS2810 DSP you can't modify the flash control registers while executing from flash. TI copies a register-set function to RAM and then calls it to init these registers. They reserve the space in a section call "ramfuncs". I created a local variable array and copied the function there to execute it. That way I didn't have to worry about where in RAM the function was - it took stack space only until the calling function returned. Imagine your wtf() copies wtf2() into buf[] and the calls it. It was very useful in that one situation. – phkahler Jan 05 '10 at 19:46
  • That's why we have '#pragma warning(disable:xxx)'. So we can ignore otherwise helpful warnings in some special cases. – AareP Jan 07 '10 at 22:34
  • 4
    Trying to read uninitialized memory gives random results, film at 11. – Nicholas Knight Jul 21 '10 at 07:16
  • I had a prof who thought this was correct. Both the returning uninitialized memory part as well as the returning stack values part. I kid you not. – Rei Miyasaka Dec 15 '10 at 22:11
-7

In JavaScript:

2 == [2]

// Even stranger 2 == [[[2]]]

// And down-right nutty var a = { "abc" : 1 }; a[[[["abc"]]]] === a["abc"]; // this is also true

Luckily the kind folks at stackoverflow.com explained the whole thing to me: http:/stackoverflow.com/questions/1724255/why-does-2-2-in-javascript

Nathan Ridley
  • 33,766
  • 35
  • 123
  • 197
  • 7
    This is an exact, copy-pasted duplicate of http://stackoverflow.com/questions/1995113/strangest-language-feature/1998050#1998050. Please delete it. – Helen Feb 08 '10 at 19:46
-7

JavaScript:

( {} == {} ) == false
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alex Dean
  • 1
  • 1
  • What's odd with this? Isn't that just `(function is a function) is false`? – Esko Aug 20 '10 at 20:32
  • 3
    object references just do not match, nothing strange – Lyubomyr Shaydariv Aug 20 '10 at 20:57
  • Every time you `{}`, you create a new object pointer. Two new object pointers aren't the same because they aren't at the same location. – Delan Azabani Aug 21 '10 at 00:58
  • 1
    not strange, it's like `( object() == object() ) == False` in Python – mykhal Aug 21 '10 at 02:48
  • 1
    @esko - Function is Object, Object is not Function. – Sky Sanders Aug 21 '10 at 13:25
  • @code: While I understand what you're saying, how does that apply to this "oddity"? After all isn't this basically about element identities and is pretty much universal to all programming languages - x isn't x unless there's a special rule saying it is. – Esko Aug 21 '10 at 15:08
  • @Delan Azabani: Definitely no, you're messing up with objects and references. `{}` is not a pointer. It's a new _empty_ object that can be referenced throught either a regular reference variable. Moreover, pointers can be "same" in any language, and point the same objects many times. – Lyubomyr Shaydariv Sep 15 '10 at 20:17
  • However, if I do this: `a = {}; b = a;` we're really setting a pointer because they point to the same object, not a copy. Try it by setting `a.c` and seeing that `b.c` is also set. – Delan Azabani Sep 15 '10 at 22:02
  • @Delan Azabani: Did I say about copying? I think you're inspired by C/C++. The term `pointer` is not so applicable for JS 'cause it's ok to say _reference_. All JavaScript objects are passed by reference - an implicit pointer saying in C++ terminology. You said, _Every time you {}, you create a new object pointer._ It's not true because you can write e.g. `function(){/*NO REF*/new CustomObject();}` (I choosed CustomObject because its constructor could e.g. display something, but a simple {} might be ommitted by JS optimizer) where a newly created object is NOT referenced at all. – Lyubomyr Shaydariv Sep 16 '10 at 09:24
-8

here is my 2 cents. In c++:

int* t = new int(15);
delete t;
kellogs
  • 2,837
  • 3
  • 38
  • 51
  • 15
    what's strange about this? – shoosh Jan 05 '10 at 11:49
  • I think he's getting () and [] confused? – gbjbaanb Jan 05 '10 at 23:17
  • Heh, int(15) casts 15 as an integer. So the line of code actually sets t = 15, rather then a pointer to an int[] of size 15. So when you delete t, it will cause an error. – Chad Okere Jan 10 '10 at 09:39
  • 8
    @Chad this will not give an error on a conforming compiler, while `int(15)` indeed casts 15 to an integer, `new int(15)` will create a dynamically allocated integer and assign the value 15 to it. `t` will be a pointer to an integer containing 15 – Pieter Jan 13 '10 at 15:04
  • Thank you Pieter. Thanks everyone else for throwing dirt at me. This is a WTF feature which you probably did not know. – kellogs Feb 03 '10 at 20:54
-8

The concatenation in Tcl is adding two strings it become one string:

set s1 "prime"
set s2 "number"
set s3 $s1$s2
puts s3

The output is

primenumber

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mallikarjunarao Kosuri
  • 1,023
  • 7
  • 25
  • 52
-12

You can throw anything throwable in Java.

class YourBoss extends Throwable {
}
public class Main{
  public void main(String[] s) throws YourBoss {
   try{
    throw new YourBoss();
   }catch(Exception e){
   }catch(Error e){
   }
  }
}
Dennis C
  • 24,511
  • 12
  • 71
  • 99
  • 4
    Well, _obviously_. There's nothing preventing you from writing `class YourBoss : Exception` in C#, either. – SLaks Jan 05 '10 at 16:06
  • 5
    CLR (but not C#) actually permits throwing any object, not just one inheriting from Exception. – Tamas Czinege Jan 05 '10 at 16:27
  • ... and with catch(Throwable t) you can also catch everything throwable and thus even prevent the termination of a thread (see ThreadDeath). – x4u Jan 06 '10 at 23:28
  • Yes, but will always extends from Exception (or even RuntimeException). I've not seen nobody to extends Error (except VM guys) and Throwable. – Dennis C Jan 07 '10 at 02:51
  • I'd love to see if anyone has tried to (mis)use the Throw/Catch facilities of Java by subclassing Throwable and Catching it somewhere down the stack trace. I'd hate to see it in real life though. – David Feb 04 '10 at 05:59
  • When main to my knowledge shan't ever throw exception, I'll be glad if you tell why it can. – Niklas Rosencrantz Mar 22 '10 at 02:10
  • 6
    Ummm... isn't that the very definition of "throwable" - that it can be thrown? – Lawrence Dol Apr 24 '10 at 22:35
-21

The BrainFuck language. It really is!

Xavi
  • 20,111
  • 14
  • 72
  • 63
alemjerus
  • 8,023
  • 3
  • 32
  • 40
  • 9
    It's not much of a "strange feature" though, is it? As a language, it's actually extremely simple, and besides, there are *much* more complicated languages out there (Malbolge, for example: http://en.wikipedia.org/wiki/Malbolge). – Will Vousden Jan 05 '10 at 03:20
  • 20
    There should be some kind of Godwin's Law for programming language threads and somebody mentioning BF. – Mark Rendle Jan 05 '10 at 09:12
  • 1
    Edit: As an online discussion about programming languages grows longer, the probability of someone mentioning, or posting a solution in, an esoteric or rarely used programming language aproaches 1. – Joe D Aug 12 '10 at 11:38
  • 2
    Not really fair. BrainFuck was created to demonstrate that you could have a working, Turing complete, language which was almost unreadable by humans. The purpose was to make "its Turing complete and it compiles" an inadmissible defense for a poorly constructed language. – James Anderson Dec 09 '10 at 02:22