Array of objects of a subtype not OK?
Monkey Forums/Monkey Programming/Array of objects of a subtype not OK?
| ||
This does not work: [monkeycode] Class Shape End Class Circle Extends Shape End Class Camera Method New(shapes:Shape[]) Print "Length is " + shapes.Length End End Function Main:Int() Local circle1:Circle = New Circle Local circle2:Circle = New Circle Local test:Camera = New Camera([circle1, circle2]) 'Compile error here: ': Error : Unable to find overload for new(Circle[]). End [/monkeycode] Can it be done somehow? Or should I use some kind of list? I really liked the idea of auto-arrays like this since it is super handy when setting things up. |
| ||
Seems like it should work, but the compiler is not smart enough to figure it out. |
| ||
Ah cool! I added a bug report in case it is unintended. Hoping for the best. |
| ||
Hi, It's by design, basically to avoid the overhead of having to check the actual type of objects assigned to array elements at runtime. It means you can't accidentally do this: Class Shape End Class Circle Extends Shape End Class Square Extends Shape End Function Test( shapes:Shapes[] ) shapes[0]=New Circle 'perfectly valid code... shapes[1]=New Square 'ditto End Function Main() Test( New Shape[2] ) 'OK Test( New Circle[2] ) 'OOPS! Test will put a Square into our Circle array! Test( New Square[2] ) 'OOPS2! End If Monkey allowed Circle[]/Square[] to Shape[] conversions like this, then it'd have to perform a runtime check every time an object was written to Shape[] arrays to make sure the type of the object being written was a subclass of the 'real' type of the array. Java and C# actually already do this assignment checking, but emulating it in other languages is harder. Apart from the overhead of the checks, it'd also mean object arrays would have to be 'wrapped' to include some runtime type info, so even all reads would be affected by an extra level of indirection. BlitzMax (and probably Blitz3D/BlitzPlus) just ignore this issue, so it's actually possible to put a Square into a Circle[] in those languages! But I decided in Monkey to just prohibit implicit array casting like this and see what happened. So far, people seem to have been able to work around it and the issue seldom comes up... |
| ||
I agree it is very rare, never encountered it myself, until I got the idea to use arrays more. I fear I might misunderstand the bottom line, however in my case above - would it not just be enough if the auto-declared array [] was assumed to be of the assigning type? Local a:= [Circle,Circle2] a is a Circle[], as expected Local a:Shape[] = [Circle,Circle2] Here since Circle and Circle2 are shapes - which is what we want, can it not be assumed that the autoArray of two Circles actually is a ShapeArray? Could not this pass runtime? Since Circle & Circle2 will always Inherit from Shape, and that won't change runtime at least. I 100% agree with the argument to not do a runtime check every time. And I'm pretty fine with not having type-casting on arrays, but letting those correct auto-created arrays [1,2,2,3] trough would be quite useful I think! |
| ||
No comment. |
| ||
I say ignore the issue and do it like bmax... let the programer be responsible (a compile warning would be cool though). the "work around" add to much more code for what gain? and they tend to be a little ugly too. |
| ||
I would not make it like BlitzMax (in fact, I would suggest a BlitzMax fix) as having a parent object into an object array is undesirable. That said, allowing a runtime check would be cool as in C# and Java would be cool, but I'm not sure wich performance costs this will add on other targets. |
| ||
I've always disliked that in Java you can't just cast anything to anything like in C++. But given that it's one of the target languages, it seems like it would be inviting trouble to let Monkey cast freely in ways that would work on some targets and not on others. I know muddy is thinking of another issue that came up lately in which functions with side effects are getting discarded by the compiler. But short of adding C++ code for run-time type checking, which would be a lot of work for a small improvement, I think Mark may have the most pragmatic solution here. I could be wrong - I guess whether things like this come up often depends on your programming style, and run-time polymorphism is not a big part of mine. |
| ||
Nope. I'm thinking of the fact that this exact same issue has been raised multiple times already and the various demonstrations that spending effort expressing views here is wasted. here: http://www.monkeycoder.co.nz/Community/posts.php?topic=2879#31930 |