On Wednesday, January 26, 2000 1:52 PM, Fergus Henderson
[SMTP:[EMAIL PROTECTED]] wrote:
>
> I agree that it is too big a change for Haskell 98.
> But I think it would be too big a change for Haskell 2000 too.
> Making a change like that could cause previously working programs
> to fail, with no warning at compile time, and with the bug showing
> up only on certain inputs. The cost of that would far outweigh
> the benefit (which, in the light of the mixed opinions here, seems
> dubious anyway). Making non-backwards-compatible changes to the
> semantics of basic prelude functions like take and drop would be
> a really bad idea, IMHO.
>
Sometimes things are just wrong, and they have to be fixed, however painful
that is.
I would rather have a definition that makes sense, than one that has always
been wrong.
This case is not grossly wrong, but it is annoying. Taking and dropping
negative numbers of values
does not make sense.
What I would like, is to have a decision about the essential properties of
the functions being
defined, (i.e what laws are satisfied), and then a definition that
implements those properties.
There has always been a tendency to make minor changes to Haskell to
satisfy immediate concerns. Not that Haskell is unique in that respect, but
it should be a polished gem of a language, not wart-encrusted.
What worries me is that these little extensions have other consequences.
Look at replicate, for example.
-- replicate n x is a list of length n with x the value of every element
replicate :: Int -> a -> [a]
replicate n x = take n (repeat x)
So, what is the value of replicate -10 1 ?
By way of interest, let's look at the history of take in Haskell
Versions 1.1. and 1.2 have
take :: (Integral a) => a -> [b] -> [b]
take 0 _ = []
take _ [] = []
take (n+1) (x:xs) = take n xs
These definitions give us
take -1 [] === 0, take -1 (x:xs) === bottom
Not very consistent, is it?
The next version I can find a copy of is 1.4. This introduces the change
that
persists into H98
take :: Int -> [a] -> [a]
take 0 _ = []
take _ [] = []
take n (x:xs) | n > 0 = x : take (n-1) xs
take _ _ = error "Prelude.take: negative argument"
I suspect the intentions were a) to eliminate n+k patterns, and b) to force
the use of
Int for efficiency reasons.
Restricting the type to Int would undoubtedly have broken some programs,
but that did not
justify not doing it.
This version has the same behaviour wrt negative argument values.
At the very least we have an inconsistancy in the treatment of negative
arguments, which should be fixed.
--brian