#1575 Using lists as arrays is difficult

dsav Thu 14 Jul 2011

Good old plain array is one of the core concepts of programming. It's used in a lot of algorithms. However, allocating arrays is a surprisingly hard task in Fantom.

As far as I know, there is no easy and effective way to do it. You can't just

int[] a = new int[100];

You need

a := Int[,].fill(0, 100)

But this is not efficient, especially when the desired size is big. You can do more efficient:

a := Int?[,]
a.size = 100

I believe, this works much faster, than calling fill. But when doing so, you're made to mess with nullables.

And what is really frustrating is working with 2 or more dimensional arrays. While 3+ dimensions are not used very often, 2-dimensional arrays are very common.

So, my question is: may be I'm missing something, and there is a way to work with arrays painlessly? If not, I'm sure Fantom would benefit from it.

DanielFath Thu 14 Jul 2011

Think there is this:

EDIT: Nvm it isn't what you want.

But in a perfect world we'd probably have something like

a := Int[,](100)

brian Thu 14 Jul 2011

However, allocating arrays is a surprisingly hard task in Fantom.

I am not sure I would call anything you do in a single line a "surprisingly hard task" :-)

In Fantom lists are always references to an object - just like all Java collections. So things always default to null if you want to pre-size a list. So you are correct that setting size and letting it default is null most efficient. Although I doubt in most cases the performance of a fill(0) would matter. Plus you can always just work with a raw Java array via FFI using IntArray.make(100).

go4 Thu 14 Jul 2011

Fantom suppert the 2-dimensional arrays:

Int[][] a := [[1,2],[3,4]]
b := a[0][0]

dsav Thu 14 Jul 2011

It's a list of lists, not a 2-dimensional array. The difference is obvious when you need to create a table of N x M, where N,M - variables. You need to do something like this:

ct := Int[][,]
for (i := 0; i < M; ++i) {
  t := Int[,]
  t.fill(0, N)
  ct.add(t)
}

DanielFath Thu 14 Jul 2011

Go4, I don't think he has problem with makin arrays, he has a problem with making 2D arrays of certain capacity and I admit I don't know how to make a Int[100][101] in Fantom. Brian is it possible to make a Int[][] that has both capacity set?

Yuri Strot Thu 14 Jul 2011

@DanielFath capacity and fill are not equal:

Int[,] { fill(0, 100) }[5] = 0  // works OK, size == 100
List.make(Int#, 100)[5] = 0     // IndexErr, size == 0

@dsav Before dreaming about Java's features in Fantom I like to think about these features in JavaScript. There are no 2D arrays in JavaScript, so you need to use list of lists as well.

@brian Looks like fill implementation is not really good both in Java and JavaScript. It'll be much faster to avoid delegation to add/insert.

DanielFath Thu 14 Jul 2011

@ystrot. I thought it Int[100] meant just set capacity to 100.

In that case List will need a new constructor like makeFill or setting size should automatically add the defVal of the element.

brian Fri 15 Jul 2011

@brian Looks like fill implementation is not really good both in Java and JavaScript. It'll be much faster to avoid delegation to add/insert.

Good point - I optimized the Java version. Andy can decide if he wants to make JS version faster or maybe you can email him a patch.

yliu Mon 18 Jul 2011

@dsav Just a suggestion:

If you think back to assembly language, multi-dimensional arrays are just a single dimension array with an algorithm to calculate the offset you need to reach the index you want to retrieve. (for 2d I believe its (colSize*x)+y? I may be wrong)

So If you are planning to use a lot of multi-dimensional arrays it shouldn't be too difficult to write your own 2-d, 3-d, etc array classes and maybe even create a pod for various projects. I'm new at Fantom, but with the implicit make/get/set methods it could end up looking pretty clean.

Login or Signup to reply.