統一関数呼び出し構文( UFCS ) または統一呼び出し構文( UCS ) は、D [ 1 ] Nim [ 2 ] Koka [ 3 ] Effekt [ 4 ] 、 Lean [ 5 ]などのプログラミング言語の機能で、レシーバを最初のパラメータとして、指定された引数を残りのパラメータとして使用することで、メソッド呼び出しの構文 (オブジェクト指向プログラミングと同様) を使用して任意の関数を呼び出すことができます。 [ 6 ]同じ手法は、AviSynthスクリプト言語で「OOP 表記法」という名前で使用されています。[ 7 ]
UFCS は、関数呼び出しが連鎖する場合に特に便利です[ 1 ] (パイプや、関数型言語で一連の式を通して値を渡すために使用できるさまざまな専用演算子と同様の動作をします)。これにより、自由関数が他の言語の拡張メソッドと同様の役割を果たすことができます。構文のもう 1 つの利点は、 IDEの補完システムに関連しており、コンテキストに応じて使用可能な関数のリストを表示するために型情報を使用します。プログラマが引数から始めると、適用可能な関数のセットが大幅に絞り込まれ、[ 8 ]発見しやすくなります。
int first ( int [] arr ) { return arr [ 0 ]; }int [] addone ( int [] arr ) { int [] result ; foreach ( value ; arr ) { result ~= value + 1 ; } return result ; }void main () { auto a = [ 0 , 1 , 2 , 3 ];// 以下はすべて正しく、同等ですint b = first ( a ); int c = a . first ();// int [] e = aを連鎖させます。アドオン()。アドオン(); }type Vector = tuple [ x , y : int ]proc add ( a , b : Vector ): Vector = ( a . x + b . x , a . y + b . y )let v1 = ( x : - 1 , y : 4 ) v2 = ( x : 5 , y : - 2 )# 以下はすべて正しいv3 = add ( v1 , v2 ) v4 = v1 . add ( v2 ) v5 = v1 . add ( v2 ). add ( v4 )メンバー関数とフリー関数の呼び出し構文の統一に関する提案は、 C++標準化の初期から議論されてきました。Glassborow (2004) は、特別な注釈が付いたフリー関数をメンバー関数表記で呼び出せるようにする統一呼び出し構文 (UCS) を提案しました。[ 9 ] 2016 年に、 Bjarne Stroustrup [ 10 ]とHerb Sutter [ 8 ]によって、フリー関数とメンバー関数の記述に関する曖昧な決定を減らし、テンプレート化されたコードの記述を簡素化するために、C ++ への追加が 2 回提案されました。多くのプログラマーは、メンバー関数構文の利点 (たとえば、メンバー関数を一覧表示する「ドットオートコンプリート」 )を得るためにメンバー関数を記述したくなります。 [ 11 ]しかし、これはクラス間の過剰な結合につながります。[ 12 ]これは、2023 年に Herb Sutter [ 13 ]によって再び提案され、新しい情報と洞察、およびcppfrontコンパイラでの実験的な実装が主張されました。
2018 年までは、修飾パス構文や明示パス構文、そして最も一般的には完全修飾パス構文を指す場合にこの用語を使用するのが一般的でした[ 14 ]。同じ構造体に実装された同じメソッドを定義する複数の特性が存在する可能性があるため、どの特性を使用するべきかを明確にするメカニズムが必要です。メンバ関数は、修飾パス (名前空間付き) を介してフリー関数としても使用できます。UFCS という用語は、メソッドを (名前空間付き) フリー関数として使用することはできますが、フリー関数をメソッドとして使用することはできないため、これらの用途には不適切です。
は以下と同等です。
a.function(b)function(a, b)