This page is no longer maintained — Please continue to the home page at www.scala-lang.org

why need empty parens?

17 replies
Ittay Dror 2
Joined: 2010-05-05,
User offline. Last seen 42 years 45 weeks ago.

Hi,

Consider this:

scala> def foo(i: Int = 2) = println(i)
foo: (i: Int)Unit

scala> foo
:7: error: missing arguments for method foo in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
foo
^

scala> foo()
2

scala> def foo(implicit i: Int = 2) = println(i)
foo: (implicit i: Int)Unit

scala> foo
2

In both cases the value used is the default value. But in the second case I don't need to specify empty parenthesis.

Maybe remove the requirement for empty parenthesis when all arguments are supplied by default values? (Probably only for the last argument list)

Ittay

rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: why need empty parens?
The reasoning is the following:
1. default arguments are exclusively used for filling up incomplete parameter lists.2. implicit parameters are used by leaving the entire implicit parameter list out. 3. if no value can be found for some implicit parameter, its default is used as a backup.
Lukas
On Thu, Oct 14, 2010 at 12:17, Ittay Dror <ittay.dror@gmail.com> wrote:


Hi,


Consider this:

scala> def foo(i: Int = 2) = println(i)
foo: (i: Int)Unit

scala> foo
<console>:7: error: missing arguments for method foo in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
      foo
      ^

scala> foo()
2

scala> def foo(implicit i: Int = 2) = println(i)
foo: (implicit i: Int)Unit

scala> foo
2


In both cases the value used is the default value. But in the second case I don't need to specify empty parenthesis.


Maybe remove the requirement for empty parenthesis when all arguments are supplied by default values? (Probably only for the last argument list)


Ittay


a-bit-of-sunshine
Joined: 2010-03-05,
User offline. Last seen 2 years 35 weeks ago.
Re: why need empty parens?

Hi Lukas, hi Everybody,

we well understand your reasoning. However, the conclusion that, if we had the
choice, "calling a method having defaults for all its parameters should include
empty parenthesis" is not obvious to me. From the callers perspective:

a)
The caller is accustomed to the scala paradigm that he is not forced to write
empty parenthesis and is taken aback at this point.

b)
Even more important, library programmers extending a no-parameter method with
parameters in a later release cannot not use defaults because this would force
all clients to update their calls from "x" to "x()". Instead, he is forced to
use implicit arguments even if not appropriate.

Maybe another reason of the status-quo is also a historical: namely that default
parameters ware a later language enhancment and until then it was clear for the
compiler that calls of functions having any parameter must include parenthesis.

What do you think?

Peter

Peter 2
Joined: 2011-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: why need empty parens?

This is meant to be an answer to the following older post from Ittay /
Lukas:

Rytz writes:

