I am exploring the type system of Julia seriously for the first time and I got stuck with a practical problem I have in one of my packages. Suppose I have various grid types following an interface:

```
@doc doc"""
A data point in an `N`-dimensional space represented by
`N` scalars (a.k.a. coordinates) of type `T`, holding a
value of type `V`.
""" ->
abstract AbstractDataPoint{N,T,V}
@doc doc"""
An iterable collection of points of type `P`.
""" ->
abstract AbstractPointCollection{P}
@doc doc"""
A grid of points of type `P`.
""" ->
abstract AbstractGrid{P}
@doc doc"""
Valid representations of a spatial domain.
""" ->
AbstractDomain = Union{AbstractPointCollection,AbstractGrid}
@doc doc"""
A path in a spatial domain of type `D`.
""" ->
abstract AbstractPath{D}
```

In this interface, I have various representations of a spatial domain `AbstractDomain`

, either grids types or point collections. I would like to traverse such domains with different types of paths. For achieving this goal I tried to introduce the `AbstractPath`

type.

Now consider one possible implementation of the interface:

```
immutable DataPoint{N} <: AbstractDataPoint{N,Real,Real}
coords::NTuple{N,Real}
value::Real
end
coords(p::DataPoint) = p.coords
value(p::DataPoint) = p.value
type PointCollection{N} <: AbstractPointCollection{DataPoint{N}}
points::AbstractVector{DataPoint{N}}
end
npoints(pc::PointCollection) = length(pc.points)
type ImageGrid{N} <: AbstractGrid{DataPoint{N}}
data::AbstractArray{Real,N}
dx::Real
dy::Real
dz::Real
ImageGrid(data) = ImageGrid(data,1.,1.,1.)
end
npoints(g::ImageGrid) = prod(size(g.data))
```

Finally, the question. Suppose there is a natural order for traversing spatial domains. For example, an image grid is naturally traversed in column-major order, a point collection is traversed in forward order, etc. I would like to define a `DefaultPath`

for all `AbstractDomain`

:

```
type DefaultPath{AbstractDomain} <: AbstractPath{AbstractDomain}
# TODO
end
```

How would you approach this problem? Should I define a `start`

, `next`

and `done`

for all new types, make them part of the interface specification and then call these methods inside of the `DefaultPath`

? How to do that in a Julian way?

Besides the question, please feel free to give feedback on the interface, if there is anything that can be done better in terms of performance, etc.