Uniform function call syntax: Difference between revisions

Content deleted Content added
fixed wording, 'chaining (similar to pipes/FP)' not 'chaining (similar to pipes) or FP..'
Uniform function call syntax was already mentioned
 
(60 intermediate revisions by 38 users not shown)
Line 1:
{{Short description|Programming language feature}}
'''Uniform Function Call Syntax''' (UFCS) or sometimes '''Universal Function Call Syntax''' is a [[programming language]] feature in [[D (programming language)|D]], [[Rust (programming language)|Rust]]<ref>https://doc.rust-lang.org/book/first-edition/ufcs.html</ref> and [[Nim (programming language)|Nim]] that allows any [[function (computer programming)|function]] to be called
'''Uniform function call syntax''' ('''UFCS''') or '''uniform call syntax''' ('''UCS''') is a [[programming language]] feature in [[D (programming language)|D]],<ref name=":0" /> [[Nim (programming language)|Nim]],<ref>{{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}}</ref> Koka,<ref>{{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}}</ref> and Effekt<ref>{{Cite web |title=Functions |url=https://effekt-lang.org/tour/functions |access-date=2025-04-09 |website=Effekt Language}}</ref> that allows any [[function (computer programming)|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.<ref>{{cite web |url=http://dlang.org/function.html#pseudo-member |title=Functions |website=D Programming Language |accessdate=1 October 2017}}</ref> The same technique is used in the [[AviSynth]] scripting language under the name "OOP notation".<ref>{{cite web |title=Operators |website=Avisynth wiki |url=http://avisynth.nl/index.php/Operators#Operator_Precedence |quote=<code>a.function(b)</code> is equivalent to <code>function(a, b)</code>}}</ref>
using the syntax for method calls (as in [[object-oriented programming]]), by using the [[receiver (object oriented programming)|receiver]] as the first parameter, and the given arguments as the remaining parameters.<ref>http://dlang.org/function.html#pseudo-member</ref> UFCS is particularly useful when function calls are chained,<ref>http://ddili.org/ders/d.en/ufcs.html</ref> (behaving similar to [[Pipe (computer science)|pipe]]s, or the various dedicated [[Operator (computer programming)|operator]]s available in [[functional language]]s for passing values through a series of [[Expression (computer science)|expression]]s). It allows free-functions to fill a role similar to [[extension method]]s in some other languages. Another benefit of the method call syntax is use with "[[dot-autocomplete]]" in [[IDE (computing)|IDE]]s, 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, aiding discoverability.
 
using the syntax for method calls (as in [[object-oriented programming]]), by using the [[receiver (object oriented programming)|receiver]] as the first parameter, and the given arguments as the remaining parameters.<ref>http://dlang.org/function.html#pseudo-member</ref> UFCS is particularly useful when function calls are chained,<ref name=":0">{{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}}</ref> (behaving similar to [[Pipe (computer science)|pipepipes]]s, or the various dedicated [[Operator (computer programming)|operatoroperators]]s available in [[functional language]]s for passing values through a series of [[Expression (computer science)|expressionexpressions]]s). It allows free- functions to fill a role similar to [[extension method]]s in some other languages. Another benefit of the method call syntax is userelated withto "[[dot-autocomplete]]"completion systems in [[IDEIntegrated (computing)development environment|IDEIDEs]]s, 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,<ref name="auto">{{cite web |title=Unified Call Syntax |url=https://isocpp.org/files/papers/N4165.pdf |website=Isocpp.org |accessdate=1 October 2017}}</ref> aiding [[discoverability]].
== C++ proposal ==
It has been proposed (as of 2016) for addition to C++ by [[Bjarne Stroustrup]]<ref>{{cite web|title="UFCS proposal"|url=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4174.pdf}}</ref> and [[Herb Sutter]]<ref>{{cite web|title="Unified Call Syntax"|url=https://isocpp.org/files/papers/N4165.pdf}}</ref>, to reduce the ambiguous decision between writing [[free function (c++)|free function]]s and member functions<ref>{{cite web|title="How Non-Member Functions improve encapsulation|url=http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197}}</ref>, to simplify the writing of [[generic programming|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 function]]s<ref>{{cite web|title=using intellisense|url=https://msdn.microsoft.com/en-us/library/hcw1s69b.aspx}}</ref>, however this leads to excessive [[Coupling (computer programming)|coupling]] between [[Class (computer programming)|classes]].
 
== Examples ==
=== D programming language ===
<sourcesyntaxhighlight lang="Dd">
import std.stdio;
 
int first(int[] arr)
{
Line 28 ⟶ 25:
auto a = [0, 1, 2, 3];
 
// Allall the followingsfollowing are correct and equivalent
int b = first(a);
int c = a.first();
int d = a.first;
 
// Chainingchaining
int[] e = a.addone().addone();
}
</syntaxhighlight>
</source>
 
=== Rust programming language ===
 
<source lang="Rust">
 
trait Foo {
fn f(&self);
fn g(&self);
}
 
trait Bar {
fn g(&self);
}
 
struct Qux;
 
impl Foo for Qux {
fn f(&self) { println!("Qux’s implementation of Foo::f"); }
fn g(&self) { println!("Qux’s implementation of Foo::g"); }
}
 
impl Bar for Qux {
fn g(&self) { println!("Qux’s implementation of Bar::g"); }
}
 
fn main() {
let q = Qux;
 
// These two are equivalent:
q.f();
Foo::f(&q);
 
// This would not work because .g() is ambiguous:
// q.g();
// But it's possible to disambiguate using UFCS
Foo::g(&q);
Bar::g(&q);
}
</source>
 
=== Nim programming language ===
<sourcesyntaxhighlight lang="Nimnim">
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(v1v4)
</syntaxhighlight>
</source>
 
== 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.<ref>{{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}}</ref>
ItIn has2016 it beenwas proposed (asa ofsecond 2016)time for addition to C++ by [[Bjarne Stroustrup]]<ref>{{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}}</ref> and [[Herb Sutter]],<ref>{{cite web|titlename="Unified Call Syntaxauto"|url=https://isocpp.org/files/papers/N4165.pdf}}</ref>, to reduce the ambiguous decision between writing [[freeFunction function(computer (cprogramming)#C and C++)|free functionfunctions]]s and member functions<ref>{{cite web|title="How Non-Member Functions improve encapsulation|url=http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197}}</ref>, to simplify the writing of [[generic programming|templated code]]. Many programmers are tempted to write member- functions to get the benefits of the member- function syntax - (e.g. "[[Code completion|dot-autocomplete]]" to list [[member function]]s);<ref>{{cite web |title=usingUsing IntelliSense intellisense|url=https://msdn.microsoft.com/en-us/library/hcw1s69b.aspx |website=MSDN |accessdate=1 October 2017}}</ref>, however, this leads to excessive [[Coupling (computer programming)|coupling]] between [[Class (computer programming)|classes]].<ref>{{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}}</ref> This was again, in 2023, proposed by Herb Sutter<ref>{{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 }}</ref> 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<ref>{{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}}</ref> 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 ==
* [[traitTrait (computer programming)]]
* [[interfaceInterface (computer programming)]]
* [[Go (programming language)]], another language with a more open philosophy to methods
* [[Loose coupling]]
* [[Duck typing]]
* [[Method chaining]]
 
== References ==
{{Reflist}}
 
[[Category:Articles with example code]]
[[Category:SourceArticles with example D code]]
[[Category:Object-oriented programming]]
[[Category:Source code]]
[[Category:Subroutines]]
[[Category:Articles with example code]]
 
 
{{compu-prog-stub}}