WTF Bites



  • @levicki said in WTF Bites:

    even the AI wants to look at naked women

    Sooner or later, it will discover Instagram :trollface:


  • I survived the hour long Uno hand

    @TimeBandit
    Sadly, it has missed the glory days of Tumblr.



  • @Zerosquare said in WTF Bites:

    sneakily reencodes all of @Zecc's music library at 32 kbps

    If it were my library, that'd just make it take up more storage space. To get a noticeable reduction in quality, you'd have to use 2k or fewer bps.



  • Are you listening to MIDI files, or is your hearing that bad?


  • Notification Spam Recipient

    @Zerosquare said in WTF Bites:

    Are you listening to MIDI files, or is your hearing that bad?

    MIDI Files? Fuck yeah!

    I need to dig up my renderer package again sometime... Literal weeks of music on a single floppy disk!


  • 🚽 Regular

    @Tsaukpaetra It's been a while since I've listened to my MOD/S3M/IT collection. I should dig it up one of these days.

    https://www.youtube.com/watch?v=P6tE8OcEHc8


  • ♿ (Parody)

    @levicki said in WTF Bites:

    Is it just me or this site used to be loading faster? It takes several seconds to load each thread I open.

    You have to make sure the polarization turns in the same direction as yoghurt does. Don't remember if that's left or right, but it sure it healthy.


  • BINNED

    @boomzilla
    I'm out of yoghurt. Please advise.


  • ♿ (Parody)

    @Luhmann said in WTF Bites:

    @boomzilla
    I'm out of yoghurt. Please advise.

    Advice is hard. Let's go shopping. For yoghurt.


  • BINNED

    @boomzilla
    Only when it's frozen


  • Java Dev

    @PleegWat said in WTF Bites:

    base64 needs 20 bits

    Actually, on further thinking, there is no need to buffer until you have 4 base64 characters. You just have to store 0, 2, 4, or 6 bits from the last partial byte plus 2 bits of which of those 4 states you're in. And that can be handily packed into a single byte.



  • @levicki said in WTF Bites:

    Is it just me or this site used to be loading faster? It takes several seconds to load each thread I open.

    What you are experiencing is a temporary distortion of reality


  • BINNED

    @boomzilla said in WTF Bites:

    @levicki said in WTF Bites:

    Is it just me or this site used to be loading faster? It takes several seconds to load each thread I open.

    You have to make sure the polarization turns in the same direction as yoghurt does. Don't remember if that's left or right, but it sure it healthy.

    @hungrier said in WTF Bites:

    What you are experiencing is a temporary distortion of reality

    Same here, there seems to be a glitch in the matrix. :thonking: :thonking: ☎

    Filed under: even the typo is still there


  • ♿ (Parody)

    @topspin said in WTF Bites:

    Filed under: even the typo is still there

    How could this be?!


  • Considered Harmful

    "Here are some of them." What are the others?Screenshot_20191025-132546_Samsung Pay.jpg


  • Discourse touched me in a no-no place

    @boomzilla said in WTF Bites:

    You have to make sure the polarization turns in the same direction as yoghurt does. Don't remember if that's left or right, but it sure it healthy.

    That depends on which hemisphere you're in. If you ever go to Australia, make sure to turn your yoghurt in the opposite direction.


  • Discourse touched me in a no-no place

    Screenshot_20191026_144717.jpg

    I was so interested in going to {{item.destinationName}}, but wasn't sure if I could afford to pay {{item.displayPrice}}...


  • Banned

    OCaml parser found in OCaml standard library (the one used by OCaml compiler but also me) does some funny things with lists.

    So, this is a sum type (a.k.a. tagged union):

    type Foo = Bar of int | Baz of int * int | Qux of int * int * int
    

    It has two constructors: Int and NoInt. This is how you use them:

    let x = Bar 3
    let y = Baz (3, 4)
    let z = Qux (3, 4, 5)
    

    Note how there is always one argument to constructor (a value or a tuple) and it's always after the constructor.

    Now, this is how you make a list in OCaml:

    let x = 1 :: []
    let y = 1 :: 2 :: []
    

    Let's focus on the first one. It uses infix ::, and syntactically it's a totally different thing from constructors above, right? Well, kinda, but OCaml parser pretends they're not. It has a whole different set of parsing rules specifically for lists, but it doesn't put it in separate AST node type - no, it reuses the constructor types. It basically pretends you wrote this:

    let x = :: (1, [])
    let y = :: (1, :: (2, []))
    

    ...and that's invalid code because :: is special.

    Aaaanyway. The AST, aside from the nodes themselves, also keeps track of their location in code. And I care very much about the location in my particular use case. So, think of what happened to locations. I have this constructor expression:

    1 :: []
    

    It starts at 0 and ends at 6. The constructor is at pos 2-3 and has two arguments, one at pos 0, another at pos 5-6. Simple, right?
    Yeah, you wish. Remember what I said earlier: constructor always has one argument. It does in this case too. The argument is a tuple of 1 and []. It's not a real tuple, but the parser pretends it is. And of course, the tuple starts at 0 and ends at 6. It has the same span as the entire expression. It also completely contains the constructor, which is not part of the tuple. It's a big fucking problem for me, and I have to write additional code that specifically checks for this case and unfucks this all up. Which honestly wouldn't be so bad, except for one thing.

    You see, there is another syntax for writing lists. It looks like this:

    let x = [1]
    let y = [1; 2]
    

    And if you think they made separate AST node type for it, you're dead wrong. It's still a constructor and a tuple. "Desugared", it also looks the same:

    let x = :: (1, [])
    let y = :: (1, :: (2, []))
    

    Yes. It's exactly the same as before. Let me repeat. The AST of 1 :: 2 :: [] and [1; 2] is identical. The only way to differentiate between these two cases is to look at positions of nodes.

    So, about positions. Every node has a position. EVERY. Even the two phantom :: inside [1; 2]. Take a guess what position the parser thinks they are. Or don't; it's impossible to guess right anyway. Counting from 0, the two phantom :: are at positions 1-5 and 4-5, respectively. In other words, 1; 2] is a double colon, and so is 2]. And ] is actually [] but it's still one character long. So fucking simple. At least they're in front of one another this time.

    TL;DR:

    If the string [] is one character long, it's square brackets, otherwise it's double colon. Saves two whole AST node types!


  • Discourse touched me in a no-no place

    @Gąska But why is this a problem for you?


  • Banned

    @dkf because I want to insert type annotations back into original code, and that requires knowing what the original code actually contains.


  • Considered Harmful

    @levicki said in WTF Bites:

    I feel the urge to just kill myself and reincarnate as an Italian so I can play the bass properly.

    🍿 Do it!


  • Banned

    @levicki said in WTF Bites:

    I feel the urge to just kill myself and reincarnate as an Italianblack so I can play the bass properly.

    FTFSouthPark


  • BINNED

    My shitty ass chinese piece of shit phone got a software update. Yay!

    New features include:

    • You can now set up themes for your lock screen
    • There's some kind of "game boost" mode for those who are so fucking useless they play videogames on phones
    • The fucking alarm simply does not work
    • Oh and for some reason you can't set a timer either, even though you could do that very easily before the update

    Nuke China.



  • @Zecc said in WTF Bites:

    @LaoC I've never seen that sign, but I presume it means "just so you know, there's an irresponsible adult playing football with a kid in the middle of the road".

    slow motion children ahead



  • When I pause javascript execution in Vivaldi, with the developer tools panel docked to the page, it stops responding to mouse clicks entirely. Which makes it slightly hard to debug code since the only thing you can do now is scroll the code up and down with the scroll wheel (or use keyboard shortcuts if you remember them).


  • BINNED

    @Polygeekery said in WTF Bites:

    I don't follow this thread all that closely, so I have no clue if this has been posted already. I ran in to it again this morning so I had to post about it.

    Let that sink in.

    Microsoft...released an update..........that broke the fucking Start menu.

    Core UI and functionality of Windows....broken by an update.

    We have a whole thread dedicated to this, and nothing else.

    In summary: Microsoft fired their whole QA team years ago. Now they're just releasing untested broken shit and let the users @levicki beta test it, while TimeBandit watches laughing and pie_flavor claims everything works fine. 🍹

    How does that get by QA/QC?

    Answer: There was no QA/QC on this update.

    Exactly!

    There couldn't have been. Shit like this should be pretty high on the list of automated tests. People who let shit like this make it through to users should be fired and shamed from the industry. They should be shoveling shit from an ox stall in Mozambique.

    Can't fire what doesn't exist.

    @Zerosquare said in WTF Bites:

    @Polygeekery said in WTF Bites:

    Where's blakey? I would love to hear his apologetics for this one.

    You know he wouldn't apologize. He would tell you MS turned to shit once they started being friendly to open-source.

    "Release broken, release often" is kind of their motto. Not that he'd be right about it.


    EDIT: Well, looks like that post doesn't exist anymore. Oops. Totally one-upped fbmac there. 🏆



  • @topspin said in WTF Bites:

    "Release broken, release often" is kind of their motto.

    They're just following industry standards now...



  • @topspin said in WTF Bites:

    and let the users @levicki beta test it, while TimeBandit watches laughing and pie_flavor claims everything works fine.

    I have the best position 🧘♂


  • BINNED

    @levicki and it’s a shitty way to do case insensitive comparisons to boot.



  • Thanks Comenity. This password both seemingly meets the requirements and does not.

    dff7e4f7-9e97-4e13-a6be-e3930f56806e-image.png


  • 🚽 Regular

    "Hello, password requirements. Pleasure to meet you."


  • BINNED

    @levicki said in WTF Bites:

    Well I am not sure if XML specification allows for FaLsE and tRUE so I guess that is a valid way of comparing valid truthy and falsy values

    Point taken, I didn't consider that.


  • Discourse touched me in a no-no place

    @levicki said in WTF Bites:

    Using const char *Values[] instead of vector<string> Values doesn't count as C++ anything in my book.

    Will that initialize as a compile-constant correctly? (I don't write much C++, so that isn't something I can remember.)


  • BINNED

    @ChaosTheEternal
    Did you try Hunter2 ? I use it all the time ...



  • @levicki said in WTF Bites:

    TinyXML2 library is rather popular. And out of the box it doesn't compile if you are using Windows API:

        static const char* TRUE[] = { "true", "True", "TRUE", 0 };
        static const char* FALSE[] = { "false", "False", "FALSE", 0 };
    

    Can you guess why?

    Anyone using Windows API for the last 30 years knows that TRUE and FALSE are macros and are extensively used in Windows code.

    Furthermore, naming arrays TRUE and FALSE is just sloppy naming. It should be TruthyValues and FalseyValues or something like that.

    Very nice of the library authors to allow you to swap in your own values for true and false, as long as you have no more than three.

    #include <utility>
    
    static const char* TRUE[] = { "true", "True", "TRUE", 0 };
    static const char* FALSE[] = { "false", "False", "FALSE", 0 };
    
    int main()
    {
        TRUE[1] = "tRuE";
        using std::swap;
        swap(FALSE[0], FALSE[1]);
    }
    //compiles with no errors or warnings even with -Wall -Wextra -pedantic
    

    @levicki said in WTF Bites:

    @topspin said in WTF Bites:

    @levicki and it’s a shitty way to do case insensitive comparisons to boot.

    Well I am not sure if XML specification allows for FaLsE and tRUE so I guess that is a valid way of comparing valid truthy and falsy values. What is idiotic is to use TRUE and FALSE as the array name, not to mention they say:

    TinyXML2 is a simple, small, efficient, C++ XML parser...
    

    Using const char *Values[] instead of vector<string> Values doesn't count as C++ anything in my book.

    Yeah. At the very least they should have gotten the const correctness right. But nope, a lot of people just use C++ as C With Classes.

    @dkf said in WTF Bites:

    @levicki said in WTF Bites:

    Using const char *Values[] instead of vector<string> Values doesn't count as C++ anything in my book.

    Will that initialize as a compile-constant correctly? (I don't write much C++, so that isn't something I can remember.)

    Using static constexpr std::array<std::string_view, 3> will: https://gcc.godbolt.org/z/ahnrk9


  • BINNED

    @dkf said in WTF Bites:

    @levicki said in WTF Bites:

    Using const char *Values[] instead of vector<string> Values doesn't count as C++ anything in my book.

    Will that initialize as a compile-constant correctly? (I don't write much C++, so that isn't something I can remember.)

    No, you’d have to go for something like constexpr std::array<std::string_view, 3> or whatever, depending on which version you’re using. It probably makes absolutely no difference, though.

    e: :hanzo:



  • WTF of my day: Question in the exam:

    Please explain the physical principles behind 'Influenz' (German for "induction")

    Answer:

    An influencer is a person in social media who... (goes on for a whole page of paper)

    My answer:

    1569919c-1ed9-42a5-be7b-fc1a22cb8ad9-image.png


  • Java Dev

    @levicki said in WTF Bites:

    While we are at it, what do you think is more efficient?

    // Their version
    bool IsTruthy(char const * const Value)
    {
    	static const char *TruthyValues[] = { "true", "True", "TRUE", 0 };
    
    	for (int i = 0; TruthyValues[i]; ++i) {
    		if (strcmp(str, TruthyValues[i]) == 0) {
    			return true;
    		}
            }
    
    	return false;
    }
    

    Or:

    // My version (works if Value can't contain '|' character)
    bool IsTruthy(char const * const Value)
    {
    	static char const * const TruthyValues = "true|True|TRUE";
    
    	return strstr(TruthyValues, Value) != nullptr ? true : false;
    }
    

    IsTruthy("e")


  • Java Dev

    @PleegWat I also think their version is faster. strstr is not particularly fast in my experience, while the strcmp() calls can probably be inlined.



  • @PleegWat said in WTF Bites:

    @PleegWat I also think their version is faster. strstr is not particularly fast in my experience, while the strcmp() calls can probably be inlined.

    You could also std::strlen() once to get/verify the length, and then std::memcmp(). For the 4-byte truthy strings the latter compiles down to a single cmp on x86 (since it can do unaligned reads).

    If you want to go full retard, then you can do 4 or 8 comparisons in parallel using SSE/AVX.

    But we're talking XML, which is the very antithesis of performance, so it's probably not worth doing.


  • BINNED

    @Rhywden said in WTF Bites:

    An influencer is a person in social media who... (goes on for a whole page of paper)

    So how many more words did that require? Two?


    Filed under: the joke of the moment, apparently



  • @Rhywden said in WTF Bites:

    WTF of my day: Question in the exam:

    Please explain the physical principles behind 'Influenz' (German for "induction")

    Answer:

    An influencer is a person in social media who... (goes on for a whole page of paper)

    My answer:

    1569919c-1ed9-42a5-be7b-fc1a22cb8ad9-image.png

    ..... i'll give you ten points for actually using that image as the response to that particular essay.


  • Java Dev

    @levicki said in WTF Bites:

    Well let's assume, for the sake of the performance argument, that both code versions are getting sane input?

    It's a parsing function. You cannot just decide to handle invalid values differently.

    @levicki said in WTF Bites:

    In their version there is pointer chasing involved (array of pointers to char arrays). Those char arrays may be in non-adjacent memory locations requiring up to three cache line prefetches instead of one. By the time you start second memcmp() whole string is already cached.

    Since the TruthyValues array is never modified, I expect the loop to be unrolled into three compares to string literals.

    Your 'three memcmps' version is incorrect since it can read beyond the end of the input.



  • @levicki said in WTF Bites:

    @topspin said in WTF Bites:

    @levicki and it’s a shitty way to do case insensitive comparisons to boot.

    Well I am not sure if XML specification allows for FaLsE and tRUE so I guess that is a valid way of comparing valid truthy and falsy values. What is idiotic is to use TRUE and FALSE as the array name, not to mention they say:

    Do those words even appear in the XML specification?

    Ah, XSD has true, false, 1, and 0. Case-sensitive, like the rest of XML.



  • It's still not fast enough. What we really need is a cluster of machines running a GPGPU-accelerated XML parser.



  • @Zerosquare said in WTF Bites:

    It's still not fast enough. What we really need is a cluster of machines running a GPGPU-accelerated XML parser.

    From TFP:

    On the other hand, when we used about 512 threads in each GPU, the performance almost got best, and stopped improving obviously. This fit well to the GPU’s cores number 448, which meant we did notwaste GPU threads in prior experiment in which we used 1024 threads.

    If you had any doubt that these people were clueless when it comes to GPUs, then this is ample proof. (The number of cores is an almost useless number - their GPU has 14 SMs, and each SM can support up to 1536 threads/48 warps. You don't necessarily need to saturate it fully (i.e., 21504 threads) ... but 448 threads makes absolutely no sense).


  • Java Dev

    @levicki said in WTF Bites:

    How would that be any different than a loop? String literals to compare with would still be in non-adjacent memory locations.

    Not necessarily, since these are compile-time literals which are never written to (Not guaranteed by the declaration, but it's static so the compiler can check for writes to that variable). So the compiler is free to place them wherever, including adjacently, or as immediate values in the instruction stream.



  • @Rhywden An influencer is a contagious disease whose symptoms include high fever, runny nose, sore throat, headache, coughing, fatigue and in some cases vomiting.


  • :belt_onion:

    @levicki said in WTF Bites:

    @hungrier said in WTF Bites:

    @Rhywden An influencer is a contagious disease whose symptoms include high fever, runny nose, sore throat, headache, coughing, fatigue and in some cases vomiting.

    No that's what you get by listening to one of those.

    No that's incest.



  • @levicki said in WTF Bites:

    While we are at it, what do you think is more efficient?

    I think the compiler optimizations would surprise you. I've seen compilers generate code that just compares two integers instead of treating them as strings, and your second version would disable that optimization. In general though, using std::string and std::string_view everywhere (where appropriate) would allow many comparisons to be faster, since checking the length is a fast and easy way to weed out strings that won't ever match. Null-terminated strings require a lot of re-scanning of most or all of the entire string.


Log in to reply