String comparison in Swift 4.1 vs 4.2

I noticed some differences between Swift 4.1 and Swift 4.2 with respect to string comparison. Here are two examples, the involved characters are

  • ¢ U+FFE0 FULLWIDTH CENT SIGN
  • :grinning: U+1F600 GRINNING FACE
  • ǟ U+01DF LATIN SMALL LETTER A WITH DIAERESIS AND MACRON
  • ä U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
  • ψ U+03C8 GREEK SMALL LETTER PSI

Swift 4.2.1, as it comes with Xcode 10.1:

$ swift
Welcome to Apple Swift version 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1). Type :help for assistance.
  1> print("\u{ffe0}" < "\u{1f600}")
false
  2> print("\u{01df}" < "\u{e4}\u{3c8}")
false

Swift 4.1.3 from swift-4.1.3-RELEASE-osx.pkg:

$ ./usr/bin/swift
Welcome to Apple Swift version 4.1.3 (swift-4.1.3-RELEASE). Type :help for assistance.
  1> print("\u{ffe0}" < "\u{1f600}")
true
  2> print("\u{01df}" < "\u{e4}\u{3c8}")
true

Is this due to a change in Swift, or related to some change in the Unicode standard? I could not find this documented in the CHANGELOG or the Swift 4.2 announcement, but of course I may have overlooked something.

Any (pointer to) information about what string comparison algorithm Swift uses and what changed between the releases is appreciated.

The change is poorly documented. I would refer you to this bug, which was filed in 2016, for details and the relevant links to code.

1 Like