Lambdas everywhere!



  • I have a colleague who keeps creating lambda functions to then call straight away, or in the code following it. For example:

    int a = [&]
    {
        if (someField == constA)
        {
            return valueA;
        }
        else if (someField == constB)
        {
            return valueB;
        }
        return valueC;
    }();
    

    In this case, a simple one-line ternary would suffice, and be just as easy to read (and he doe use ternaries, albeit poorly-formatted nested ones). Some of his other uses involve giving the lambda function a name, and then calling it from a loop under it. There's no reason these lambda functions can't be member functions. I'm pretty sure the compiler will inline them.

    It compiles. It works. But it's weird and difficult to parse mentally, especially when he's calling his lambda from a loop under it. I'm trying to steer him towards simpler code.

    Is it just my problem because I'm not expecting it, or is that weird to anyone else?


  • Java Dev

    Sounds like someone found a shiny new tool and wants to use it everywhere, even if it's the wrong tool for the job.



  • Once when I was rather tired, I made an in function lambda to use in a loopish way.
    When I got in and saw my code the following day, I berated myself for my dumb and shitty code, and made a proper private function out of it instead.


  • BINNED

    @prueg said in Lambdas everywhere!:

    creating lambda functions to then call straight away

    Too much JS background? Some other languages like Rust also seem to go big on expression (vs. statement) blocks, maybe inspired from FP.
    I see no use for the given example, but it might be more idiomatic in different languages.



  • Beyond that, let me guess that someField and constA/B are integers which actually should be an enum? And, in some occasions, there might be :fun: fun with closures (especially when the loop's indexing variable is used...).



  • This kind of pattern can be useful for creating const variables that require complicated setup. I've written stuff like this:

    const auto square_hash_values =
    []()
    {
        std::array<std::array<uint64_t, 13>, 64> hash_cache;
        for(auto& square_indexed_row : hash_cache)
        {
            std::generate(square_indexed_row.begin(),
                          square_indexed_row.end(),
                          Random::random_uint64);
        }
        return hash_cache;
    }();
    

    This is part of a Zobrist hash scheme for my chess engine. The example in the OP is simple enough that the lambda function is overkill (even if nested ternaries make my teeth itch). If he's calling named lambdas in a loop, he should probably be using something from <algorithm> or <numeric>.


  • 🚽 Regular

    I'm not sure why I find this funny, but I do.

    d697e714-664a-4a47-8e69-ab5696ae7c9c-image.png



  • @MZH said in Lambdas everywhere!:

    std::generate

    :giggity:


  • BINNED

    @BernieTheBernie that's kind of far fetched, considering you already got std::vector everywhere. :pendant:


  • Discourse touched me in a no-no place

    @topspin In that case, :doing_it_wrong: would have been better?


  • Considered Harmful

    @Carnage said in Lambdas everywhere!:

    Once when I was rather tired, I made an in function lambda to use in a loopish way.
    When I got in and saw my code the following day, I berated myself for my dumb and shitty code, and made a proper private function out of it instead.

    🤷 Sometimes a piece of code only makes sense in this very particular context (I've used quite a bit like @MZH's example) so it makes sense to only have it available in a certain scope. If you make it a private function, you have to at least name it, polluting the namespace with irrelevant (to everybody else who might be working on different parts of the class) entries, and often you required to document it and end up with a painstaking description or shit like "never mind, only used to better structure the foo() method" where in context a simple comment would be sufficient.
    Perl has lexical functions for that, but if you only have lambdas, fine. The example in the OP is silly though.



  • @LaoC said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    Once when I was rather tired, I made an in function lambda to use in a loopish way.
    When I got in and saw my code the following day, I berated myself for my dumb and shitty code, and made a proper private function out of it instead.

    🤷 Sometimes a piece of code only makes sense in this very particular context (I've used quite a bit like @MZH's example) so it makes sense to only have it available in a certain scope. If you make it a private function, you have to at least name it, polluting the namespace with irrelevant (to everybody else who might be working on different parts of the class) entries, and often you required to document it and end up with a painstaking description or shit like "never mind, only used to better structure the foo() method" where in context a simple comment would be sufficient.
    Perl has lexical functions for that, but if you only have lambdas, fine. The example in the OP is silly though.

    I prefer functions being a first class citizen in the language, and I don't really see naming contexts as a bad thing, not that it wasn't already named as a lambda stored in a variable. :mlp_shrug:
    And in this case, doing so made the code easier to read than having a big blob of comparison code that was very easy to give a short and descriptive name.


  • Considered Harmful

    @Carnage said in Lambdas everywhere!:

    @LaoC said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    Once when I was rather tired, I made an in function lambda to use in a loopish way.
    When I got in and saw my code the following day, I berated myself for my dumb and shitty code, and made a proper private function out of it instead.

    🤷 Sometimes a piece of code only makes sense in this very particular context (I've used quite a bit like @MZH's example) so it makes sense to only have it available in a certain scope. If you make it a private function, you have to at least name it, polluting the namespace with irrelevant (to everybody else who might be working on different parts of the class) entries, and often you required to document it and end up with a painstaking description or shit like "never mind, only used to better structure the foo() method" where in context a simple comment would be sufficient.
    Perl has lexical functions for that, but if you only have lambdas, fine. The example in the OP is silly though.

    I prefer functions being a first class citizen in the language, and I don't really see naming contexts as a bad thing, not that it wasn't already named as a lambda stored in a variable. :mlp_shrug:
    And in this case, doing so made the code easier to read than having a big blob of comparison code that was very easy to give a short and descriptive name.

    Lambdas are first class citizens, they just don't pop up when someone tries to autocomplete a method somewhere else.
    You could have named it f locally :tro-pop:



  • @LaoC said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    @LaoC said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    Once when I was rather tired, I made an in function lambda to use in a loopish way.
    When I got in and saw my code the following day, I berated myself for my dumb and shitty code, and made a proper private function out of it instead.

    🤷 Sometimes a piece of code only makes sense in this very particular context (I've used quite a bit like @MZH's example) so it makes sense to only have it available in a certain scope. If you make it a private function, you have to at least name it, polluting the namespace with irrelevant (to everybody else who might be working on different parts of the class) entries, and often you required to document it and end up with a painstaking description or shit like "never mind, only used to better structure the foo() method" where in context a simple comment would be sufficient.
    Perl has lexical functions for that, but if you only have lambdas, fine. The example in the OP is silly though.

    I prefer functions being a first class citizen in the language, and I don't really see naming contexts as a bad thing, not that it wasn't already named as a lambda stored in a variable. :mlp_shrug:
    And in this case, doing so made the code easier to read than having a big blob of comparison code that was very easy to give a short and descriptive name.

    Lambdas are first class citizens, they just don't pop up when someone tries to autocomplete a method somewhere else.
    You could have named it f locally :tro-pop:

    In Java they also carry a lot of unnecessary baggage.


  • Considered Harmful

    @Carnage said in Lambdas everywhere!:

    @LaoC said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    @LaoC said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    Once when I was rather tired, I made an in function lambda to use in a loopish way.
    When I got in and saw my code the following day, I berated myself for my dumb and shitty code, and made a proper private function out of it instead.

    🤷 Sometimes a piece of code only makes sense in this very particular context (I've used quite a bit like @MZH's example) so it makes sense to only have it available in a certain scope. If you make it a private function, you have to at least name it, polluting the namespace with irrelevant (to everybody else who might be working on different parts of the class) entries, and often you required to document it and end up with a painstaking description or shit like "never mind, only used to better structure the foo() method" where in context a simple comment would be sufficient.
    Perl has lexical functions for that, but if you only have lambdas, fine. The example in the OP is silly though.

    I prefer functions being a first class citizen in the language, and I don't really see naming contexts as a bad thing, not that it wasn't already named as a lambda stored in a variable. :mlp_shrug:
    And in this case, doing so made the code easier to read than having a big blob of comparison code that was very easy to give a short and descriptive name.

    Lambdas are first class citizens, they just don't pop up when someone tries to autocomplete a method somewhere else.
    You could have named it f locally :tro-pop:

    In Java they also carry a lot of unnecessary baggage.

    I consider myself lucky not to have to deal with this shit.



  • @LaoC said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    @LaoC said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    @LaoC said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    Once when I was rather tired, I made an in function lambda to use in a loopish way.
    When I got in and saw my code the following day, I berated myself for my dumb and shitty code, and made a proper private function out of it instead.

    🤷 Sometimes a piece of code only makes sense in this very particular context (I've used quite a bit like @MZH's example) so it makes sense to only have it available in a certain scope. If you make it a private function, you have to at least name it, polluting the namespace with irrelevant (to everybody else who might be working on different parts of the class) entries, and often you required to document it and end up with a painstaking description or shit like "never mind, only used to better structure the foo() method" where in context a simple comment would be sufficient.
    Perl has lexical functions for that, but if you only have lambdas, fine. The example in the OP is silly though.

    I prefer functions being a first class citizen in the language, and I don't really see naming contexts as a bad thing, not that it wasn't already named as a lambda stored in a variable. :mlp_shrug:
    And in this case, doing so made the code easier to read than having a big blob of comparison code that was very easy to give a short and descriptive name.

    Lambdas are first class citizens, they just don't pop up when someone tries to autocomplete a method somewhere else.
    You could have named it f locally :tro-pop:

    In Java they also carry a lot of unnecessary baggage.

    I consider myself lucky not to have to deal with this shit.

    I've said for a long time that Java is the modern day COBOL. Even so, it puts the food on the table. 🐃 💵
    I'd not mind working in another tech stack, but Java is what seems to be prevalent currently. My own projects I write in a fairly wide range of languages and platforms.


  • ♿ (Parody)

    @Carnage it's kind of clunky sometimes and doesn't have a lot of the shiny bells and whistles that a lot of things have but it's generally predictable and pretty easy to get things done with.



  • @boomzilla said in Lambdas everywhere!:

    @Carnage it's kind of clunky sometimes and doesn't have a lot of the shiny bells and whistles that a lot of things have but it's generally predictable and pretty easy to get things done with.

    Yeah, COBOL did too. I've spent almost two decades replacing old systems written in COBOL that did their jobs well enough.
    Java is stable, boring, simple and good enough. Exactly what you want when you're building systems to last a decade or three until the next poor sap comes along to replace it with the next Java, because all the Java devs are graybeards that are well into retirement ages now.



  • @MZH I occasionally use lambdas for the same reason.

    I can even see something like OP's code making sense (with the result being const at least). The specific example is perhaps a bit too simple, but if the expressions / conditions are a bit more complex, being able to return various results out of the lambda is neat.

    If it's one-off code, I don't see much utility in making this a (private) member function. Just seems like extra clutter in e.g. a header. Plus, if the lambda references more than a handful of values from the captured scope, things become messy.



  • @Carnage said in Lambdas everywhere!:

    Java is stable, boring, simple and good enough. Exactly what you want when you're building systems to last a decade or three until the next poor sap comes along to replace it with the next Java, because all the Java devs are graybeards that are well into retirement ages now.

    I did Java for six years (and may again when this contract expires), but that's not how I would describe it. The problem is that every six months there's a new hot framework (remember Wicket?) that you have to learn.



  • @jinpa :topper: That's nothing. In JavaScript, there is a new hot framework that you have to learn every other day!



  • @jinpa said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    Java is stable, boring, simple and good enough. Exactly what you want when you're building systems to last a decade or three until the next poor sap comes along to replace it with the next Java, because all the Java devs are graybeards that are well into retirement ages now.

    I did Java for six years (and may again when this contract expires), but that's not how I would describe it. The problem is that every six months there's a new hot framework (remember Wicket?) that you have to learn.

    I'm in the enterprise or springboot world, there is not much movement there and those two platforms generally provide most of the stuff you need.



  • @prueg said in Lambdas everywhere!:

    I have a colleague who keeps creating lambda functions to then call straight away, or in the code following it. For example:

    int a = [&]
    {
        if (someField == constA)
        {
            return valueA;
        }
        else if (someField == constB)
        {
            return valueB;
        }
        return valueC;
    }();
    

    In this case, a simple one-line ternary would suffice, and be just as easy to read (and he doe use ternaries, albeit poorly-formatted nested ones).

    In this case it does indeed look weird. It isn't shorter than a ternary and it isn't more readable either.

    Maybe if it was a switch, though I'd probably stick to the imperative form (declare a, then set it in each branch). It's C++ after all.

    Some of his other uses involve giving the lambda function a name, and then calling it from a loop under it. There's no reason these lambda functions can't be member functions. I'm pretty sure the compiler will inline them.

    Member functions, at least for helpers, are evil¹. For example they have to be declared in the header. It often makes more sense to have file-static helpers instead, but that is fine if they can get all the individual members of the object they need as arguments, because they are not in the class. So if you need a helper inside the class so it sees the private members, but don't want to leak that implementation detail into the header, a local function is a good variant. Except C++ does not have local functions, only closures or local classes, so you use one of those.

    It compiles. It works. But it's weird and difficult to parse mentally, especially when he's calling his lambda from a loop under it. I'm trying to steer him towards simpler code.

    … of course you shouldn't factor out a two-line body of a loop. Always depends on context.

    Is it just my problem because I'm not expecting it, or is that weird to anyone else?

    Lambdas are a good tool, and there are cases where even defining a lambda and immediately calling it makes sense, but it does look like your colleague needs to learn to recognize when things are not nails. But you should get used to the fact that sometimes they are.


    ¹ As per definition of evil in the C++ FAQ



  • @jinpa said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    Java is stable, boring, simple and good enough. Exactly what you want when you're building systems to last a decade or three until the next poor sap comes along to replace it with the next Java, because all the Java devs are graybeards that are well into retirement ages now.

    I did Java for six years (and may again when this contract expires), but that's not how I would describe it. The problem is that every six months there's a new hot framework (remember Wicket?) that you have to learn.

    I know that I am not the first one, but this cannot be overstated: try JavaScript and you will see how wrong your perspective is.


  • Considered Harmful

    @Kamil-Podlesak said in Lambdas everywhere!:

    @jinpa said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    Java is stable, boring, simple and good enough. Exactly what you want when you're building systems to last a decade or three until the next poor sap comes along to replace it with the next Java, because all the Java devs are graybeards that are well into retirement ages now.

    I did Java for six years (and may again when this contract expires), but that's not how I would describe it. The problem is that every six months there's a new hot framework (remember Wicket?) that you have to learn.

    I know that I am not the first one, but this cannot be overstated: try JavaScript and you will see how wrong your perspective is.

    The FED on one project and I had a plan to make a framework facade called duJour that exposed the framework du juor - pretty much the state of the pop art.



  • @Carnage said in Lambdas everywhere!:

    I'm in the enterprise or springboot world, there is not much movement there and those two platforms generally provide most of the stuff you need.

    I was including Spring as one of the many frameworks you have to learn. If you're the guy who gets to pick what's used, you have an easier job than the people who have to use it.



  • @Kamil-Podlesak said in Lambdas everywhere!:

    I know that I am not the first one, but this cannot be overstated: try JavaScript and you will see how wrong your perspective is.

    This cannot be overstated: the existence of worse does not show that recognizing something as bad is a wrong perspective.



  • @jinpa said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    I'm in the enterprise or springboot world, there is not much movement there and those two platforms generally provide most of the stuff you need.

    I was including Spring as one of the many frameworks you have to learn. If you're the guy who gets to pick what's used, you have an easier job than the people who have to use it.

    Every language has frameworks, and my opinion is that you should learn the frameworks you work with. But I haven't really seen any framework churn in my work. Each new gig has maybe 1 or 2 new toys that I haven't worked with, learning that isn't taxing. The current flavor is cloud, which strikes equally across all languages so :mlp_shrug:


  • Discourse touched me in a no-no place

    @boomzilla said in Lambdas everywhere!:

    it's kind of clunky sometimes and doesn't have a lot of the shiny bells and whistles

    From 8 onwards, you can make do very nicely for the most part. You might need to craft a few extra functional interfaces, but that's the only extra bit of work. More of an issue is that you only have limited type inference available (because it doesn't look at the use sites), which is one of those things that might be fixable but which hasn't been yet. But that's mostly not an issue.

    Without lambdas, doing inner-function-like stuff in Java required lots of explicit inner classes and so on. Yes, it would work, but it would be insanely verbose and wouldn't be anything that you'd want to actually use. (One of the repositories I look after had a glorious branch where I stripped all that shit out, a PR with a net decrease of nearly a thousand lines of code...) That in turn was vastly better than the horrible things you had to do back in the beginning before they even had inner classes. So. Much. Verbosity.

    I suspect a lot of Java programmers haven't had the experience with other languages to really understand how important the change was. You think about problem solving very differently when you have inline code snippets.



  • @dkf said in Lambdas everywhere!:

    I suspect a lot of Java programmers haven't had the experience with other languages to really understand how important the change was.

    I suspect the reason is that most Java programmers who did get experience with other languages never wanted to come back to Java.



  • @Bulb said in Lambdas everywhere!:

    @dkf said in Lambdas everywhere!:

    I suspect a lot of Java programmers haven't had the experience with other languages to really understand how important the change was.

    I suspect the reason is that most Java programmers who did get experience with other languages never wanted to come back to Java.

    I've done PHP, Python, Perl, Kotlin and C++ professionally, apart from Java. And possibly a few more. I can't say that there is a huge disadvantage of doing Java development, aside from the idiots that can't grasp anything more advanced than the featureset of Java 1.4 but all platforms have idiots.



  • @Carnage do JavaScript professionally next!


  • ♿ (Parody)

    @jinpa said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    I'm in the enterprise or springboot world, there is not much movement there and those two platforms generally provide most of the stuff you need.

    I was including Spring as one of the many frameworks you have to learn. If you're the guy who gets to pick what's used, you have an easier job than the people who have to use it.

    Were you working on new projects every six months?



  • @Arantor said in Lambdas everywhere!:

    @Carnage do JavaScript professionally next!

    I sniffed it 8 or so years ago and decided I'd be better off doing meth professionally.


  • ♿ (Parody)

    @dkf said in Lambdas everywhere!:

    @boomzilla said in Lambdas everywhere!:

    it's kind of clunky sometimes and doesn't have a lot of the shiny bells and whistles

    From 8 onwards, you can make do very nicely for the most part. You might need to craft a few extra functional interfaces, but that's the only extra bit of work. More of an issue is that you only have limited type inference available (because it doesn't look at the use sites), which is one of those things that might be fixable but which hasn't been yet. But that's mostly not an issue.

    Yeah, that's one of those things that would be nice to have but isn't a massive drawback to being productive.

    Without lambdas, doing inner-function-like stuff in Java required lots of explicit inner classes and so on. Yes, it would work, but it would be insanely verbose and wouldn't be anything that you'd want to actually use. (One of the repositories I look after had a glorious branch where I stripped all that shit out, a PR with a net decrease of nearly a thousand lines of code...) That in turn was vastly better than the horrible things you had to do back in the beginning before they even had inner classes. So. Much. Verbosity.

    💯 My main issue with java lamdas is that they don't play well with the debugger (i.e., to the compiler it looks similar to changing a method declaration or something that breaks the debugger link). At least in 8, which is what I use.

    I suspect a lot of Java programmers haven't had the experience with other languages to really understand how important the change was. You think about problem solving very differently when you have inline code snippets.

    Yep.



  • @Carnage it's gotten BeTtEr in the last 8 years. Whatever language you currently dislike, JavaScript will remind you of all its good points.



  • @Arantor said in Lambdas everywhere!:

    @Carnage it's gotten BeTtEr in the last 8 years. Whatever language you currently dislike, JavaScript will remind you of all its good points.

    Yeah, I guess. I just want it all to burn for all the evils it's inflicted upon the world.



  • @Carnage Me too. Me too.


  • Discourse touched me in a no-no place

    @Carnage said in Lambdas everywhere!:

    the idiots that can't grasp anything more advanced than the featureset of Java 1.4

    Oh yes. Websphere users.



  • @boomzilla said in Lambdas everywhere!:

    Were you working on new projects every six months?

    Sometimes. Sometimes I was working on legacy software that had been touched by different people every six months.



  • @dkf said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    the idiots that can't grasp anything more advanced than the featureset of Java 1.4

    Oh yes. Websphere users.

    Stabby feels.



  • @Carnage said in Lambdas everywhere!:

    I've done PHP, Python, Perl, Kotlin and C++ professionally, apart from Java. And possibly a few more. I can't say that there is a huge disadvantage of doing Java development, aside from the idiots that can't grasp anything more advanced than the featureset of Java 1.4 but all platforms have idiots.

    You and I disagree on what makes an idiot. A programmer who over-complicates things without asking themselves if the new features are necessary is just a different kind of idiot, and should not be in any decision-making capacity.



  • @jinpa said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    I've done PHP, Python, Perl, Kotlin and C++ professionally, apart from Java. And possibly a few more. I can't say that there is a huge disadvantage of doing Java development, aside from the idiots that can't grasp anything more advanced than the featureset of Java 1.4 but all platforms have idiots.

    You and I disagree on what makes an idiot. A programmer who over-complicates things without asking themselves if the new features are necessary is just a different kind of idiot, and should not be in any decision-making capacity.

    The two are not mutually exclusive.


  • Considered Harmful

    @Bulb said in Lambdas everywhere!:

    @dkf said in Lambdas everywhere!:

    I suspect a lot of Java programmers haven't had the experience with other languages to really understand how important the change was.

    I suspect the reason is that most Java programmers who did get experience with other languages never wanted to come back to Java.

    Dunno, Scala drives me right back to Java.


  • Considered Harmful

    @dkf said in Lambdas everywhere!:

    @Carnage said in Lambdas everywhere!:

    the idiots that can't grasp anything more advanced than the featureset of Java 1.4

    Oh yes. Websphere users.

    Also SAP devs, iirc.


  • Considered Harmful

    @Carnage said in Lambdas everywhere!:

    @Arantor said in Lambdas everywhere!:

    @Carnage do JavaScript professionally next!

    I sniffed it 8 or so years ago and decided I'd be better off doing meth professionally.

    What was that other thing you did, PCP? 🏆



  • @prueg said in Lambdas everywhere!:

    Is it just my problem because I'm not expecting it, or is that weird to anyone else?

    It's a very common JavaScript idiom. Maybe that's his background?


  • BINNED

    @dkf said in Lambdas everywhere!:

    Without lambdas, doing inner-function-like stuff in Java required lots of explicit inner classes and so on. Yes, it would work, but it would be insanely verbose and wouldn't be anything that you'd want to actually use. (One of the repositories I look after had a glorious branch where I stripped all that shit out, a PR with a net decrease of nearly a thousand lines of code...) That in turn was vastly better than the horrible things you had to do back in the beginning before they even had inner classes. So. Much. Verbosity.

    Reminds me of C++ pre-11 (before lambdas existed). The advocates for how you should use the language were (and are) big on generic programming and seperating data from algorithms. But for anything in the <algorithm> header that actually requires a predicate (and not just a bunch of iterators) using that is an absolute fucking pain. No thanks. I'm not going to write some class with an overloaded function call operator somewhere completely else. Too verbose, too much loss of locality, sucks to read and write.

    Now with lambdas you can finally actually use these things without going crazy. Although std::for_each is still way inferior to range-based for loops, so there basically was never any time that was usable.



  • @topspin said in Lambdas everywhere!:

    Although std::for_each is still way inferior to range-based for loops, so there basically was never any time that was usable.

    Well ... you can use the parallel execution policies with for_each. :half-trolleybus-tl:


  • BINNED

    @cvi #pragma omp parallel for. 🐠


Log in to reply