December 28, 2011
On 2011-12-28 18:15, deadalnix wrote:
> Le 28/12/2011 13:54, bearophile a écrit :
>> Timon Gehr:
>>
>>> => expr
>>>
>>> should imo be a shorthand for
>>>
>>> () => expr.
>>>
>>> It saves some ((())(()))().
>>
>> It saves few (), but zero argument lambdas aren't that common in my
>> functional-style code, and I think it decreases syntax uniformity and
>> code readability. So I think it's a bad idea.
>>
>> On the other hand I think extending the applicability of this syntax
>> to free functions/methods (as in Scala and Ada2012) is a nice idea, to
>> shorten tiny functions/methods, that are common enough:
>>
>> class C {
>> private int x;
>> int getX() => x;
>> }
>>
>
> That would be great ! Uniformity is something we should look for.
>
>> ------------------------
>>
>> Walter:
>>
>>> They expect to see it, or else they mark D as "not having lambdas"
>>> and "not supporting functional programming".<
>>
>> To me this sounds like a bit silly argument to base language design on.
>>
>> In my opinion the most important reason for the introduction of this
>> anonymous function syntax is that it makes D functional-style code
>> (and generally code that uses lot of callbacks) less noisy, so it
>> makes it more easy to write and read.
>>
>> Bye,
>> bearophile
>
> Both argument are fallacy. Javascript is a successful language (even if
> some design decisions are arguably very bad). It use a lot of callback,
> and promote event drivent programming so this type of consrtruct is used
> everywhere. In addition, in Javascript, code source size matters.
>
> The syntax to do such a thing is more verbose in javascript. So
> definitively, this is a nice syntax, but this isn't that ground
> breaking, and this isn't even required for people to use this type of
> constructs.

I use CoffeeScript (which compiles to JavaScript) and it has a lot nice lambda syntax.

foo = (arg) ->
    arg()

foo ->
    # lambda code here

-- 
/Jacob Carlborg
December 28, 2011
On 12/28/2011 09:57 PM, Jonathan M Davis wrote:
> On Wednesday, December 28, 2011 21:44:01 Timon Gehr wrote:
>>> I also don't think that they add much unless you have functions with way
>>> too many parameters, and those sorts of functions shouldn't be
>>> happening anyway. And I don't like the additional complication of the
>>> possibility of reordering functiion arguments. You should be able to
>>> look at a function and know which parameters its arguments go with
>>> purely by the order, which named arguments destroy.
>> Why would that be beneficial?
>
> I'd hate to have a function like
>
> void func(float x, float y);
>
> where calling it
>
> func(1.0, 2.0);
>
> and
>
> func(y : 1.0, x : 2.0);
>
> don't do the same thing. All of a sudden, I have to pay attention to what
> names the arguments were given.  I can't just read the function call like I
> would now. It becomes error-prone in that regard and violates the current
> expectations of argument order.  It will make code harder to read for minimal
> benefit IMHO. I do _not_ think that name arguments are an improvement.
>

So it is the usual "because the feature can be misused it is bad" argument?

