It always seems that I have cases where I need to return an empty list. To prevent allocating a bunch of empty lists, I typically write my Java code like this:
public class Widget
{
public Widget[] children()
{
if (kids == null) return none;
return (Widget[])kids.toArray(new Widget[kids.size()]);
}
private static final Widget[] none = new Widget[0];
private ArrayList kids;
}
Fan makes this a bit difficult because I can't declare a Widget[] static field since Widget isn't const.
The more important thing is it seems we can easily move this pattern into the library. My proposal is a new method on Type which would always return the empty immutable list for the type:
Obj[] Type.emptyList()
Now I can rewrite my Java code above in Fan as:
class Widget
{
public Widget[] children()
{
if (kids == null) return Widget.type.emptyList
return kids.ro
}
private Widget[] kids
}
Comments?
cbeustWed 16 Jul 2008
Fan makes this a bit difficult because I can't declare a Widget[] static field since Widget isn't const.
Really? How come const and static are so tightly linked? Can't I declare a static field that is not const?
At any rate, I think it should be possible for Fan to declare such convenient constants (similar to Java's Collections.EMPTY_LIST and Collections.EMPTY_MAP) without having to resort to a method.
-- Cedric
brianWed 16 Jul 2008
Well the two things are kind of orthogonal. Even if I could declare a const static empty list, that doesn't mean I wouldn't want one global empty list easily accessible from something like Type.emptyList.
How come const and static are so tightly linked?
All static fields must be const. That guarantees thread safety because static fields are like global variables which are visible between all threads. A core principle of Fan is that you can't share mutable state between threads.
In this case there isn't anything to say I don't let you define a Widget[] as a const static field. The compiler would implicitly call toImmutable, which would in turn fail at runtime for anything but an empty list. But right now the compiler flags an error if a const field isn't itself a const type.
cbeustWed 16 Jul 2008
All static fields must be const. That guarantees thread safety
Really? Can't you still share mutable state when different threads access data on the same instance?
brianWed 16 Jul 2008
Yeap really. This is what sets Fan apart from Java and C#, which have a shared memory space (Scala has actors, but doesn't actually enforce no shared memory).
Static fields are immutable, can't share state that way. Thread is const, so you can't store any mutable state in a Thread's fields. So the only way to pass objects between threads is via message passing, which requires immutable or serializable objects.
JohnDGWed 16 Jul 2008
I don't really like sticking this into every type. Seems wrong to stick collection-oriented methods or objects into Type. Why not just stick it into the type for Array, as a method that accepts the element type and returns an immutable list containing zero elements of that type?
brianWed 16 Jul 2008
Actually I like that more, so let's say a new static method on List:
Obj[] makeEmpty(Type t)
Don't love the name. Any better ideas?
tompalmerWed 16 Jul 2008
I agree with putting it on List.
By the way, I also like only-const-statics from the singletons-are-evil perspective. Or rather Fan automatically encourages injection over singletons. And that makes for a more easily flexible code base.
JohnDGWed 16 Jul 2008
Don't love the name. Any better ideas?
Java uses emptyList, which I like because it's declarative and more amenable to DSLish code than an imperative name like makeEmpty.
jodastephenWed 16 Jul 2008
I would probably stick with the original suggestion of placing it on Type. The method name emptyList() works well there, and it is an acceptable location given that lists are a language feature.
tompalmerThu 17 Jul 2008
On the subject of mutable data between threads, how do you implement things like connection pools in Fan? Do you pass around the (presumably mutable) connections as messages such that only one thread owns one at a time?
brianThu 17 Jul 2008
On the subject of mutable data between threads, how do you implement things like connection pools in Fan?
It kind of depends on what the "connection" is. But you'd either use immutable objects, or else messaging passing. The Namespace concept is another technique (although not fully baked yet).
Writing multi-threaded code in Fan is very, very different than using locks in Java. It requires new design patterns, but it is immensely liberating not having to think about synchronization. The languages guarantees that your mutable objects only ever live in one thread.
brian Wed 16 Jul 2008
It always seems that I have cases where I need to return an empty list. To prevent allocating a bunch of empty lists, I typically write my Java code like this:
Fan makes this a bit difficult because I can't declare a Widget[] static field since Widget isn't const.
The more important thing is it seems we can easily move this pattern into the library. My proposal is a new method on Type which would always return the empty immutable list for the type:
Now I can rewrite my Java code above in Fan as:
Comments?
cbeust Wed 16 Jul 2008
Really? How come const and static are so tightly linked? Can't I declare a static field that is not const?
At any rate, I think it should be possible for Fan to declare such convenient constants (similar to Java's Collections.EMPTY_LIST and Collections.EMPTY_MAP) without having to resort to a method.
-- Cedric
brian Wed 16 Jul 2008
Well the two things are kind of orthogonal. Even if I could declare a const static empty list, that doesn't mean I wouldn't want one global empty list easily accessible from something like
Type.emptyList
.All static fields must be const. That guarantees thread safety because static fields are like global variables which are visible between all threads. A core principle of Fan is that you can't share mutable state between threads.
In this case there isn't anything to say I don't let you define a Widget[] as a const static field. The compiler would implicitly call toImmutable, which would in turn fail at runtime for anything but an empty list. But right now the compiler flags an error if a const field isn't itself a const type.
cbeust Wed 16 Jul 2008
Really? Can't you still share mutable state when different threads access data on the same instance?
brian Wed 16 Jul 2008
Yeap really. This is what sets Fan apart from Java and C#, which have a shared memory space (Scala has actors, but doesn't actually enforce no shared memory).
Static fields are immutable, can't share state that way. Thread is const, so you can't store any mutable state in a Thread's fields. So the only way to pass objects between threads is via message passing, which requires immutable or serializable objects.
JohnDG Wed 16 Jul 2008
I don't really like sticking this into every type. Seems wrong to stick collection-oriented methods or objects into Type. Why not just stick it into the type for Array, as a method that accepts the element type and returns an immutable list containing zero elements of that type?
brian Wed 16 Jul 2008
Actually I like that more, so let's say a new static method on List:
Don't love the name. Any better ideas?
tompalmer Wed 16 Jul 2008
I agree with putting it on
List
.By the way, I also like only-const-statics from the singletons-are-evil perspective. Or rather Fan automatically encourages injection over singletons. And that makes for a more easily flexible code base.
JohnDG Wed 16 Jul 2008
Java uses
emptyList
, which I like because it's declarative and more amenable to DSLish code than an imperative name likemakeEmpty
.jodastephen Wed 16 Jul 2008
I would probably stick with the original suggestion of placing it on Type. The method name
emptyList()
works well there, and it is an acceptable location given that lists are a language feature.tompalmer Thu 17 Jul 2008
On the subject of mutable data between threads, how do you implement things like connection pools in Fan? Do you pass around the (presumably mutable) connections as messages such that only one thread owns one at a time?
brian Thu 17 Jul 2008
It kind of depends on what the "connection" is. But you'd either use immutable objects, or else messaging passing. The Namespace concept is another technique (although not fully baked yet).
Writing multi-threaded code in Fan is very, very different than using locks in Java. It requires new design patterns, but it is immensely liberating not having to think about synchronization. The languages guarantees that your mutable objects only ever live in one thread.