Fwd: Make parenthesis optional in parameterless functions definitions

---------- Forwarded message ---------- From: Mahan Marwat <mahanmarwat@gmail.com> Date: Thu, Mar 31, 2016 at 9:09 PM Subject: Make parenthesis optional in parameterless functions definitions To: python-ideas@python.org Hi, I have an idea of making parenthesis optional for functions having no parameters. i.e def greet: # note the missing parenthesis print('hello') The less awkward characters we have, the more readable our code will be (Beautiful is better then ugly). Some people argued that function definition with parenthesis seems to them natural. But actually it seems to us natural, because we have been used to it a-lot. IMHO parenthesisless functions definitions are natural and readable. In Python we have already adopted this. i.e parenthesis are optional in `if` statements, in class definition, in tuple etc if x == 1: # parenthesis are optional here pass class Greet: # now we don't explicitly inherit from `object` pass Tuple = 1, 2, 3 # parenthesis are optional here too Please, give your opinion. Thanks, Adnan Khan

Alexander Walters <tritium-list@sdamon.com> writes:
are the two extra keystrokes really a problem?
Who said the keystrokes are a problem? Not the original poster. Instead, the issue raised is of readability:
No mention of keystrokes. I'm endlessly disappointed that discussions of “too much noise in the code” are mis-interpreted as *only* about writing, not about reading. -- \ “Always do right. This will gratify some people, and astonish | `\ the rest.” —Mark Twain | _o__) | Ben Finney

On 3/31/2016 19:22, Ben Finney wrote:
There are four pieces of information in the first line of that definition. It starts with the keyword at the beginning of the line. Readers of languages that are left to right will instantly know they are in a function definition. The next piece of information is the identifier that the function will be assigned too, and that is clearly defined right there. The proposal would not change this. The third is the argument list, in this case an empty one. The fourth is the 'block delimiter' for lack of anything better for me to call it. As this example sits, that line should be read as "define a function named foo that explicitly takes no arguments with the following code." Omitting the parens changes the way it reads to something along the lines of "define a function named foo with the following code." The proposal has removed vital visual information. I said earlier that if this suggestion was made in 1991 it should have been accepted to make functions more consistent with classes. I have changed my mind; in 1991 classes should have been corrected to always require parens.

On 2 April 2016 at 00:36, Alexander Walters <tritium-list@sdamon.com> wrote:
In fact, the one change made in this area since then was to *permit* empty parens on class definitions back in Python 2.5: https://hg.python.org/cpython/rev/a0d3f773543d Prior to that, the empty parens were mandatory for functions and explicitly disallowed for classes. Making them mandatory for classes would break too much code for not enough benefit, while making them optional for functions would introduce an additional stylistic choice with no demonstrable benefit to code maintainability, and a clear disadvantage in creating a new opportunity for style inconsistencies. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Thu, Mar 31, 2016 at 09:29:36PM +0500, Mahan Marwat wrote:
-1 I don't think that the benefit (two fewer characters to type) is worth the effort of learning the special case. Right now, the rule is simple: the def keyword ALWAYS needs parentheses after the name of the function, regardless of whether there is one argumemt, two arguments, twenty arguments, or zero arguments. Why treat zero as special?
The less awkward characters we have, the more readable our code will be (Beautiful is better then ugly).
I don't think that function declarations missing the parens are more beautiful than them with the parens. The Zen also says: Special cases aren't special enough to break the rules. Why do you think that zero-argument functions are special enough to justify breaking the rules? Just to save two characters?
When I was a beginner, I found that it was very helpful that I *always* needed to use parens after functions: def func(): ... # later result = func() Otherwise I would forget the parens, and get a syntax error: def func: ... or a strange and mysterious (well, mysterious to me, as a beginner) error: result = func # oops, forgot to call the func answer = result + 1 # TypeError So I think that is a positive feature that we have to write parens after function declarations, even for zero-argument functions. I think it would make Python a lesser language to make that optional: - one more special case to memorise; - loss of a good, helpful reminder for beginners that parens are needed for both function definitions and function calls. And for what gain? Saving a couple of characters. It's not worth it.
In Python we have already adopted this. i.e parenthesis are optional in `if` statements, in class definition, in tuple etc
I think you are confused about these. Except for the class definition, where it is optional for backwards compatibility with Python 2 "classic classes", in all the other cases it isn't so much that parens are optional as that parens are not part of the syntax. You can *add* parens nearly everywhere, where they just act to group expressions:
if x == 1: # parenthesis are optional here pass
if (x) == (1): # parens are just used for grouping expressions if (x == 1): # still just used for grouping expressions In both cases, it's a waste of time to group the expressions, but it's not an error to do so.
class Greet: # now we don't explicitly inherit from `object` pass
This is a good example. In my opinion, I'm not actually happy that classes will *implicitly* inherit from object. But it is necessary for backwards compatibility.
Tuple = 1, 2, 3 # parenthesis are optional here too
Again, the parens are not part of the syntax for tuples, except for the zero-length tuple (), so they're only used for grouping. -- Steven

On 31 March 2016 at 14:57, Steven D'Aprano <steve@pearwood.info> wrote:
Because class definitions already do so? So, if it is possible to omit parentheses when inheriting from the default object when declaring a class, not needing parenthesis for default parameterless functions would not be an exception - it would be generalizing the idea of "Python admits less clutter". For that, I'd think of this a good idea - but I don't like changing the idea syntax in such a fundamental way - so I am +0 on this thing. I think this can be an interesting discussion - but I dislike people taking a ride on this to suggest omitting parentheses on function calls as well - that is totally broken. :-) js -><-

On Fri, Apr 1, 2016 at 1:37 PM, Joao S. O. Bueno <jsbueno@python.org.br> wrote:
Class definitions aren't quite the same thing. A function *must* have a set of arguments, and a function call *must* have a set of parameters. But you can think about a class definition without ever thinking about inheritance; the fact that all objects are instances of 'object' doesn't mean you have to say so every time you construct a class. When I explain classes and the "is-a" relationship to my students, it's easier to pretend that classes completely stand alone than to dig into the fact that, in Python's world, your Dog (subclass of Animal) is actually closely related to ValueError (subclass of Exception). If Python (or a style guide) mandated that classes MUST declare what they're subclassing, it would want to say "(object)", not "()". No class in Python 3 can truly have an empty inheritance list. ChrisA

Le 01/04/2016 04:37, Joao S. O. Bueno a écrit :
Yes, and because after more than a decade of Python, I still forget to type out the parenthesis some time, then go back and realize that it's silly that I have to since I don't with classes. That, and: - it's a common student error; - really it wouldn't hurt anyone. Is there really a strong case against it than just "it's not pure" ? I've seen of lot of this argument on the list lately and I find it counter productive. There are dozen of good way to oppose an idea, just saying "we got a moral stand to not do it" is not convincing. Espacially in a language with so many compromised like len(foo) instead of foo.len, functional paradigme and Poo and immutability and mutability, etc. Python has an history of making things to get out of the way: - no {} for indentation; - optional parentheses for tuples; - optional parenthesis for classes; If this changes does not hurt readability, ability to debug and doesn't make your code/program any worst than it was but does't help even a little, why not ?
+1. This is for another thread (that hope will die).

On 1 April 2016 at 12:49, Michel Desmoulin <desmoulinmichel@gmail.com> wrote:
You seem to have missed the argument that's been made a couple of times, which is that you would then have two ways of doing the same thing (empty parentheses would need to still be allowed for backward compatibility) and Python has a strong tradition of "there should only be one way of doing things". (Yes, it's not always followed 100%, as with any real life situation not everything is perfect). You may prefer to allow people to choose their own style and have options. But as a maintainer, I can confirm that I personally prefer code that I have to maintain to have a consistent style, and Python's lack of multiple ways to say the same thing is a benefit in ensuring that happens. So for me, your proposal would result in extra work, and no benefit (I would continue adding "()" as I find that style more readable and consistent). This is not a "moral stand". The "one way to do things" principle is a highly practical decision based on experience of different programming environments - Perl in particular allowed many ways of doing the same thing ("there's more than one way to do it" was a catch phrase in the Perl community) and it's an acknowledged fact that Perl code is hard to maintain as a consequence (unless strict style guidelines are imposed). As someone proposing a change to the Python language, the onus is on you to argue the benefits of your change, not on others to argue against it. If no-one does anything, Python won't change so you have to convince people. At the moment your argument is little more than "it looks neater", and opinions on that are clearly divided. As there's a *huge* amount of material that would need changing as a result of the change (documentation, training courses, style guides, IDEs, ...) you need a much better argument - and complaining that the people pointing out that your argument isn't strong enough are being "counter productive" is not helpful. If we're discussing "I've seen a lot of it on this list lately", then I would argue that there has been an awful lot of ideas proposed here recently which don't take into account the significant and genuine costs involved in *any* change to Python, and as a result don't even try to offer a justification for the proposal that is in proportion to the impact of the change. It's perfectly possible to propose a change here, have it supported, and get it implemented - but it needs *work*, and a lot of the discussions here are pointless because no-one is willing to do any work (not even the amount of work needed to convince the core developers that their proposal is worthwhile). It's very easy to accuse people of not being willing to listen to your proposals - but I challenge you to try to get a change like this included into C++ or Java, if you think that about Python! Paul

On Fri, Apr 01, 2016 at 01:49:03PM +0200, Michel Desmoulin wrote:
There are dozen of good way to oppose an idea, just saying "we got a moral stand to not do it" is not convincing.
Nobody has made that argument.
Espacially in a language with so many compromised like len(foo) instead of foo.len,
len(foo) isn't a compromise, it is an intentional feature.
functional paradigme and Poo and immutability and mutability, etc.
"Paradigm". You might not be aware that "poo" is an English euphemism for excrement, normally used for and by children. So I'm completely confused by what you mean by "and Poo".
Python has an history of making things to get out of the way:
There are many people who would say that Python's case sensitivity and significant indentation "get in the way".
- no {} for indentation; - optional parentheses for tuples;
No. Parentheses have nothing to do with tuples (except the empty tuple). Parentheses are used for *grouping*. Parens don't make tuples, and they aren't "optional" any more than parens are "optional" in addition because you can write `result = (a+b)`. The parens here have nothing to do with addition, and it would be misleading to say "optional parentheses for addition". Writing (1, 2, 3) is similar to writing ([1, 2, 3]) or ("abc") or (123). Apart from nested tuples, it's almost never needed.
- optional parenthesis for classes;
Needed for backwards compatibility. Let's not copy that misfeature into future misfeatures.
Who says that it doesn't hurt readability? My personal experience tells me that it DOES hurt readability, at least a little, and adds confusion to the rules of what needs parens when and what doesn't. You might not agree with my personal experience, but you shouldn't just dismiss it or misrepresent it as a "moral stand". My argument cuts right to the core of the argument that making parens optional helps -- my experience is that it *doesn't help*, it actually HURTS. -- Steve

