openlang

Is an NFC key a sensible default for name lookup?

Okay, I paste my name and it ends in e followed by U+0301. Next week I type the same name and the keyboard gives me U+00E9. Same name to me. Canonically equivalent, too. Still two different strings.

My plan for the form is to keep whatever was submitted for display and derive an NFC key for lookup. I see my own spelling on screen, and lookup stops caring which of the two I used. The cost is two representations, plus being clear about which one each operation reads. (And no, a TypeScript string annotation won't tell you normalize("NFC") ever ran. It just names the type.)

Here's the part I'm less sure about. NFC doesn't decide whether two matching names can belong to different accounts. That's a product call. Compatibility normalization and case folding are their own choices, and none of this stops two names that merely look alike.

Is that a sensible default for display-name lookup, as long as identity gets decided somewhere else? I want the screen to keep a person's spelling without one derived key quietly deciding who they are.

The conversation continues 3

Follow the reasoning
  1. Permalink

    Agreed on the split. Lookup should accept only the normalized key, with the submitted text carried next to it.

    What does absence mean here, though? If the form lets someone leave the name out, null should mean they supplied none. It shouldn't double as normalization not having run yet. Two callers show the difference. The saved-name view wants the spelling as submitted. The search caller wants the derived key. If two accounts can end up with the same key, search returns several matches or asks for another identifier. A Kotlin String without the question mark promises a value is present. It says nothing about NFC, and nothing about whose name it is.

  2. Permalink

    Type the name. Submit. normalize("NFC") runs right there and both versions leave together. So no stored name ever sits in a not-normalized-yet state, and hollis's null keeps meaning exactly one thing.

    If lookup is async, the list of matches it eventually produces is its own result. It isn't a new meaning for the name. And once that list can hold more than one account, the search caller stops being an ownership check and turns into a picker. That's when an account id actually pays for itself.

  3. Permalink

    "e\u{301}" == "\u{E9}" is true in Swift, which I find kind of fun. String equality is canonical equivalence, and hashing follows it, so a [String: Account] already treats your two spellings as one key. Which sounds like it solves your problem, and partly does.

    But the stored string is still whichever one came in, and the moment that key goes to a database or another language it compares by code units again. I'd still derive the NFC key explicitly and store it next to the original.

Other sides of the same question

  1. NFC lookup keys and JCS signatures

    Signing complicates kim_dh's earlier question, which separates the submitted name from an NFC lookup key. A JSON payload hold…