Thread overview
Re: Passing function parameters by name
Dec 04, 2007
bearophile
Dec 04, 2007
David Wilson
Dec 04, 2007
Artyom Shalkhakov
Dec 04, 2007
Bill Baxter
Dec 04, 2007
Robert Fraser
Dec 04, 2007
bearophile
Dec 04, 2007
Kirk McDonald
Dec 04, 2007
bearophile
December 04, 2007
Artyom Shalkhakov:
>     foo( b : 2.5f, a : -3 ); // sort of struct initializer

Python uses =

foo(b=2.5f, a=-3);

This is a very useful feature, I use it often in Python. But if you try to translate this Python code:

from sys import argv
def a(c="A"): print c
def b(c="B"): print c
l = [a, b]
if argv[1] == "1": l.reverse()
l[1]()

to D/C++ you can find a problem, becasue the "A" and "B" must be associated with the function. And the function must know what parameters aren't actually given to it. So you may need to silently pass an array of booleans too (and uint/ulong suffices) that encode what parameters you have actually given to the function (there are other solutions, based on pointers, but they seem even slower to me).

Bye,
bearophile
December 04, 2007
On 12/4/07, bearophile <bearophileHUGS@lycos.com> wrote:
> Artyom Shalkhakov:
> >     foo( b : 2.5f, a : -3 ); // sort of struct initializer
>
> Python uses =
>
> foo(b=2.5f, a=-3);
>
> This is a very useful feature, I use it often in Python. But if you try to translate this Python code:
>
> from sys import argv
> def a(c="A"): print c
> def b(c="B"): print c
> l = [a, b]
> if argv[1] == "1": l.reverse()
> l[1]()
>
> to D/C++ you can find a problem, becasue the "A" and "B" must be associated with the function. And the function must know what parameters aren't actually given to it. So you may need to silently pass an array of booleans too (and uint/ulong suffices) that encode what parameters you have actually given to the function (there are other solutions, based on pointers, but they seem even slower to me).


This one is pretty close to my heart too, but I can't quite decide what the resulting feature would look like in D. I made an effort to port Python's awesome ElementTree XML library to D, but found most of its convenient syntax was lost because D doesn't support named arguments.

A further twist to this is Python's ability to take arbitrary named arguments and build an associative array from them ("dict"). Implementing this feature would probably mean tight integration with AA literal syntax for uniformity's sake, but I couldn't come up with a syntax worth proposing.

Desirable:
 - Ability to specify non-default parameters after default parameters.
 - Ability to lazy-build an associative array argument to a function,
without using AA literal syntax.


Rough idea:

void foo(int a, bool b = true, bool c = false, char[][char[]] args);
foo(0xcafebabe, c: true, strangeArg: "hello", otherArg: "world");


Except I'm sure there's a plethora of things I've forgotten about (interactions with templates for example?)


David.


>
> Bye,
> bearophile
>
December 04, 2007
David Wilson Wrote:

> On 12/4/07, bearophile <bearophileHUGS@lycos.com> wrote:
> > Artyom Shalkhakov:
> > >     foo( b : 2.5f, a : -3 ); // sort of struct initializer
> >
> > Python uses =
> >
> > foo(b=2.5f, a=-3);
> >
> > This is a very useful feature, I use it often in Python. But if you try to translate this Python code:
> >
> > from sys import argv
> > def a(c="A"): print c
> > def b(c="B"): print c
> > l = [a, b]
> > if argv[1] == "1": l.reverse()
> > l[1]()
> >
> > to D/C++ you can find a problem, becasue the "A" and "B" must be associated with the function. And the function must know what parameters aren't actually given to it. So you may need to silently pass an array of booleans too (and uint/ulong suffices) that encode what parameters you have actually given to the function (there are other solutions, based on pointers, but they seem even slower to me).
> 
> 
> This one is pretty close to my heart too, but I can't quite decide what the resulting feature would look like in D. I made an effort to port Python's awesome ElementTree XML library to D, but found most of its convenient syntax was lost because D doesn't support named arguments.
> 
> A further twist to this is Python's ability to take arbitrary named arguments and build an associative array from them ("dict"). Implementing this feature would probably mean tight integration with AA literal syntax for uniformity's sake, but I couldn't come up with a syntax worth proposing.
> 
> Desirable:
>  - Ability to specify non-default parameters after default parameters.
>  - Ability to lazy-build an associative array argument to a function,
> without using AA literal syntax.
> 
> 
> Rough idea:
> 
> void foo(int a, bool b = true, bool c = false, char[][char[]] args);
> foo(0xcafebabe, c: true, strangeArg: "hello", otherArg: "world");
> 
> 
> Except I'm sure there's a plethora of things I've forgotten about (interactions with templates for example?)
> 
> 
> David.
> 
> 
> >
> > Bye,
> > bearophile
> >

I'm not into getting D so close to Python... I think that the default-parameter-values should remain as-is, with the added ability to address parameters by their name.