>>> But all of that has been discussed at length before. I'm completely
>>> opposed to the idea, but I seem to be in the minority (at least out of
>>> those who spoke up).
>>>
>>> - Jonathan M Davis
>>
>> I don't need named arguments either, but I don't think they would hurt
>> if implemented as a purely optional feature.
>
> Since they affect the API, they _do_ hurt. Since then any changes to parameter
> names break code. So, it has a definite affect on code maintainibility even if I
> don't use the feature myself. I also don't want to see them in code. If the
> example above were possible, then someone would use it in their code (even if
> I didn't), and I'd have to deal with all of the code readibility issues that
> it causes. Named arguments _would_ hurt the language even if they were purely
> optional.
>
> - Jonathan M Davis

That is not what I'd call purely optional.

Timon Gehr wrote:
> That assumes every parameter is implicitly named. If named arguments ever get
> into the language, then they should imho be marked as named arguments explicitly
> at function declaration point.


December 28, 2011
On 2011-12-28 18:15, deadalnix wrote:
> Le 28/12/2011 13:54, bearophile a écrit :
>> Timon Gehr:
>>
>>> => expr
>>>
>>> should imo be a shorthand for
>>>
>>> () => expr.
>>>
>>> It saves some ((())(()))().
>>
>> It saves few (), but zero argument lambdas aren't that common in my
>> functional-style code, and I think it decreases syntax uniformity and
>> code readability. So I think it's a bad idea.
>>
>> On the other hand I think extending the applicability of this syntax
>> to free functions/methods (as in Scala and Ada2012) is a nice idea, to
>> shorten tiny functions/methods, that are common enough:
>>
>> class C {
>> private int x;
>> int getX() => x;
>> }
>>
>
> That would be great ! Uniformity is something we should look for.
>
>> ------------------------
>>
>> Walter:
>>
>>> They expect to see it, or else they mark D as "not having lambdas"
>>> and "not supporting functional programming".<
>>
>> To me this sounds like a bit silly argument to base language design on.
>>
>> In my opinion the most important reason for the introduction of this
>> anonymous function syntax is that it makes D functional-style code
>> (and generally code that uses lot of callbacks) less noisy, so it
>> makes it more easy to write and read.
>>
>> Bye,
>> bearophile
>
> Both argument are fallacy. Javascript is a successful language (even if
> some design decisions are arguably very bad). It use a lot of callback,
> and promote event drivent programming so this type of consrtruct is used
> everywhere. In addition, in Javascript, code source size matters.
>
> The syntax to do such a thing is more verbose in javascript. So
> definitively, this is a nice syntax, but this isn't that ground
> breaking, and this isn't even required for people to use this type of
> constructs.

I use CoffeeScript (which compiles to JavaScript) and it has a lot nicer lambda syntax.

foo = (arg) ->
    arg()

foo ->
    # lambda code here

-- 
/Jacob Carlborg
December 28, 2011
On 2011-12-28 18:54, Timon Gehr wrote:
> On 12/28/2011 05:59 PM, Jacob Carlborg wrote:
>> On 2011-12-28 13:54, bearophile wrote:
>>> Timon Gehr:
>>>
>>>> => expr
>>>>
>>>> should imo be a shorthand for
>>>>
>>>> () => expr.
>>>>
>>>> It saves some ((())(()))().
>>>
>>> It saves few (), but zero argument lambdas aren't that common in my
>>> functional-style code, and I think it decreases syntax uniformity and
>>> code readability. So I think it's a bad idea.
>>
>> It can already be done with the lazy arguments.
>>
>> void foo (lazy int a)
>> {
>> auto b = a();
>> }
>>
>> int bar ();
>> foo(bar());
>>
>
> It is not the same thing. lazy arguments do not create a closure.

Didn't thought of that.

-- 
/Jacob Carlborg
December 28, 2011
On Wed, 28 Dec 2011 22:57:32 +0200, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> I'd hate to have a function like
>
> void func(float x, float y);
>
> where calling it
>
> func(1.0, 2.0);
>
> and
>
> func(y : 1.0, x : 2.0);
>
> don't do the same thing. All of a sudden, I have to pay attention to what
> names the arguments were given. I can't just read the function call like I
> would now. It becomes error-prone in that regard and violates the current
> expectations of argument order. It will make code harder to read for minimal
> benefit IMHO. I do _not_ think that name arguments are an improvement.

Are you aware all the points you made support the need for named arguments rather than what you were trying to achieve?
Named parameter fixed a bug in your code and you are trying to explain how crap a feature is NP? :)

If you are "trying" to read a function call when it uses named parameters, its not the fault of the feature but its implementation in given language.
For this reason i kept saying we shouldn't inherit it from other languages but keep it simple.
The feature supposed to ease the reading of a function call and enforce some guarantees.

