Tutorial :Strangest language feature



Question:

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

Please only one feature per answer.


Solution:1

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.


Solution:2

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.


Solution:3

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();  }  


Solution:4

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.


Solution:5

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.


Solution:6

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.


Solution:7

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.


Solution:8

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


Solution:9

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...


Solution:10

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.


Solution:11

In SQL

NULL is not equal to NULL

So you can't do:

WHERE myValue == NULL  

This will always return false.

NULL != NULL  


Solution:12

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.


Solution:13

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.


Solution:14

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.


Solution:15

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.


Solution:16

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.


Solution:17

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  


Solution:18

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.


Solution:19

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

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

Useful, eh?


Solution:20

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.


Solution:21

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


Solution:22

In javaScript, NaN is a global variable.


Solution:23

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.


Solution:24

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.


Solution:25

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      }  


Solution:26

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.


Solution:27

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.


Solution:28

In Java,

int x = 010;

This assigns x to have the value 8.

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


Solution:29

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".


Solution:30

C++:

void f(int bitand i){ //WTF      i++;  }  int main(){      int i = 0;      f(i);      cout << i << endl; //1      return 0;  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »