You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Title vs suffix is purely positional — a word matching TITLES at the front becomes title; the same word matching the suffix sets at the end becomes suffix (never both, regardless of the word's real-world meaning).
That is not quite what the code does, and the gap is the point. Leading position runs a structural inference — any multi-letter word ending in a period is a title — and that inference outranks vocabulary:
parse("Esq. Smith") # title='Esq.' — 'esq' is SUFFIX-only vocabularyparse("Esq Smith") # given='Esq' — no period, no inference
Trailing position has no counterpart. So the real asymmetry is: an abbreviation is interpreted in pre-nominal position and not in post-nominal position, and where it is interpreted it overrides the vocabulary that disagrees.
Why the doctrine exists, and why it can't simply be inverted
TITLES carries 692 words that are in no suffix set, and many are ordinary English surnames:
A blanket "vocabulary outranks position" rule would be severe:
parse("Mary Jane King") # would become title='King', family='Jane'parse("Robert Prince") # would become title='Prince', no family at all
In leading position a title shadows the given name, which the docs already warn about. In trailing position it would shadow the family name — strictly worse, since that is the field callers most depend on.
Proposal
Two parts, because the hazard above is entirely about bare words.
(a) Period-marked words: vocabulary decides the field, position does not. A trailing period marks an abbreviation, and the only name parts that get abbreviated are the ones standing outside the name — titles and post-nominals. So consult the vocabulary and route accordingly, in either position:
parse("John Smith Prof.") # title='Prof.' — title vocabularyparse("John Smith Esq.") # suffix='Esq.' — suffix vocabulary (unchanged)parse("Mary Jane King") # family='King' — no period, untouched (unchanged)
This is safe precisely because King is a surname and King. is not. It also removes the Esq. Smith oddity, where a credential is reported as a title.
(b) A curated bare-safe subset for the words that are never surnames.Dr, Mr, Mrs, Prof are not English surnames, so they can be recognized without the period:
parse("Smith Dr") # title='Dr', family='Smith'
This is the same shape as GLUED_HONORIFICS ⊆ SUFFIX_NOT_ACRONYMS (#308) — a riskier position gets a narrower, harsher subset of the base vocabulary, with the subset relation enforced. Entries qualify only if they can never end a name, which is exactly the test #308 already applies.
Both rest on the premise that the caller is handing the parser a name and not prose, so a trailing period means abbreviation rather than sentence punctuation. That premise is worth stating in the docs alongside this, if it is adopted.
What it would not change
Unrecognized abbreviations. parse("John Smith Xyz.") gives family='Xyz.' today, and under (a) still would — nothing in the vocabulary has an opinion. Whether the trailing slot should get a structural fallback the way the leading slot does is a separate question, and deliberately not bundled here: (a) and (b) move known words only, which is measurable; a fallback moves unknown ones, which the differential corpora cannot evidence (they hold only names someone wrote down).
Open questions
Does the doctrine amendment need to be stated as "vocabulary decides for period-marked words, position decides for bare ones"? That is the honest summary, and it is more subtle than what the docs said before.
Should (a) also apply to a leading suffix-only word, i.e. should Esq. Smith give suffix='Esq.'? It is the same principle, but it means the leading inference stops being unconditional, and Consider names followed by a period as titles or suffixes #109 shipped it that way on purpose.
Scale: (a) touches 692 title-only words in a position they have never been recognized in. Differential coverage will be thin — the corpora hold few trailing honorifics — so this likely wants a dedicated probe set rather than reliance on a green run.
Should the fork be reported as an Ambiguity? Probably not for (a) and (b): under the input-is-a-name premise a period-marked title is not a fork a reader would hesitate over. Revisit if a shape turns up where it is.
Related: is esq really an acronym?
Adjacent cleanup for the same milestone, since it is the same kind of question — whether a vocabulary entry describes the word or merely the machinery.
esq is the only member of SUFFIX_ACRONYMS ∩ SUFFIX_NOT_ACRONYMS. It entered SUFFIX_ACRONYMS in af5bdab ("add post-nominal list from wikipedia", #93) as part of a bulk import rather than a judgement, and Esquire is a contraction, not an initialism. The acronym membership uniquely covers exactly one spelling:
parse("John Smith Esq") # suffix='Esq' — word setparse("John Smith Esq.") # suffix='Esq.' — word setparse("John Smith Esquire") # suffix='Esquire' — word setparse("John Smith E.S.Q.") # suffix='E.S.Q.' — ONLY the acronym set
d4dd8a1 restored it after a bad "deduplication" and justified it on 1.4-parity grounds, which is correct as far as it goes — but the spelling it protects is one nobody writes. Dropping it would make SUFFIX_ACRONYMS ∩ SUFFIX_NOT_ACRONYMS == ∅ assertable and retire a gotcha, a non-assert comment and a case row. It is a classified behavior change, since 2.x has shipped with it.
The comma-suffix bundle (#296) removes dr and sra from the suffix vocabulary, which drops them into the behavior described at the top — "John Smith Dr." moves from suffix='Dr.' to family='Dr.'. That is not a new defect: it makes dr consistent with prof, mr and rev, which have always parsed that way, and the v1-residue suffix entry was the only thing that had been hiding it. This issue is the general fix, and grouping the two into the same release avoids shipping the gap and its repair a version apart.
A title word appearing after the name is read as part of the name, so the family name lands on the honorific:
The comma path disagrees with itself about this — it routes the same word to
title:The rule this questions
AGENTS.mdrecorded the doctrine as:That is not quite what the code does, and the gap is the point. Leading position runs a structural inference — any multi-letter word ending in a period is a title — and that inference outranks vocabulary:
Trailing position has no counterpart. So the real asymmetry is: an abbreviation is interpreted in pre-nominal position and not in post-nominal position, and where it is interpreted it overrides the vocabulary that disagrees.
Why the doctrine exists, and why it can't simply be inverted
TITLEScarries 692 words that are in no suffix set, and many are ordinary English surnames:abbot,bailiff,baron,bishop,chancellor,chaplain,deacon,friar,judge,king,master,mayor,pope,prince,provost,ranger,sergeant,sheriff,wardenA blanket "vocabulary outranks position" rule would be severe:
In leading position a title shadows the given name, which the docs already warn about. In trailing position it would shadow the family name — strictly worse, since that is the field callers most depend on.
Proposal
Two parts, because the hazard above is entirely about bare words.
(a) Period-marked words: vocabulary decides the field, position does not. A trailing period marks an abbreviation, and the only name parts that get abbreviated are the ones standing outside the name — titles and post-nominals. So consult the vocabulary and route accordingly, in either position:
This is safe precisely because
Kingis a surname andKing.is not. It also removes theEsq. Smithoddity, where a credential is reported as a title.(b) A curated bare-safe subset for the words that are never surnames.
Dr,Mr,Mrs,Profare not English surnames, so they can be recognized without the period:This is the same shape as
GLUED_HONORIFICS ⊆ SUFFIX_NOT_ACRONYMS(#308) — a riskier position gets a narrower, harsher subset of the base vocabulary, with the subset relation enforced. Entries qualify only if they can never end a name, which is exactly the test #308 already applies.Both rest on the premise that the caller is handing the parser a name and not prose, so a trailing period means abbreviation rather than sentence punctuation. That premise is worth stating in the docs alongside this, if it is adopted.
What it would not change
Unrecognized abbreviations.
parse("John Smith Xyz.")givesfamily='Xyz.'today, and under (a) still would — nothing in the vocabulary has an opinion. Whether the trailing slot should get a structural fallback the way the leading slot does is a separate question, and deliberately not bundled here: (a) and (b) move known words only, which is measurable; a fallback moves unknown ones, which the differential corpora cannot evidence (they hold only names someone wrote down).Open questions
Esq. Smithgivesuffix='Esq.'? It is the same principle, but it means the leading inference stops being unconditional, and Consider names followed by a period as titles or suffixes #109 shipped it that way on purpose.Ambiguity? Probably not for (a) and (b): under the input-is-a-name premise a period-marked title is not a fork a reader would hesitate over. Revisit if a shape turns up where it is.Related: is
esqreally an acronym?Adjacent cleanup for the same milestone, since it is the same kind of question — whether a vocabulary entry describes the word or merely the machinery.
esqis the only member ofSUFFIX_ACRONYMS ∩ SUFFIX_NOT_ACRONYMS. It enteredSUFFIX_ACRONYMSinaf5bdab("add post-nominal list from wikipedia", #93) as part of a bulk import rather than a judgement, and Esquire is a contraction, not an initialism. The acronym membership uniquely covers exactly one spelling:d4dd8a1restored it after a bad "deduplication" and justified it on 1.4-parity grounds, which is correct as far as it goes — but the spelling it protects is one nobody writes. Dropping it would makeSUFFIX_ACRONYMS ∩ SUFFIX_NOT_ACRONYMS == ∅assertable and retire a gotcha, a non-assert comment and a case row. It is a classified behavior change, since 2.x has shipped with it.Relationship to #291 / #296
The comma-suffix bundle (#296) removes
drandsrafrom the suffix vocabulary, which drops them into the behavior described at the top —"John Smith Dr."moves fromsuffix='Dr.'tofamily='Dr.'. That is not a new defect: it makesdrconsistent withprof,mrandrev, which have always parsed that way, and the v1-residue suffix entry was the only thing that had been hiding it. This issue is the general fix, and grouping the two into the same release avoids shipping the gap and its repair a version apart.