Why is this "for" loop returning [ ]void?

I wanted a [ ]creative_prop, but somehow I made a [ ]void from the following snippet

# Let's try to get an array of 4 creative_props (from 4 spawns)
PropsList: []creative_prop = for (N:=0..3):
            MaybeProp := SpawnProp(PropAssetRef, vector3{X:=N, Y:=N, Z:=0.0}, IdentityRotation())(0)
            if (Prop := MaybeProp?): # MaybeProp: ?creative_prop
                Prop # Prop: creative_prop

Anyway, the error message is:

This variable expects to be initialized with a value of type []creative_prop, but this initializer is an incompatible value of type []void.(3509)

My question is what am I missing/doing wrong?

Andre

Hi,

You should have gotten errors with this code. A vector3 takes float values as the X, Y, Z values but you use the integer N value.

Try changing the SpawnProp line to MaybeProp := SpawnProp(PropAssetRef, vector3{X:=N * 1.0, Y:=N * 1.0, Z:=0.0}, IdentityRotation()) and see if that works.

The way the type option MaybeProp? works is that if the prop fails to spawn, you can’t assign it to the Prop value and the if fails. That way, it returns void instead of creative_prop. Since your spawnprop is probably failing due to the int values instead of float values, the if-statement fails and returns void.

I also have a question, what does the (0) do at the end of your SpawnProp line?

Hope it works!

Thanks for you’re help.
Sorry about the “int” issue. That came about due to me trying to make a small snippet to illustrate the problem.

I’ve used float constants instead.

You will notice I put a call to SpawnProp before the offending snippet to illustrate that is does seem to be a valid call.

The (0) is what I believe to be how one indexes into a tuple, wihch is returned from SpawnProp.

With the example “int” issue resolved, the problem of not getting a list of creative_props still remains.

The following workaround does work though: Props does become an array of creative_props.

So why is the “for” loop producing []void and not []creative_prop

Andre

Ah yes, I forgot the tuple :sweat_smile:

As to your issue, I haven’t initialized variables that way enough to see the issue. My guess would be that because of the option type creative_prop? if-statement, it doesn’t work.

For example, if you create a function that returns a creative_prop like this

Test():creative_prop=
        MaybeProp := SpawnProp(PropAssetRef, vector3{X:=N, Y:=N, Z:=0.0}, IdentityRotation())(0)
            if (Prop := MaybeProp?): # MaybeProp: ?creative_prop
                return Prop # Prop: creative_prop

That also doesn’t work because the function isn’t sure that it ALWAYS returns a creative_prop. The same principle applies to your issue. Since it’s not all paths that lead to a creative_prop being returned, it fails and sets the return type to void as a failsafe.

Hi. I haven’t tested it, but how about the following code?

# Let's try to get an array of 4 creative_props (from 4 spawns)
PropsList: []creative_prop = for:
    N:=0..3
    MaybeProp := SpawnProp(PropAssetRef, vector3{X:=N, Y:=N, Z:=0.0}, IdentityRotation())(0)
    Prop := MaybeProp?
do:
    Prop # Prop: creative_prop

I think the original code would not work because it would return a tuple with a mix of creative_prop and void.

image

Your code worked perfectly. A single asset is spawned on a 3 by 3 grid, creating a creative_prop array in the process.

Nice one! Thank you very much t.tutiya,
Kind regards,
Andre

1 Like

P.S. I’d still like to know why the original “for” loop was returning [ ]void. Knowing why will go towards a better understanding of Verse.

My thoughts are as follows.
The following code is as same as the original code.

PropsList: []creative_prop = for (N:=0..3):
            MaybeProp := SpawnProp(PropAssetRef, vector3{X:=N, Y:=N, Z:=0.0}, IdentityRotation())(0)
            if (Prop := MaybeProp?): # MaybeProp: ?creative_prop
                Prop #  add creative_prop to []creative_prop
            else:
                #no op. add void to []creative_prop (<--ERROR!)

Even if, “if” expression is fail, but “for” loop is living. so else claues is evaluted, then return “void”.

The problem with your original code is that if without an else does not yield a useful value. if(a) then b else c yields b or c, but if(a) then b is only useful for its side effects.

The for is just evaluating the body expression for each possible value in the domain, and creating an array containing the yielded values. The body expression in this case was a block with multiple subexpressions, so it uses the value yielded by the final subexpression in the block. Your if-without-else does not yield a useful value, so it creates an array of useless values.

As others have pointed out, if don’t want some iteration of the for to produce an element in the output array, then you need to make the domain of the for (the part in parentheses) fail for that iteration.

2 Likes