Let me make one more attempt to persuade the committee to change the way
strictness annotations are to be introduced.

First of all, let's recognise that strictness annotations and the seq
function are of enormous importance; this is a vital extension to the
language, not a small detail. Space debugging consists to quite a large
extent of placing applications of seq correctly, and we all know what
dramatic effects space debugging has been able to achieve. The strictness
features are going to be very heavily used in the future.

Recording uses of polymorphic strictness annotations using class Data has
both advantages and disadvantages. A big disadvantage is that curing a space
bug may change the types of many functions in many modules, which at the
least may require a lot of recompilation. The programmer who likes to state
the type of each function will be especially hard hit, of course, which will
unfortunately discourage such a style. But class Data seems to be vital for
cheap deforestation, which is such an important optimisation as to outweigh
the disadvantages.

However, it is an independent question whether or not strictness annotations
should be applicable to function types. And this is where I disagree with
the committee. To quote `Introducing Haskell 1.3',

        Every data type, except ->, is a member of the Data class.

In other words, in Haskell 1.3

        FUNCTIONS ARE NOT FIRST-CLASS CITIZENS

To design a functional language today, in which this is true, is in my view
deeply mistaken. In the past, I've argued that it will be very frustrating
for those programmers who do discover they need to apply seq to a function
in order to cure a space bug, to find that they are unable to do so. Even
more seriously, programmers weighing up a choice of representation for an
abstract datatype, choosing between a representation as a function or as a
`Data' type, will know that if they choose the function then problems with
space debugging may lurk in the future. Excluding (->) from class Data is a
step away from true `functional' programming towards a style in which
higher-order functions are just a kind of macro.

I see a very great cost in such a philosophical change, and I do not see
that the arguments against strictly evaluating function values are so very
compelling. 

  Implementation difficulties? hbc has provided it for years, and
  even under the STG machine is the problem so very much harder than handling
  shared partial applications correctly? 

  Semantic difficulties? The semantics of lifted function spaces are 
  perfectly well defined. OK, so it's not the exponential of a CCC --- but 
  Haskell's tuples aren't the product either, and I note the proposal to 
  change that has fallen by the wayside. 

  Weaker strictness analysis? I'd like to hear the effect quantified. How
  much slower will Haskell 1.3 run if function spaces are lifted in the
  semantics? Will it be measurable? I'm prepared to pay a few percent.

So here's my proposal: change `Introducing Haskell 1.3' to read

        Every data type, including ->, is a member of the Data class.

John Hughes


Reply via email to