On Tue, Nov 22, 2005 at 02:32:47PM +0000, Rob Ennals wrote: > Since discussion has returned to records, it might be useful for me to > post a link to a proposal that I knocked up a while back when this > topic came up a few years ago: > > http://www.cambridge.intel-research.net/~rennals/records.pdf
Looks pretty nice. > To go through Dave's issues: > > 1. Field namespaces: solved by using type classes But these classes are required to be manually specified, right? This avoids the problem of proliferation of typeclasses if one had one class per field, but does mean that coordination is necesary in order to avoid namespace clashes. As far as I can tell, this means that we'd have issues with data StupidDouble = StupidDouble { value :: Double } data StupidInt = StupidInt { value :: Int } unless we use multiparameter typeclasses or something. This is a stupid example (thus the type names), but I think there are real cases where you'd like to create constructors like this. > 2. Multi-constructor getters: solved by desugaring to functions > 3. "Safe" getters for multi-constructor data types: ditto I think either you misunderstood my meaning by "safe", or I misunderstood your paper. I meant that if I write data FooBar = Foo { foo :: String } | Bar { bar :: String } there shouldn't be accessors of type foo :: FooBar -> String bar :: FooBar -> String which die when given bad input (e.g. calling (foo $ Bar "bar")). I'd rather in this case either not have these functions generated (and require that I use pattern matching) or have them have type foo :: FooBar -> Maybe String bar :: FooBar -> Maybe String I just don't like bottom. Perhaps it wouldn't be so bad if we got decent error messages, but when you call (foo $ Bar "bar") you get no hint as to where the bug actually is. > 7. Unordered records: yep (if I understand the problem correctly) I don't think you understood correctly. What I'd like (and this is another one of those David-specific issues--I've never heard anyone else complain about this) is to be able to create a data type that has no order. If I write data FooBar = FooBar { foo, bar :: String } I can construct this (either with Haskell 98 or with your proposal, as I understand it) with either fb = FooBar { foo = "a", bar = "b" } or with fb = FooBar "a" "b" I'd prefer to at least optionally be able to make the second syntax fail to compile--which is what I mean by an unordered record. The same goes for pattern matching. This feature is orthogonal to almost all the other record issues, and really a compiler warning would probably be enough to satisfy me, although I'd prefer to have this in the language. The point (in case I've been unclear again) is that I'd like to be able to later change the definition to data FooBar = FooBar { foo, bar :: String } without the possibility of breaking the code. This is a silly example, and noone would actually make this change, simply because it would be too hard to go through the code and verify that all the patterns have been swapped (and didn't get swapped twice). It's something that one could implement with code policy, but on the other hand, you could in principle say the same thing about static typing. -- David Roundy http://www.darcs.net _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell