#563 List and Map object hierarchy

jodastephen Fri 1 May 2009

So it seems that Fan has followed the Java arrays model for lists rather than the Java generics one. This has led to a discussion on validating list contents.

Obj[] objs := Obj[,]
objs.add("a").add(1)
Str[] strs := objs
str := strs[1]  // CastErr

This is fine, however it does effectively separate Fan from the everything is an object principle. Lists (and Maps) are a special kind of object with a different hierarchy. Variables of these types can be in an invalid state, although the List/Map instance itself never is.

This thread is to ask the question as to whether we are happy with that trade off. And to document the decision.

We need to bear in mind that Java has often been criticised for having arrays with special rules like these. Are we sure that we understand those criticisms and are not replicating them by accident?

(I also can't find anything quickly in the docs that describe this behaviour)

The first alternative is to validate the entire List/Map when casting and on all subsequent adds to the List/Map. This can be achieved by having the List/Map store additional type info:

List {
  Type originalDeclaredType
  Type[] subsequentCastTypes
  Obj[] data
}

When the cast occurs, the type of the cast would be added to the subsequentCastTypes list. Each add would check if the added item fits all the types in that list. Since most lists don't get cast, most add checks wouldn't be slowed down.

The second alternative is to accept the current behaviour. CastErr might occur at a later point in the code.

The third alternative is to allow optional checking of the contents. This is a clear enhancement on option 2, as it allows developers to choose to be more secure.

Are there any other options?

With my be safe hat on, I would typically prefer option 1. The overhead occurs at the cast site (as the whole list is checked) and on subsequent adds.

alexlamsl Fri 1 May 2009

I can be totally out of touch here - but I thought in Fan Obj is the marker for raw types in Java Generics, i.e. you do not need to explicitly cast for Obj, Obj[] or Obj:Obj

I didn't expect a Int[] could be casted to a Num[], if Int extends Num.

brian Fri 1 May 2009

This thread is to ask the question as to whether we are happy with that trade off. And to document the decision.

I am not sure what exactly it is we are affirming.

Fan doesn't have a user defined generics system. Java's added on in 1.5 and it added huge complexity, and as JohnDG pointed out still isn't really that flexible. You can take a look at Scala's type system to see what OO-plus-generics looks like if you really want to try it do it right with variance options (with their + and - annotations). Personally that is too complicated for my tastes, which is why Fan doesn't obsess over trying to have pure type correctness. We use types where they add value, but not at the expense of complexity.

Where we do use generics, each of the special 3 types uses its own rules for correctness which is designed to maximum flexibility. In regards to a parametrized list, I allow you to upcast based on the list's item type:

nums := Num[,]
Obj[] objs := num   // no cast needed
Int[] ints := nums  // auto-cast
Str[] strs := nums  // compiler error

Map works like List, but Func actually works differently than List/Map regarding type compatibility. See Func type compatibility. But the types are just a tool to use where it makes sense. In the end a lot of Fan code is dynamic and thrives on not having a strict type system. I don't think this debate is much difference than the nullable type debate - you have to balance type checking value versus simplicity.

One of the things we decided last year was to support auto-casting. That was a pretty huge decision regarding the evolution of Fan because it meant that most casts are not visible anymore. This means that casts cannot be expensive.

tompalmer Fri 1 May 2009

Map works like List, but Func actually works differently than List/Map regarding type compatibility.

Hmm. Having all three follow roughly similar rules would make things easier to grok. (I'm a minimalist. Not everyone is, though.)

Login or Signup to reply.