December 05, 2007
guslay:
> GC seems to have been pushed after c++0x. http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!330.entry

I see, thank you for the link. They are adding features to allow a simpler support of an external GC instead. I think this will keep D "better" for some more time then :-) (I have used quotes because often you can't tell langage X is better than Y because they are better regarding specific purposes).

Bye,
bearophile
December 05, 2007
>> I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?
> Because it's simpler, and there's an enormous body of code (C, C++ for example) which demonstrates a language can get by perfectly well without it;

With hacks in the compiler such as the special case for memset I talked about, I don't think that it works 'perfectly well'.


> Is the extra cost worth the benefit?
> 
>> To answer your question: passing parameter by name increase the readability of the source, reduce the number of mistake when writing the code (and with a good IDE the number of character to type would be the same).
> 
> But it also means that if you change the name of a parameter in a library, user code will break. Certainly, you'd need some special syntax to specify which parameters are part of the API, otherwise you get horribly brittle code.

Uh? Why would renaming the parameters of a function happen more frequently than say renaming a function?

> Overload lookup rules could become complicated.

If two function overloaded function have a different set of parameters name, then if you call a function passing a parameter by name then, then either it's a 'common' name and the normal overload rules apply either it's a name which appears in only one function so it's not an overload anymore (if you have two parameters specific to two different function, it's an error) ..


>>> Named arguments are potentially a disastrous feature, if completely unrestricted. It was when COM needed to support VB's named arguments that Windows programming really nose-dived.
>>
>> Could you explain this point? (I know nothing about COM).
> 
> <flame>
> VB allows you to call a C++ COM object by giving a list of argument names (as a text array, with whatever stupid VB formats are possible) together with the argument values as VB Variants. Languages like C++ were supposed to support any  combination the VB programmer chose to use. A massive complication of COM code, just to support sloppy practice by VB programmers, and even then it was only necessary because the VB interpreter was too lazy to put the parameters in the right order.
> </flame>

Interesting.

Regards,
renoX
December 05, 2007
bearophile a écrit :
> guslay:
>> GC seems to have been pushed after c++0x. http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!330.entry
>> 
> 
> I see, thank you for the link. They are adding features to allow a
> simpler support of an external GC instead. I think this will keep D
> "better" for some more time then :-)

"better" only if D's GC is considered reliable enough for "serious" projects which is debatable currently: having memory leaks in some case due to the GC isn't acceptable IMHO.

renoX

> (I have used quotes because
> often you can't tell langage X is better than Y because they are
> better regarding specific purposes).
> 
> Bye, bearophile
December 06, 2007
On Dec 5, 2007 1:48 PM, renoX <renosky@free.fr> wrote:
> I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?

I often write constructor functions which look something like this

    this(int x_, int y_, int z_)
    {
        x = x_;
        y = y_;
        z = z_;
    }

If parameter names were part of the API, then anyone calling my code would have to refer to those constructor parameters as x_, y_ and z_, complete with trailing underscores

