David Barton writes:

    I submit (for everyone's consideration) that arrays should not be
    distinct from functions; indeed, that an array is an alternative
    mechanism for defining a function.  "Indexing" an array is an artifact
    of the Fortran mechanism of viewing an array.  An array should be
    evaluated just as a function is evaluated.

and then goes on: 

    I am not sure how the parametric type class ideas tie into all this
    (if they do at all).  

Well, parametric type classes can give you a type-systematic basis for doing
this. Using some of the notation of our Lisp and FP '92 paper, you could define:

   class f :: Function a b where        -- the class of functions
     ($) :: f -> a -> b                 -- 'apply' is expressed as infix '$'.

   inst a -> b :: Function a b where    -- '->' is the classical instance type
     f $ x = f x

   class (f :: Function a b, a :: Ix) => f :: FiniteFunction a b where
     dom: f -> (a, a)                   
                                        -- the class of finite functions
                                        -- (with rectangular domains),
                                        -- defined as a subclass of Function

   inst Array a b :: FiniteFunction a b where
     arr $ x = arr ! x                  -- an instance of a finite function
     dom arr = bounds arr

You might object that all we did was exchange one awkward symbol for indexing
(!) by another ($). To be able to use juxtaposition for array indexing, we need
to get a "handle" on juxtaposition. One way to do that would be by decreeing:

   f x      is syntactic sugar for f$x .

In that case we need to adapt the instance declaration of arrow:

   inst a -> b :: Function a b where
     f $ x = primApply f x

And we are done. 

However, I am not sure we want to do that, since principal types become very
unwieldy. For instance, if composition were defined as usual

   (f . g) x = f (g x) ,

its principal type would be

    (ft :: Function b c, gt :: Function a b) => ft -> gt -> a -> c.

[Aside: This is another example where multiple argument type classes lead to
ambiguities, but parametric type classes don't.]

The principal type is what it should be, since each of f and g can be an array
instead of a function (or it can be some other instance of class Function).  You
see, the cost of generality is increased complexity of many principal type
expressions. I am not sure whether this cost is worth the gains (it might be).
On the other hand, having an explicit overloaded infix operator for application
does not seem to complicate anything.
 
-- Martin Odersky


Reply via email to