Kinetic Code Camp - Bring your skills, or lack thereof.. :dumpster_fire:

Statement Lambdas (Snippet)

Back on the subject of lambdas

We’ve already covered Expression lambdas here, and the posts above and below, so let’s move on to Statement lambdas.

You use statement lambdas, when you need to do more than one statement, or do some more complex logic than an expression statement.

For example:

//using LINQ here (I just make this crap up, who knows if this is remotely correct.)
string someString = Db.PerCon.Where(p => p.PerConID == "ROCK").FirstOrDefault()
    .Select(str =>
    {
        string t1 = p.Name.ToUpper();
        string t2 = p.FirstName.ToLower();
        string t3 = p.LastName.ToUpper();
        if(t3.Length() > t2.Length())
        {
            return "Yo";
        }
        else return "Bollocks";
    }); //I said it was gibberish, but it's logic.

//or an Event, in a form: (try not to do this)
UD01Form.Shown += (sender, eventArgs) =>
{
    someClassLevelVariable = ((Control)sender).Name;
    MessageBox.Show(JsonConvert.SerializeObject(eventArgs, Formatting.Indented));
};

And that’s pretty much it. It’s a method, where you can do what you want in it.

If y’all want more on this one, please ask a specific question, and I’ll see if I can answer it, or prod me with a needed example.

Aha! Got one:

//Returning a list of new object from LINQ AND manipulating the output with a filter.
//This is bs code, don't do this lol
var listOfPeople = Db.PerCon.Where(p => p.LastName.StartsWith("Q"))
    .Select(p =>
    {
        var person = new
        {
             name = p.FirstName + " " +  p.LastName,
             hasMiddle = !String.IsNullOrWhiteSpace(p.MiddleName)
        }; 

        if(person.HasMiddle) return new
        {
             name = p.FirstName + " " + p.MiddleName + " " + p.LastName,
             hasMiddle = !String.IsNullOrWhiteSpace(p.MiddleName)
        }
        else return person;
    }).ToList();

My examples suck today, but I hope it’s clear.

2 Likes

I’m back. Sorry in advance.

I’m still lost on the lambdas, but I am trying to figure out how to contribute here while not being too much of “that guy.”

So, you can skip this paragraph, but for context, I’m the widget guy. I’m low-code or die. Now, that still means some code, of course, and that’s why I am here infecting this thread. When I need code, it’s almost always going to be a one-line snippet that I can just hurl into a Set Variable widget, or worst-case, a few lines in a code block. I’m not looking to create my own classes or delegates or what have you; I can go as far as a Func<> and that’s about it.

With that, I have read the replies here several times and googled about lambdas, but nothing is connecting for me.

Am I beneath the intelligence of this thread? Probably. But then there’s “What is a variable,” and like the Jeopardy viewer who gets one question right and thinks, “I could totally be on that show,” I too feel like I can hang with the crew here.

So, all of that is to preface the simple point of: I simply don’t get it with lambdas.

Here’s what I am piecing together:

  1. Lambda expressions are a single line (no need for curly braces or other programmer stuff),
  2. Lambda statements are multi-line, with curly braces and semicolons galore, and the word return in there. But it’s essentially an expanded version of #1.
    a. (This doesn’t get me any closer to having a clue.)
  3. There’s a scope thing going on here (bet you didn’t know I knew that word).
    a. What’s funny is that several of you point out that lambdas can see outer objects (I see this is a trade phrase), implying that normal is that inner objects cannot see outer objects? Is that right?
    b. (I am used to innermost objects having the most limited scope - outer has global scope and can be seen by anything inside of it, while inner cannot be seen by outer unless you do something wacky.)
    c. (Still no closer to understanding)
  4. Can I get some parentheses on this?! What on earth is the order of operations here?
    image

I think it’s

Db.PerCon.Where((p => p.PerConID) == "ROCK")

I don’t even know if that would work or not, but my point is, is that what is logically happening?

But my most fundamental question is: What kind of thing is a lambda returning? Is it a list? Is it more like a representation of a field in a table?

I have to run, but that’s what I have so far. Thanks to anyone that might still be bearing with me.

I keep telling you…