>
>
> The reasoning is the following:
>
> 1. default arguments are exclusively used for filling up incomplete parameter lists.
> 2. implicit parameters are used by leaving the entire implicit parameter list out.
>
>
> 3. if no value can be found for some implicit parameter, its default is used as a backup.
>
> Lukas
>
> On Thu, Oct 14, 2010 at 12:17, Ittay Dror wrote:
>
> Hi,
> Consider this:
> scala> def foo(i: Int = 2) = println(i)
> foo: (i: Int)Unit
> scala> foo
> :7: error: missing arguments for method foo in object $iw;
> follow this method with `_' if you want to treat it as a partially applied function
> foo
> ^
> scala> foo()
> 2
> scala> def foo(implicit i: Int = 2) = println(i)
> foo: (implicit i: Int)Unit
> scala> foo
> 2
> In both cases the value used is the default value. But in the second case I don't need to specify empty parenthesis.
> Maybe remove the requirement for empty parenthesis when all arguments are supplied by default values? (Probably only for the last argument list)
>
> Ittay

rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: Re: why need empty parens?


On Mon, May 16, 2011 at 09:35, Sonnenschein <peter.empen@bitmarck.de> wrote:
Hi Lukas, hi Everybody,

we well understand your reasoning. However, the conclusion that, if we had the
choice, "calling a method having defaults for all its parameters should include
empty parenthesis" is not obvious to me. From the callers perspective:

a)
The caller is accustomed to the scala paradigm that he is not forced to write
empty parenthesis

That's not really a scala paradigm. The reason why scala allows you to omitempty parameter lists in
  def foo() = ...  val x = foo
is solely for Java compatibility, it allows you to do for instance
  val len = "ldkfjl".length
In fact, we encourage Scala programmers to make the difference between a property / getter (no parameter list) and a procedure, both when defining andwhen calling them. I even heard here at EPFL that some people would like toenforce this for Scala-defined methods, i.e. infer the empty parameter list only if the method is defined in Java.
 
and is taken aback at this point.

b)
Even more important, library programmers extending a no-parameter method with
parameters in a later release cannot not use defaults because this would force
all clients to update their calls from "x" to "x()".

Again, one could argue that "x" looks like reading a property. if a parameter is addedto a method, the method changes from returning a property to computing a function, and the parameter list indicates that.
But I agree it's also a matter of taste :)
 
Instead, he is forced to
use implicit arguments even if not appropriate.

Maybe another reason of the status-quo is also a historical: namely that default
parameters ware a later language enhancment and until then it was clear for the
compiler that calls of functions having any parameter must include parenthesis.


It would also be difficult to spec. Consider:
   def f(a: Int = 1)(b: Int = 1) = ...    f(2)
   def f(a: Int = 1)(b: String = "uh") = ...   f(1) // OK?   f("oh") // OK?
Lukas
 

What do you think?

Peter


Peter 2
Joined: 2011-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: why need empty parens?

Hi Lukas,

> In fact, we encourage Scala programmers to make the difference between a
> property / getter (no parameter list) and a procedure, both when defining
> and when calling them. I even heard here at EPFL that some people would like to
> enforce this for Scala-defined methods, i.e. infer the empty parameter list
> only if the method is defined in Java.

I doubt, the majority would like it. The point is that "property" is
not a Scala language term, is it?

Moreover, studying the code style of sophisticated programmers I
cannot see they care of whether a method is a property or not but they
tend to simply omit empty parens whenever possible - that is why I
used the term paradigm. What about "toList", for example? In how many
cases do they call "toList()" and not "toList" in the core library?
Approx. 1:50? Or am I wrong to suppose that "toList" is a procedure in
your sense?

By the way how should a caller decide whether a method is a property?
Would that not mean the caller must know the implementation?

> It would also be difficult to spec. Consider:
>
>    def f(a: Int = 1)(b: Int = 1) = ...
>    f(2)

f
:9: error: missing arguments for method f in object $iw;
follow this method with `_' if you want to treat it as a partially
applied function

If you need a partially applied function, the compiler forces you to
append "_". So if you don't append "_", the compiler could be free to
suppose theat you mean a fully applied call quite unambiguously.

Anyway, the Scala compiler is intelligent enough to omit "ambiguous"
errors. I don't want to say that it is easy for the compiler to handle
even more, but I he is quite intelligent already...

Cheers, Peter

Ruediger Keller 2
Joined: 2010-04-30,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: why need empty parens?

AFAIK, the recommended practice is to use an empty parameter list when
the method is side effecting and to omit it when the method is not
side effecting. Also, the method call should always reflect this, even
though Scala allows to omit the empty parameter list for more
convenient Java interoperability.

As the toList, toSeq, etc. methods are not side effecting the are
defined without the empty parameter list.

Regards,
Rüdiger

