PHP: Turkish locale makes all your class names lowercase



  • I got this via Jeff Atwood of Coding Horror's Twitter feed @codinghorror: Setting locale to 'tr_TR' lowercases class names

    This, IMO, fits neatly into the category: "you've got to be shitting me".



  • I was going to say that this is old as the first bug report was in 2002. Then I read the history. Sweet Baby Jeezus ain't never going to stop crying over that one.

    At least the comment on 2011-09-15 explains what is happening.



  • Fuuuuuuu......



  •  Isn't it wonderful how the differences between bugs and features in PHP are but shades of grey?

     Right, all together now: the real WTF is...



  • @Severity One said:

     Isn't it wonderful how the differences between bugs and features in PHP are but shades of grey?

    You mean in the line of Fifty Shades of Grey (By which I mean the BDSM aspects)



  • @toon said:

    I got this via Jeff Atwood of Coding Horror's Twitter feed

    Jeff Atwood looks like John Wayne Gacy (without the clown makeup) and I organically dislike both of them. I think I will open a Twitter account and follow everybody except him just so his stats go down a little. I'd rather fedex a dollar to Cliff Yablonski than watch a youtube video featuring Jeff Atwood.



  •  I see at the bottom there's a patch for it, only ten years after it was first reported. I wonder what the patch will unfix?



  • OK, so let me get this straight, the php interpreter is trying to be multilingual? Because that's what I understand from this:

    In Turkish, the undotted ı is the lowercase of I, and the dotted İ is the uppercase of i.

    Shouldn't "class Öbject" throw some error even if my locale is de_DE? This is how every no-german programming language works... right?

    Weird shit they have in there.

    @cankoy at ymail dot com said:

    I told 2 years ago and will say it again: PHP should provide a way to turn off case-insensitive function/class name lookup. No good programmer uses this Basic language feature since identifiers are case-sensitive in all real languages like Python, Ruby, C#, Java.

    Dude, don't compare apples with oranges :-)



  • @ubersoldat said:

    OK, so let me get this straight, the php interpreter is trying to be multilingual? Because that's what I understand from this:

    In Turkish, the undotted ı is the lowercase of I, and the dotted İ is the uppercase of i.

    Shouldn't "class Öbject" throw some error even if my locale is de_DE? This is how every no-german programming language works... right?

    Weird shit they have in there.

    You can have umlauts and all sorts of other stuff (source):

    Function names follow the same rules as other labels in PHP. A valid function name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]


  • @ubersoldat said:

    Shouldn't "class Öbject" throw some error even if my locale is de_DE? This is how every no-german programming language works... right?

    Checked to be sure: you Germans like your Scharfes Es? well that's also allowed. So is the copyright sign. And the Yen sign. And the dagger. The degree sign, the "half" and "quarter" characters, the Trademark thing, the ellipsis, you name them. It's bizarre.



  • @ubersoldat said:

    OK, so let me get this straight, the php interpreter is trying to be multilingual? Because that's what I understand from this:

    In Turkish, the undotted ı is the lowercase of I, and the dotted İ is the uppercase of i.

    Shouldn't "class Öbject" throw some error even if my locale is de_DE? This is how every no-german programming language works... right?

    Weird shit they have in there.

    Contrary to popular belief, not every country in the world uses English as its main language. So if your native language is German or Turkish or Swahili, it stands to reason that you might want to use that language in the names of classes and members.

    Java supports that, and I've never seen a single comment of this mucking up; apparently, PHP supports it too, but goes as far as providing a "feature" that is basically a hack for lazy programmers that are too lame to press the "shift" key.



  • @Severity One said:

    Java supports that, and I've never seen a single comment of this mucking up; apparently, PHP supports it too, but goes as far as providing a "feature" that is basically a hack for lazy programmers that are too lame to press the "shift" key.
    Visual Basic supports international stuff too (I loved turning in some code with "✉" as a function name just to screw with my professor), but it handles case insensitivity the "right" way: All case comparison is always done in the C locale for code. Which is what PHP should have done, and what the Zend guys thought they did, only they decided to use an internal non-exported non-C-locale function buried deep in the C runtime on Windows... for some stupid reason.



  • @cankoy at ymail dot com said:

    I told 2 years ago and will say it again: PHP should provide a way to turn off case-insensitive function/class name lookup. No good programmer uses this Basic language feature since identifiers are case-sensitive in all real languages like Python, Ruby, C#, Java.

    What a maroon!

    Case sensitivity is a horrible language feature because it allows for case sensitivity abuse.  Sometimes it even becomes idiomatic; look at how often you see crap declarations like "HWND hwnd;" in Windows graphics code.  Or in Java, it's far too common to declare a variable whose name is identical to its classname, just with different capitalization.  Code like that makes me wanna smack somebody.



  • @Mason Wheeler said:

    Case sensitivity is a horrible language feature because it allows for case sensitivity abuse.  Sometimes it even becomes idiomatic; look at how often you see crap declarations like "HWND hwnd;" in Windows graphics code.  Or in Java, it's far too common to declare a variable whose name is identical to its classname, just with different capitalization.  Code like that makes me wanna smack somebody.

    In that case (haha), it's not a problem. How are you ever going to confuse an identifier and a class name? It's obviously bad when someone uses the identifiers n, N, nr, Nr, NR and nR in the same function, but for the rest, I don't see the problem. A case-sensitive language that can become case-insensitive on the other hand, that is a major WTF. Or a language where you can overload the class member definition. Or a language where just adding parentheses changes the type of the expression.



  • Mason Wheeler is posting from 1987, before IDEs ran on color monitors.



  • The Turkish locale is known as the "torture test" locale for localization. Something going horribly wrong in Turkish isn't so much as a WTF as something that happens to pretty much all code that hasn't been tested in that locale.



  • @TGV said:

    Or a language where just adding parentheses changes the type of the expression.

    You mean like in C, where "myFunction;" is a function pointer, but "myFunction();" is call to a function with 0 parameters?

    I've heard that that's actually a useful disambiguation because a weird corner case can exist where the return type of myFunction is a function pointer with the same signature as myFunction.  In practice, I've never actually seen that happen, though.

     



  • I just program as a hobby, so I'm not as cool and smart as everyone else here.  But I don't think myFunction() is valid C.  I think C requires void in parameterless functions.

    Turn your warnings up on max and use the .c extension.  I don't think C++ requires it.  I don't think mainstream compilers generate an error if you leave out void even when enforcing strict C.  I could be wrong, but I'm not a real programmer.  You gain nothing by flaming me, and I probably won't check for replies to this post.



  • @pauly said:

    But I don't think myFunction() is valid C.  I think C requires void in parameterless functions.

    In the definition yes. In the call, no.
    @pauly said:
    Turn your warnings up on max and use the .c extension.

    [pjh@sofa tmp]$ cat -n fp.c
         1  #include <stdio.h>
         2
         3  int foo(void){
         4          printf("foo()\n");
         5          return 0;
         6  }
         7  int main(void){
         8          int (*myFunction)(void) = foo;
         9          printf("Without Parens\n");
        10          myFunction;
        11          printf("With Parens\n");
        12          myFunction();
        13          return 0;
        14  }
        15
    [pjh@sofa tmp]$ gcc fp.c -o fp -Wall
    fp.c: In function ‘main’:
    fp.c:10:2: warning: statement with no effect
    [pjh@sofa tmp]$ ./fp
    Without Parens
    With Parens
    foo()
    [pjh@sofa tmp]$
    


  •  @Mason Wheeler said:

    @TGV said:

    Or a language where just adding parentheses changes the type of the expression.

    You mean like in C, where "myFunction;" is a function pointer, but "myFunction();" is call to a function with 0 parameters?

    I've heard that that's actually a useful disambiguation because a weird corner case can exist where the return type of myFunction is a function pointer with the same signature as myFunction.  In practice, I've never actually seen that happen, though.

    Hadn't thought of that. I had Perl in mind: when a is an array, (a) is a scalar, or something weird like that.

    But in C, I've seen my fair share of function pointers. Love 'm! They can make your program short, concise and totally ununderstandable.



  • .. missed off the flag that warns on a missing void:

    [pjh@sofa tmp]$ cat -n fp.c | grep " 3"
         3  int foo(void){
    [pjh@sofa tmp]$ gcc fp.c -o fp -Wall -Wstrict-prototypes
    fp.c: In function ‘main’:
    fp.c:10:2: warning: statement with no effect
    [pjh@sofa tmp]$
    
    [pjh@sofa tmp]$ cat -n fp.c | grep " 3"
         3  int foo(){
    [pjh@sofa tmp]$ gcc fp.c -o fp -Wall -Wstrict-prototypes
    fp.c:3:5: warning: function declaration isn’t a prototype
    fp.c: In function ‘main’:
    fp.c:10:2: warning: statement with no effect
    [pjh@sofa tmp]$
    


  • @toon said:

    I got this via Jeff Atwood of Coding Horror's Twitter feed @codinghorror: Setting locale to 'tr_TR' lowercases class names

    This, IMO, fits neatly into the category: "you've got to be shitting me".

    Got to love the patch suggested by the comment on [2012-05-15 20:54 UTC]: https://github.com/net-alper/php-src/commit/0515360e9a8dcc86facb38cddeebe759e87dca52:

    1909     while (str < end) {
    1910 -      *result++ = zend_tolower((int)*str++);
    1910 +      *result++ = (*str == 'I') ? 'i' : zend_tolower((int)*str);
    1911 +      str++;
    1912     }

    + same "fix" in a different function.



  • Many years ago a Turkish guy, with his Turkish notebook computer, came to work with us. We had dial-up internet access, and the password was "banphai". He could not connect. He tried and failed. I tried and failed. I typed "banphai" into Notepad and copied it into the password prompt; no luck. Finally I saved it as a txt file and dumped it in hex. The darned "i" at the end was a high-order character that, on the screen, looked like an ASCII lower-case "i". How could any idiot disable ASCII?

    I hex-edited it to a standard "i". To log in, he had to display that file, then copy and paste that word into the password prompt.

     



  • @TGV said:

    I had Perl in mind: when a is an array, (a) is a scalar, or something weird like that.
     

    @a is an array, $a is a scalar and %a is a hash. These are all separate. $a[0] would select the first element of @a. $#a is the index of the last element of @a. $a{'foo'} is the foo key in %a. And AFAICT ($a) would return an array with one element, but it probably depends on context. My Perl is a little rusty too.

    @AndyCanfield said:

    Many years ago a Turkish guy, with his Turkish notebook computer

    Sounds like Turkish is TRWTF:

    [quote user="tokul"]Turkish language can trigger some i18n programming errors in case insensitive comparison functions, because small latin i is not equal to capital latin i in Turkish language.[/quote]

    I notice that all the class names they are having trouble with contain an "I".



  • @toon said:

    I got this via Jeff Atwood of Coding Horror's Twitter feed @codinghorror: Setting locale to 'tr_TR' lowercases class names
    The title isn't quite correct.  From what I'm reading there, it's not the locale setting that causes class names to be converted to lower case.  PHP appears to have an internal function that converts all class names to lower case, and everything works fine until you encounter Turkish, where  i  is not the lower case of  I .

    TRWTF is that they've ignored the problem for 9 years.



  •  @Mason Wheeler said:

    Or in Java, it's far too common to declare a variable whose name is identical to its classname, just with different capitalization.  Code like that makes me wanna smack somebody.
    Well, as our little furry friend already pointed out, people in general and developers in particular have moved away from 80x24 monochrome screens, and modern IDEs actually show you the difference between a class and an instance. Heck, even vi(m) does it.

    But it's really simple. In Java, if it starts with a capital, it's a class. If it starts with a lower case character, it's an instance. If someone goes against this convention, he should be taken out and shot.

     



  • @Severity One said:

    @ubersoldat said:

    OK, so let me get this straight, the php interpreter is trying to be multilingual? Because that's what I understand from this:

    In Turkish, the undotted ı is the lowercase of I, and the dotted İ is the uppercase of i.

    Shouldn't "class Öbject" throw some error even if my locale is de_DE? This is how every no-german programming language works... right?

    Weird shit they have in there.

    Contrary to popular belief, not every country in the world uses English as its main language. So if your native language is German or Turkish or Swahili, it stands to reason that you might want to use that language in the names of classes and members.

    Java supports that, and I've never seen a single comment of this mucking up; apparently, PHP supports it too, but goes as far as providing a "feature" that is basically a hack for lazy programmers that are too lame to press the "shift" key.

    Wow... and after all this years, I never tried to write a class, method or variable in my native tongue in any programming language.



  • @ubersoldat said:

    Wow... and after all this years, I never tried to write a class, method or variable in my native tongue in any programming language.
    I can't help but notice that there isn't an Umlaut in 'über' in your nickname.

     



  • @ubersoldat said:

    Wow... and after all this years, I never tried to write a class, method or variable in my native tongue in any programming language.

    I've written a project using Spanish names for everything. It turned out to have compatibility issues due to some filesystems not having support for accented characters.



  • @Severity One said:

    But it's really simple. In Java, if it starts with a capital, it's a class. If it starts with a lower case character, it's an instance. If someone goes against this convention, he should be taken out and shot.

    So interfaces, static variables, packages, enums, parameters and local variables are forbidden now?

     



  • @pjt33 said:

    I've written a project using Spanish names for everything. It turned out to have compatibility issues due to some filesystems not having support for accented characters.

    Just compile it on an embedded system!



  • @Severity One said:

    In Java, if it starts with a capital, it's a class.
     

    cough finals pedantic



  • @pjt33 said:

    @ubersoldat said:
    Wow... and after all this years, I never tried to write a class, method or variable in my native tongue in any programming language.

    I've written a project using Spanish names for everything. It turned out to have compatibility issues due to some filesystems not having support for accented characters.

    Does the upside-down question mark work for wildcards? Or is it a reverse wildcard?



  • @no laughing matter said:

    So interfaces, static variables, packages, enums, parameters and local variables are forbidden now?
     

    About bloody time! Who needs all that modern, fancy schmancy lowercase stuff? Communists, that's who! Everything uppercase and implicit typing based on the first character of the identifier is all a decent programmer needs.



  • Maybe its just me.. but in PHP 5.4.0.. The "bug" that they exhibit doesn't work (or would break be the correct term?) at all for me. Tried it in Windows (Server 2008) and OS X (10.8)... and it works as one would expect.



  • @no laughing matter said:

    @Severity One said:
    But it's really simple. In Java, if it starts with a capital, it's a class. If it starts with a lower case character, it's an instance. If someone goes against this convention, he should be taken out and shot.
    So interfaces, static variables, packages, enums, parameters and local variables are forbidden now?
    Trust a bunch of developers to go all anal over a generalisation.

     



  • @Zemm said:

    Sounds like Turkish is TRWTF

    Turkish is a language spoken by millions and millions of people. The IT world should just cope. TRWTF is that computer builders in the seventies didn't care about any languages other than English (which is understandable) and in the year 2012, we're still struggling to overcome the fact that some folks want to write different languages.

    Unfortunately it works the other way around, too. In my native language of Dutch, there is a letter that is a ligature of the letters i and j, making an 'ij' letter; I don't know how to make one with my keyboard. Anyone who types Dutch, you see, just types an i and a j. I've yet to meet the first exception to that statement. But TRWTF is that when I try to explain to people that this character exists, I am met with disbelief and even mockery. In practice, the character has actually vanished from the alphabet and it's no longer taught in schools AFAIK. All of this started with the advent of the typewriter. Having said that, one might make the case that since the character is a ligature of two other ones that are already in the alphabet, it might have disappeared, typewriter or no.

    Anyway, I'd like to argue here and now that if there is one language that is TRWTF, then it's English and not Turkish.



  • @toon said:

    TRWTF is that computer builders in the seventies didn't care about any languages other than English (which is understandable)

    Not so much of a WTF, as you say it is understandable
    @toon said:
    in the year 2012, we're still struggling to overcome the fact that some folks want to write different languages

    This is definitely TRWTF
    @toon said:
    In practice, the character has actually vanished from the alphabet and it's no longer taught in schools AFAIK.

    Languages evolve, Italian lost ligatures ages ago and we survived.
    @toon said:
    Anyway, I'd like to argue here and now that if there is one language that is TRWTF, then it's English and not Turkish.

    Considering i and ı to be different characters still seems a WTF to me.



  • @dargor17 said:

    @toon said:
    TRWTF is that computer builders in the seventies didn't care about any languages other than English (which is understandable)

    Not so much of a WTF, as you say it is understandable
    @toon said:
    in the year 2012, we're still struggling to overcome the fact that some folks want to write different languages

    This is definitely TRWTF

    That's actually what I meant. Sorry if I implied that the original assumption was flawed; I don't think it was.

    @dargor17 said:
    Considering i and ı to be different characters still seems a WTF to me.

    Those characters are pronounced very differently (one is pronounced 'ee' and the other a very short 'uh'), and unlike the other vowels in the Turkish alphabet. Also, who are you or I to dismiss any character in a foreign language?



  • What I mean is, they look very similar and it seems weird to me that they have such a different pronounce. It's as if in Italian i and ì sounded completely different, it would be stupid.



  • @dargor17 said:

    What I mean is, they look very similar and it seems weird to me that they have such a different pronounce.
     

    language how does it work

    we just don't know



  • @toon said:

    Unfortunately it works the other way around, too. In my native language of Dutch, there is a letter that is a ligature of the letters i and j, making an 'ij' letter; I don't know how to make one with my keyboard. Anyone who types Dutch, you see, just types an i and a j. I've yet to meet the first exception to that statement. But TRWTF is that when I try to explain to people that this character exists, I am met with disbelief and even mockery. In practice, the character has actually vanished from the alphabet and it's no longer taught in schools AFAIK. All of this started with the advent of the typewriter. Having said that, one might make the case that since the character is a ligature of two other ones that are already in the alphabet, it might have disappeared, typewriter or no.
    It's a bit more subtle than that, according to Wikipedia:

    http://en.wikipedia.org/wiki/IJ_(digraph)

    For me, the 'ij' is very much like the Maltese għ (in capitals GĦ) which in Maltese is considered one letter (it is, in fact, silent and only influences the sound of nearby vowels), although it doesn't use the same capitalisation as the 'IJ' in Dutch. An example is the town name of Għargħur. Which according to the rules should be pronounced 'Ayrooyr' (English approximation), but everybody calls in 'Gargoor', probably because that's what the British did.

     



  • @toon said:

    Having said that, one might make the case that since the character is a ligature of two other ones that are already in the alphabet, it might have disappeared, typewriter or no.

    Maybe the vacwm cleaner ate it...

    Speaking of Turkish, I wonder if Java has a similar bug to PHP? Java "properties" seem to be defined by chopping off "get" and "set" from method names, and lowercasing the letter that comes after the "get" or "set" - e.g. the "cost" property would have methods getCost() and setCost(). So what happens if you have a property that begins with one of those special Turkish characters? MethodNotFoundException???



  • @toon said:

    @Zemm said:

    Sounds like Turkish is TRWTF

    Turkish is a language spoken by millions and millions of people. The IT world should just cope.

     

    I did some reading of the I/i and İ/ı and it appears that they could have designed it better ("They" as in IT people, not the Turks). Since strtoupper('i')=='I' in everything except the Turkish languages it causes problems. So they need their own version of the latin I/i to make case insensitive comparisons work properly. This wouldn't cause more issues than the latin vs cyrillic look-a-likes, which can be a bit of a problem ('A' != 'А' for example). Unless this is what Andy Canfield came across? Anytway, my "TRWTF" comment is directed at the people who tried to cram Turkish into Unicode...

    That said, I couldn't replicate the locale problem in my PHP systems, and they are all running older versions (early 5.3.x and some 5.2.x) on Linux, OSX and Windows.

    setlocale(LC_ALL, "tr_TR.UTF-8");
    class InfoBlob {  
        public static function Intresting() {
            return __CLASS__ . ": is it not?\n";
        }
    }
    echo "infoBlob " . (class_exists("infoBlob") ? 'exists' : 'fail') . "\n";
    echo "InfoBlob " . (class_exists("InfoBlob") ? 'exists' : 'fail') . "\n";

    Prints "exists" twice on all platforms (changing the locale to "trk" in Windows) for me.

    @toon said:

    In my native language of Dutch, there is a letter that is a ligature of the letters i and j, making an 'ij' letter; I don't know how to make one with my keyboard

    Interestingly those ligatures are right next to the dotted I/dotless i in the unicode pages: U+0130 through U+0133 are İ, ı, IJ, ij. To get those I used Character Viewer (I'm not saying you "should" be using them or anything; just that it is interesting) and even switching to Dutch keyboard they still aren't available, even hidden behind alt (I'm using Mac ATM). Though œ and æ are alt-q and atl-' respectively! These letters do technically appear in English: Enclopædia is the correct spelling, for example, though it has been corrupted over the years. Again I'm not saying this is bad or wrong, just some trivia.

    @toon said:

    Anyway, I'd like to argue here and now that if there is one language that is TRWTF, then it's English and not Turkish.

    All languages have WTFs: spoken, technical, programming, etc.

     


  • BINNED

    @toon said:

    Turkish is a language spoken by millions and millions of people. The IT world should just cope. TRWTF is that computer builders in the seventies didn't care about any languages other than English (which is understandable) and in the year 2012, we're still struggling to overcome the fact that some folks want to write different languages.

    Unfortunately it works the other way around, too. In my native language of Dutch, there is a letter that is a ligature of the letters i and j, making an 'ij' letter; I don't know how to make one with my keyboard. Anyone who types Dutch, you see, just types an i and a j. I've yet to meet the first exception to that statement. But TRWTF is that when I try to explain to people that this character exists, I am met with disbelief and even mockery. In practice, the character has actually vanished from the alphabet and it's no longer taught in schools AFAIK. All of this started with the advent of the typewriter. Having said that, one might make the case that since the character is a ligature of two other ones that are already in the alphabet, it might have disappeared, typewriter or no.

    Anyway, I'd like to argue here and now that if there is one language that is TRWTF, then it's English and not Turkish.

    Well, digraphs are still alive and well in Croatian, we have a grand total of 3: 'dž', 'lj', 'nj' ('ž' also being a valid letter by itself). Of course, people just use 2 letters for them anyway since the standard Croatian layout doesn't have them. There is however a layout with Croatian digraphs on Linux at least, so I gave it a go and it maps those digraphs to "unused" 'q', 'w' and 'x' which don't exist in Croatian alphabet. Curiously, on that layout 'ž' is mapped to keyboard twice, to '\' key, where it usually is, and to 'y' key (which is swapped with Z, making keyboard layout QWERTZ instead of QWERTY, which is a pain in the behind by itself). But I digress.

    php copes with them no problem:

    <?php
    
        setlocale(LC_ALL, 'hr_HR');
        
        $lower = 'č ć ž š đ dž lj nj';
        $upper = 'Č Ć Ž Š Đ Dž Lj Nj';
        
        echo strtoupper($lower);
        echo '<br>';
        echo strtolower($upper);
    
    ?>
    Output:
        č ć ž š đ dž lj nj
        Č Ć Ž Š Đ Dž Lj Nj
    

    I wonder how much of the blame for the Turkish debacle goes to php, and how much it's just unicode's fault. I didn't really check how turkish locale is mapped in unicode, but seeing how php has no problem with obscure digraphs used in something like 2 or 3 minor languages yet completely fails on Turkish makes me think the problem is a bit deeper than just php sucking.

    That said, locale handling in php, especially when paired with MySQL, can be a PITA in itself, so plenty of blame to go around.



  • @Mason Wheeler said:

    Case sensitivity is a horrible language feature because it allows for case sensitivity abuse.
    Case insensitivity is even more of a problem. The Unicode standard is evolving, which means that collation maps are different between different standard revisions, so case-insensitive comparison of two characters that returns false in the current standard could start returning true in the future (not to mention that different locales have different ideas about what characters are to be considered identical - just look at this whole mess with Turkish I/İ).



  • @Onyx said:

    php copes with them no problem:

    <?php
    
        setlocale(LC_ALL, 'hr_HR');
        
        $lower = 'č ć ž š đ dž lj nj';
        $upper = 'Č Ć Ž Š Đ Dž Lj Nj';
        
        echo strtoupper($lower);
        echo '<br>';
        echo strtolower($upper);
    
    ?>
    Output:
        č ć ž š đ dž lj nj
        Č Ć Ž Š Đ Dž Lj Nj
    

    Shouldn't the first line be upper case and the second line be lower case?



  • @fatbull said:

    Shouldn't the first line be upper case and the second line be lower case?

    Only if your browser is set to Turkish locale.



  • @Onyx said:

    php copes with them no problem:
     

    It "copes" by ignoring the dodgy characters?


  • BINNED

    @dhromed said:

    It "copes" by ignoring the dodgy characters?

    Not sure if I should suggest laying off the shrooms or bad browsers

    Also, yes, rendering IS awful when using a monospaced font (doubly so on Windows), especially on digraphs, but the output is correct.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.