Low-Code / Widgets / Bobbins → It’s Code
Low-Code / Widgets / Bobbins → It’s Code
Low-Code / Widgets / Bobbins → It’s Code

Post away, fill it up, teach us O’ wise one, just don’t ask me to touch your widgets…

disgusted new girl GIF

You’ll get no hate from me, just me silently (openly) judging your choices. :rofl:

This thread, is more about mindset and problem solving, than technique, even though technique is the way it’s being presented.

continue tv land GIF by #Impastor

3 Likes

I don’t believe you can access items outside your scope. In the following case:

ds.table.Where(x => x.field1 == value).Sum(y => y.field2)

“y” cannot be any row (not really a row, but whatever) that was already excluded in the Where call.

SIdenote: I didn’t have to use “y” in the second lambda. I could have used “x” in both, since the x variable is contained within the scope of the call. However, I always switch up the names because x & y represent two different things. YMMV.

Every good fantasy or scifi story has one character that’s a proxy for the audience, who doesn’t know the backstory and has to be there so everyone can slow down and explain things in plain English.

Those characters are vital and so are you.

2 Likes

You got it. (mostly) Sometimes you need return, sometimes not, depending on what you are doing.

Been working my whole life on getting one, and I don’t either. Cope.

No, you can always see items in your scope, and any enclosing scopes (scopes you are inside of)

Ok no, it’s

Db.PerCon.Where(p => p.PerConID == "ROCK")

That says Using the Db context, and from the PerCon table (object),
select objects Where match some criteria.

That criteria being defined by a lambda.

The lambda itself says: Define variable p, where p is being fed from the Db.PerCon rows (it is the rows (Maybe we need to define what extension methods are, that would make some of this clearer.)), and then creates an anonymous function that returns true or false → p.PerConID == "ROCK"

p => p.PerConID == "ROCK"

//is equivalent to

if(PerConID == "ROCK") return my row

It depends on the context.
In a where clause in linq, it’s true or false.
In a select statements, it’s fields or new objects.
In other contexts, you may return nothing at all.

Lambdas are not LINQ, but LINQ uses a lot of lambdas, don’t confuse the two.

1 Like

Remember, a lambda is just a function. Another name for them is Anonymous functions. Its just a more compact, short hand way of creating a function that you are only using in one place. If you understand a regular function, the only things to get hung up on are the syntax and the fact that the variable scope is a little different than a full fledged function.

Speaking of Lambda Lambda Lambda…

I found an old picture of me.

I think a more relevant example is calls multiple methods in one service in ERP.

CallService<Erp.Contracts.EngWorkBenchSvcContract>(ewb =>
{ 
    foreach (var method in methods)
    {
        ewb.ClearAll(...);
        ewb.GetDetailsFromMethods(...);
        //Parameters removed from methods for brevity.
    }
});

You can write this exactly the same as two lambda expressions and it will do what you want. It’s just more verbose and maybe has an overhead cost for repeatedly connecting/disconnecting from the service. Not sure about that part.

The LINQ methods all call an internal (invisible) method called MoveNext after every iteration.

So you have a list (essentially) of PerCon objects, it starts with the first one and runs the anonymous function:

p = PerCon #1, if p.PerConID == “ROCK” add it to the results of Where, now MoveNext
p = PerCon #2, if p.PerConID == “ROCK” add it to the results of Where, now MoveNext

until you reach the end of the content of the DB.PerCon table and you have a new set of data populated by essentially moving through the list and applying the same rules against each line

I think the next topic is “Extension Methods”.

1 Like

Snippet: (Tuples & Func<T>… Action<T>)

Ok, imagine this little function (Func<T>) is a real one, and is much longer, and this will make more sense to you.

Anyway…
I had a function (really a Func<T>) that was very long and hard to read. So I used a Tuple so it would be clearer. Yes one can argue that to some this would be less clear, but just sharing the technique in case someone needs it.

//Snippet (Tuples & Func<T>...)

//Kinda funky
Func<string, string, string, string, string, string, string, bool> SomeConfusingFunction = (a, b, c, d, e, f, g) =>
{
    if(a == e)
    {
        return false;
    }
    else
    {
        return true;
    }
};

