Skip to content

strings: Document use of simple case-folding in EqualFold  #52022

@typesanitizer

Description

@typesanitizer

At the moment, the documentation for EqualFold says:

EqualFold reports whether s and t, interpreted as UTF-8 strings, are equal under Unicode case-folding, which is a more general form of case-insensitivity.

However, this is under-specified. EqualFold uses simple case-folding, not full case-folding, which can be surprising. For example, Python 3 and Swift default to full case folding:

$ python3
> "ß".casefold()
'ss'
$ swift
> import Foundation
> "ß".folding(options: [.caseInsensitive], locale: nil)
$R0: String = "ss"

I think it would be better to explicitly state that simple case-folding is being used. Perhaps something like:

EqualFold reports whether s and t, interpreted as UTF-8 strings,
are equal under simple Unicode case-folding, which is a more
general form of case-insensitivity. For more information,
see https://www.unicode.org/Public/UNIDATA/CaseFolding.txt.

In general, EqualFold(s1, s2) == (ToLower(s1) == ToLower(s2)).

Perhaps it would be also helpful to have an example like:

func ExampleEqualFold() {
  fmt.Println(strings.EqualFold("AB", "ab")) // true because comparison uses simple case-folding
  fmt.Println(strings.EqualFold("ß", "ss"))  // false because comparison does not use full case-folding
  // Output: true
  // Output: false
}

One can also add a fuzz test if so desired:

func FuzzEqualFold(f *testing.F) {
    f.Fuzz(func(t *testing.T, s1 string, s2 string) {
        lower := strings.ToLower(s1) == strings.ToLower(s2)
        equalFold := strings.EqualFold(s1, s2)
        if lower != equalFold {
            t.Fatalf("mismatch between ToLower and EqualFold: s1 = %s, s2 = %s, via Lower = %v, via EqualFold = %v", s1, s2, lower, equalFold)
        }
    )
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    DocumentationIssues describing a change to documentation.FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.help wanted

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions