Uniform function call syntax

{{Short description|Programming language feature}}

Uniform function call syntax (UFCS) or uniform call syntax (UCS) or sometimes universal function call syntax is a programming language feature in D, Nim,{{Cite web |title=Nim by Example - Procs |url=https://nim-by-example.github.io/procs/ |access-date=2024-05-19 |website=nim-by-example.github.io}} Koka,{{Cite web |title=The Koka Programming Language |url=https://koka-lang.github.io/koka/doc/book.html |access-date=2024-05-19 |website=koka-lang.github.io}} and Effekt{{Cite web |title=Functions |url=https://effekt-lang.org/tour/functions |access-date=2025-04-09 |website=Effekt Language}} that allows any function to be called using the syntax for method calls (as in object-oriented programming), by using the receiver as the first parameter and the given arguments as the remaining parameters.{{cite web |url=http://dlang.org/function.html#pseudo-member |title=Functions |website=D Programming Language |accessdate=1 October 2017}} The same technique is used in the AviSynth scripting language under the name "OOP notation".{{cite web |title=Operators |website=Avisynth wiki |url=http://avisynth.nl/index.php/Operators#Operator_Precedence |quote=a.function(b) is equivalent to function(a, b)}}

UFCS is particularly useful when function calls are chained{{cite web |url=http://ddili.org/ders/d.en/ufcs.html |title=Universal Function Call Syntax (UFCS) |website=Programming in D |accessdate=1 October 2017}} (behaving similar to pipes, or the various dedicated operators available in functional languages for passing values through a series of expressions). It allows free functions to fill a role similar to extension methods in some other languages. Another benefit of the syntax is related to completion systems in IDEs, which use type information to show a list of available functions, dependent on the context. When the programmer starts with an argument, the set of potentially applicable functions is greatly narrowed down,{{cite web |title=Unified Call Syntax |url=https://isocpp.org/files/papers/N4165.pdf |website=Isocpp.org |accessdate=1 October 2017}} aiding discoverability.

Examples

= D programming language =

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];

// all the following are correct and equivalent

int b = first(a);

int c = a.first;

// chaining

int[] e = a.addone().addone();

}

= Nim programming language =

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)

# all the following are correct

v3 = add(v1, v2)

v4 = v1.add(v2)

v5 = v1.add(v2).add(v4)

C++ proposal

Proposals for a unification of member function and free function calling syntax have been discussed from the early years of C++ standardization. Glassborow (2004) proposed a uniform calling syntax (UCS), allowing specially annotated free functions to be called with member function notation.{{cite web |title=N1585: Uniform Calling Syntax (Re-opening public interfaces) |author=Francis Glassborow |date=2 May 2004 |url=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1585.pdf |accessdate=17 December 2018}}

In 2016 it was proposed a second time for addition to C++ by Bjarne Stroustrup{{cite web |title=UFCS proposal |url=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4174.pdf |website=Open-std.org |accessdate=1 October 2017}} and Herb Sutter, to reduce the ambiguous decision between writing free functions and member functions, to simplify the writing of templated code. Many programmers are tempted to write member functions to get the benefits of the member function syntax (e.g. "dot-autocomplete" to list member functions);{{cite web |title=Using IntelliSense |url=https://msdn.microsoft.com/en-us/library/hcw1s69b.aspx |website=MSDN |accessdate=1 October 2017}} however, this leads to excessive coupling between classes.{{cite web |title=How Non-Member Functions Improve Encapsulation |url=https://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197 |website=Drdobbs.com |accessdate=1 October 2017}} This was again, in 2023, proposed by Herb Sutter{{Cite web |last=Sutter |first=Herb |date=13 October 2023 |title=Unified function call syntax (UFCS) |url=https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p3021r0.pdf }} claiming new information and insights, as well as an experimental implementation in the cppfront compiler.

Rust usage of the term

Until 2018, it was common{{Cite web |title=Rename UFCS to accurately reflect its functionality. · Issue #1140 · rust-lang/rfcs |url=https://github.com/rust-lang/rfcs/issues/1140 |access-date=2024-05-19 |website=GitHub |language=en}} to use this term when actually referring to [https://github.com/rust-lang/rfcs/issues/1140#issuecomment-108644620 qualified/explicit path syntax] and most commonly the [https://doc.rust-lang.org/1.30.0/book/2018-edition/ch19-03-advanced-traits.html?highlight=trait,function,call#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name fully qualified path syntax]: because it is possible to have several traits defining the same method implemented on the same struct, a mechanism is needed to disambiguate which trait should be used. Member functions can also be used as free functions through a qualified (namespaced) path. The term UFCS is incorrect for these uses, as it allows using methods as (namespaced) free functions, but not using free functions as methods.

See also

References