Simplifying functions syntax

Python is a simple language to understand, but to me functions are a special case. And according to the Zen of Python (PEP20 <https://www.python.org/dev/peps/pep-0020/>): `Special cases aren't special enough to break the rules.`. For beginners, Python functions can cause some pain that boils down to three points that shows some lack of standardization. 1. Function declaration needs keyword `def`: If you are a long time Python (1991) developer, you surely got used to the keyword `def` to declare a function, same goes if you are a Ruby (1995) programmer. In Fortran (1957) you start them with the word `function` and in Perl (1987) you use the word `sub`. In C-family languages C (1972), C++ (1985), C# (2000), also in Java (1995) you don't need any word to declare it: return_type function_name(args) In languages from the last decade you have Rust (2010) with the keyword `fn`, Kotlin with `fun`. Dart (2011) follows C-family style and Julia (2012) offers two ways of defining a named function: using the word `function` or the compact version with no keyword `f(x,y) = x + y`. Following PEP20 <https://www.python.org/dev/peps/pep-0020/> aphorism of `Simple is better than complex.` I would say no word like C-family is simpler. But there is also `Explicit is better than implicit.`. I would choose `fun` or even `fn` since they at least resemble the word function. Eg:
def x(args):
... pass would turn into:
fun x(args):
... pass Resemblance of function leads me to my next point. 2. Class name Again, functions are an exception.
x = 1
type(x)
<class 'int'> *# not integer*
x = {"a": 1}
type(x)
<class 'dict'> *# not dictionary*
def x(args):
... pass ...
type(x)
<class 'function'> *# not fun =(* 3. Type hinting This is when the syntax gets trickier. With PEP 585 <https://www.python.org/dev/peps/pep-0585/> you don't have to do:
from typing import Dict, List, Set
to have:
def x(foo: dict[string, int], bar: list[float]) -> None:
... pass But if you have a function as a parameter, your only option is to use Callable. It breaks the rule again having a totally different syntax:
from typing import Callable
def x(method: Callable[[int, dict], None]) -> None:
... pass So you have `def`, `function`, `Callable` and also this [[args], return] syntax, also different from the rest of type hinting syntax. I would add a `fun` type without the need of an import. Also Callable syntax could also be simplified with the -> operator into something like:
def x(method: fun[int, dict] -> None) -> None:
... pass === Preliminary Proposal === With the same goal of removing the pain and making life of Python teachers easier (PEP 585 <https://www.python.org/dev/peps/pep-0585/>), I would change this:
from typing import Callable
def x(method: Callable[[int, dict], None]) -> None:
... pass ...
type(x)
<class 'function'> Into something like this:
fun x(method: fun[int, dict] -> None) -> None:
... pass ...
type(x)
<class 'fun'> In order to make this possible the following changes would be needed: 1. adding `fun` keyword to method definition (maintaining `def` for backwards compatibility); 2. adding `fun` built-in type in addition to Callable; 3. supporting `->` as return syntax for type hinting. Isn't it much more `fun` to learn the language this way? Kind regards, Thiago Carvalho D'Ávila

On Tue, Jul 21, 2020 at 8:10 AM Thiago Carvalho D' Ávila <thiagocavila@gmail.com> wrote:
If it's a built-in type AND a keyword, won't that create hard-to-understand error messages? I would strongly recommend creating a transpiler that converts your proposed syntax into currently-legal Python, and seeing how advantageous it really is. ChrisA

Chris Angelico, you have a good point. An alternative solution that would achieve similar or even better results in terms of simplification would be not creating `fun` as a keyword and allowing developers to create functions in Python without a keyword (like in C-family). That way, a new proposal would be changing:
Into this:
What do you think?

On Tue, Jul 21, 2020 at 10:34 AM Thiago Carvalho D'Ávila <thiagocavila@gmail.com> wrote:
Exactly the same thing: that you would do better to create a transpiler that converts your proposed syntax into legal syntax. That way, you get to try things out and see how it actually feels, and the process of creating the transpiler will reveal ambiguities to you :) (If you want me to be a little more direct about it: I am strongly against this proposal, as are others.) ChrisA

I'm not sure why I'm bothering to engage, but: On Tue, Jul 21, 2020 at 2:31 AM MRAB <python@mrabarnett.plus.com> wrote:
one trick is that x(some, stuff) is currently a valid expression. One real difference between C and Python is that C has "declarations", and not just of functions. Python does not, hence the keyword. As you pointed out in your initial post -- many languages use a keyword to declare a function -- I can't see the gain from getting rid of that -- even if it were a new language, and we didn't have backward compatibility to worry about. I haven't written a whole lot of C, but I always found the function declaration syntax kind of confusing. -CHB
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

There is absolutely no possibility that this will go anywhere. It breaks every single Python program written since 1989, with absolutely ZERO new functionally. Changing the spelling of a few of the most come keywords is a non-starter. If you can time travel to 1987 and propose differently spelled keywords, yours are no worse... But also no better. On Mon, Jul 20, 2020, 6:06 PM Thiago Carvalho D' Ávila < thiagocavila@gmail.com> wrote:

On Mon, Jul 20, 2020 at 05:16:54PM -0300, Thiago Carvalho D' Ávila wrote:
I have many years of experience helping beginners on mailing lists, and I cannot remember even a single case of anyone being confused by the need to use "def" to declare a function.
I would choose `fun` or even `fn` since they at least resemble the word function.
The keyword "def" is short for "define". def iter() is read as "define iter". In any case, this is a matter of bikeshedding. I think that using "fun" is a terrible choice, because it's not necessarily fun at all: fun pallative_care_for_the_dying(): but it really doesn't matter. There is zero chance that we will break thirty years of code, tutorials, StackOverflow posts, instructional videos, books etc just to change the colour of this bikeshed from "def" to "fun".
Are they? We have tuple, not "tup"; list, not "lst", float, not "flt"; bytearray, not "btar"; ValueError, not "VEr". Abbreviated three or four letter type names are the exception.
But if you have a function as a parameter, your only option is to use Callable. It breaks the rule again having a totally different syntax:
I don't know whether that is the only way, but Callable doesn't just mean function. Callable means any object with a `__call__` method (what C++ refers to as "functor", I believe, not to be confused with Haskell functors, which are completely unrelated), which includes but is not limited to funtions and classes.
With the same goal of removing the pain and making life of Python teachers easier
Making 30 years of tutorials, documentation and books obsolete will not make the life of Python teachers easier.
1. adding `fun` keyword to method definition (maintaining `def` for backwards compatibility);
Having to teach two ways to declare a function instead of one, and answer a thousand questions "What's the difference between def and fun? Which should I use?", doesn't make life easier for teachers. -- Steven

(The only not unreasonable suggestion in the OP's proposal is to try and come up with something better than Callable --- we've introduced other syntax specifically for type annotations, and are likely to do so again. But **PLEASE** start a new thread for that.) On Mon, Jul 20, 2020 at 7:37 PM Steven D'Aprano <steve@pearwood.info> wrote:
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

Actually, Callable is fine the way it is, the chosen name is most fitting and the generic syntax is slightly difference than how it's done in C/C++ (Known difference are due to language differences between Python and C/C++)

On Tue, Jul 21, 2020 at 8:10 AM Thiago Carvalho D' Ávila <thiagocavila@gmail.com> wrote:
If it's a built-in type AND a keyword, won't that create hard-to-understand error messages? I would strongly recommend creating a transpiler that converts your proposed syntax into currently-legal Python, and seeing how advantageous it really is. ChrisA

Chris Angelico, you have a good point. An alternative solution that would achieve similar or even better results in terms of simplification would be not creating `fun` as a keyword and allowing developers to create functions in Python without a keyword (like in C-family). That way, a new proposal would be changing:
Into this:
What do you think?

On Tue, Jul 21, 2020 at 10:34 AM Thiago Carvalho D'Ávila <thiagocavila@gmail.com> wrote:
Exactly the same thing: that you would do better to create a transpiler that converts your proposed syntax into legal syntax. That way, you get to try things out and see how it actually feels, and the process of creating the transpiler will reveal ambiguities to you :) (If you want me to be a little more direct about it: I am strongly against this proposal, as are others.) ChrisA