On 4/1/2016 7:49 AM, Michel Desmoulin wrote:
Yes, and because after more than a decade of Python, I still forget to type out the parenthesis some time,
Only in function definitions, or also in function calls. then go back and realize that it's
silly that I have to since I don't with classes.
The parallel in invalid. To repeat what I said in the my initial response and what others have said: the header in a def statement shows now to call the function (the signature). The header in a class statement does no such thing. The () in a def statement represent the call operator. The () is a class statement do not. There serve a visual grouping and subordination purpose. "class mystring(str)" does not say anything about how to use mystring as a callable.
Is there really a strong case against it
Yes, as has been presented before, but ignored by proponents. For one: I believe that omitting () in def will encourage people to even more ofter omit () in calls, when needed, and that is BAD. I consider this a killer argument against it.
than just "it's not pure" ?
I have seen this too often. Practical arguments against a proposal are either ignored or wrongly dismissed as 'purity arguments'. To me, this makes the discussion useless. -- Terry Jan Reedy

On 3/31/2016 12:29 PM, Mahan Marwat wrote: Forwarded from Adnan Khan
I have an idea of making parenthesis optional for functions having no parameters. i.e
I presume you mean only in function definitions and not in function calls.
def greet: # note the missing parenthesis print('hello')
-1 This will lead people to think even more often than they do now that they can omit () in the call.
In Python we have already adopted this. i.e parenthesis are optional in `if` statements, in class definition, in tuple etc
Irrelevant. *Every* expression can be optionally enclosed in (). The () used to delimit the scope of operators is somewhat different from identifier(args) used to indicate a call and the scope of the argument list.
if x == 1: # parenthesis are optional here pass
They are optional because they are irrelevant. The above is the same as 'if ((((((((x==1)))))))):pass'. The extraneous ()s are deleted. However, greet() != greet(()) as the inner () is not deleted but passed as an empty tuple, which raises TypeError. -- Terry Jan Reedy

On 31.03.2016 20:06, Terry Reedy wrote:
Interesting that you mentioned it. Doesn't Ruby handle it this way? Let's see how this would look like in Python: def distance of point1, point2: # Pythagoras point1 = (3, 1) point2 = (1, 4) print distance of point1, point2 Hmmm. Although I like the lightness of this, it's somewhat confusing, isn't? Best, Sven

(Let's hope I'm doing this right) … Hmmm. Although I like the lightness of this, it's somewhat confusing, isn't? It would also lead to parse errors, or alternatively parentheses being required sometimes in the case of function calls as arguments Take as an example a function with two functions being called as the arguments: f(x(y, z), a(b, c)) with parentheses, however without you get f of x of y z a of b c in the second case its ambiguous if f is a function on 3 arguments or two. In other words, is the function f(x(y, z), a(b, c)) or f(x(y, z), a(b), c)? This is also all against the Zen. There should be one-- and preferably only one --obvious way to do it. Regards, Josh On Thu, Mar 31, 2016 at 4:57 PM Sven R. Kunze <srkunze@mail.de> wrote:

I born in 1994. So, no chance of suggestion in 1991. It is not about the keystrokes. Its about the visual cluttering. (and yes it can save two keystrokes too and also four on Seven R. Kuze keyboard :-) ) As I have been stated in the Subject. My idea is only about function definition, not function calling.
For readability (Readability counts).
Some people argued that function definition with parenthesis seems to them natural. But actually it seems to us natural, because we have been used to it a-lot. IMHO parenthesisless functions definitions are natural and readable. The Zen also says:
I think empty parenthesis for no apparent reason does not make any sense. When I was a beginner, I found that it was very helpful that I *always*
needed to use parens after functions:
We are beginner only for once and expert for life. Between you can asked in your novice level, that why there are empty parenthesis if a function don't have parameters?

On Fri, Apr 01, 2016 at 05:12:56AM +0500, Mahan Marwat wrote:
What makes you think that removing the parens increases readability? I think it *decreases* readability, because now there is a inconstency between the zero argument case and every single other case. Now the reader looks at function definitions and every single function definition has the same pattern: def name ( parameter-list ) : (where the parameter-list might have one parameter, or ten, or zero). With your proposal the reader will *nearly always* see the consistent pattern: def name ( parameter-list ) : but very occasionally, maybe one time in a hundred functions, or a thousand, see: def name : and be surprised. Even if it is just for a millisecond, that doesn't help readability, it hurts it.
Yes yes, you said those exact same words before. I disagree the first time you said it, and I still disagree now.
Of course it makes sense. The parameter list is empty. How do you get an empty list? With list delimiters with nothing inside them. Are you confused by "thelist = []"? Function parameter lists use round brackets instead of square brackets, but otherwise are the same. An empty parameter list is indicated by empty parameter list delimiters.
If I claim to be an expert, but am confused by an empty parameter list, then I shouldn't be surprised if others wonder how expert I actually am. This matter boils down to a question of taste. You apparently don't like the look of "def spam()", I do. I think my experience supports the current requirement, you think that it hurts readability, I don't. Unless you can give some objective evidence that it hurts readability, you aren't going to convince me.
Between you can asked in your novice level, that why there are empty parenthesis if a function don't have parameters?
Because the list of parameters is empty. -- Steve

Hmm, The fact that the class definition doesn't require empty parentheses works against a few of these arguments. I like Mahan's idea and don't find it confusing, though I agree it isn't a big pain point either way. -Mike On 2016-03-31 17:43, Steven D'Aprano wrote:
parenthesis if a function don't have parameters? Because the list of parameters is empty.

Mike Miller <python-ideas@...> writes:
There is a difference. Classes can be used like C-structs:
In order to use equational reasoning, functions need the empty argument list in the definition:
Read: We define f, when applied to the empty argument list, to equal 10 * 20. f by itself does not equal 10 * 20. It is a function symbol. Stefan Krah

On 3/31/2016 8:43 PM, Steven D'Aprano wrote:
In addition to all of Steven's points, it's just way, way to late for this change. I don't see us ever changing Python to allow (or require!) you to omit the parens on a function definition with no parameters. For backward compatibility, you'd have to allow the parens. And then what's the point in having two ways to do the same thing? You'd just be creating confusion. Eric.

On 01.04.2016 07:46, Eric V. Smith wrote:
And then what's the point in having two ways to do the same thing? You'd just be creating confusion.
Class definitions allows this, function definitions don't? I'd call this confusing. Best, Sven

On 01.04.2016 02:43, Steven D'Aprano wrote:
I disagree. I remember this "issue" with decorators as well. @property def foo.... @lru_cache() # really? def bar... All decorators created with context_manager have this behavior. The proposal is about removing () for function definitions, so this differs. However, decorators have a very declarative style as do function definitions. So what do those special characters serve? IMHO It's just visual clutter. Best, Sven

On 4/1/2016 5:25 AM, Sven R. Kunze wrote:
There is a sematic difference between the two examples. The ()s are not optional. 'property' is a decorator that is applied to foo after it is defined. 'lru_cache()' is a function call that returns a decorator. Quite different. -- Terry Jan Reedy

On 01.04.2016 11:52, Terry Reedy wrote:
@Terry Thanks for snipping away the relevant explanation and not addressing my point. >.< @others Never said it were optional. Decorating and function definitions have a declarative style in common. The point was that these () don't serve anything in case of declarations. Best, Sven

On 04/01/2016 03:10 AM, Sven R. Kunze wrote:
Your "point" appears to be that ()s are optional in the case of decorators, and they are not -- decorators don't need them, and can't have them*, while functions that return a decorator do need them and must have them. If you meant something else please offer a better explanation -- no need to be snide with Terry. -- ~Ethan~ * Okay, it is possible to write a decorator that works either with or without parens, but it's a pain, not general-purpose, and can be confusing to use.

On Thu, Mar 31, 2016 at 10:49:47PM +0200, Sven R. Kunze wrote:
I don't know that Ruby allows function calls like that. It doesn't work in Ruby 1.8, which is the most recent version I have installed: steve@orac:~$ irb irb(main):001:0> def foo(x) irb(main):002:1> return x+1 irb(main):003:1> end => nil irb(main):004:0> foo(7) => 8 irb(main):005:0> foo of 7 NoMethodError: undefined method `of' for main:Object from (irb):5 from :0 irb(main):006:0> However, Hypertalk, and other similar "XTalk" languages, do. Function calls in Hypertalk generally have a long form and a short form. The long form will be something like: total = the sum of field "expenses" while the short form is the more familiar: total = sum(field "expenses") Although Hypercard only allowed the long form if there was exactly one argument.
Hmmm. Although I like the lightness of this, it's somewhat confusing, isn't?
In Hypertalk, it worked very well. But I wouldn't think it would be a good fit to Python. In a previous email, Sven also wrote:
I think the keystrokes are less important than the visual clutter one have with those parentheses.
I don't think they introduce "visual clutter" to the function. I think they make it explicit and clear that the function has no arguments. That's not clutter. When I was learning Python, I found it hard to remember when I needed parens and when I didn't, because the inconsistency between class and def confused me. I would write `class X()` or `def spam` and get a syntax error (this was back in Python 1.5). My own experience tells me strongly that the inconsistency between: class X: # must not use parens in Python 1.5 class Y(X): # must use parens and the inconsistency between class and def was harmful. If I could, I'd make parens mandatory for both. So I think that making parens optional for functions doesn't simplify the syntax so much as make the syntax *more complicated* and therefore harder to learn. And I do not agree that the empty parens are "clutter" or make the function definition harder to read. -- Steve

On 01.04.2016 02:27, Steven D'Aprano wrote:
The 'of' was just off the top of my head. You shouldn't take that too literally. http://www.howtogeek.com/howto/programming/ruby/ruby-function-method-syntax/ It works without the 'of'.
Interesting. I think I will have a look at Hypertalk. :) Why do you think it would not fit into Python?
Interesting view. It never occurred to me that this might be a problem. But I started with a later Python version. So, it was just no a problem because both is possible now. Best, Sven

On Fri, Apr 01, 2016 at 11:32:00AM +0200, Sven R. Kunze wrote:
Unfortunately, Hypertalk is long dead. Apple never quite understood why it was popular, or what to do with it. But it influenced the design of the WWW and Javascript, and it lives on in a couple of languages such as OpenXion and LiveCode: https://github.com/kreativekorp/openxion https://livecode.com/download/ (LiveCode has a booming user community, OpenXion is all but dead, but it works and lets you experiment with the language.) If you have an old Classic Mac capable of running System 6 through 9 (pre OS X), or an emulator for the same, then you might be able to run Hypercard, which was a sort of combined software development kit, Rolodex application, and IDE. Hypercard was the GUI to the Hypertalk language, and Hypertalk was the scripting language that controlled the Hypercard GUI. https://en.wikipedia.org/wiki/HyperCard
Why do you think it would not fit into Python?
Hypertalk's execution model, data model and syntax are all very different from Python's. Hypertalk was also linked very heavily to the GUI, which makes it a relatively weak fit with less specialised languages like Python. But mostly, Python already has a standard syntax for calling functions: value = function(arg) There's no need to add a more verbose "the function of arg" syntax. -- Steve

I have an idea of making parenthesis optional for functions having no
Mahan Marwat <mahanmarwat@...> writes: parameters. i.e
def greet: # note the missing parenthesis print('hello')
This is an interesting idea, but it does not play well with the concept of function evaluation and higher order functions. Evaluation of functions is triggered when they're applied to something:
If a function does not take any arguments, it must be eagerly evaluated when it is stored in a list. There is an exception: OCaml allows argument-less *methods*: let greeterInTheKingdomOfNouns = object method greet = print_string "hello\n" end;; val greeterInTheKingdomOfNouns : < greet : unit > = <obj> # greeterInTheKingdomOfNouns#greet;; hello - : unit = () This is different though: Here one sends the message "greet" to the object "greeterInTheKingdomOfNouns", so function application is replaced by message passing. In short, these argument-less functions are amusing but not so useful in practice. Stefan Krah

Alexander Walters <tritium-list@sdamon.com> writes:
are the two extra keystrokes really a problem?
Who said the keystrokes are a problem? Not the original poster. Instead, the issue raised is of readability:
No mention of keystrokes. I'm endlessly disappointed that discussions of “too much noise in the code” are mis-interpreted as *only* about writing, not about reading. -- \ “Always do right. This will gratify some people, and astonish | `\ the rest.” —Mark Twain | _o__) | Ben Finney

On 3/31/2016 19:22, Ben Finney wrote:
There are four pieces of information in the first line of that definition. It starts with the keyword at the beginning of the line. Readers of languages that are left to right will instantly know they are in a function definition. The next piece of information is the identifier that the function will be assigned too, and that is clearly defined right there. The proposal would not change this. The third is the argument list, in this case an empty one. The fourth is the 'block delimiter' for lack of anything better for me to call it. As this example sits, that line should be read as "define a function named foo that explicitly takes no arguments with the following code." Omitting the parens changes the way it reads to something along the lines of "define a function named foo with the following code." The proposal has removed vital visual information. I said earlier that if this suggestion was made in 1991 it should have been accepted to make functions more consistent with classes. I have changed my mind; in 1991 classes should have been corrected to always require parens.

On 2 April 2016 at 00:36, Alexander Walters <tritium-list@sdamon.com> wrote:
In fact, the one change made in this area since then was to *permit* empty parens on class definitions back in Python 2.5: https://hg.python.org/cpython/rev/a0d3f773543d Prior to that, the empty parens were mandatory for functions and explicitly disallowed for classes. Making them mandatory for classes would break too much code for not enough benefit, while making them optional for functions would introduce an additional stylistic choice with no demonstrable benefit to code maintainability, and a clear disadvantage in creating a new opportunity for style inconsistencies. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Thu, Mar 31, 2016 at 09:29:36PM +0500, Mahan Marwat wrote:
-1 I don't think that the benefit (two fewer characters to type) is worth the effort of learning the special case. Right now, the rule is simple: the def keyword ALWAYS needs parentheses after the name of the function, regardless of whether there is one argumemt, two arguments, twenty arguments, or zero arguments. Why treat zero as special?
The less awkward characters we have, the more readable our code will be (Beautiful is better then ugly).
I don't think that function declarations missing the parens are more beautiful than them with the parens. The Zen also says: Special cases aren't special enough to break the rules. Why do you think that zero-argument functions are special enough to justify breaking the rules? Just to save two characters?
When I was a beginner, I found that it was very helpful that I *always* needed to use parens after functions: def func(): ... # later result = func() Otherwise I would forget the parens, and get a syntax error: def func: ... or a strange and mysterious (well, mysterious to me, as a beginner) error: result = func # oops, forgot to call the func answer = result + 1 # TypeError So I think that is a positive feature that we have to write parens after function declarations, even for zero-argument functions. I think it would make Python a lesser language to make that optional: - one more special case to memorise; - loss of a good, helpful reminder for beginners that parens are needed for both function definitions and function calls. And for what gain? Saving a couple of characters. It's not worth it.
In Python we have already adopted this. i.e parenthesis are optional in `if` statements, in class definition, in tuple etc
I think you are confused about these. Except for the class definition, where it is optional for backwards compatibility with Python 2 "classic classes", in all the other cases it isn't so much that parens are optional as that parens are not part of the syntax. You can *add* parens nearly everywhere, where they just act to group expressions:
if x == 1: # parenthesis are optional here pass
if (x) == (1): # parens are just used for grouping expressions if (x == 1): # still just used for grouping expressions In both cases, it's a waste of time to group the expressions, but it's not an error to do so.
class Greet: # now we don't explicitly inherit from `object` pass
This is a good example. In my opinion, I'm not actually happy that classes will *implicitly* inherit from object. But it is necessary for backwards compatibility.
Tuple = 1, 2, 3 # parenthesis are optional here too
Again, the parens are not part of the syntax for tuples, except for the zero-length tuple (), so they're only used for grouping. -- Steven

On 31 March 2016 at 14:57, Steven D'Aprano <steve@pearwood.info> wrote:
Because class definitions already do so? So, if it is possible to omit parentheses when inheriting from the default object when declaring a class, not needing parenthesis for default parameterless functions would not be an exception - it would be generalizing the idea of "Python admits less clutter". For that, I'd think of this a good idea - but I don't like changing the idea syntax in such a fundamental way - so I am +0 on this thing. I think this can be an interesting discussion - but I dislike people taking a ride on this to suggest omitting parentheses on function calls as well - that is totally broken. :-) js -><-

On Fri, Apr 1, 2016 at 1:37 PM, Joao S. O. Bueno <jsbueno@python.org.br> wrote:
Class definitions aren't quite the same thing. A function *must* have a set of arguments, and a function call *must* have a set of parameters. But you can think about a class definition without ever thinking about inheritance; the fact that all objects are instances of 'object' doesn't mean you have to say so every time you construct a class. When I explain classes and the "is-a" relationship to my students, it's easier to pretend that classes completely stand alone than to dig into the fact that, in Python's world, your Dog (subclass of Animal) is actually closely related to ValueError (subclass of Exception). If Python (or a style guide) mandated that classes MUST declare what they're subclassing, it would want to say "(object)", not "()". No class in Python 3 can truly have an empty inheritance list. ChrisA

Le 01/04/2016 04:37, Joao S. O. Bueno a écrit :
Yes, and because after more than a decade of Python, I still forget to type out the parenthesis some time, then go back and realize that it's silly that I have to since I don't with classes. That, and: - it's a common student error; - really it wouldn't hurt anyone. Is there really a strong case against it than just "it's not pure" ? I've seen of lot of this argument on the list lately and I find it counter productive. There are dozen of good way to oppose an idea, just saying "we got a moral stand to not do it" is not convincing. Espacially in a language with so many compromised like len(foo) instead of foo.len, functional paradigme and Poo and immutability and mutability, etc. Python has an history of making things to get out of the way: - no {} for indentation; - optional parentheses for tuples; - optional parenthesis for classes; If this changes does not hurt readability, ability to debug and doesn't make your code/program any worst than it was but does't help even a little, why not ?
+1. This is for another thread (that hope will die).

On 1 April 2016 at 12:49, Michel Desmoulin <desmoulinmichel@gmail.com> wrote:
You seem to have missed the argument that's been made a couple of times, which is that you would then have two ways of doing the same thing (empty parentheses would need to still be allowed for backward compatibility) and Python has a strong tradition of "there should only be one way of doing things". (Yes, it's not always followed 100%, as with any real life situation not everything is perfect). You may prefer to allow people to choose their own style and have options. But as a maintainer, I can confirm that I personally prefer code that I have to maintain to have a consistent style, and Python's lack of multiple ways to say the same thing is a benefit in ensuring that happens. So for me, your proposal would result in extra work, and no benefit (I would continue adding "()" as I find that style more readable and consistent). This is not a "moral stand". The "one way to do things" principle is a highly practical decision based on experience of different programming environments - Perl in particular allowed many ways of doing the same thing ("there's more than one way to do it" was a catch phrase in the Perl community) and it's an acknowledged fact that Perl code is hard to maintain as a consequence (unless strict style guidelines are imposed). As someone proposing a change to the Python language, the onus is on you to argue the benefits of your change, not on others to argue against it. If no-one does anything, Python won't change so you have to convince people. At the moment your argument is little more than "it looks neater", and opinions on that are clearly divided. As there's a *huge* amount of material that would need changing as a result of the change (documentation, training courses, style guides, IDEs, ...) you need a much better argument - and complaining that the people pointing out that your argument isn't strong enough are being "counter productive" is not helpful. If we're discussing "I've seen a lot of it on this list lately", then I would argue that there has been an awful lot of ideas proposed here recently which don't take into account the significant and genuine costs involved in *any* change to Python, and as a result don't even try to offer a justification for the proposal that is in proportion to the impact of the change. It's perfectly possible to propose a change here, have it supported, and get it implemented - but it needs *work*, and a lot of the discussions here are pointless because no-one is willing to do any work (not even the amount of work needed to convince the core developers that their proposal is worthwhile). It's very easy to accuse people of not being willing to listen to your proposals - but I challenge you to try to get a change like this included into C++ or Java, if you think that about Python! Paul

On Fri, Apr 01, 2016 at 01:49:03PM +0200, Michel Desmoulin wrote:
There are dozen of good way to oppose an idea, just saying "we got a moral stand to not do it" is not convincing.
Nobody has made that argument.
Espacially in a language with so many compromised like len(foo) instead of foo.len,
len(foo) isn't a compromise, it is an intentional feature.
functional paradigme and Poo and immutability and mutability, etc.
"Paradigm". You might not be aware that "poo" is an English euphemism for excrement, normally used for and by children. So I'm completely confused by what you mean by "and Poo".
Python has an history of making things to get out of the way:
There are many people who would say that Python's case sensitivity and significant indentation "get in the way".
- no {} for indentation; - optional parentheses for tuples;
No. Parentheses have nothing to do with tuples (except the empty tuple). Parentheses are used for *grouping*. Parens don't make tuples, and they aren't "optional" any more than parens are "optional" in addition because you can write `result = (a+b)`. The parens here have nothing to do with addition, and it would be misleading to say "optional parentheses for addition". Writing (1, 2, 3) is similar to writing ([1, 2, 3]) or ("abc") or (123). Apart from nested tuples, it's almost never needed.
- optional parenthesis for classes;
Needed for backwards compatibility. Let's not copy that misfeature into future misfeatures.
Who says that it doesn't hurt readability? My personal experience tells me that it DOES hurt readability, at least a little, and adds confusion to the rules of what needs parens when and what doesn't. You might not agree with my personal experience, but you shouldn't just dismiss it or misrepresent it as a "moral stand". My argument cuts right to the core of the argument that making parens optional helps -- my experience is that it *doesn't help*, it actually HURTS. -- Steve

On 4/1/2016 7:49 AM, Michel Desmoulin wrote:
Yes, and because after more than a decade of Python, I still forget to type out the parenthesis some time,
Only in function definitions, or also in function calls. then go back and realize that it's
silly that I have to since I don't with classes.
The parallel in invalid. To repeat what I said in the my initial response and what others have said: the header in a def statement shows now to call the function (the signature). The header in a class statement does no such thing. The () in a def statement represent the call operator. The () is a class statement do not. There serve a visual grouping and subordination purpose. "class mystring(str)" does not say anything about how to use mystring as a callable.
Is there really a strong case against it
Yes, as has been presented before, but ignored by proponents. For one: I believe that omitting () in def will encourage people to even more ofter omit () in calls, when needed, and that is BAD. I consider this a killer argument against it.
than just "it's not pure" ?
I have seen this too often. Practical arguments against a proposal are either ignored or wrongly dismissed as 'purity arguments'. To me, this makes the discussion useless. -- Terry Jan Reedy

On 3/31/2016 12:29 PM, Mahan Marwat wrote: Forwarded from Adnan Khan
I have an idea of making parenthesis optional for functions having no parameters. i.e
I presume you mean only in function definitions and not in function calls.
def greet: # note the missing parenthesis print('hello')
-1 This will lead people to think even more often than they do now that they can omit () in the call.
In Python we have already adopted this. i.e parenthesis are optional in `if` statements, in class definition, in tuple etc
Irrelevant. *Every* expression can be optionally enclosed in (). The () used to delimit the scope of operators is somewhat different from identifier(args) used to indicate a call and the scope of the argument list.
if x == 1: # parenthesis are optional here pass
They are optional because they are irrelevant. The above is the same as 'if ((((((((x==1)))))))):pass'. The extraneous ()s are deleted. However, greet() != greet(()) as the inner () is not deleted but passed as an empty tuple, which raises TypeError. -- Terry Jan Reedy

On 31.03.2016 20:06, Terry Reedy wrote:
Interesting that you mentioned it. Doesn't Ruby handle it this way? Let's see how this would look like in Python: def distance of point1, point2: # Pythagoras point1 = (3, 1) point2 = (1, 4) print distance of point1, point2 Hmmm. Although I like the lightness of this, it's somewhat confusing, isn't? Best, Sven

(Let's hope I'm doing this right) … Hmmm. Although I like the lightness of this, it's somewhat confusing, isn't? It would also lead to parse errors, or alternatively parentheses being required sometimes in the case of function calls as arguments Take as an example a function with two functions being called as the arguments: f(x(y, z), a(b, c)) with parentheses, however without you get f of x of y z a of b c in the second case its ambiguous if f is a function on 3 arguments or two. In other words, is the function f(x(y, z), a(b, c)) or f(x(y, z), a(b), c)? This is also all against the Zen. There should be one-- and preferably only one --obvious way to do it. Regards, Josh On Thu, Mar 31, 2016 at 4:57 PM Sven R. Kunze <srkunze@mail.de> wrote:

I born in 1994. So, no chance of suggestion in 1991. It is not about the keystrokes. Its about the visual cluttering. (and yes it can save two keystrokes too and also four on Seven R. Kuze keyboard :-) ) As I have been stated in the Subject. My idea is only about function definition, not function calling.
For readability (Readability counts).
Some people argued that function definition with parenthesis seems to them natural. But actually it seems to us natural, because we have been used to it a-lot. IMHO parenthesisless functions definitions are natural and readable. The Zen also says:
I think empty parenthesis for no apparent reason does not make any sense. When I was a beginner, I found that it was very helpful that I *always*
needed to use parens after functions:
We are beginner only for once and expert for life. Between you can asked in your novice level, that why there are empty parenthesis if a function don't have parameters?

On Fri, Apr 01, 2016 at 05:12:56AM +0500, Mahan Marwat wrote:
What makes you think that removing the parens increases readability? I think it *decreases* readability, because now there is a inconstency between the zero argument case and every single other case. Now the reader looks at function definitions and every single function definition has the same pattern: def name ( parameter-list ) : (where the parameter-list might have one parameter, or ten, or zero). With your proposal the reader will *nearly always* see the consistent pattern: def name ( parameter-list ) : but very occasionally, maybe one time in a hundred functions, or a thousand, see: def name : and be surprised. Even if it is just for a millisecond, that doesn't help readability, it hurts it.
Yes yes, you said those exact same words before. I disagree the first time you said it, and I still disagree now.
Of course it makes sense. The parameter list is empty. How do you get an empty list? With list delimiters with nothing inside them. Are you confused by "thelist = []"? Function parameter lists use round brackets instead of square brackets, but otherwise are the same. An empty parameter list is indicated by empty parameter list delimiters.
If I claim to be an expert, but am confused by an empty parameter list, then I shouldn't be surprised if others wonder how expert I actually am. This matter boils down to a question of taste. You apparently don't like the look of "def spam()", I do. I think my experience supports the current requirement, you think that it hurts readability, I don't. Unless you can give some objective evidence that it hurts readability, you aren't going to convince me.
Between you can asked in your novice level, that why there are empty parenthesis if a function don't have parameters?
Because the list of parameters is empty. -- Steve

Hmm, The fact that the class definition doesn't require empty parentheses works against a few of these arguments. I like Mahan's idea and don't find it confusing, though I agree it isn't a big pain point either way. -Mike On 2016-03-31 17:43, Steven D'Aprano wrote:
parenthesis if a function don't have parameters? Because the list of parameters is empty.

Mike Miller <python-ideas@...> writes:
There is a difference. Classes can be used like C-structs:
In order to use equational reasoning, functions need the empty argument list in the definition:
Read: We define f, when applied to the empty argument list, to equal 10 * 20. f by itself does not equal 10 * 20. It is a function symbol. Stefan Krah

On 3/31/2016 8:43 PM, Steven D'Aprano wrote:
In addition to all of Steven's points, it's just way, way to late for this change. I don't see us ever changing Python to allow (or require!) you to omit the parens on a function definition with no parameters. For backward compatibility, you'd have to allow the parens. And then what's the point in having two ways to do the same thing? You'd just be creating confusion. Eric.

On 01.04.2016 07:46, Eric V. Smith wrote:
And then what's the point in having two ways to do the same thing? You'd just be creating confusion.
Class definitions allows this, function definitions don't? I'd call this confusing. Best, Sven

On 01.04.2016 02:43, Steven D'Aprano wrote:
I disagree. I remember this "issue" with decorators as well. @property def foo.... @lru_cache() # really? def bar... All decorators created with context_manager have this behavior. The proposal is about removing () for function definitions, so this differs. However, decorators have a very declarative style as do function definitions. So what do those special characters serve? IMHO It's just visual clutter. Best, Sven