//Call like so...
bool myBool1 = SomeConfusingFunction("I", "am", "a", "man", "of", "constant", "sorrow");



//Slightly better... Notice parenthesis in Func<  (  [inType1][inName1], [inType2][inName2] ... )  , [outType]>
//This is a Tuple, so we are actually only passing one object, the "tuple" named "input"
Func<(string a, string b, string c, string d, string e, string f, string g), bool> SomeSlightlyLessConfusingFunction = (input) =>
{
    if(input.a == input.e)
    {
        return false;
    }
    else
    {
        return true;
    }
};

//Call like so... (Notice double parenthesis - You are actually passing a Tuple)
bool myBool2 = SomeSlightlyLessConfusingFunction(("I", "am", "a", "man", "of", "constant", "sorrow"));
1 Like

that would be

const bool bandersonIsCranky = true;

I’d like to hope you aren’t cranky all the time, and if that’s the case then you would be variably cranky :slight_smile:

He is cranky all the time, but it’s usually the good cranky.

Cant Speak Nathan Fillion GIF

I like to do this instead of using lots of inputs on a delegate as well. Delegate help make your code more modular and readable, but the readable bit gets murky if there are a ton of inputs like this.

Since all of the inputs are of a single type, like in this case, I probably would use either a List<T> (or a Dictionary<T,T1> if I wanted to be extra careful).


Func<Dictionary<int,string>,bool> EvenLessConfusingFunction = input =>
{
    return input["a"] != input["e"] )
};

//Defining the Dictionary outside of the function call
var LyricsDict = new Dictionary<string,string>
{
    { "a", "I" },
    { "b", "am" },
    { "c", "a" },
    { "d", "man" },
    { "e", "of" },
    { "f", "constant" },
    { "g", "sorrowwwwwww" }
};

// Call by passing in the Dictionary
bool myBool3 = EvenLessConfusingFunction ( LyricsDict );


// Or the same thing, but with a list<T>
Func<List<string>,bool> ListConfusingFunction = input =>
{
    if ( input[0] == input[4] )
    {
        return false;
    }
    else
    {
        return true;
    }
};

// Define the list
var LyricsList = new List<string> { "I", "am", "a", "man", "of", "constant", "sorrow" };

bool myBool4 = ListConfusingFunction( LyricsList );


2 Likes

Yep, 6 of 1, half a dozen of the other.

Just personal preferences here, or whatever makes sense for what you’re doing. :wink:

Loops

There comes a time in everyone’s life where you can’t just act upon one infinitesimally small object, but you must reach out into the ether, and take hold of many, or each and every object, and act upon it with great passion. It is written. It is known. The author is ridiculous.
KL - The Art of Overdoing a Bit Suspicious Monkey GIF by MOODMAN

Loops you say?

I do, and by loops, I mean iterating. This is a pretty simple concept, so I will basically just point out some of the different kinds of loops you can do in C#, since that is what is most relevant here, but first, a slight bit more explanation.

A loop at its core is a control structure used in programming that is done multiple times until a condition is met (or while a condition is true, depending on how you look at it…). This condition can be simple or complex, and take many forms, here are some:

FOR loop

The FOR loop is composed of the following structure:

for( [ init statement ] ; [ condition statement(evaluates to boolean) ] ; [ iteration statement ])
{
[ This is the code block ]
Code you want to run until your condition is false goes here…
}

  • init statement: This statement runs once before the loop
  • conditon statement: This statement needs to evaluate to a boolean (true/false). While this statement is true, your loop will continue to run. (Unless you exit manually, or error…)
  • iteration statement: This statement will run every iteration of the loop, after the code in the code block.

With the above rules in mind, you can do the simplest and most traditional form of the FOR loop…

for(int x = 0; x < 5; x++) // 'x++' is a shorthand for 'x = x + 1' or 'x += 1'
{
    Console.WriteLine("The value of x is " + x.ToString() + " ...");
}

Explanation:

  • Here, in the init statement, we defined a variable, x as an integer.
  • In the condition statement, we want to loop or iterate while x is less than 5.
  • In the iteration statement, we add 1 to x, and store it in x, so x is literally one more than it was.
  • Each time it looped, the code in the code block was executed, and we did an action. We also have access to the variable x inside the code block, which is very useful.

