Because:
The function returns a sequence of text nodes.
Atomization turns that into a sequence of strings.
And xsl:value-of uses the default separator, “ ”, between those strings.
One way to eliminate the “extra” spaces is to explicitly set the separator to the empty string:
<xsl:value-of select="xf:compare('apple', 'apple')" separator=""/>