Subject: [Jmap] Address Groups - proposals

From: Bron Gondwana <[email-masked]>
Date: Tue, 17 Jul 2018 06:12:49 +1000

There's been a bunch of discussion both here, in the meeting today, and
on Jabber.  I figured I'd give them all catchy names and write up how
they'd look for this theoretical header line:
To: "First Person" <[email-masked]>, Friends: "My Friend" <[email-masked]>, [email-masked]; [email-masked], "A Third person" <[email-masked]>, undisclosed-recipients:;
*Flat no groups:*
*lossy of group information
*

[
{ name: "First Person", email: "[email-masked]" },
{ name: "My Friend", email: "[email-masked]" },
{ name: null, email: "[email-masked]" },
{ name: null, email: "[email-masked]" },
{ name: "A Third person", email: "[email-masked]" },
]

*Flat group names:*
*lossy of empty groups and adjacent groups of same name
*

[
{ name: "First Person", email: "[email-masked]" },
{ name: "My Friend", email: "[email-masked]", group: "Friends" },
{ name: null, email: "[email-masked]", group: "Friends" },
{ name: null, email: "[email-masked]" },
{ name: "A Third person", email: "[email-masked]" },
]

*Flat group names null: (like SQL left join)
*
*lossy of adjacent groups of same name*

[
{ name: "First Person", email: "[email-masked]" },
{ name: "My Friend", email: "[email-masked]", group: "Friends" },
{ name: null, email: "[email-masked]", group: "Friends" },
{ name: null, email: "[email-masked]" },
{ name: "A Third person", email: "[email-masked]" },
{ name: null, email: null, group: "undisclosed-recipients" },
]

*Flat group names null numbered:*
*full fidelity, no data loss.
*

[
{ name: "First Person", email: "[email-masked]" index: 0},
{ name: "My Friend", email: "[email-masked]", group: "Friends",
index: 1 },{ name: null, email: "[email-masked]", group: "Friends",
index: 1 },{ name: null, email: "[email-masked]", index: 2 },
{ name: "A Third person", email: "[email-masked]", index: 2 },
{ name: null, email: null, group: "undisclosed-recipients", index: 3 },]

*Flat Implicit Group Markers: (null email for group markers)
*
*full fidelity, no data loss.*

*CURRENT SPEC
*

[
{ name: "First Person", email: "[email-masked]" },
{ name: "Friends", email: null },
{ name: "My Friend", email: "[email-masked]" },
{ name: null, email: "[email-masked]" },
{ name: null, email: null },
{ name: null, email: "[email-masked]" },
{ name: "A Third person", email: "[email-masked]" },
{ name: "undisclosed-recipients", email: null },
{ name: null, email: null },
]

*Flat Explicit Group Markers: (like XML SAX)
*
*full fidelity, no data loss.*

[
{ name: "First Person", email: "[email-masked]" },
{ name: "Friends", group: "start" },
{ name: "My Friend", email: "[email-masked]" },
{ name: null, email: "[email-masked]" },
{ name: "Friends", group: "end" },
{ name: null, email: "[email-masked]" },
{ name: "A Third person", email: "[email-masked]" },
{ name: "undisclosed-recipients", group: "start" },
{ name: "undisclosed-recipients", group: "end" },
]

(optional variant: null for name on end markers)

*Nested Mixed:
*
*full fidelity, no data loss.*

[
{ name: "First Person", email: "[email-masked]" },
{ group: "Friends", addresses: [
  { name: "My Friend", email: "[email-masked]" },
  { name: null, email: "[email-masked]" },
] },
{ name: null, email: "[email-masked]" },
{ name: "A Third person", email: "[email-masked]" },
{ group: "undisclosed-recipients", addresses: [] },
]

*Nested Full:
*
*full fidelity, no data loss.*

{ group: null, addresses: [
  { name: "First Person", email: "[email-masked]" },
] },
{ group: "Friends", addresses: [
  { name: "My Friend", email: "[email-masked]" },
  { name: null, email: "[email-masked]" },
] },
{ group: null, addresses: [
  [ { name: null, email: "[email-masked]" }],
  [ { name: "A Third person", email: "[email-masked]" }],
] },
{ group: "undisclosed-recipients", addresses: [] },

*asGroupAddresses:*

Two ways to get data - asAddresses is "Flat no groups", asGroupAddresses
is "Nested Full".
============

I think that's every proposal that's out there.  There's obviously pros
and cons to all of them.  We need to pick one.
Ok - FIGHT!

Bron.

--
  Bron Gondwana, CEO, FastMail Pty Ltd
  [email-masked]

---

From: Ricardo Signes <[email-masked]>
Date: Mon, 16 Jul 2018 16:37:08 -0400

* Bron Gondwana <[email-masked]> [2018-07-16T16:12:49]
> they'd look for this theoretical header line:

Thanks for this!

My thinking here is:

1.  I love that JMAP makes working with email so approachable for non-domain
    experts.  It's an easy to understand API, and you can get to work by using
    it in a beginner's way before progressing, if ever, to more complex modes
    of operation.  I want to build on this property of JMAP when possible.

2.  I love that even for advanced operation, it is almost never necessary to
    resort to fetching the message/rfc822 blob.  Most data is available in raw
    or differently-processed forms.  Even experts shouldn't have to resort to
    blob processing most of the time.

Mailbox groups are worth making available because of reason #2.  Experts
shouldn't have to get the raw header, encoded-warts and all, and work out the
header structure.

On the other hand, mailbox groups are rarely seen and even more rarely worth
noting.  The casual user can, I assert, pay them no mind.  Groups should not
complicate the life of the casual user.

Providing a flat list is nice for the casual user, but if the flat list
contains weird-o non-address sentinel values, *it's no longer a flat list*.
It's a deeper structure that has been serialized into a flat list.  I think
it's worse for both sets of users: it's an unnatural expression of the
structured data that an advanced user might want, and it's an unnatural
expression of the simple data that a beginner might want.

(I also think that in the simple case, any entry with a null email is not
great.)

This is why I think we're best off providing two distinct forms:  one to
provide the simplest form for 99.9% of input and for casual users, and one with
an appropriate data structure for those who care about group structure.

I would suggest that :asAddresses does what Bron called "flat no groups", and
that :asGroupedAddresses does "nested full".

I think that trying to be understandable is a good goal, but using a
pre-existing IMAP convention that will be understandable to already-minted
experts in IMAP is far less compelling to me than to simply be understandable
by using a self-explanatory data structure.

-- 
rjbs