Array autoboxing

Monkey Forums/Monkey Programming/Array autoboxing

Samah(Posted 2011) [#1]
Mark, can you add this to boxes.monkey please?
Class ArrayObject<T>
	Field value:T[]
	
	Method New(value:T[])
		Self.value = value
	End
End

I'm not sure how hard it will be to do autoboxing with that (non-trivial, I'd assume), but it'd be nice to have this class as part of the official distribution so we can put arrays in maps and lists without custom wrapper classes.


Rixarn(Posted 2011) [#2]
I'm not 100% sure, but i believe that version 5 of Java and up don't allow generic array creation..


Samah(Posted 2011) [#3]
I'm not 100% sure, but i believe that version 5 of Java and up don't allow generic array creation..

It's not creating a generic array; you pass one into the constructor. It might be a problem for the actual autoboxing, but there's nothing wrong with the code I've provided.

Also, Java's "generics" are just a dirty hack, really. You can't instantiate T or an array of T because at runtime, T is indistinguishable from Object. Type erasure is a nasty thing.


marksibly(Posted 2011) [#4]
Hi,

I'll be looking at the generic stuff again soon, but this will not be going into Monkey just yet.

The main problem is that there is no way to 'cast' arrays in Monkey at the moment, which makes dealing with T[] arrays a bit tricky.

By rights, since there is no array casting, there should be no way to pass T[] arrays to methods or return them (as they have to be converted to Object[] arrays for the generic class to be able to use them). The fact that you can is really a 'hole' in the generic system that doesn't work well on all targets (try your ArrayObject in C++).


Samah(Posted 2011) [#5]
That's a pity, because you can in Java. :(
I assume that making arrays objects would be a huge undertaking...


marksibly(Posted 2011) [#6]
Hi,

> I assume that making arrays objects would be a huge undertaking...

Well, not that huge...but it's actually a bit more complicated than that with arrays.

The big issue is that while Java allows you to convert a Derived[] array to a Base[] array, in order for this to work safely Java must check ALL writes to the Base[] array to make sure you aren't writing a non-Derived object.

Such a 'write barrier' is hard/inefficient to do for all targets. Possible by all means, but I was worried about the overhead involved (esp. for the dynamic languages which don't have 'typed' arrays at all) so decided not to implement it in Monkey, and disallow 'casting' of arrays entirely. Of course, there's also the fact that some of these issues weren't entirely clear to me at the outset either!

All in all, I think it's best to think of Monkey arrays as being considerably lower level than in other languages. They're designed for speed, not comfort, so are good for behind-the-scenes grunt work, but for higher level tasks you should stick with stacks/vector/arraylists/lists etc built on top of arrays.

And I don't think that's such a bad approach for a multi-target language as it offers great flexibility over how arrays may be implemented.


Samah(Posted 2011) [#7]
@marksibly: The big issue is that while Java allows you to convert a Derived[] array to a Base[] array

Uhh.... no you can't. String[] does not extend Object[]. It does however extend Object (non-array).

Edit: My bad, apparently you can. This is news to me...


marksibly(Posted 2011) [#8]
Hi,

I sort of knew 'of it'...but the ramifications of it are pretty major, esp. the runtime array write checking. And without being able to cast arrays, as you've/we've found out, using generic arrays is hard/impossible with Java style generics.

C++ *doesn't* support array upcasts like this, in that it wont implictly convert Derived** to Base** - an age old 'WTF' sort of issue in the C++ world! I guess C# must though, as it uses a similar generic system to Java's.

I am starting to get very interested in the idea of moving to C++/macro style generics - it solves a TON of problems in one hit, is probably more suited to a multi-target translator where you have limited control over the runtime env, is IMO more in the style of what is supposed to be a 'simple' language (eg: you can 'use' methods when writing the template without having to declare 'T Extends Blah') and should be pretty easy to implement - and would be fully backward compatible.

However, it would be at the cost of some code bloat, as each generic instantiation would get it's own 'real' class, instead of sharing a single class. Still, Monkey's dead code elimination would help keep this to a minimum, and besides, how many types of List does an app REALLY use anyway?

I originally went with Java style generics because I assumed it'd produce more optimal (well, smaller) code, and yes, it does. But I didn't really realize how limiting it'd be, and the amount of compiler side effort that'd be required to get any decent mileage out of it.