Der erste Vergleich ergibt „ungleich“. Dies entspricht meiner Erwartung, da ich davon ausgehe, dass hier nicht {\ss} und \ss miteinander verglichen werden, sondern { und \ss, da dies die ersten beiden Token nach \ifx sind.
Der zweite Vergleich ergibt „gleich“. Dies scheint zwar semantisch sinnvoll, ist aber überraschend, denn erstens ist \token_if_eq_meaning:NNTF mit Hilfe von \ifx definiert, wie man dem Dokument source3 entnehmen kann, sollte sich also genauso verhalten. Zweitens verbietet die expl3-Anleitung die Verwendung geschweifter Klammern für N-Argumente.
Wieso ergeben beide Vergleiche unterschiedliche Ergebnisse?
Ich komme aus folgendem Grund auf die Frage:
Eine Funktion mit N-Argument könnte missbräuchlich mit einem Argument in geschweiften Klammern aufgerufen werden. Dann würde aber der \token_if_eq_meaning:NNTF-Befehl, der innerhalb dieser Funktion auftritt durcheinander kommen.
Der dritte Aufruf von \meinbefehl:N ergibt „Eszett gelesenkein Eszett gelesen“. Hier wird offenbar nicht ab mit \ss verglichen, sondern a mit b, sodass der True-Code zum False-Code wird und der False-Code nicht mehr als Befehlsargument aufgefasst wird und somit einfach angehängt wird.
Ich habe mich nun gefragt, ob es sinnvoll wäre, das unerwünschte Verhalten durch geschweifte Klammern auszuschließen:
Die scheinbar unterschiedlichen Ergebnisse ergeben sich aus der Tatsache, dass \token_if_eq_meaning:NNTF ein Makro ist und daraus, wie Makros ihre Argumente lesen.
Du hast recht: \ifx vergleicht die zwei als nächstes folgenden Token, das heißt im Fall von
Warum funktioniert's dann mit \token_if_eq_meaning:NNTF? Antwort: weil es ein Makro ist und ein Makro als Argument entweder ein Token nimmt oder eine „braced group“ und dabei das äußere Paar „Braces“ entfernt. Darum gibt hier alles „gleich“:
Noch was zu expl3: ein N als Argument Specifier bedeutet immer nimm ein Token und keine braced group, im Gegensatz zu n, das genau das Gegenteil bedeutet. Als Code-Schreiber sollte man da drauf achten und User-Input ggf vorab „bearbeiten“, damit man der Funktion das richtige zu essen gibt. Man darf sich nicht auf die Implementierung einer „Funktion“ verlassen, sondern nur auf ihre dokumentierte Funktionsweise.
Man könnte nun zwar mit einigem Recht behaupten, dass \token_if_eq_meaning:NNTF {\ss} das falsche Ergebnis liefert, da .{ und \ss nun mal nicht gleich sind, aber es ist dokumentiert, dass das nicht geht:
Note that an explicit begin group token cannot be tested in this way, as it is not a valid N-type argument.
Das heißt nichts anderes als, dass \token_if_eq_meaning:NNTF {\ss} falsche Anwendung ist. Das gleiche gilt für \meinbefehl:N {ab}. Das ist ebenfalls eine falsche Anwendung. Dass dann was anderes herauskommt als erwartet, sollte nicht überraschen.