>> > But all of that has been discussed at length before. I'm completely
>> > opposed to the idea, but I seem to be in the minority (at least out of
>> > those who spoke up).
>> >
>> > - Jonathan M Davis
>>
>> I don't need named arguments either, but I don't think they would hurt
>> if implemented as a purely optional feature.
>
> Since they affect the API, they _do_ hurt. Since then any changes to parameter
> names break code. So, it has a definite affect on code maintainibility even if I
> don't use the feature myself. I also don't want to see them in code. If the
> example above were possible, then someone would use it in their code (even if
> I didn't), and I'd have to deal with all of the code readibility issues that
> it causes. Named arguments _would_ hurt the language even if they were purely
> optional.

It doesn't create readability issues, it is there to solve them.
Maintainability issues? How?
If you change "anything" in your interface, it is already a breaking change.
December 28, 2011
On 12/28/2011 11:34 PM, so wrote:
> If you change "anything" in your interface, it is already a breaking
> change.

That is why it is desirable to not let parameter names contribute to the interface. Jonathan definitely has a point against making all parameters named parameters by default.

From a recent thread in D.learn:

Christophe wrote:
> Timon Gehr wrote:
>> but the drawback is that the parameter names become part of the
>> public interface.
>
> Well, that's precisely the point. And it is a drawback if parameters are
> systematically names, but not if it is triggered only on demand.
>
> Example :
>
> void foo(int a, int b:, int c:);
>
> void main() {
> 	foo(1, 2, 3);
> 	foo(1, c: 3, b: 2;
> 	foo(a: 1, b: 2, c: 3); // error : a is not a named parameter.
> }
>
> In the example, ":" is used to make a named parameter to recall the use
> when you call the function.

I thought that was pretty convincing.
December 28, 2011
deadalnix:

> bearophile:
>> In my opinion the most important reason for the introduction of this anonymous function syntax is that it makes D functional-style code (and generally code that uses lot of callbacks) less noisy, so it makes it more easy to write and read.

> Both argument are fallacy. Javascript is a successful language (even if some design decisions are arguably very bad). It use a lot of callback, and promote event drivent programming so this type of consrtruct is used everywhere. In addition, in Javascript, code source size matters.
> 
> The syntax to do such a thing is more verbose in javascript. So definitively, this is a nice syntax, but this isn't that ground breaking, and this isn't even required for people to use this type of constructs.

Javascript is successful mostly for being the only language available on a very important platform, not for its many qualities and features. D lacks a killer app still, and it exists in an already mature ecosytem dominated by other languages like C++. So it has to compete on different grounds of quality.

I agree the new short lambda syntax is not necessary, but it's good to have. I have written a good amount of functional-style code in D2 (while I have not written a significant amount of functional-style code in Javascript), I have written some code in OCaML and Haskell, and I have seen that the amount of parentheses and brackets in such D code make it not easy to write and read for me, compared to equivalent code in more functional languages. So you need to try harder if you want to change my mind :-)

Bye,
bearophile
December 28, 2011
On Thu, 29 Dec 2011 00:48:54 +0200, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 12/28/2011 11:34 PM, so wrote:
>> If you change "anything" in your interface, it is already a breaking
>> change.
>
> That is why it is desirable to not let parameter names contribute to the interface. Jonathan definitely has a point against making all parameters named parameters by default.

/// A.d
void fun1(int Arg);
void fun2(int x);

/// B.d
void fun1(int arg);
void fun2(int y);

I am having hard time understanding the issue really.
Now as a user i don't know why the library dev. changed the interface:

/// without NP
fun1(arg); // recompile no edit,
fun2(x);   // well

You are saying like changing a parameter name in lib code is always so harmless.
You guys making your case on a dumb developer that goes for a breaking change just to fix a always harmless typo.
Then, what makes you so sure he won't do this?
December 28, 2011
Jonathan M Davis:

> The primary reason that I really don't like named arguments is the fact that the names of the parameters become part of the API.

Sometimes I don't mind to make the names part of the API.
And as you remember we have suggested an idea adapted from Scala.


void foo(int x) {}
void main() {
    foo(x: 5);
}


A deprecated() gives some transition time to change the API:

void foo(int xx deprecated(x)) {}
void main() {
    foo(x: 5); // deprecated 'x' warning
    foo(xx: 5);
}


> I also don't think that
> they add much unless you have functions with way too many parameters, and
> those sorts of functions shouldn't be happening anyway.

I'd like to use names even for functions with 3 arguments.
And named arguments offer you more flexibility in using functions. As example look at Python built-in sorted (that performs a schwartz sort on a copy of the input sequence), that has two optional arguments, using them with their name is the idiomatic way in Python because you are able to use only one of them at a time:


>>> a = [1, 5, -3, 9, -2]
>>> sorted(a)
[-3, -2, 1, 5, 9]
>>> sorted(a, key=abs)
[1, -2, -3, 5, 9]
>>> sorted(a, reverse=True)
[9, 5, 1, -2, -3]

-------------------------

> I'd hate to have a function like
> 
> void func(float x, float y);
> 
> where calling it
> 
> func(1.0, 2.0);
> 
> and
> 
> func(y : 1.0, x : 2.0);
> 
> don't do the same thing. All of a sudden, I have to pay attention to what names the arguments were given. I can't just read the function call like I would now. It becomes error-prone in that regard and violates the current expectations of argument order. It will make code harder to read for minimal benefit IMHO. I do _not_ think that name arguments are an improvement.

Expectations change and adapt to the language and you will read the function calls in a different way, taking a look at the argument order too. In many cases names are not present at the call point, so you don't need to take care of this. If the names are present at the call point you take a look at the order. The name of the arguments keep the code readable.

Regarding the "error-prone" nature of named arguments, I think you are wrong, in Ada named arguments are regarded as means to reduce possible bugs, because they avoid you to assign arguments "blindly" as now. In Python I like to know what argument I am assigning an argument to, this avoids some mistakes at the call point.


> If the
> example above were possible, then someone would use it in their code (even if
> I didn't), and I'd have to deal with all of the code readibility issues that
> it causes. Named arguments _would_ hurt the language even if they were purely
> optional.

Right, if language features like this are present they can't be really "optional", you find them in code written by other people.

But named argument make code _more_ readable, because they tell you what arguments you are assigning to.

Bye,
bearophile
December 28, 2011
On 12/29/2011 12:29 AM, so wrote:
> On Thu, 29 Dec 2011 00:48:54 +0200, Timon Gehr <timon.gehr@gmx.ch> wrote:
>
>> On 12/28/2011 11:34 PM, so wrote:
>>> If you change "anything" in your interface, it is already a breaking
>>> change.
>>
>> That is why it is desirable to not let parameter names contribute to
>> the interface. Jonathan definitely has a point against making all
>> parameters named parameters by default.
>
> /// A.d
> void fun1(int Arg);
> void fun2(int x);
>
> /// B.d
> void fun1(int arg);
> void fun2(int y);
>
> I am having hard time understanding the issue really.
> Now as a user i don't know why the library dev. changed the interface:
>
> /// without NP
> fun1(arg); // recompile no edit,
> fun2(x); // well
>
> You are saying like changing a parameter name in lib code is always so
> harmless.
> You guys making your case on a dumb developer that goes for a breaking
> change just to fix a always harmless typo.

I have a hard time understanding your case. You wrote /// without NP. Without NP it is perfectly reasonable to fix the typo and there is no breaking change. That is part of why having no NP by default is desirable. The moment NP by default is introduced is the moment all parameter names in all libraries are set in stone. Those names were mere implementation details prior to that point in time.
Having parameter names contribute to the interface means that all developers need to spend time thinking about the best possible names for their function parameters.

> Then, what makes you so sure he won't do this?

What makes you so sure that if he does, he actually remembers to change the functionality too?