Output:

The value of x is 0 ...
The value of x is 1 ...
The value of x is 2 ...
The value of x is 3 ...
The value of x is 4 ...

And that is the traditional for loop.
Those of you a little more advanced readers may be seeing how I described the above rules, and either know or suspect that that is not the end of the story, and indeed
The Next Generation Star GIF
it is not, which I will cover in a snippet, as it is a more advanced topic…


WHILE loop

The WHILE loop is composed of the following structure:

while( [ condition statement(evaluates to boolean) ] )
{
[ This is the code block ]
Code you want to run while your condition is true
}

  • conditon statement: This statement needs to evaluate to a boolean (true/false). While this statement is true, your loop will continue to run. (Unless you exit manually, or error…)

With the above rule in mind, you can do the simplest and most traditional form of the WHILE loop…

int x = 0; //I needed something to check for my condition

while( x < 5)
{
    Console.WriteLine("The value of x is " + x.ToString() + " ...");
    x++; // 'x++' is a shorthand for 'x = x + 1' or 'x += 1'
}

Explanation:

  • I made a variable x, as an integer, as I needed something to check in my condition statement, and a way to exit the loop.
  • The entire time the condition statement is true, my heart will go on the code block will execute.
  • I wrote the output of my variable x to the console again, and since this is a simpler form of loop, I added my own iteration statement to increment x by one.
  • When x gets to 5, my condition is no longer true, so the loop is complete, and we move on.

Output:

The value of x is 0 ...
The value of x is 1 ...
The value of x is 2 ...
The value of x is 3 ...
The value of x is 4 ...

Note: A WHILE loop is very simple, but very powerful. Be careful out there.
Example…

string letsCrash = "ok...";
while(true) //forever, unless YOU exit manually
{
    letsCrash += letsCrash;
    //This code has no way to exit the loop, see you at the out of memory error bar.
}

DO / WHILE loop

The DO / WHILE loop is composed of the following structure:

do
{
[ This is the code block ]
Runs at least once.
Code you want to run while your condition is true
Also known as until your condition is false…
}
while( [ condition statement(evaluates to boolean) ] )

  • conditon statement: This statement needs to evaluate to a boolean (true/false). While this statement is true, your loop will continue to run. (Unless you exit manually, or error…)
  • This code will ALWAYS run the code block once BEFORE checking if the condition is true.

With the above rule in mind, you can do the simplest and most traditional form of the DO / WHILE loop…

int x = 0; //I needed something to check for my condition

do
{
    Console.WriteLine("The value of x is " + x.ToString() + " ...");
    x++; // 'x++' is a shorthand for 'x = x + 1' or 'x += 1'
}
while( x < 5);

Explanation:

  • I made a variable x, as an integer, as I needed something to check in my condition statement, and a way to exit the loop.
  • The code block will execute first, and when it is done, the condition is checked, if it is true, the loop continues
  • The entire time the condition statement is true, the code block will execute.
  • I wrote the output of my variable x to the console again, and since this is a simpler form of loop, I added my own iteration statement to increment x by one.
  • When x gets to 5, my condition is no longer true, so the loop is complete, and we move on.

Output:

The value of x is 0 ...
The value of x is 1 ...
The value of x is 2 ...
The value of x is 3 ...
The value of x is 4 ...

FOR EACH loop

The FOR EACH loop is composed of the following structure:

foreach( [ Type ItemName ] in [ SomeTypeOfCollection ] )
{
[ This is the code block ]
Code you want to run until all of your items (ItemName) have been iterated through
}


  • This will iterate over all the items in a collection, and run some code for each one, and continue when done.
List<string> lstRadioHeadSongs = new List<string>(){"Karma Police", "Creep", "Fake Plastic Trees", "Paranoid Android"};

foreach(string niceSong in lstRadioHeadSongs)
{
    Console.WriteLine($"I like the song {niceSong} by Radiohead."); //This is string interpolation
}

Explanation:

  • I created a list of strings, and I added some text to it.
  • In the loop, for each item in my list, I printed some text
  • When I ran out of items, the loop is done

Output:

I like the song Karma Police by Radiohead.
I like the song Creep by Radiohead.
I like the song Fake Plastic Trees by Radiohead.
I like the song Paranoid Android by Radiohead.

BREAK / CONTINUE (Controlling a loop manually)

BREAK
To jump OUT of a loop completely, you can use the break keyword.
Example:

for(int x = 0; x < 5; x++) // 'x++' is a shorthand for 'x = x + 1' or 'x += 1'
{
    if(x == 3) break; //This will exit this loop right here

    Console.WriteLine("The value of x is " + x.ToString() + " ...");
}

CONTINUE
To jump OUT of a loop for ONE iteration, you can use the continue keyword.
Example:

for(int x = 0; x < 5; x++) // 'x++' is a shorthand for 'x = x + 1' or 'x += 1'
{
    if(x == 3) continue; //This will exit this loop right here, but keep running the loop

    Console.WriteLine("The value of x is " + x.ToString() + " ...");
}

Note: If you are inside multiple loops, both of these keywords apply to the closest enclosing loop statement. Maybe an example would help:

List<string> lstRadioHeadSongs = new List<string>(){"Karma Police", "Creep", "Fake Plastic Trees", "Paranoid Android"};

foreach(string niceSong in lstRadioHeadSongs)
{
    Console.WriteLine($"I like the song {niceSong} by Radiohead."); //This is string interpolation
    for(int x = 0; x < 5; x++)
    {
        Console.WriteLine("Woot"!);
        if(x == 2) break; //This only exits THIS loop, the regular for loop in this example
    }
    //You exited to here
}
//You did NOT exit here

Bonus → GOTO loop

I’m going to get some :fire: heat :fire: for this one, but I don’t care. :dumpster_fire:
The goto keyword has a bit of a bad rep, but the keyword itself is not inherently bad. Improper use however can be um, let’s just say detrimental. We can have the goto discussion more later. As for now, it’s mentioned here as it can be used for looping, and in some (very) early programming languages, it was pretty much the only way before other control structures were introduced.

  • A loop with goto is completely manual.
  • The goto keyword is an unconditional jump instruction. (Again, if you want conditional, you’ll have to do it.)
  • The goto keyword changes execution flow to a label in your code, which could be almost anywhere, so it needs to make sense. (ah I’m getting off topic)

Anyway, on to the bonus example:

    int x = 0; //I needed something to check for my condition

    loopStart:
        Console.WriteLine("Yo");
        x++;

        if(x > 2) goto loopEnd;
        goto loopStart;
    loopEnd:        

    Console.WriteLine("Adrian");

Explanation:

  • I made a variable x, as an integer, as I needed something to check in my condition statement, and a way to exit the loop.
  • I added a label loopStart:, so I could jump back to it.
  • I did my work inside, writing “Yo” and incrementing x.
  • I checked a condition on x, and if it was true, I would jump to my label at the end of the loop: loopEnd:
  • If my condition was not met, it continues to the next line, which jumps back to loopStart:, thus looping
Yo
Yo
Yo
Adrian
2 Likes

Snippet: Dumb, but occasionally useful things to do with a for loop…

Main Post → Here!

The rules & structure…


Which means that the below dumb code is perfectly valid:

for(Console.WriteLine("Hello"); true; Console.WriteLine("World!"))
{
    Console.WriteLine("Is this thing broken?");
}

Output, which repeats forever:

Hello                          <-- Init statement
Is this thing broken?          <-- Code Block
World!                         <-- Iteration statement
Is this thing broken?
World!
Is this thing broken?
World!
Is this thing broken?
World!

So, you can do some crazy stuff with for? As you can imagine, yes, yes you can.
Should you? Mmmm, most times probably not, but I imagine the more experienced of you can see how this can be used for good.

I would advise if you use “for” outside of the traditional way, to make it crystal clear in your code what you are doing, or you may confuse someone easily, including yourself! :rofl:

1 Like

New content added this weekend:

Loops

Snippet: Dumb, but occasionally useful things to do with a for loop…

1 Like

Quagmire's Famous Giggity GIF