2011/5/16 Sonnenschein :
> Hi Lukas,
>
>> In fact, we encourage Scala programmers to make the difference between a
>> property / getter (no parameter list) and a procedure, both when defining
>> and when calling them. I even heard here at EPFL that some people would like to
>> enforce this for Scala-defined methods, i.e. infer the empty parameter list
>> only if the method is defined in Java.
>
> I doubt, the majority would like it. The point is that "property" is
> not a Scala language term, is it?
>
> Moreover, studying the code style of sophisticated programmers I
> cannot see they care of whether a method is a property or not but they
> tend to simply omit empty parens whenever possible - that is why I
> used the term paradigm. What about "toList", for example? In how many
> cases do they call "toList()" and not "toList" in the core library?
> Approx. 1:50? Or am I wrong to suppose that "toList" is a procedure in
> your sense?
>
> By the way how should a caller decide whether a method is a property?
> Would that not mean the caller must know the implementation?
>
>> It would also be difficult to spec. Consider:
>>
>>    def f(a: Int = 1)(b: Int = 1) = ...
>>    f(2)
>
> f
> :9: error: missing arguments for method f in object $iw;
> follow this method with `_' if you want to treat it as a partially
> applied function
>
> If you need a partially applied function, the compiler forces you to
> append "_". So if you don't append "_", the compiler could be free to
> suppose theat you mean a fully applied call quite unambiguously.
>
> Anyway, the Scala compiler is intelligent enough to omit "ambiguous"
> errors. I don't want to say that it is easy for the compiler to handle
> even more, but I he is quite intelligent already...
>
> Cheers, Peter
>

Philippe Lhoste
Joined: 2010-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: why need empty parens?

On 16/05/2011 11:53, Sonnenschein wrote:
> Moreover, studying the code style of sophisticated programmers I
> cannot see they care of whether a method is a property or not but they
> tend to simply omit empty parens whenever possible - that is why I
> used the term paradigm. What about "toList", for example? In how many
> cases do they call "toList()" and not "toList" in the core library?
> Approx. 1:50? Or am I wrong to suppose that "toList" is a procedure in
> your sense?

General style advice in the Scala world is to avoid calling parameterless functions (or
methods) with side effect without parentheses.

Ie. something like foo.incr where incr changes the state of foo is discouraged.

So, in practice, I suppose this mostly limit this usage to getters, pure or, as with
toList, transforming the content of the object to an output format. That's still a getter,
IMHO.

Re-reading Lukas' answer, I see that's what he means.
In my mind, "procedure" conveys the meaning of "function with side effect" (modifying the
state of one or several objects, or of the world itself) but in light of Lukas' answer, it
might be just a generic term for function/method (as you know, they are slightly different
in Scala), probably requiring a parameter list: as I point out above, a parameter-less
function is quite limited to getters, or perhaps to random number generators... or
callback of a timer?

Peter 2
Joined: 2011-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: why need empty parens?

My intention was also to discuss the following use case:

Library release 1/ method f in class C (if you want without side
effect) with signature:
--------------------
def f

Client usage of release 1 with c of type C:
c.f

Library release 2 with extended parameter list of f (still without
side effect) with signature (d being a default value of type T):
--------------------
def f(p: T = d)

Client usage of release 2:
c.f // compile error! - clients must update
c.f() // after updating o.k. (but for some people meaning that f has a
side effect?)
c.f(x) // to use the new feature

So if the library designer wants to avoid client updates, the only way
for him is seemingly to use an implicit parameter list instead of a
default parameter.

As you see now, this issue must not have to do anything with code
style considerations.

Mirco Dotta
Joined: 2009-02-25,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: why need empty parens?

Hi Peter,

Did you consider overloading?

Philippe Lhoste
Joined: 2010-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: why need empty parens?

On 16/05/2011 14:46, Sonnenschein wrote:
> My intention was also to discuss the following use case:
>
> Library release 1/ method f in class C (if you want without side
> effect) with signature:
> --------------------
> def f
>
> Client usage of release 1 with c of type C:
> c.f
>
> Library release 2 with extended parameter list of f (still without
> side effect) with signature (d being a default value of type T):
> --------------------
> def f(p: T = d)
>
> Client usage of release 2:
> c.f // compile error! - clients must update
> c.f() // after updating o.k. (but for some people meaning that f has a
> side effect?)
> c.f(x) // to use the new feature
>
> So if the library designer wants to avoid client updates, the only way
> for him is seemingly to use an implicit parameter list instead of a
> default parameter.
>
> As you see now, this issue must not have to do anything with code
> style considerations.

Let see. I tried with simple cases, that might not fit your use case.

object T extends App
{
class CF
{
def f = 42
}
val cf = new CF
println(cf.f)
}

So far, so good.
I add a new definition:

object T extends App
{
class CF
{
def f = 42
def f(x: Int): Int = if (x == 0) f else x
}
val cf = new CF
println(cf.f)
println(cf.f(0))
println(cf.f(10))
}

Still working. Now, we want a default value:

object T extends App
{
class CF
{
def f = 42
def f(x: Int = 66): Int = if (x == 0) f else x
}
val cf = new CF
println(cf.f)
println(cf.f())
println(cf.f(0))
println(cf.f(10))
}

Still seems OK. Of course, I cheat a bit by keeping parameterless f, I don't know if it is
annoying in your case. Can fall back on calling f(), I suppose:

class CF
{
def f: Int = f()
def f(x: Int = 66): Int = if (x == 0) 111 else x
}

Just exploring some possibilities...

Peter 2
Joined: 2011-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: why need empty parens?

Hi Philippe,

you are right. I forgot to mention that keeping both variants is a
valid workaround:

Library release 2:
--------------------
def f(p: T = d) = ... here goes the real functionality
def f = f() // just for backward compatibility

But nobody likes such workarounds examining such a buty language
otherwise.

@Mirco: Releasewise overloading would be rather an overkill, wouldn't
it?

Curiously, this kind of overloading is valid but it doesn't work in
REPL unless entered by :paste.

Cheers Peter

E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.
why need empty parens?

On 2011-05-16 16:06, Sonnenschein wrote:
> def f(p: T = d) = ... here goes the real functionality
> def f = f() // just for backward compatibility
>
> But nobody likes such workarounds examining such a buty language
> otherwise.

I agree. Empty-parens and parameterless notations should be interchangable and mean the same thing.

Particularly,
def f = 5
f()
println
should be allowed.

This would unify and simplify the language rules.

On 2011-05-16 10:39, Lukas Rytz wrote:
> It would also be difficult to spec. Consider:

Something like first match principle (in order)?

> def f(a: Int = 1)(b: Int = 1) = ...
> f(2)

f(2) == f(a=2)(b=1) // OK

> def f(a: Int = 1)(b: String = "uh") = ...
> f(1) // OK?

f(1) == f(a=1)(b="uh") // OK

> f("oh") // OK?

f("oh") == f(a=1)(b="oh") // OK

f("ops")(2) == f(a=1)(b="ops")??? // error

regards,
Eugen

E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.
Re: why need empty parens?

> Empty-parens and parameterless notations should be interchangable and mean the same thing:
a parameterless method.
Omitting parens for parameterless methods can be seen simply as a syntactic sugar.

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: why need empty parens?

On 5/16/11 8:05 AM, Eugen Labun wrote:
> I agree. Empty-parens and parameterless notations should be interchangable and mean the same thing.

What's your plan here?

scala> def f = () => 5
f: () => Int

scala> println(f)

scala> println(f())
5

> This would unify and simplify the language rules.

The only way you're going to get any simplification in the rules is by
being stricter, not by creating additional ambiguities.

E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.
Re: why need empty parens?

hmmm... complicated
Parens are overloaded
- for bounding parammeter lists in method notation and
- as a literal for empty value of type Unit, which is also treated like "void",
right?

So to avoid ambiguity I could only propose to introduce "void":
def f = void => 5

OTOH your sample seems to be a special case: a method returning a function value, where the function
has no parameters.

How to distinguish between
- a method call (returning a function value) and
- calling the_return_value_of_a_method (which is a function value in this case) as a function?

Demanding f.apply for the second case seems to be the only real and unambiguous way.
Or we should introduce some special notation for this case if f.apply is not appropriate.

On 2011-05-16 17:27, Paul Phillips wrote:
> On 5/16/11 8:05 AM, Eugen Labun wrote:
>> I agree. Empty-parens and parameterless notations should be interchangable and mean the same thing.
>
> What's your plan here?
>
> scala> def f = () => 5
> f: () => Int
>
> scala> println(f)
>
>
> scala> println(f())
> 5
>
>> This would unify and simplify the language rules.
>
> The only way you're going to get any simplification in the rules is by
> being stricter, not by creating additional ambiguities.
>

Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: why need empty parens?


On 16 May 2011 16:59, Eugen Labun <labun@gmx.net> wrote:
hmmm... complicated
Parens are overloaded
- for bounding parammeter lists in method notation and
- as a literal for empty value of type Unit, which is also treated like "void",
right?

So to avoid ambiguity I could only propose to introduce "void":
def f = void => 5


Which is a bit like saying that all integers should use null instead of 0, which ambiguously looks a bit like the letter O
void and Unit are not really the same thing, they just appear that way because Scala uses Unit to represent the return value of void methods from Java.  For starters, you can pass around an instance of Unit; as a subclass of AnyVal it's even possible to box the thing.  To call a unit "void" is about as wrong and misleading as claiming that an existential type is a raw type.
If anything, it would be nice if the idea of tuples and argument lists could be unified, so that Unit and an empty param list become one and the same thing.  Problem is, to make that work we'd also need the concept of a tuple with named/default values to be introduced into the language.  

OTOH your sample seems to be a special case: a method returning a function value, where the function
has no parameters.


Not really.  This is a very common pattern, used when you explicitly want to provide a `Function` instance that then doesn't need to be partially-applied with a trailing `_` when passed as a parameter to a high-order method/function.
 

How to distinguish between
- a method call (returning a function value) and
- calling the_return_value_of_a_method (which is a function value in this case) as a function?

Demanding f.apply for the second case seems to be the only real and unambiguous way.
Or we should introduce some special notation for this case if f.apply is not appropriate.


On 2011-05-16 17:27, Paul Phillips wrote:
> On 5/16/11 8:05 AM, Eugen Labun wrote:
>> I agree. Empty-parens and parameterless notations should be interchangable and mean the same thing.
>
> What's your plan here?
>
> scala> def f = () => 5
> f: () => Int
>
> scala> println(f)
> <function0>
>
> scala> println(f())
> 5
>
>> This would unify and simplify the language rules.
>
> The only way you're going to get any simplification in the rules is by
> being stricter, not by creating additional ambiguities.
>




--
Kevin Wright

gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.
Re: why need empty parens?

Paul, Kevin,

As you see it's difficult to propose something useful without a deep understanding of a wide variety
of concepts behind Scala + having appropriate experience.

The concept of a "Unit" in Scala is really not quite understandable to me.

But I will try my best and learn from your posts!

On 2011-05-16 18:22, Kevin Wright wrote:
> Which is a bit like saying that all integers should use null instead of 0, which ambiguously looks a
> bit like the letter O
> ...

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland