开发者

Why does java/javascript/python force the use of () after a method name, even if it takes no arguments?

开发者 https://www.devze.com 2023-01-16 22:18 出处:网络
One of my most common bugs is that I can never remember whether something is a method or a property, so I\'m constantly adding or removing parentheses.

One of my most common bugs is that I can never remember whether something is a method or a property, so I'm constantly adding or removing parentheses.

So I was wondering if there was good logic behind making the difference between calling on an object's properties and methods explicit.

Obviously, it allows you to have properties and methods that share the same name, but I don't think that comes up much.

The only big benefit I can come up with is readability. Sometimes you might want to know whether something is a method or a property while you're looking at code, but I'm having trouble coming up with specific examples when that would be really helpful. Bu开发者_C百科t I am a n00b, so I probably just haven't encountered such a situation yet. I'd appreciate examples of such a situation.

Also, are there other languages where the difference isn't explicit?

Anyways, if you could answer, it will help me be less annoyed every time I make this mistake ^-^.

UPDATE: Thanks everyone for the awesome answers so far! I only have about a week's worth of js, and 1 day of python, so I had no idea you could reference functions without calling them. That's awesome. I have a little more experience with java, so that's where I was mostly coming from... can anyone come up with an equally compelling argument for that to be the case in java, where you can't reference functions? Aside from it being a very explicit language, with all the benefits that entails :).


All modern languages require this because referencing a function and calling a function are separate actions.

For example,

def func():
    print "hello"
    return 10
a = func
a()

Clearly, a = func and a = func() have very different meanings.

Ruby--the most likely language you're thinking of in contrast--doesn't require the parentheses; it can do this because it doesn't support taking references to functions.


In languages like Python and JavaScript, functions are first–class objects. This means that you can pass functions around, just like you can pass around any other value. The parentheses after the function name (the () in myfunc()) actually constitute an operator, just like + or *. Instead of meaning "add this number to another number" (in the case of +), () means "execute the preceding function". This is necessary because it is possible to use a function without executing it. For example, you may wish to compare it to another function using ==, or you may wish to pass it into another function, such as in this JavaScript example:

function alertSomething(message) {
    alert(message);
}

function myOtherFunction(someFunction, someArg) {
   someFunction(someArg);
}

// here we are using the alertSomething function without calling it directly
myOtherFunction(alertSomething, "Hello, araneae!"); 

In short: it is important to be able to refer to a function without calling it — this is why the distinction is necessary.


At least in JS, its because you can pass functions around.

var func = new Function();

you can then so something like

 var f = func
 f()

so 'f' and 'func' are references to the function, and f() or func() is the invocation of the function.

which is not the same as

var val = f();

which assigns the result of the invocation to a var.

For Java, you cannot pass functions around, at least like you can in JS, so there is no reason the language needs to require a () to invoke a method. But it is what it is.

I can't speak at all for python.

But the main point is different languages might have reasons why syntax may be necessary, and sometimes syntax is just syntax.


I think you answered it yourself:

One of my most common bugs is that I can never remember whether something is a method or a property, so I'm constantly adding or removing parentheses.

Consider the following:

if (colorOfTheSky == 'blue')

vs:

if (colorOfTheSky() == 'blue')

We can tell just by looking that the first checks for a variable called colorOfTheSky, and we want to know if its value is blue. In the second, we know that colorOfTheSky() calls a function (method) and we want to know if its return value is blue.

If we didn't have this distinction it would be extremely ambiguous in situations like this.

To answer your last question, I don't know of any languages that don't have this distinction.

Also, you probably have a design problem if you can't tell the difference between your methods and your properties; as another answer points out, methods and properties have different roles to play. Furthermore it is good practice for your method names to be actions, e.g. getPageTitle, getUserId, etc., and for your properties to be nouns, e.g., pageTitle, userId. These should be easily decipherable in your code for both you and anyone who comes along later and reads your code.


If you're having troubles, distinguishing between your properties and methods, you're probably not naming them very well.

In general, your methods should have a verb in them: i.e. write, print, echo, open, close, get, set, and property names should be nouns or adjectives: name, color, filled, loaded.

It's very important to use meaningful method and property names, without it, you'll find that you'll have difficulty reading your own code.


In Java, I can think of two reasons why the () is required:

1) Java had a specific design goal to have a "C/C++ like" syntax, to make it easy for C and C++ programmers to learn the language. Both C and C++ require the parentheses.

2) The Java syntax specifically requires the parentheses to disambiguate a reference to an attribute or local from a call to a method. This is because method names and attribute / local names are declared in different namespaces. So the following is legal Java:

public class SomeClass {
    private int name;
    private int name() { ... }

    ...

    int norm = name;  // this one
}

If the () was not required for a method call, the compiler would not be able to tell if the labeled statement ("this one") was assigning the value of the name attribute or the result of calling the name() method.


The difference isn't always explicit in VBA. This is a call to a Sub (i.e. a method with no return value) which takes no parameters (all examples are from Excel):

Worksheets("Sheet1").UsedRange.Columns.AutoFit

whereas this is accessing an attribute then passing it as a parameter:

MsgBox Application.Creator

As in the previous example, parentheses are also optional around parameters if there is no need to deal with the return value:

Application.Goto Worksheets("Sheet2").Range("A1")

but are needed if the return value is used:

iRows = Len("hello world")


Because referencing and calling a method are two different things. Consider X.method being the method of class X and x being an instance of X, so x.method == 'blue' would'nt ever be able to be true because methods are not strings.

You can try this: print a method of an object:


>>> class X(object):
...   def a(self):
...     print 'a'
...
>>> x=X()
>>> print x.a
<bound method X.a of <__main__.X object at 0x0235A910>>


Typically properties are accessors, and methods perform some sort of action. Going on this assumption, it's cheap to use a property, expensive to use a method.

Foo.Bar, for example, would indicate to me that it would return a value, like a string, without lots of overhead.

Foo.Bar() (or more likely, Foo.GetBar()), on the other hand, implies needing to retrieve the value for "Bar", perhaps from a database.

Properties and methods have different purposes and different implications, so they should be differentiated in code as well.

By the way, in all languages I know of the difference in syntax is explicit, but behind the scenes properties are often treated as simply special method calls.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号