Ich frage mich gerade, ob es wirklich so ein großes Problem ist, oder etwas was nach einer gewissen Gewöhnung an eine Sprache in Fleisch und Blut übergeht.
Bei Perl5 brauchte ich eine Weile um zu verstehen, dass
$s auf ein Skalar zugreift
$s[0] aber auf ein Element des Arrays
@s und
$s{a} auf einen Eintrag im Hash
%s. Jetzt erscheint es mir das Natürlichste der Welt - bis ein Kollege, der nur selten Perl benutzt, sich darüber wundert.
Dass eine Methode und eine Funktion ganz unterschiedliche Dinge sind, dürfte in den meisten Sprachen der Fall sein. Da ist Perl5 eher die Ausnahme. (Wobei: für die Perl5-Äquivalenz müsste das Objekt der Funktion ja als erster und nicht als letzter Parameter übergeben werden.)
Im konkreten Beispiel bekommen die
map-Methode und die
map-Funktion ja sogar ziemlich unterschiedliche Paramenter übergeben: Einmal 1 Objekt + 1 Codeblock/ref (Methode) gegenüber 1 Codeblock/ref + eine beliebig lange Liste von Objekten (Funktion)
Wahrscheinlich erscheint einem das unterschiedliche Verhalten der beiden
map-Konstrukte also nach kurzer Gewöhnung an Perl6 nicht nur logisch sondern auch intuitiv richtig.
Wie könnte man das Verhalten von
map so ändern, dass es sich auch ohne Gewöhnung an Perl6 "intuitiv richtig" anfühlt?
Ein paar Ideen:
- Unterschiedliche Namen für Methoden und Funktionen verwenden. Konsequenterweise müsste man dann die Namen der build-in-Funktionen zu reservierten Worten machen, die nirgendwo sonst verwendet werden dürfen. Das würde aber die Möglichkeiten, Perl6 zu überladen, anzupassen etc. stark einschränken. (Ähnlich könnte man das o.g. Problem mit Skalaren, Arrays und Hashes verhindern, in dem man festlegt, dass ein Variablenname nur einmal verwendet werden darf. Aber das wäre dann nicht mehr Perl.)
- auf Parcels o.ä. komplex geschachtelte Datenobjekte verzichten. ((1,2),3,(4,5)) wäre dann das gleiche wie 1,2,3,4,5, weil Listen gleich geflattet und die Klammern entfernt würden. Würde wohl ebenfalls Perl6 einiger interessanter Möglichkeiten berauben.
- die Parameterliste der map-Funktion an die der Methode anpassen: hinter dem Code-Block/ref darf nur noch ein Objekt übergeben werden, dass dann vom Typ Liste/Array sein muss. Die Syntax wäre dann wohl map {...}, $((1,2),3,(4,5));.
Überzeugen tut mich keine dieser Ideen.