Of course, I could go back and change all my code to

    this(int x, int y, int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

but that would be a lot of code to change, and it might break calling code!










> To answer your question: passing parameter by name increase the readability of the source, reduce the number of mistake when writing the code (and with a good IDE the number of character to type would be the same).
>
>
> > Named arguments are potentially a disastrous feature, if completely unrestricted. It was when COM needed to support VB's named arguments that Windows programming really nose-dived.
>
> Could you explain this point? (I know nothing about COM).
>
> > (OTOH: A string mixin can, given the name of a function, tell you what the names of all of it's default arguments are (as well as what their default values are). I can in fact write a string mixin implementation of this feature; it's perfectly feasible. But is the concept actually a good idea?)
>
> Note that passing parameter by name is only useful if programmers doesn't have to jump through hoops to do it, otherwise nobody will use it.
>
> renoX
>
December 06, 2007
> I often write constructor functions which look something like this

And not just constructors, by the way - any "setter" property function is likely to apply the same convention.
December 06, 2007
Janice Caron wrote:
> On Dec 5, 2007 1:48 PM, renoX <renosky@free.fr> wrote:
>> I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?
> 
> I often write constructor functions which look something like this
> 
>     this(int x_, int y_, int z_)
>     {
>         x = x_;
>         y = y_;
>         z = z_;
>     }
> 
> If parameter names were part of the API, then anyone calling my code
> would have to refer to those constructor parameters as x_, y_ and z_,
> complete with trailing underscores
> 
> Of course, I could go back and change all my code to
> 
>     this(int x, int y, int z)
>     {
>         this.x = x;
>         this.y = y;
>         this.z = z;
>     }
> 
> but that would be a lot of code to change, and it might break calling code!
> 
> 

That's why any named parameter proposal is going to have to flag the named parameters somehow.  Non-flagged parameters will continue to behave as always.

--bb
December 06, 2007
On Dec 5, 2007 1:48 PM, renoX <renosky@free.fr> wrote:
> I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?

Another thought. If the name were part of the API then could one overload functions by parameter name? e.g.

    void f(int a) { /* do something */ }
    void f(int b) { /* do something different */ }

After all, if the name were part of the API, then they have different APIs.

I'm not convinced that this is a good idea. It's also not the only alternative. I have in the past written programs which take parameters of the same underlying type in any order, using only D-as-it-is-now (or C++), and it's not so hard. For example, suppose you want a function that looks like

    MyDate makeDate(int month, int day, int year)

but you think callers might get confused about what order to pass the parameters in (European date order, American date order, YMD date order, whatever...)

    typedef int Year;
    typedef int Month;
    typedef int Day;

    MyDate makeDate(Year y; Month m, Day d) {/*...*/ }
    MyDate makeDate(Year y, Day d, Month m) { return MyDate(y,m,d); }
    MyDate makeDate(Day d, Month m, Year y) { return MyDate(y,m,d); }
    MyDate makeDate(Month m, Day d, Year y) { return MyDate(y,m,d); }

That forces callers to name their arguments, as in:

    MyDate date = makeDate(cast(Day)11, cast(Month)11, cast(Year)1999);

If you wanted, you could also add a "default" function that took ints but required parameters in the right order.

And that, basically, is problem solved, as far as I can see.
December 06, 2007
Janice Caron wrote:
> On Dec 5, 2007 1:48 PM, renoX <renosky@free.fr> wrote:
>> I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?
> 
> Another thought. If the name were part of the API then could one
> overload functions by parameter name? e.g.
> 
>     void f(int a) { /* do something */ }
>     void f(int b) { /* do something different */ }
> 
> After all, if the name were part of the API, then they have different APIs.
> 
> I'm not convinced that this is a good idea. It's also not the only
> alternative. I have in the past written programs which take parameters
> of the same underlying type in any order, using only D-as-it-is-now
> (or C++), and it's not so hard. For example, suppose you want a
> function that looks like
> 
>     MyDate makeDate(int month, int day, int year)
> 
> but you think callers might get confused about what order to pass the
> parameters in (European date order, American date order, YMD date
> order, whatever...)
> 
>     typedef int Year;
>     typedef int Month;
>     typedef int Day;
> 
>     MyDate makeDate(Year y; Month m, Day d) {/*...*/ }
>     MyDate makeDate(Year y, Day d, Month m) { return MyDate(y,m,d); }
>     MyDate makeDate(Day d, Month m, Year y) { return MyDate(y,m,d); }
>     MyDate makeDate(Month m, Day d, Year y) { return MyDate(y,m,d); }
> 
> That forces callers to name their arguments, as in:
> 
>     MyDate date = makeDate(cast(Day)11, cast(Month)11, cast(Year)1999);
> 
> If you wanted, you could also add a "default" function that took ints
> but required parameters in the right order.
> 
> And that, basically, is problem solved, as far as I can see.

Gee that's so clean!  Not.
You've taken one simple function and turned it into 4 functions plus 3 extra types.
It's a workaround at best.

--bb
December 06, 2007
On Thu, 06 Dec 2007 08:58:40 -0000, Bill Baxter <dnewsgroup@billbaxter.com> wrote:

> Janice Caron wrote:
>> On Dec 5, 2007 1:48 PM, renoX <renosky@free.fr> wrote:
>>> I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?
>>  Another thought. If the name were part of the API then could one
>> overload functions by parameter name? e.g.
>>      void f(int a) { /* do something */ }
>>     void f(int b) { /* do something different */ }
>>  After all, if the name were part of the API, then they have different APIs.
>>  I'm not convinced that this is a good idea. It's also not the only
>> alternative. I have in the past written programs which take parameters
>> of the same underlying type in any order, using only D-as-it-is-now
>> (or C++), and it's not so hard. For example, suppose you want a
>> function that looks like
>>      MyDate makeDate(int month, int day, int year)
>>  but you think callers might get confused about what order to pass the
>> parameters in (European date order, American date order, YMD date
>> order, whatever...)
>>      typedef int Year;
>>     typedef int Month;
>>     typedef int Day;
>>      MyDate makeDate(Year y; Month m, Day d) {/*...*/ }
>>     MyDate makeDate(Year y, Day d, Month m) { return MyDate(y,m,d); }
>>     MyDate makeDate(Day d, Month m, Year y) { return MyDate(y,m,d); }
>>     MyDate makeDate(Month m, Day d, Year y) { return MyDate(y,m,d); }
>>  That forces callers to name their arguments, as in:
>>      MyDate date = makeDate(cast(Day)11, cast(Month)11, cast(Year)1999);
>>  If you wanted, you could also add a "default" function that took ints
>> but required parameters in the right order.
>>  And that, basically, is problem solved, as far as I can see.
>
> Gee that's so clean!  Not.
> You've taken one simple function and turned it into 4 functions plus 3 extra types.
> It's a workaround at best.
>
> --bb

That is a bad example of when (not) to use named parameters. A better one is:

typedef double Radions;
typedef double Degrees;

double sin(Degrees angleInDegrees);
double sin(Radions angleInRadians);

I think this is the classic example used to justify named parameters in Fortran-90.
The typedef trick doesn't always work. You can use const for memset

memset(void* dest, const void* source, int value);

but not for file copy:

void copyFile(string source, string dest);

Here source and dest are easily confusee leading to errors hard to pick up at runtime.
It would be nice if you could switch on an extra compiler warning that forces you to use
the parameter names to disambiguiate.
Some would argue that an alternative more OO solution would be:

File sourceFile(source);
sourceFile.copyTo(dest);

This kind of thing will be even easier when you can extend classes using any function
whose first argument is the right type for 'this'. Though there is a danger of serious
encapsulation breakage there.

Regards,

Bruce.




December 06, 2007
Bill Baxter, el  6 de diciembre a las 16:58 me escribiste:
> Janice Caron wrote:
> >On Dec 5, 2007 1:48 PM, renoX <renosky@free.fr> wrote:
> >>I could ask the opposite question: why should we restrict the API to the function and object name instead of using the full data that we have?
> >I often write constructor functions which look something like this
> >    this(int x_, int y_, int z_)
> >    {
> >        x = x_;
> >        y = y_;
> >        z = z_;
> >    }
> >If parameter names were part of the API, then anyone calling my code
> >would have to refer to those constructor parameters as x_, y_ and z_,
> >complete with trailing underscores
> >Of course, I could go back and change all my code to
> >    this(int x, int y, int z)
> >    {
> >        this.x = x;
> >        this.y = y;
> >        this.z = z;
> >    }
> >but that would be a lot of code to change, and it might break calling code!
> 
> That's why any named parameter proposal is going to have to flag the named parameters somehow.  Non-flagged parameters will continue to behave as always.

I don't see what's the big problem with named parameters being part of the API (when, by convention, you are told so). This is widely used on Python and works just great and it's damn useful.

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
A can of diet coke will float in water
While a can of regular coke will sink