# About type sharing (mostly) and records (desugaring, mostly)

**URL:** https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016
**Category:** Learn
**Created:** [July 16, 2023, 1:35pm UTC](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016 "2023-07-16T13:35:25Z")
**Posts on this page:** 9
**Page:** 2

<div class="post-metadata">

### Author: ![AntC2](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/antc2/32/1872_2.png) [@AntC2](https://discourse.haskell.org/u/AntC2)
#### Post date: [July 19, 2023, 10:51am UTC](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016/22 "2023-07-19T10:51:20Z")

</div>

> [@atravers](#):
>
> Haskell 2010 Report about what the intended meaning …

That bit’s unchanged since the '98 Report. Although there might be still around some people spatio-temporally contiguous with its authors, I very much doubt they’ll remember the intent at the time. We’d better try to interpret the words as given:

> A constructor with associated field labels may still be used as an ordinary constructor; features using labels are simply a shorthand for operations using an underlying positional constructor.

So in `purescript`, that bit up to the semicolon does not hold: if your constructor is declared with field labels, you can only build values or access components using field labels; there’s no (visible) ‘underlying positional’ anything.

In SML, [per my description in that earlier thread](http://discourse.haskell.org/t/haskell-records-compare-standard-ml/5933) records are “not tied to any data type/not needing a data constructor prefix”. No ‘ordinary constructor’/no constructor at all. So again, you can only build or access record types using labels. There is a positional structure under the hood in the implementation; it’s abstracted away/you can’t access it directly from program code.

`Hugs.Trex` is very similar to SML: there’s no constructor [\*\*] – that’s what it means by ‘anonymous’. (See my example decls above.) Some label `fieldC` might or might not appear in any particular record type. Even knowing that under the hood records are normalised to alphabetic sequence of field labels doesn’t help without knowing what other labels appear.

[\*\*] Or you could argue there’s the same constructor `Rec( )` for all record types. Then you’ll have to say it allows a variadic number of fields, with any combination of field names. So it ai’n’t a H98 constructor.

IOW without an actual proposal for records in front of us, we can’t presume in terms of “just another notational addtitive”. Just like (say) MultiParam Type Classes or FunDeps/Type Families or Scoped Type Variables can’t be ‘translated’ as just another notation for H2010: they express something beyond the semantics of H2010.

> [@](#):
>
> meaning … _should_ be…

The H2010 report doesn’t help with what the meaning of (say) duplicate field labels ‘should be’. It merely says they’re not allowed in H2010 “A label cannot be shared by more than one type in scope.” The report isn’t trying to guess the future of Haskell. Heck it didn’t even describe _de facto_ Haskell as supported by the two main compilers at the time it was published.

---

<div class="post-metadata">

### Author: ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)
#### Post date: [July 19, 2023, 2:18pm UTC](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016/23 "2023-07-19T14:18:45Z")

</div>

> [@](#):
>
> A constructor with associated field labels may still be used as an ordinary constructor; features using labels are simply a shorthand for operations using an underlying positional constructor.

…hence the term _“record syntax”_. Your long list of _record systems_ and their collective unsuitability for use with that syntax only excludes those systems - it isn’t a proof that a record system **will never** support Haskell 2010/1998 record syntax in a backwards-compatible way.

What that long list does show is just how stubbornly difficult it was (and still is) to find a solution to _“the records problem”_ that’s:

- suitable for Haskell, now and into the future,

- and most people can at least tolerate, including people with prior experience with one or more of those systems from your long list.

> [@](#):
>
> (page 10 of 55)
> 
> In the end, the committee wholeheartedly embraced _superficial_  
> complexity; for example, the syntax supports many ways of expressing the same thing, in contradiction to our original inclinations (Section 4.4). In other places, we eschewed _deep_ complexity, despite the cost in expressiveness — for example, we avoided parametrised modules (Section 8.2) and extensible records (Section 5.6).
> 
> [A History of Haskell: Being Lazy With Class](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.168.4008&rep=rep1&type=pdf) (2007).

- [A proposal for records in Haskell](https://web.archive.org/web/20120418060012/http://research.microsoft.com/en-us/um/people/simonpj/Haskell/records.html) (2003).

---

<div class="post-metadata">

### Author: ![AntC2](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/antc2/32/1872_2.png) [@AntC2](https://discourse.haskell.org/u/AntC2)
#### Post date: [July 23, 2023, 7:58am UTC](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016/24 "2023-07-23T07:58:54Z")

</div>

I’m a lot puzzled by this response:

> [@atravers](#):
>
> long list of _record systems_

I mentioned three programming languages, of which two are very firmly in the Haskell stable. [Here’s an example long list](https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(algebraic_data_type)). (A reasonable sample, but by no means comprehensive. Note Pascal had records from the get-go 1970.) BTW I think records for non-functional languages are entirely suitable to compare. We don’t want mutable data structures; but we surely do want the ability to return a new data structure mostly copied from a previous ‘version’.

> [@](#):
>
> collective unsuitability for use with that syntax

`purescript`’s `data` syntax for declaring record structures is exactly the same syntax as Haskell’s. What it allows is same-named fields appearing in different datatypes – so it’s the _semantics_ that’s different.

SML’s syntax if you’re going to put the record inside a `data` type with a constructor prefixing then is exactly the same syntax as Haskell’s. Again there’s no restriction on same-named fields. You can also use records stand-alone, again possibly with fields same-named as those inside a `data`.

Hugs.Trex was forced to use different syntax so that its records could co-exist with H98 `data` in the same module. I find that a dubious motivation – since Trex field names are in a different namespace vs H98. I think it could be arranged to choose module-wide H98 vs Trex semantics over the same syntax; including export/import of the different datatypes. (But you’d need namespace control to access Trex records from H98 semantics or _v.v._ – I have something of a prototype achieving that.)

> [@](#):
>
> most people can at least tolerate

As at early 2000’s a lot of people were voiciferous they could barely tolerate H98 records. A fair few of them were coming from SML. I see some have returned to SML. Anyhoo, many have abandoned Haskell.

> [@History of Haskell](#):
>
> the syntax supports many ways of expressing the same thing, … we avoided … extensible records (Section 5.6)

That’s talking about design decisions up to the H98 standard.

> [@Section 5.6](#):
>
> This minimal design has left the field open for more sophisticated proposals, of which the best documented is TRex …

I agree that as at H98 it would have been unwise to commit to a relatively unexplored design. 25 years have passed and … the field for design is still open. But nobody developed any robust designs, meanwhile a (by now) insurmountable fatberg of legacy code uses the allegedly ‘stopgap’ approach.

I find the emphasis on _syntax_ curiously conservative for Haskell: most Haskell extensions deliberately also exploit additional syntax. Sometimes the old syntax can be treated as a special case of the new (MultiParam Type Classes take in H98 classes as a special case).

> [@Language report requoted](#):
>
> features using labels are simply a shorthand for operations using an underlying positional constructor.

Yep all records proposals amount to that. The question is whether to expose the underlying positional access. And the clamour for labelled fields was precisely because that’s **bad practice** as soon as you have more than a couple of fields.

---

<div class="post-metadata">

### Author: ![bradrn](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/bradrn/32/264_2.png) [@bradrn](https://discourse.haskell.org/u/bradrn)
#### Post date: [July 23, 2023, 8:40am UTC](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016/25 "2023-07-23T08:40:01Z")

</div>

> [@AntC2](#):
>
> `purescript`’s `data` syntax for declaring record structures is exactly the same syntax as Haskell’s. What it allows is same-named fields appearing in different datatypes – so it’s the _semantics_ that’s different.

As a pedantic note, it actually isn’t the same syntax, because in PureScript you can do something like this ([source](https://github.com/purescript/documentation/blob/master/language/Records.md)):

```purescript
author :: { name :: String, interests :: Array String }
author =
    { name: "Phil"
    , interests: ["Functional Programming", "JavaScript"]
    }

```

A PureScript declaration like `data Person = Person { name :: String, interests :: Array String }` may superficially look like Haskell, but it’s parsed differently — really it’s the equivalent of Haskell `data Person = Person (String, [String])`. Consult the [differences from Haskell](https://github.com/purescript/documentation/blob/master/language/Differences-from-Haskell.md#records) document for more information.

---

<div class="post-metadata">

### Author: ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)
#### Post date: [July 23, 2023, 8:44am UTC](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016/26 "2023-07-23T08:44:34Z")

</div>

Alright, let’s look at how well your _“insufferable-groaning”_ technique is working…

* * *

**_Other_ posts and threads by you about Haskell’s record syntax** :

- `http://discourse.haskell.org/t/well-typed-blog-anonymous-or-large-records-with-overloadedrecorddot-and-overloadedrecordupdate/5939/2`

- `http://discourse.haskell.org/t/haskell-records-compare-standard-ml/5933` (36 posts)

- `http://discourse.haskell.org/t/using-haskell-for-commercial-data-intensive-applications-name-clashes/4595` (4 posts)

- `http://discourse.haskell.org/t/the-evolution-of-ghc/4008/13`

**Progress towards solution in Haskell you would find satisfactory** :

```
(...none!)

```

* * *

You _really should_ consider finding another technique: your current choice just doesn’t seem to be having the desired result…

---

<div class="post-metadata">

### Author: ![AntC2](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/antc2/32/1872_2.png) [@AntC2](https://discourse.haskell.org/u/AntC2)
#### Post date: [July 23, 2023, 8:55am UTC](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016/27 "2023-07-23T08:55:47Z")

</div>

> [@atravers](#):
>
> You _really should_ consider finding another technique:

[Like implementing more sophisticated behaviour](https://mail.haskell.org/pipermail/hugs-users/2020-May/thread.html)?

Or [combining records with Overlaps/FunDeps, to build projection and extension methods](https://mail.haskell.org/pipermail/hugs-users/2022-September/000939.html)?

So I don’t just groan. I also document possible designs – as you yourself linked to earlier in the thread.

---

<div class="post-metadata">

### Author: ![AntC2](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/antc2/32/1872_2.png) [@AntC2](https://discourse.haskell.org/u/AntC2)
#### Post date: [July 23, 2023, 9:02am UTC](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016/28 "2023-07-23T09:02:27Z")

</div>

> [@bradrn](#):
>
> As a pedantic note,

Hey thanks! I didn’t know that (so the syntax is more like SML’s). I looked at purescript a while back and saw only the more Haskell-like `data` decl. (Is that anonymous version a recent-ish change?) Yes I knew of the different parsing – I was focusing on the superficially similar syntax giving a different semantics.

Also I thought `purescript`’s records were a thin veneer over Javascript. Is that still the case?

---

<div class="post-metadata">

### Author: ![bradrn](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/bradrn/32/264_2.png) [@bradrn](https://discourse.haskell.org/u/bradrn)
#### Post date: [July 23, 2023, 9:14am UTC](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016/30 "2023-07-23T09:14:23Z")

</div>

> [@AntC2](#):
>
> (Is that anonymous version a recent-ish change?) […] Also I thought `purescript`’s records were a thin veneer over Javascript. Is that still the case?

I don’t use PureScript, but I believe it’s always been like this. Insofar as I’m aware, this is precisely because they are just JavaScript records.

---

<div class="post-metadata">

### Author: ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)
#### Post date: [July 23, 2023, 9:24am UTC](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016/31 "2023-07-23T09:24:23Z")

</div>

> I also document possible designs […]

So here’s an idea for another one: since GHC will soon have a JS backend, maybe you can devise a way to bring JS’s record system into Haskell. But as you noted earlier in the thread, designs without working code don’t usually amount to anything (much like insufferable groaning).

[Previous page](https://discourse.haskell.org/t/about-type-sharing-mostly-and-records-desugaring-mostly/7016.md?page=1)