On 4/1/2016 5:25 AM, Sven R. Kunze wrote:
There is a sematic difference between the two examples. The ()s are not optional. 'property' is a decorator that is applied to foo after it is defined. 'lru_cache()' is a function call that returns a decorator. Quite different. -- Terry Jan Reedy

On 01.04.2016 11:52, Terry Reedy wrote:
@Terry Thanks for snipping away the relevant explanation and not addressing my point. >.< @others Never said it were optional. Decorating and function definitions have a declarative style in common. The point was that these () don't serve anything in case of declarations. Best, Sven

On 04/01/2016 03:10 AM, Sven R. Kunze wrote:
Your "point" appears to be that ()s are optional in the case of decorators, and they are not -- decorators don't need them, and can't have them*, while functions that return a decorator do need them and must have them. If you meant something else please offer a better explanation -- no need to be snide with Terry. -- ~Ethan~ * Okay, it is possible to write a decorator that works either with or without parens, but it's a pain, not general-purpose, and can be confusing to use.

On Thu, Mar 31, 2016 at 10:49:47PM +0200, Sven R. Kunze wrote:
I don't know that Ruby allows function calls like that. It doesn't work in Ruby 1.8, which is the most recent version I have installed: steve@orac:~$ irb irb(main):001:0> def foo(x) irb(main):002:1> return x+1 irb(main):003:1> end => nil irb(main):004:0> foo(7) => 8 irb(main):005:0> foo of 7 NoMethodError: undefined method `of' for main:Object from (irb):5 from :0 irb(main):006:0> However, Hypertalk, and other similar "XTalk" languages, do. Function calls in Hypertalk generally have a long form and a short form. The long form will be something like: total = the sum of field "expenses" while the short form is the more familiar: total = sum(field "expenses") Although Hypercard only allowed the long form if there was exactly one argument.
Hmmm. Although I like the lightness of this, it's somewhat confusing, isn't?
In Hypertalk, it worked very well. But I wouldn't think it would be a good fit to Python. In a previous email, Sven also wrote:
I think the keystrokes are less important than the visual clutter one have with those parentheses.
I don't think they introduce "visual clutter" to the function. I think they make it explicit and clear that the function has no arguments. That's not clutter. When I was learning Python, I found it hard to remember when I needed parens and when I didn't, because the inconsistency between class and def confused me. I would write `class X()` or `def spam` and get a syntax error (this was back in Python 1.5). My own experience tells me strongly that the inconsistency between: class X: # must not use parens in Python 1.5 class Y(X): # must use parens and the inconsistency between class and def was harmful. If I could, I'd make parens mandatory for both. So I think that making parens optional for functions doesn't simplify the syntax so much as make the syntax *more complicated* and therefore harder to learn. And I do not agree that the empty parens are "clutter" or make the function definition harder to read. -- Steve

On 01.04.2016 02:27, Steven D'Aprano wrote:
The 'of' was just off the top of my head. You shouldn't take that too literally. http://www.howtogeek.com/howto/programming/ruby/ruby-function-method-syntax/ It works without the 'of'.
Interesting. I think I will have a look at Hypertalk. :) Why do you think it would not fit into Python?
Interesting view. It never occurred to me that this might be a problem. But I started with a later Python version. So, it was just no a problem because both is possible now. Best, Sven

On Fri, Apr 01, 2016 at 11:32:00AM +0200, Sven R. Kunze wrote:
Unfortunately, Hypertalk is long dead. Apple never quite understood why it was popular, or what to do with it. But it influenced the design of the WWW and Javascript, and it lives on in a couple of languages such as OpenXion and LiveCode: https://github.com/kreativekorp/openxion https://livecode.com/download/ (LiveCode has a booming user community, OpenXion is all but dead, but it works and lets you experiment with the language.) If you have an old Classic Mac capable of running System 6 through 9 (pre OS X), or an emulator for the same, then you might be able to run Hypercard, which was a sort of combined software development kit, Rolodex application, and IDE. Hypercard was the GUI to the Hypertalk language, and Hypertalk was the scripting language that controlled the Hypercard GUI. https://en.wikipedia.org/wiki/HyperCard
Why do you think it would not fit into Python?
Hypertalk's execution model, data model and syntax are all very different from Python's. Hypertalk was also linked very heavily to the GUI, which makes it a relatively weak fit with less specialised languages like Python. But mostly, Python already has a standard syntax for calling functions: value = function(arg) There's no need to add a more verbose "the function of arg" syntax. -- Steve

I have an idea of making parenthesis optional for functions having no
Mahan Marwat <mahanmarwat@...> writes: parameters. i.e
def greet: # note the missing parenthesis print('hello')
This is an interesting idea, but it does not play well with the concept of function evaluation and higher order functions. Evaluation of functions is triggered when they're applied to something:
If a function does not take any arguments, it must be eagerly evaluated when it is stored in a list. There is an exception: OCaml allows argument-less *methods*: let greeterInTheKingdomOfNouns = object method greet = print_string "hello\n" end;; val greeterInTheKingdomOfNouns : < greet : unit > = <obj> # greeterInTheKingdomOfNouns#greet;; hello - : unit = () This is different though: Here one sends the message "greet" to the object "greeterInTheKingdomOfNouns", so function application is replaced by message passing. In short, these argument-less functions are amusing but not so useful in practice. Stefan Krah
participants (16)
-
Alexander Walters
-
Ben Finney
-
Chris Angelico
-
Eric V. Smith
-
Ethan Furman
-
Joao S. O. Bueno
-
Joshua Morton
-
Mahan Marwat
-
Michel Desmoulin
-
Mike Miller
-
Nick Coghlan
-
Paul Moore
-
Stefan Krah
-
Steven D'Aprano
-
Sven R. Kunze
-
Terry Reedy