I'm not sure why I'm bothering to engage, but: On Tue, Jul 21, 2020 at 2:31 AM MRAB <python@mrabarnett.plus.com> wrote:
one trick is that x(some, stuff) is currently a valid expression. One real difference between C and Python is that C has "declarations", and not just of functions. Python does not, hence the keyword. As you pointed out in your initial post -- many languages use a keyword to declare a function -- I can't see the gain from getting rid of that -- even if it were a new language, and we didn't have backward compatibility to worry about. I haven't written a whole lot of C, but I always found the function declaration syntax kind of confusing. -CHB
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

There is absolutely no possibility that this will go anywhere. It breaks every single Python program written since 1989, with absolutely ZERO new functionally. Changing the spelling of a few of the most come keywords is a non-starter. If you can time travel to 1987 and propose differently spelled keywords, yours are no worse... But also no better. On Mon, Jul 20, 2020, 6:06 PM Thiago Carvalho D' Ávila < thiagocavila@gmail.com> wrote:

On Mon, Jul 20, 2020 at 05:16:54PM -0300, Thiago Carvalho D' Ávila wrote:
I have many years of experience helping beginners on mailing lists, and I cannot remember even a single case of anyone being confused by the need to use "def" to declare a function.
I would choose `fun` or even `fn` since they at least resemble the word function.
The keyword "def" is short for "define". def iter() is read as "define iter". In any case, this is a matter of bikeshedding. I think that using "fun" is a terrible choice, because it's not necessarily fun at all: fun pallative_care_for_the_dying(): but it really doesn't matter. There is zero chance that we will break thirty years of code, tutorials, StackOverflow posts, instructional videos, books etc just to change the colour of this bikeshed from "def" to "fun".
Are they? We have tuple, not "tup"; list, not "lst", float, not "flt"; bytearray, not "btar"; ValueError, not "VEr". Abbreviated three or four letter type names are the exception.
But if you have a function as a parameter, your only option is to use Callable. It breaks the rule again having a totally different syntax:
I don't know whether that is the only way, but Callable doesn't just mean function. Callable means any object with a `__call__` method (what C++ refers to as "functor", I believe, not to be confused with Haskell functors, which are completely unrelated), which includes but is not limited to funtions and classes.
With the same goal of removing the pain and making life of Python teachers easier
Making 30 years of tutorials, documentation and books obsolete will not make the life of Python teachers easier.
1. adding `fun` keyword to method definition (maintaining `def` for backwards compatibility);
Having to teach two ways to declare a function instead of one, and answer a thousand questions "What's the difference between def and fun? Which should I use?", doesn't make life easier for teachers. -- Steven

(The only not unreasonable suggestion in the OP's proposal is to try and come up with something better than Callable --- we've introduced other syntax specifically for type annotations, and are likely to do so again. But **PLEASE** start a new thread for that.) On Mon, Jul 20, 2020 at 7:37 PM Steven D'Aprano <steve@pearwood.info> wrote:
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

Actually, Callable is fine the way it is, the chosen name is most fitting and the generic syntax is slightly difference than how it's done in C/C++ (Known difference are due to language differences between Python and C/C++)
participants (9)
-
Chris Angelico
-
Christopher Barker
-
David Mertz
-
Guido van Rossum
-
MRAB
-
Steven D'Aprano
-
Thiago Carvalho D' Ávila
-
Thiago Carvalho D'Ávila
-
William Pickard