I suggest looking at D's struct initializers. (Make the process of initializing an array and calling a function more 'uniform'.)
December 04, 2007
Artyom Shalkhakov wrote:
> David Wilson Wrote:
> 
>> On 12/4/07, bearophile <bearophileHUGS@lycos.com> wrote:
>>> Artyom Shalkhakov:
>>>>     foo( b : 2.5f, a : -3 ); // sort of struct initializer
>>> Python uses =
>>>
>>> foo(b=2.5f, a=-3);
>>>
>>> This is a very useful feature, I use it often in Python. But if you try to translate this Python code:
>>>
>>> from sys import argv
>>> def a(c="A"): print c
>>> def b(c="B"): print c
>>> l = [a, b]
>>> if argv[1] == "1": l.reverse()
>>> l[1]()
>>>
>>> to D/C++ you can find a problem, becasue the "A" and "B" must be associated with the function. And the function must know what parameters aren't actually given to it. So you may need to silently pass an array of booleans too (and uint/ulong suffices) that encode what parameters you have actually given to the function (there are other solutions, based on pointers, but they seem even slower to me).
>>
>> This one is pretty close to my heart too, but I can't quite decide
>> what the resulting feature would look like in D. I made an effort to
>> port Python's awesome ElementTree XML library to D, but found most of
>> its convenient syntax was lost because D doesn't support named
>> arguments.
>>
>> A further twist to this is Python's ability to take arbitrary named
>> arguments and build an associative array from them ("dict").
>> Implementing this feature would probably mean tight integration with
>> AA literal syntax for uniformity's sake, but I couldn't come up with a
>> syntax worth proposing.
>>
>> Desirable:
>>  - Ability to specify non-default parameters after default parameters.
>>  - Ability to lazy-build an associative array argument to a function,
>> without using AA literal syntax.
>>
>>
>> Rough idea:
>>
>> void foo(int a, bool b = true, bool c = false, char[][char[]] args);
>> foo(0xcafebabe, c: true, strangeArg: "hello", otherArg: "world");
>>
>>
>> Except I'm sure there's a plethora of things I've forgotten about
>> (interactions with templates for example?)
>>
>>
>> David.
>>
>>
>>> Bye,
>>> bearophile
>>>
> 
> I'm not into getting D so close to Python... I think that the default-parameter-values should remain as-is, with the added ability to address parameters by their name.
> 
> I suggest looking at D's struct initializers. (Make the process of initializing an array and calling a function more 'uniform'.)

I think for any keyword argument proposal to fly, it's going to need to specially mark the keyword args.  D's parameter declaration syntax is tied very closely to that of C/C++ and changing that wholesale will break tons of D code and probably make interfacing with C code a confusing mess.  In C/C++/D You can declare prototypes using different parameter names from the actual implementation, or with no names at all.  This is behavior that is relied upon in many places.

However, if the keyword arguments were differentiated from the regular arguments, it might be workable.   Lisp uses some kind of token like "&keyword" to separate keyword arguments from others.  When calling, the keyword for a keyword arg must always be specified.  That sort of things seems like it might be doable in a backwards-compatible way.  So something like:
    void myFunc(int x, &&, float key1=10, float key2=20);
    ...
    myFunc(3, key2:10);

I think the problem with any keyword arg proposal at this point is that the cost/benefit ratio is low.  Thoroughly specing it out and implementing it will be difficult, but the benefit will not be that great.  It just adds a little extra convenience.   Fixing template overload issues, for instance, would be a much bigger win.  Or implementing real reference types.  Or Tuples as return values.

--bb
December 04, 2007
bearophile wrote:
> to D/C++ you can find a problem, becasue the "A" and "B" must be associated with the function. And the function must know what parameters aren't actually given to it. So you may need to silently pass an array of booleans too (and uint/ulong suffices) that encode what parameters you have actually given to the function (there are other solutions, based on pointers, but they seem even slower to me).

The call is bound at compile-time, so there's no runtime cost associated. The default parameters are passed in explicitly for the parameters that the user doesn't supply.
December 04, 2007
Robert Fraser:
> The call is bound at compile-time,

I can't understand how you can fully solve that problem I have shown at compile time. A function pointer can be managed at runtime, so at runtime you can choose to give or to not give the default parameter...

Bye,
bearophile
December 04, 2007
bearophile wrote:
> Robert Fraser:
> 
>>The call is bound at compile-time,
> 
> 
> I can't understand how you can fully solve that problem I have shown at compile time. A function pointer can be managed at runtime, so at runtime you can choose to give or to not give the default parameter...
> 
> Bye,
> bearophile

Function pointers don't know anything about default parameters. That is, the following does not work:

void foo(int i=20) {}

void main() {
    void function() fn = &foo; // Error: typeof(&foo) is
                               // void function(int)
    fn();
}

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org
December 04, 2007
Kirk McDonald Wrote:
> Function pointers don't know anything about default parameters. That is, the following does not work:

I was talking about adding things to D. So it can solve the kind of problem I have shown in my first post. I am talking about possible enhancements...

Bye,
bearophile