Blue Bananas and Confused Potatoes: A photographic journey through Scope and Passing

Blue Bananas and Confused Potatoes: A photographic journey through Scope and Passing


There can be a lot of ambiguity in code. The “why” behind the “how”. It can be frustrating, not seeing the whole picture. I don’t like “black box” coding. I want to know what's going on. I have spent multiple sessions of hours at a time grilling ChatGPT about all kinds of things. One day I was thinking about immutability of strings and I got into a “Yes, but why?” rabbit hole with ChatGPT. I am going to share some of what I learned with you so that, when you look at the code you’re writing, you’ll know a little bit more about what’s happening back there!


Lettuce begin


I'll be using C# in my examples today instead of JavaScript. Don’t worry, though, if you’re more familiar with JavaScript. The core principles of coding languages don’t really change, so you'll find that following along with C# won't be difficult. I've chosen C# because, as a strongly typed language, it requires explicit declarations of intent in your code. This might sound a bit technical, but in simpler terms, it means that C# is very clear about what each piece of your code is doing. This clarity can be incredibly helpful for understanding fundamental programming concepts.


Cool? Great. Now let’s get to the fun part. I promised blue bananas and I’m gonna give them to you!


String beans and code strings...


Let's start with a little snippet of code:

string banana = "banana";
string potato = "potato";
string otherFruit = "orange";        

As you can see, we have some fruits and a lonely vegetable. The potato is an odd man out, but its ok, he'll be exiting stage left imminently. Until then, we continue. If we were to log out each of our variables, our results would be fairly easy to guess:

Console.WriteLine($"The banana is: {banana}.");// The banana is banana.
Console.WriteLine($"The potato is: {potato}.");// The potato is potato.
Console.WriteLine($"The other fruit is: {otherFruit}.");//The other fruit is orange.        

With me? Of course you are! Smart cookies. Ok so let's take a look at what this might look like if we want to see something tangible.

Here, our cards will represent our variables and our foods will represent our strings!


Pass the peas. And the variables, please.


In C#, when we pass data to a function, it's usually done 'by value'. What does that mean? Well, let's consider strings. When we give a string to a function, it's like we're giving the function a note with the location of the string in the computer's memory. The function can use this note to find and read the string, but it doesn't get the actual string itself. It can see it, it can read it, it can copy it to its own local scope, but it can't modify the original one. This is how passing by value works with strings in C# functions. We're gonna start the fun stuff now.


Let's expand on our snippet of code:

string banana = "banana";
string potato = "potato";
string otherFruit = "orange";

string ShowMeBlue(string item){ 
    return "blue " + item;
};

Console.WriteLine(ShowMeBlue(banana));        

Knowing now that C# variables are passed by value, we are saying: "I want to see a copy of each item I give you in blue." And then "Show me this banana in blue." Let's take a look at our code in action!

This is what we would see. The function will first create the "item" reference that points to the global banana. Then we ask it to show us the banana in blue, return "blue " +

This was fun, but there's more fun below!


No potatoes in my fruit salad! Direct reassignment it is!


Now let's take a look at something interesting. Let's modify our code a little bit:

string banana = "banana";
string potato = "potato";
string otherFruit = "orange";

string ShowMeBlue(string item){
    potato = "apple";
    return "blue " + item;
};

Console.WriteLine(ShowMeBlue(potato));        

So we know already that we are passing the reference value of the potato string to the function, but then what happens? Well let's take a look. We're saying "Here's where the potato is. Change it to an apple and show me a blue potato." What do you think we are going to see on our console?


Let's break it down some and take a look at what's going on:

Direct reassignment of the global potato variable. But locally, item still points to "potato"!

The first thing our function does is create a temporary reference to the global potato. Just like it did with the banana. So now it has its own reference to that particular string in memory. But the very next line tells our function to change the global reference point to a new string "apple". Our function's reference point doesn't change on this loop through. So we will see this:

Our potato string is gonna hang out in its spot in memory until "garbage collection" happens. Memory allocation will be cleaned up automatically every so often.

Wait but didn't you say what happens in functions doesn't change the global variables? Yes I did! Good for you, listening! Well, there's an exception: direct reassignment.


Inside our function ShowMeBlue, when we set potato to "apple", we're not just changing it temporarily. We're actually updating the global potato. However, here's the fun part: the local variable item inside the function still holds the initial value of potato, which was "potato" when we called the function. So, the function returns "blue " + item, and that's why we get "blue potato" as the result the first time through.


In essence, direct reassignment alters the global variable going forward, but local variables like item keep a snapshot of the value they had when the function started.


This is a crucial distinction: changing global variables affects all future uses of them, while local variables are like frozen snapshots of the past.


Fruit Basket!


Well I painted a bunch of blue fruit, so let's get crazy!

string banana = "banana";
string potato = "potato";
string otherFruit = "orange";

string ShowMeBlue(string item){
    potato = "apple";
    return "blue " + item;
};

Console.WriteLine(ShowMeBlue(potato));//blue potato
Console.WriteLine(ShowMeBlue(banana));//blue banana
Console.WriteLine(ShowMeBlue(potato));//blue apple
Console.WriteLine(ShowMeBlue(otherFruit));//blue orange        

Let's take a look at our code in action!

It's worth saying, each time we run the function, we're actually creating a new "apple" string and changing the global reference again. It's a lot to add to the photos, but it is important that you know this.


Nested functions make it berry interesting.


Well that was fun. So much fun that I think we should see what happens when we add another function!

string banana = "banana";
string potato = "potato";
string otherFruit = "orange";

string ShowMeBlue(string item){
    potato = "apple";
    return "blue " + item;
};

string ShowMeStripes(string item){
    return "striped " + item;
};

Console.WriteLine(ShowMeStripes(potato));
Console.WriteLine(ShowMeStripes(ShowMeBlue(otherFruit)));
Console.WriteLine(ShowMeBlue(ShowMeStripes(banana)));        

Let's see the first line. Remember, the global potato was changed:

Our global potato is still "apple"

So here our result will be "striped apple".


Now on the next line, we're sending the otherFruit through ShowMeStripes by way of ShowMeBlue which means we will see:

Based on the order, our fruit comes out as a blue striped orange.

When we pass a function through a function, we work inside out! First, our fruit goes through the ShowMeBlue function, giving us a "blue orange". From there it goes in to the ShowMeStripes function which concatenates "striped " onto our item making it a "striped blue orange"


Our last line requests to send our banana through ShowMeBlue by way of ShowMeStripes so our result is a little bit different, but the difference is important to note:

With the new order, we get a striped blue banana.

So here we can see how scope and the order we call our functions in make a difference in our end results!


Romaine calm and code on!


And here our time together comes to an end. There is so much more to all of this. So much deeper that you can dive with scope and passing values but I hope I've given you enough to have some aha moments when you're doing your thing!


Remember, it's a big coding universe out there, and there's more than one way to peel a... potato? Or is it debug a program? Either way, I'm all ears(subtle corn pun) if you've got a different take to share. I'm always open to learning!


As always, I'm here if you want to ask questions or have a chat. Now have fun, stay a-maize-ing, and happy coding!

(No produce was harmed in the making of these puns.)

Megan OKuly

Designer dedicated to creating inclusive media, marketing, and advertising, and more.

1 年

Thank you for this! It was a fun and educational read.

要查看或添加评论,请登录

Andrea Presto的更多文章

社区洞察

其他会员也浏览了