Is possible some day add Uniform Function Call Syntax (UFCS) in Python like Dlang?

Is possible some day add Uniform Function Call Syntax (UFCS) in Python like Dlang? Example: https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs

In theory it could be checked to see if a given function exists in the same namespace as a given variable if it doesn't exist in it that variable's object's method resolution order and try calling it using the syntax described here, but I don't think it affords the language any added elegance or communicative power. It would have to be determined which takes precedence when a class has a certain method that shares a name with one in the same namespace as an instance. If a method with a given name is not part of a class, the proposed syntax would cause what function calls are valid for a given instance to sometimes be context dependent rather than dependent only on the definition of the class. I'm concerned about what this would mean for language learning and debugging. The potential use case seems to be tied to nested function calls that take one argument in the innermost call. If we were to change the syntax to streamline these constructions, I'd want to see composite functions with @ revisited. Steele On Sun, Jun 28, 2020, 11:00 AM <marcone@email.com> wrote:

On Sun, Jun 28, 2020 at 02:23:38PM -0000, marcone@email.com wrote:
Is possible some day add Uniform Function Call Syntax (UFCS) in Python like Dlang?
Example: https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs
That converts calls like: a.fun() to fun(a) I don't think that will be a good match for Python. In D, the compiler can decide at compile time: - the instance `a` has no `fun` method; - there is a global function `fun`; - which takes a single parameter that matches the type of `a`; and so convert the method call to a function call at compile time, with no loss of efficiency or safety. But in Python, none of that information is available until runtime: - the compiler doesn't know what type `a` will have; - whether or not it has a `fun` method; - whether or not there is a global function `fun`; - and whether it takes an argument matching `a`. So all of that would have to happen at run time. That means that using UFCS would make slow code. The interpreter would have to try calling `a.fun()`, and if that failed with an AttributeError, it would then try `fun(a)` instead. -- Steven

It's been said, but one more tidbit: On Sun, Jun 28, 2020 at 10:32 PM Steven D'Aprano <steve@pearwood.info> wrote:
and then it would have to see if fun(a) was successful, as there would be no way to know if 'a' was indeed a type that fun() could be called on -- AND you'd never know if it did the right thing it if happened not to fail. if fun() is method of the a object, you know that it will be passed a a object as it's first parameter (self) -- but stand alone? there is no way to know that that's the function that's wanted. -CHB
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

A large number of topics have come up that wish to make Python more "fluent" (https://en.wikipedia.org/wiki/Fluent_interface). This is an example of the same general idea. In every single case, the goal has been almost universally rejected as opposite Python's attitude. Converting fun(a) to a.fun() might be possible automatically, but if most such fun() functions return None because they are mutating functions, this does not get chaining of methods, which is the underlying goal. While technically, Python *could* usually return self from most method calls (and libraries like Pandas do exactly that), the Python developers have very deliberately decided that they don't want that. On Sun, Jun 28, 2020 at 11:00 AM <marcone@email.com> wrote:
-- The dead increasingly dominate and strangle both the living and the not-yet born. Vampiric capital and undead corporate persons abuse the lives and control the thoughts of homo faber. Ideas, once born, become abortifacients against new conceptions.

In theory it could be checked to see if a given function exists in the same namespace as a given variable if it doesn't exist in it that variable's object's method resolution order and try calling it using the syntax described here, but I don't think it affords the language any added elegance or communicative power. It would have to be determined which takes precedence when a class has a certain method that shares a name with one in the same namespace as an instance. If a method with a given name is not part of a class, the proposed syntax would cause what function calls are valid for a given instance to sometimes be context dependent rather than dependent only on the definition of the class. I'm concerned about what this would mean for language learning and debugging. The potential use case seems to be tied to nested function calls that take one argument in the innermost call. If we were to change the syntax to streamline these constructions, I'd want to see composite functions with @ revisited. Steele On Sun, Jun 28, 2020, 11:00 AM <marcone@email.com> wrote:

On Sun, Jun 28, 2020 at 02:23:38PM -0000, marcone@email.com wrote:
Is possible some day add Uniform Function Call Syntax (UFCS) in Python like Dlang?
Example: https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs
That converts calls like: a.fun() to fun(a) I don't think that will be a good match for Python. In D, the compiler can decide at compile time: - the instance `a` has no `fun` method; - there is a global function `fun`; - which takes a single parameter that matches the type of `a`; and so convert the method call to a function call at compile time, with no loss of efficiency or safety. But in Python, none of that information is available until runtime: - the compiler doesn't know what type `a` will have; - whether or not it has a `fun` method; - whether or not there is a global function `fun`; - and whether it takes an argument matching `a`. So all of that would have to happen at run time. That means that using UFCS would make slow code. The interpreter would have to try calling `a.fun()`, and if that failed with an AttributeError, it would then try `fun(a)` instead. -- Steven

It's been said, but one more tidbit: On Sun, Jun 28, 2020 at 10:32 PM Steven D'Aprano <steve@pearwood.info> wrote:
and then it would have to see if fun(a) was successful, as there would be no way to know if 'a' was indeed a type that fun() could be called on -- AND you'd never know if it did the right thing it if happened not to fail. if fun() is method of the a object, you know that it will be passed a a object as it's first parameter (self) -- but stand alone? there is no way to know that that's the function that's wanted. -CHB
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

A large number of topics have come up that wish to make Python more "fluent" (https://en.wikipedia.org/wiki/Fluent_interface). This is an example of the same general idea. In every single case, the goal has been almost universally rejected as opposite Python's attitude. Converting fun(a) to a.fun() might be possible automatically, but if most such fun() functions return None because they are mutating functions, this does not get chaining of methods, which is the underlying goal. While technically, Python *could* usually return self from most method calls (and libraries like Pandas do exactly that), the Python developers have very deliberately decided that they don't want that. On Sun, Jun 28, 2020 at 11:00 AM <marcone@email.com> wrote:
-- The dead increasingly dominate and strangle both the living and the not-yet born. Vampiric capital and undead corporate persons abuse the lives and control the thoughts of homo faber. Ideas, once born, become abortifacients against new conceptions.
participants (5)
-
Christopher Barker
-
David Mertz
-
marcone@email.com
-
Steele Farnsworth
-
Steven D'Aprano