Search code examples
godotgdscript

Need explanation on function input error (beginner question)


I'm taking the initial gdquest course and ran into an issue in one of the practice questions. It asks users to create a for loop to generate 3 rectangles, each of which don't overlap. For the draw_rectangle function I used the Vector2 array entry "size" but the solution uses size.x and size.y.

Could someone explain why inputting the array Vector2 doesn't work?

MY SOLUTION:

var rectangle_sizes = [Vector2(200, 120), Vector2(140, 80), Vector2(80, 140), Vector2(200, 140)]

func run():
    for size in rectangle_sizes:
        draw_rectangle(size)
        jump(size.x, 0)

GDQUEST SOLUTION:

var rectangle_sizes = [Vector2(200, 120), Vector2(140, 80), Vector2(80, 140), Vector2(200, 140)]

func run():
    for size in rectangle_sizes:
        draw_rectangle(size.x, size.y)
        jump(size.x, 0)

Solution

  • This is just like asking "Can you explain why I can't drive in a flat head screw with a square screwdriver?" The function draw_rectangle() takes two arguments: a number representing width and a number representing height. The choice to take two arguments rather than single vector argument is more or less arbitrary. The person who wrote the function could have written it to take a vector instead of two numbers, but that's just not how they decided to write it.

    Programming is people creating pipelines for numbers and objects. They go through the pipes and do all kinds of things. But if you put the wrong thing in the wrong pipe, the program won't work. It's just the way it is. Whoever makes the pipes initially gets to decide what the "right way" is and everyone else has to deal or make their own thing.

    EDIT: Seems some confusion on why functions can't take a vector as two arguments. I'll explain by writing the draw_rectangle out. I don't know godot, so this will just be pseudo code (it may not actually be "correct" code, but it should get the idea across)

    //First, I will define the function the way it is IRL
    func draw_rectangle(width, height):
        for x in width:
            for y in height: 
                paint(x, y)
    
    //now, the way you were using it:
    func draw_rectangle_keega(size):
        for x in size.x:
            for y in size.y:
                paint(x, y)
    
    

    Note that the way you reference the arguments changes depending on whether the width and height are two properties of a single object, or two entirely separate objects. So when you called the function it looked at the first argument you supplied and went "That doesn't look like a number, that looks like a vector. That's wrong" and then it looked at the second argument and went "That doesn't look like a number, that looks like nothing. I need a number for the width."

    Now, some languages do some things to try to help developers. Make it so there are multiple ways to do things and things are forgiving. For example, both of these are acceptable in python:

    maxValue = max(1, 2)
    listOfValues = [1, 2]
    maxValue2 = max(listOfValues)
    

    That's because the max function is defined like this:

    def max(arg1, arg2):
        if arg1 is List:
            //if you give the function a list, it ignores arg2
            if(arg1[0] > arg1[1]):
                return arg1[0]
            else:
                return arg1[1]
        else:
            //if you don't give the function a list, it uses both arguments
            if(arg1 > arg2):
                return arg1
            else:
                return arg2
    

    I know this is limited to two arguments and the real one isn't but this is for demo purposes

    The reason both are acceptable is because the function was specifically written to accept both kinds of input and distinguish between them. This has a lot of downsides though. For one thing, it's more straightforward if there is one and only one right way to do things. It means there are fewer edge cases, fewer weird bugs. It also means it's easy to tell developers when they make a mistake and tell them exactly what the mistake is. Additionally, it creates pointless overhead. Now, on top of actually calculating the max value, it needs to work out what format the data is in. If there is only one way to provide the data, then that if statement is eliminated and the function can be shorter and more performant.