[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

More on dictionaries



To: Mark.Jones@prg.oxford.ac.uk
Cc: haskell@cs.glasgow.ac.uk
Subject: More on dictionaries
Date: Fri, 01 Mar 91 12:12:05 +0000
From: Simon L Peyton Jones <simonpj@cs.glasgow.ac.uk>
Sender: haskell-request@cs.glasgow.ac.uk


Replies to Mark's replies.

Simon

 
| Firstly, Simon points out that the Glasgow compiler translates my example:
| 
| |     example x []     = False
| |     example x (p:ps) = p==(x,'c') || example x ps
| 
| to give:
| 
| |     example d = example'
| |                  where
| |                  example' x [] = False
| |                  example' x (p:ps) = (==) d1 p (x,'c') || example' x ps
| |                  d1 = dictEqPair d dictEqChar
| 

(Note from Simon: I've swapped the dashes over in this code, to make
the following less confusing.)

| which certainly doesn't cause the problem of repeated construction of the
| dictionary d1 that I described.  My original translation was based on the
| approach taken in the type classes paper,
| rather than the more sophisticated
| translation scheme described in "A static semantics of Haskell".
| 
| However, I do not think that sophisticated 
| translation schemes can completely
| eliminate repeated construction of dictionaries, even using the program
| transformations that Simon describes.  
| As an example, consider the expression:
| 
|                        map (example x) zs
| 
| Surely (please correct me if I'm wrong) this will still entail the repeated
| construction of d1 for each element in the list zs?


Absolutely not!  The expression translates to

	map (example actual_d x) zs

for some suitable dictionary actual_d.  The expression in the
brackets is shared lazily between all applications to each elt of
zs.  It is a redex, because (example actual_d) reduces to

	example' where example' = ....
		       d1 = ...

Hence the d1 is shared between all applications of the function being 
mapped.

Here's a simpler example of the same thing:

	map (f 3 4) zs
	where
	f x = g where g y = d1+y
		      d1 = x*2

x is only squared once!



| Finally, at the risk of changing the direction of this discussion, I am
| rather puzzled by the idea that it would be easier to apply strictness
| analysis to:
| 
| |   map f xs = map' xs where map' [] = []
| |                            map' (x:xs) = f x : map' xs
| 
| rather than the original definition of map.  Whilst I can see that the
| definition of map' takes only a first-order argument, surely we still
| need to account for the abstract value of f in finding the abstract
| value of map' ... which seems to lead us straight back to the problem
| we started with.  Could somebody enlighten me please?


Certainly.  But you don't need to find the *fixpoint* of a function with
functional arguments, which is the expensive part.