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.
DanielFathThu 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)
brianThu 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).
go4Thu 14 Jul 2011
Fantom suppert the 2-dimensional arrays:
Int[][] a := [[1,2],[3,4]]
b := a[0][0]
dsavThu 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)
}
DanielFathThu 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?
@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.
DanielFathThu 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.
brianFri 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.
yliuMon 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.
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
You need
But this is not efficient, especially when the desired size is big. You can do more efficient:
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:
But in a perfect world we'd probably have something like
brian Thu 14 Jul 2011
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:
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:
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 aInt[][]
that has both capacity set?Yuri Strot Thu 14 Jul 2011
@DanielFath capacity and fill are not equal:
@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 thedefVal
of the element.brian Fri 15 Jul 2011
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.