[m-users.] String comparison when compiling to C

Zoltan Somogyi zoltan.somogyi at runbox.com
Tue Aug 27 21:27:07 AEST 2024


On Mon, 26 Aug 2024 12:49:42 +1200, "Richard O'Keefe" <raoknz at gmail.com> wrote:
> It's not clear to me why S1 < S2 is any more or less type-specific
> than compare(<, S1, S2).

If you are talking in the abstract, the two notions are equivalent.
If you are talking in the concrete case of Mercury, the two are diffferent.

The compare predicate in the builtin module of the standard library
has the signature

  :- pred compare(comparison_result, T, T).

and can thus compare pairs of values of any type. Its implementation
uses runtime type information (RTTI), which has a bit of overhead.

The standard library modules that define numerical types, which are
int.m, uint.m, their 8-, 16-, 32- and 64-bit versions, rational.m and float.m,
define predicates named <, >, =< and >= that each operate on values
of the type that the module is named for. All of these predicates, with
the exception of the ones in rational.m, are builtins, and are implemented
with essentially no overhead.

In our view, this gives users the freedom to choose what they value more;
genericity, or performance.

Note that while <, >, =< and >= are not generic operations, builtin.m
does define predicates named @<, @>, @=< and @>=. These *are* generic,
because they are implemented in terms of builtin.compare.

This thread started because string.m does not define <. That may seem strange
at first glance, but whatever comparison method we picked (case sensitive
vs case insensitive, respecting white space vs ignoring white space, etc)
would be right for some use cases but wrong for others. And in practice,
many programs (I am not claiming all, or even most programs, but many)
can simply do without such a predicate. This is because the most common
use case for string comparison is using strings as keys in maps, and that
is code that users don't have to write, because the Mercury standard library
provides several modules (such as map.m) that already provide that capability.
They do it by using builtin.compare, and for their purposes, it does not matter
*which* comparison method that predicate uses.

If someone needs a comparison predicate on strings that works in a given
specific way, they are free to implement it themselves. It is not hard.
Having seen some of the web pages that pass for documentation for the libraries
of languages such as C# and Java, I wouldn't be surprised if it took less time
for someone to implement a string comparison predicate in Mercury
than it would take them to select the right method from a C# or Java class,
*and convince themselves that it does what it says/implies it does* ,
especially if one cares about what the comparison does in the presence
of non-well-formed unicode strings :-(

Zoltan.


More information about the users mailing list