I'm thinking non-primitive arrays are mapped as Fan list types such as JavaObj[]. That requires some "boxing/unboxing" when calling b/w Fan and Java. The other alternative is to pass arrays around as a special type like:
class Array
{
Int size
Obj get(Int i)
Void set(Int i)
}
The special type methods can be efficiently mapped into array opcodes - so we'd get native array performance with casting overhead (we have the casting overhead with lists too). The advantage is we don't need to "box/unbox". The disadvantage is that we loose static typing and convenience of working with a list.
Arrays of primitives are another story because boxing to a Fan list is way too much overhead to efficiently work with Java. I'm thinking primitive arrays need special interop wrappers such as:
class Int32Array
{
Int size()
Int get(Int)
Void set(Int)
}
I'm not planning on doing anything with Java generics at this point.
Any comments?
jodastephenFri 21 Nov 2008
Could the array question be one to improve the performance of arrays in Fan in general?
What I'm thinking is could an immutable list in Fan be implemented as an array in bytecode. Would the array be suitably safe for passing between threads at the bytecode level?
That way, there would be no need for a dedicated public Array class - there would be a hidden subclass of List instead. There would need to be a method on Fan's list class to determine if the length cannot be changed.
Fully mutable - list
Fully immutable - array
Mutable fixed length - array
brianFri 21 Nov 2008
We really already have that functionality in List - handled by the toRO and toImmutable subclasses. However note the best we can do it read-only since we can't guarantee a Java class is immutable (at least not yet). We could make some special cases for things like String - maybe even load the immutable class list from a text file.
Since Array is already backed by an Object[] (since my rework last month), boxing an array is really just a single object allocation which would create a fan.sys.List under the covers backed by the original array.
So then the question becomes do box to a mutable or read-only array? It actually doesn't really hurt anything to box as mutable - the only change is that when I grow the array I'll use reflection to grow using the original type. That way unboxing is simply a field access and cast operation.
But I'd definitely be open to hear votes on whether a Java array is boxed as a mutable list or read-only list.
jodastephenFri 21 Nov 2008
It actually doesn't really hurt anything to box as mutable - the only change is that when I grow the array I'll use reflection to grow using the original type.
If I've understood correctly, then I don't think this works.
Java defines an API in an interface that takes an array. The calling code passes an array in and expects the results to be available in the array that was passed in (yes, this is a hack, but it does happen). If the Fan code implementing this interface adds to the list, then Fan creates a new array, meaning that the calling code doesn't see the changes made in the Fan implementation method.
list = list.toFixedLength()
(BTW, shouldn't ro() and rw() be renamed to toRO() and toRW()? )
So I want to see a mutable, fixed-length implementation of a List in Fan, because that will allow foreign APIs to be implemented properly.
brianFri 21 Nov 2008
(BTW, shouldn't ro() and rw() be renamed to toRO() and toRW()? )
I prefer ro myself, but for consistency maybe we should rename. I'd like to hear other opinions.
So I want to see a mutable, fixed-length implementation of a List in Fan, because that will allow foreign APIs to be implemented properly.
I can see that angle, but that is really just a tradeoff in flexibility versus trying to babysit the developer. As long as you treat the list like an array and just get/set then it works fine. Also I don't think that is a very common case, I don't think I've seen an API in my life which passes you an array to fill in. The 99% case is when a method returns an array like Class.getFields.
So I'm more included to say an array is boxed to a mutable list.
jodastephenFri 21 Nov 2008
I don't think I've seen an API in my life which passes you an array to fill in.
Java's list class - toArray(array).
I agree that it could be left to trust the developer, but its quite a magical one to explain. Sometimes the code side effects the calling Java code, and sometimes it doesn't... yuck.
brianFri 21 Nov 2008
Java's list class - toArray(array).
Good point (although I think that is more of a 1% case).
katoxFri 21 Nov 2008
I don't think I've seen an API in my life which passes you an array to fill in.
Not exactly an API but there is a a common hack how to avoid final restriction of local variable access in inner classes.
Example (codeguru.com):
//: DirList3.java
// Building the anonymous inner class "in-place"
import java.io.*;
public class DirList3 {
public static void main(final String[] args) {
try {
File path = new File(".");
String[] list;
if(args.length == 0)
list = path.list();
else
list = path.list(
new FilenameFilter() {
public boolean
accept(File dir, String n) {
String f = new File(n).getName();
return f.indexOf(args[0]) != -1;
}
});
for(int i = 0; i < list.length; i++)
System.out.println(list[i]);
} catch(Exception e) {
e.printStackTrace();
}
}
} ///:~
JohnDGFri 21 Nov 2008
The big outstanding issue is how to map arrays.
Why can't they be represented as native arrays in all cases, with methods delegating to a static class somewhere? As I recall, this is how you handle non-null primitives.
However, I should point out that arrays are not used much in day-to-day programming. On the Java side, the JCF is far more common.
If you can do VM-specific methods, then perhaps you could have a fromList static method accepting a JFC class, and a toList() method that converts a Fan array into a Java list. This would at least make interop more bearable.
On the Fan side, I'd like to see auto-conversion someday, which would eliminate the need to explicitly call the fromXXX, toXXX methods.
While I'm complaining, let me say I don't like the new home page. :-) The picture of the fan neighborhood is nice, but programmers don't care about where a language came from and aren't interested in reading lists of features. They want to see actual code samples for things they might like to do.
So if it's a choice between the picture and the code sample, please go back to the code sample. :-)
brianFri 21 Nov 2008
Why can't they be represented as native arrays in all cases, with methods delegating to a static class somewhere? As I recall, this is how you handle non-null primitives.
Primitives are different because we have a closed set of types which are represented on a one-to-one basis with a Fan type. Arrays are a type system anomaly which we can't map into Fan's type system. That is why the two choices are to use a List (keep the type info) or use a generic Array class for all array types (and lose the type info):
The third alternative would be come up with real array syntax for Fan - but that doesn't sit well with me.
So if it's a choice between the picture and the code sample, please go back to the code sample. :-)
I think the issue is that any short sample can easily be an immediate turn-off. I've gotten all sorts of comments about the original code sample (more negative than positive). What is the right code sample for a home page?
katoxFri 21 Nov 2008
What is the right code sample for a home page?
A compilable one ;) but I prefer a code sample to the current picture too. Or maybe use a stock photo. Let's move that to another topic.
jodastephenSat 22 Nov 2008
That is why the two choices are to use a List (keep the type info) or use a generic Array class for all array types (and lose the type info)
I definitely vote for something that keeps the types, and since an array is really just a length restricted list, the List class seems most sensible.
BTW, what is the strategy for alternate implementations of List/Map in Fan? With Java, much power is derived from user produced implementations, such as a list that filters for you, or is backed by a remote data source and so on. Can users create their own List/Map implementations? Is that intended/desirable?
brianSat 22 Nov 2008
To get started I will map to a normal mutable List. We can play with it and decide how we like that mapping. I'd prefer not to create a new mode of lists which are mutable but not resizable (although we could do that under the covers).
Java array types will be represented in fcode as:
java.bar.Baz[] => [java]foo.bar::[Baz
Although you can't use primitives and array types directly in Fan as variables - we do need a formal representation of the types for the JVM to generate the correct call signatures.
BTW, what is the strategy for alternate implementations of List/Map in Fan?
Right now to keep things simple I've made List and Map final. This avoids the whole problem of user generics. My personal design tastes are to model application domain collections in their own right versus as collection customizations:
Things like that are duck typed replacements for Lists. But I know in the Java world that people love to create all sorts of various implementations and subclasses of Java collections - so I'd be open to discuss strategies.
alexlamslSun 23 Nov 2008
Even though the concurreny utilities in Java does not suit the Fan model well, the basic Java Collection Framework is what I missed most in Fan at the moment.
brianSun 23 Nov 2008
Java Collection Framework is what I missed most in Fan at the moment.
OK - if others would like to discuss the Fan strategy for the collection framework, then let's create another topic.
brianMon 24 Nov 2008
Does anyone have any compelling cases for supporting multi-dimensional arrays in phase 1 of the Java FFI?
They aren't used very heavily in the J2SE APIs - ResourceBundle, GridBagLayout, some of the java.awt.image classes.
jodastephenMon 24 Nov 2008
I can't remember using multi-dimensional arrays, so they could probably be dropped in phase 1.
brian Tue 18 Nov 2008
I've "spiked" the Java FFI design and gotten the most basic case working end-to-end. Here is my simple test case which now works:
The code has been pushed to hg if you wish to review.
brian Fri 21 Nov 2008
Update on my progress - I've got the following working:
Date()
int
Java primitives are mapped into Fan using the following qnames:
The big outstanding issue is how to map arrays.
I'm thinking non-primitive arrays are mapped as Fan list types such as
JavaObj[]
. That requires some "boxing/unboxing" when calling b/w Fan and Java. The other alternative is to pass arrays around as a special type like:The special type methods can be efficiently mapped into array opcodes - so we'd get native array performance with casting overhead (we have the casting overhead with lists too). The advantage is we don't need to "box/unbox". The disadvantage is that we loose static typing and convenience of working with a list.
Arrays of primitives are another story because boxing to a Fan list is way too much overhead to efficiently work with Java. I'm thinking primitive arrays need special interop wrappers such as:
I'm not planning on doing anything with Java generics at this point.
Any comments?
jodastephen Fri 21 Nov 2008
Could the array question be one to improve the performance of arrays in Fan in general?
What I'm thinking is could an immutable list in Fan be implemented as an array in bytecode. Would the array be suitably safe for passing between threads at the bytecode level?
That way, there would be no need for a dedicated public Array class - there would be a hidden subclass of List instead. There would need to be a method on Fan's list class to determine if the length cannot be changed.
brian Fri 21 Nov 2008
We really already have that functionality in List - handled by the
toRO
andtoImmutable
subclasses. However note the best we can do it read-only since we can't guarantee a Java class is immutable (at least not yet). We could make some special cases for things like String - maybe even load the immutable class list from a text file.Since Array is already backed by an Object[] (since my rework last month), boxing an array is really just a single object allocation which would create a fan.sys.List under the covers backed by the original array.
So then the question becomes do box to a mutable or read-only array? It actually doesn't really hurt anything to box as mutable - the only change is that when I grow the array I'll use reflection to grow using the original type. That way unboxing is simply a field access and cast operation.
But I'd definitely be open to hear votes on whether a Java array is boxed as a mutable list or read-only list.
jodastephen Fri 21 Nov 2008
If I've understood correctly, then I don't think this works.
Java defines an API in an interface that takes an array. The calling code passes an array in and expects the results to be available in the array that was passed in (yes, this is a hack, but it does happen). If the Fan code implementing this interface adds to the list, then Fan creates a new array, meaning that the calling code doesn't see the changes made in the Fan implementation method.
(BTW, shouldn't ro() and rw() be renamed to toRO() and toRW()? )
So I want to see a mutable, fixed-length implementation of a List in Fan, because that will allow foreign APIs to be implemented properly.
brian Fri 21 Nov 2008
I prefer
ro
myself, but for consistency maybe we should rename. I'd like to hear other opinions.I can see that angle, but that is really just a tradeoff in flexibility versus trying to babysit the developer. As long as you treat the list like an array and just get/set then it works fine. Also I don't think that is a very common case, I don't think I've seen an API in my life which passes you an array to fill in. The 99% case is when a method returns an array like
Class.getFields
.So I'm more included to say an array is boxed to a mutable list.
jodastephen Fri 21 Nov 2008
Java's list class - toArray(array).
I agree that it could be left to
trust the developer
, but its quite a magical one to explain. Sometimes the code side effects the calling Java code, and sometimes it doesn't... yuck.brian Fri 21 Nov 2008
Good point (although I think that is more of a 1% case).
katox Fri 21 Nov 2008
Not exactly an API but there is a a common hack how to avoid
final
restriction of local variable access in inner classes.Example (codeguru.com):
JohnDG Fri 21 Nov 2008
Why can't they be represented as native arrays in all cases, with methods delegating to a static class somewhere? As I recall, this is how you handle non-null primitives.
However, I should point out that arrays are not used much in day-to-day programming. On the Java side, the JCF is far more common.
If you can do VM-specific methods, then perhaps you could have a
fromList
static method accepting a JFC class, and atoList()
method that converts a Fan array into a Java list. This would at least make interop more bearable.On the Fan side, I'd like to see auto-conversion someday, which would eliminate the need to explicitly call the
fromXXX
,toXXX
methods.While I'm complaining, let me say I don't like the new home page. :-) The picture of the fan neighborhood is nice, but programmers don't care about where a language came from and aren't interested in reading lists of features. They want to see actual code samples for things they might like to do.
So if it's a choice between the picture and the code sample, please go back to the code sample. :-)
brian Fri 21 Nov 2008
Primitives are different because we have a closed set of types which are represented on a one-to-one basis with a Fan type. Arrays are a type system anomaly which we can't map into Fan's type system. That is why the two choices are to use a List (keep the type info) or use a generic
Array
class for all array types (and lose the type info):The third alternative would be come up with real array syntax for Fan - but that doesn't sit well with me.
I think the issue is that any short sample can easily be an immediate turn-off. I've gotten all sorts of comments about the original code sample (more negative than positive). What is the right code sample for a home page?
katox Fri 21 Nov 2008
A compilable one ;) but I prefer a code sample to the current picture too. Or maybe use a stock photo. Let's move that to another topic.
jodastephen Sat 22 Nov 2008
I definitely vote for something that keeps the types, and since an array is really just a length restricted list, the List class seems most sensible.
BTW, what is the strategy for alternate implementations of List/Map in Fan? With Java, much power is derived from user produced implementations, such as a list that filters for you, or is backed by a remote data source and so on. Can users create their own List/Map implementations? Is that intended/desirable?
brian Sat 22 Nov 2008
To get started I will map to a normal mutable List. We can play with it and decide how we like that mapping. I'd prefer not to create a new mode of lists which are mutable but not resizable (although we could do that under the covers).
Java array types will be represented in fcode as:
Although you can't use primitives and array types directly in Fan as variables - we do need a formal representation of the types for the JVM to generate the correct call signatures.
Right now to keep things simple I've made List and Map final. This avoids the whole problem of user generics. My personal design tastes are to model application domain collections in their own right versus as collection customizations:
Things like that are duck typed replacements for Lists. But I know in the Java world that people love to create all sorts of various implementations and subclasses of Java collections - so I'd be open to discuss strategies.
alexlamsl Sun 23 Nov 2008
Even though the concurreny utilities in Java does not suit the Fan model well, the basic Java Collection Framework is what I missed most in Fan at the moment.
brian Sun 23 Nov 2008
OK - if others would like to discuss the Fan strategy for the collection framework, then let's create another topic.
brian Mon 24 Nov 2008
Does anyone have any compelling cases for supporting multi-dimensional arrays in phase 1 of the Java FFI?
They aren't used very heavily in the J2SE APIs - ResourceBundle, GridBagLayout, some of the java.awt.image classes.
jodastephen Mon 24 Nov 2008
I can't remember using multi-dimensional arrays, so they could probably be dropped in phase 1.