odin-lang / Odin

Odin Programming Language
https://odin-lang.org
BSD 3-Clause "New" or "Revised" License
6.55k stars 570 forks source link

Uniform Function Call Syntax? #442

Closed Valmar33 closed 4 years ago

Valmar33 commented 4 years ago

Is your feature request related to a problem? Please describe. Overview here: https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax

When writing complex function calls, it can be difficult to keep track of the control flow, especially with function calls nested in function calls.

To pinch an example of code (written in D) (https://old.reddit.com/r/programming/comments/rif9x/uniform_function_call_syntax_for_the_d/c462m7k/):

auto answer = reduce!"a + b"(filter!"a % 2 == 0"(until!"a > 4_000_000"(recurrence!"a[n-1] + a[n-2]"(1, 1))));

becomes

auto answer = recurrence!"a[n-1] + a[n-2]"(1, 1)
              .until!"a > 4_000_000"()
              .filter!"a % 2 == 0"()
              .reduce!"a + b"();

Which is much easier to reason about. At a glance, it's much easier to see what's happening, and understand the control flow.

This way, you can OOP-style syntax, without the nastiness of OOP. Your functions and data can be kept separate, rather than becoming bundled together.

With a struct as the first argument of a function, for example, you can emulate OOP. Coupled with function overloading (which I think exists in Odin?), the feature becomes seamless.

Describe the solution you'd like Allow the first argument of a function to be treated as if it were an "object" of which the function is a "member", as is the case in OOP languages.

Additional context D and Nim both have this feature, which has been heavily praised by its users.

As for C++... C++'s UFCS proposal is to do it backwards... instead of x.f(y,...) being resolved to f(x,y,...) by the compiler, they want to allow f(x,y,...) being resolved to x.f(y,...), which defeats the purpose of UFCS entirely.

Even Bjarne Stroustrup wanted D / Nim-style UFCS, but the C++ Committee overruled him, in their infinite wisdom...

gingerBill commented 4 years ago

UFCS (Uniform Function Call Syntax) is never going to happen. The main reason is that it doesn't make any sense in Odin.

It's not "uniform" as Odin does not have the concept of a method. And because Odin has the concept of import names for packages, this means procedures are declared within different scopes, meaning it would not make any sense syntactically.

One of Odin's goals is simplicity and striving to only one way to do things, to improve clarity. x.f(y) meaning f(x, y) is ambiguous as x could have a field called f. It's not at all clear what it means.

Very early on during Odin's development (2+ years ago), I experimented with infix and suffix syntax for procedure calls but I removed them as I found that they were virtually never used nor did they actually aid with code clarity either.

One reason many people want it is because the method call syntax allows for "dot-autocomplete" in many IDEs, allowing the ability to show a list available procedures, dependent on the context. It's entirely possible to have this with normal procedure call syntax but most IDEs just don't do it for whatever reason.

Lastly, aesthetically, the suffix approach to procedure calls can be emulated with variables.

a := recurrence(array);
b := until(a, until_proc);
c := filter(b, filter_proc);
d := reduce(c, reduce_proc);
Valmar33 commented 4 years ago

I see. Makes sense. Thank you. :)

gingerBill commented 4 years ago

I have added this question to the FAQ: https://odin-lang.org/docs/faq/#why-does-odin-not-have-uniform-function-call-syntax-ufcs