> The support for records in Haskell is if not pathetic is very poor.
Be specific. Support for record field access is fine. Support for record creation is fine. Support for pattern matching on records is fine. There are two "problems with records" in Haskell.
First, unlike many languages, records don't create implicit namespaces, so if you define Foo { x :: a } and Bar { x :: b } in the same module you have ambiguity. This is addressed, in part, by several recent GHC extensions. It could always be handled by putting Foo and Bar in different modules (with some added complexity if Foo and Bar are mutually recursive), but the community has settled on prefixing (Foo { fooX :: a }, Bar { barX :: a }) which is a little ugly but perfectly workable.
Second, while support for member update is okay when shallow, it compounds in a particularly nasty way when it gets deep. So what in Java would be "x.y.z.a = 7", in Haskell is something like "x { y = (y x) { z = (z (y x)) { a = 7 } } }" - horrific, I agree. But note that "x.y.z.a = 7" isn't great practice in Java, either! Why do I know about the fields of a field of a field of my object? Far better if that's packaged up in a setter. And if you define setters, the Haskell gets cleaner too. Lens is a principled way of defining getters and setters (and more) that can be composed and manipulated consistently - but it does have a huge vocabulary which obviously creates a barrier until you've learned it. But you don't need lens to write setters (and for that matter, you don't need to know all of lens to use some pieces of it).
I've also found that RecordWildCards makes records genuinely nice to work with in many cases - unpack the record into the local scope, at which point the prefixed names don't seem verbose, transform things as I want, and then re-collect the fields I can while explicitly setting those I need to.
Be specific. Support for record field access is fine. Support for record creation is fine. Support for pattern matching on records is fine. There are two "problems with records" in Haskell.
First, unlike many languages, records don't create implicit namespaces, so if you define Foo { x :: a } and Bar { x :: b } in the same module you have ambiguity. This is addressed, in part, by several recent GHC extensions. It could always be handled by putting Foo and Bar in different modules (with some added complexity if Foo and Bar are mutually recursive), but the community has settled on prefixing (Foo { fooX :: a }, Bar { barX :: a }) which is a little ugly but perfectly workable.
Second, while support for member update is okay when shallow, it compounds in a particularly nasty way when it gets deep. So what in Java would be "x.y.z.a = 7", in Haskell is something like "x { y = (y x) { z = (z (y x)) { a = 7 } } }" - horrific, I agree. But note that "x.y.z.a = 7" isn't great practice in Java, either! Why do I know about the fields of a field of a field of my object? Far better if that's packaged up in a setter. And if you define setters, the Haskell gets cleaner too. Lens is a principled way of defining getters and setters (and more) that can be composed and manipulated consistently - but it does have a huge vocabulary which obviously creates a barrier until you've learned it. But you don't need lens to write setters (and for that matter, you don't need to know all of lens to use some pieces of it).
I've also found that RecordWildCards makes records genuinely nice to work with in many cases - unpack the record into the local scope, at which point the prefixed names don't seem verbose, transform things as I want, and then re-collect the fields I can while explicitly setting those I need to.