View mode: basic / threaded / horizontal-split · Log in · Help
June 26, 2005
Associative parameters
Okay... I vaguely remember this getting mentioned, either by myself, or Matthew, or some 
other D-ite with some Python experience, and then getting discussed briefly, and 
more-or-less forgotten...  Well, recently I found myself randomly loving it again, and 
decided to bring it up once more.  :)

In python, suppose a define a function, let's call it 'foo', and suppose it takes three 
paramters, let's call them 'x', 'y', and 'z'.  Now, ordinarily one would just call it in 
the usual way:

# foo( someX, someY, someZ )

But suppose, for some reason -- maybe the values look better this way, maybe it suits the 
overall style of the coder writing the call, whatever -- someone decides they'd like to 
pass them in a different order, or that they'd like to be explicit about what each 
parameter is (I've felt this way often with the Win32 API, for example, and usually go 
about it using comments).  In python, you would do something like this:

# foo (
#   x = someX ,
#   y = someY ,
#   z = someZ
#   )

Now isn't that just nifty?  So... given the following D function decleration:

# void myfunc (Cartesian grid, Point rectOrigin, Size rectSize, Translation action) {
#   // do stuff
# }

Wouldn't it be nice to be able to do something like... this:

# myfunc(
#   action     : Translation.Move(5, 10)       ,
#   rectOrigin : Point(p_rect.x, p_rect.y)     ,
#   rectSize   : Size(p_rect.w, p_rect.h)      ,
#   grid       : g_grid                        ,
# );

Now... isn't that descriptive?  :)  Naturally there would have to be strict rules.  Either 
A) make a given function call either associative or not, never both, or B) require that 
any non-associative parameters come first and be in proper order (which if I remember 
right, is what Python does).  Also it would, of course, have to be an error to pass a 
parameter twice.

I know I'm probably blowing smoke, but its something I'm fond of.  (The associative 
parameters, not the smoke.)

-- Chris Sauls
June 26, 2005
Re: Associative parameters
In article <d9lnrr$26q3$1@digitaldaemon.com>, Chris Sauls says...
> In python, you would do something like this:
>
># foo (
>#   x = someX ,
>#   y = someY ,
>#   z = someZ
>#   )
>
>Now isn't that just nifty?


This is also called "named parameters" in some languages (since parameters
are resolved by name, not by position). And, yes, I like it too :)

Best regards,
Stefan
June 27, 2005
Re: Associative parameters
"Sefan Zobel" <Sefan_member@pathlink.com> wrote in message
news:d9n5i9$aad$1@digitaldaemon.com...
> In article <d9lnrr$26q3$1@digitaldaemon.com>, Chris Sauls says...
> > In python, you would do something like this:
> >
> ># foo (
> >#   x = someX ,
> >#   y = someY ,
> >#   z = someZ
> >#   )
> >
> >Now isn't that just nifty?
>
>
> This is also called "named parameters" in some languages (since parameters
> are resolved by name, not by position). And, yes, I like it too :)

Named parameters are problematic when overloading is thrown into the mix.
June 27, 2005
Re: Associative parameters
Chris Sauls wrote:

> Okay... I vaguely remember this getting mentioned, either by myself, or 
> Matthew, or some other D-ite with some Python experience, and then 
> getting discussed briefly, and more-or-less forgotten...  Well, recently 
> I found myself randomly loving it again, and decided to bring it up once 
> more.  :)
> 
> In python, suppose a define a function, let's call it 'foo', and suppose 
> it takes three paramters, let's call them 'x', 'y', and 'z'.  Now, 
> ordinarily one would just call it in the usual way:
> 
> # foo( someX, someY, someZ )
> 
> But suppose, for some reason -- maybe the values look better this way, 
> maybe it suits the overall style of the coder writing the call, whatever 
> -- someone decides they'd like to pass them in a different order, or 
> that they'd like to be explicit about what each parameter is (I've felt 
> this way often with the Win32 API, for example, and usually go about it 
> using comments).  In python, you would do something like this:
> 
> # foo (
> #   x = someX ,
> #   y = someY ,
> #   z = someZ
> #   )
> 
> Now isn't that just nifty?  So... given the following D function 
> decleration:
> 
> # void myfunc (Cartesian grid, Point rectOrigin, Size rectSize, 
> Translation action) {
> #   // do stuff
> # }
> 
> Wouldn't it be nice to be able to do something like... this:
> 
> # myfunc(
> #   action     : Translation.Move(5, 10)       ,
> #   rectOrigin : Point(p_rect.x, p_rect.y)     ,
> #   rectSize   : Size(p_rect.w, p_rect.h)      ,
> #   grid       : g_grid                        ,
> # );
> 
> Now... isn't that descriptive?  :)  Naturally there would have to be 
> strict rules.  Either A) make a given function call either associative 
> or not, never both, or B) require that any non-associative parameters 
> come first and be in proper order (which if I remember right, is what 
> Python does).  Also it would, of course, have to be an error to pass a 
> parameter twice.
> 
> I know I'm probably blowing smoke, but its something I'm fond of.  (The 
> associative parameters, not the smoke.)
> 
> -- Chris Sauls


// Closest hack I can think of:

import std.stdio;

template myfunc()
{
  int x=0, y=0, z=0;

  void call( int xx = x, int yy=y, int zz = z )
  {
    writefln( "X %s, Y %s, Z %s", xx, yy, zz );
  }
}

void main( char[][] arg )
{
  with( myfunc!() )
  {
    x = 100;
    y = 200;
    z = -20;
    call();
  }
}
July 10, 2007
Re: Associative parameters
Walter Wrote:

> 
> "Sefan Zobel" <Sefan_member@pathlink.com> wrote in message
> news:d9n5i9$aad$1@digitaldaemon.com...
> > In article <d9lnrr$26q3$1@digitaldaemon.com>, Chris Sauls says...
> > > In python, you would do something like this:
> > >
> > ># foo (
> > >#   x = someX ,
> > >#   y = someY ,
> > >#   z = someZ
> > >#   )
> > >
> > >Now isn't that just nifty?
> >
> >
> > This is also called "named parameters" in some languages (since parameters
> > are resolved by name, not by position). And, yes, I like it too :)
> 
> Named parameters are problematic when overloading is thrown into the mix.
> 
> 
What is problematic? I used named parameters with Ada and I'm not aware of any problems with it.
In addition to making the code easier to read, named parameters avoid the burden of creating "dummy" functions when some parameters are optional.
I found nothing on the net telling that python's or ada's implementation of named parameters is problematic.
Can someone confirm/infirm on this point?
July 10, 2007
Re: Associative parameters
Greg wrote:
> Walter Wrote:
> 
>> "Sefan Zobel" <Sefan_member@pathlink.com> wrote in message
>> news:d9n5i9$aad$1@digitaldaemon.com...
>>> In article <d9lnrr$26q3$1@digitaldaemon.com>, Chris Sauls says...
>>>> In python, you would do something like this:
>>>>
>>>> # foo (
>>>> #   x = someX ,
>>>> #   y = someY ,
>>>> #   z = someZ
>>>> #   )
>>>>
>>>> Now isn't that just nifty?
>>>
>>> This is also called "named parameters" in some languages (since parameters
>>> are resolved by name, not by position). And, yes, I like it too :)
>> Named parameters are problematic when overloading is thrown into the mix.
>>
>>
> What is problematic? I used named parameters with Ada and I'm not aware of any problems with it.
> In addition to making the code easier to read, named parameters avoid the burden of creating "dummy" functions when some parameters are optional.
> I found nothing on the net telling that python's or ada's implementation of named parameters is problematic.
> Can someone confirm/infirm on this point?

I don't know about Ada, but Python doesn't have function overloading.
A given module can only have one function called 'foo'.

But I do recall reading an essay/rant somewhere talking about how 
sometimes just picking one way to do something makes life easier for 
everyone, and the handling of function overloading was mentioned.  I 
think it mentioned Ada's way and Python's way specifically. 
Unfortunately I can't seem to find it now.

--bb
July 10, 2007
Re: Associative parameters
Bill Baxter wrote:
> Greg wrote:
>> Walter Wrote:
>>
>>> "Sefan Zobel" <Sefan_member@pathlink.com> wrote in message
>>> news:d9n5i9$aad$1@digitaldaemon.com...
>>>> In article <d9lnrr$26q3$1@digitaldaemon.com>, Chris Sauls says...
>>>>> In python, you would do something like this:
>>>>>
>>>>> # foo (
>>>>> #   x = someX ,
>>>>> #   y = someY ,
>>>>> #   z = someZ
>>>>> #   )
>>>>>
>>>>> Now isn't that just nifty?
>>>>
>>>> This is also called "named parameters" in some languages (since 
>>>> parameters
>>>> are resolved by name, not by position). And, yes, I like it too :)
>>> Named parameters are problematic when overloading is thrown into the 
>>> mix.
>>>
>>>
>> What is problematic? I used named parameters with Ada and I'm not 
>> aware of any problems with it.
>> In addition to making the code easier to read, named parameters avoid 
>> the burden of creating "dummy" functions when some parameters are 
>> optional.
>> I found nothing on the net telling that python's or ada's 
>> implementation of named parameters is problematic.
>> Can someone confirm/infirm on this point?
> 
> I don't know about Ada, but Python doesn't have function overloading.
> A given module can only have one function called 'foo'.

Just my $0.02 here: Lately I have been doing a lot more python programming and I've found it's named arguments to be a 
good substitute for overloading.  It's not perfect replacement, but it does have its advantages.  I have yet to find it 

problematic.

I can't speak for Ada though.

FWIW, ColdFusion script also offers named arguments, but it takes the all-or-nothing approach; if you name one arg, you 
must name all that you pass.  IMO, the python strategy (positional followed by named arguments) is much more intuitive.

But from what I can tell, named arguments are no more or less problematic than overloads mixed with default arguments. 
Right now, it's possible to create two or more overloads that can be called the same way, resulting in an ambiguity that 
is easily flagged by the compiler.  Named arguments just provide another way to make the same kind of mistake, so the 
developer must be no more aware than before.

void foobar(int d);
void foobar(int a=0,int b=0,int c=0,int d=0);
foobar(d=42); // which one?
foobar(69);   // which one?



> 
> But I do recall reading an essay/rant somewhere talking about how 
> sometimes just picking one way to do something makes life easier for 
> everyone, and the handling of function overloading was mentioned.  I 
> think it mentioned Ada's way and Python's way specifically. 
> Unfortunately I can't seem to find it now.
> 
> --bb


-- 
- EricAnderton at yahoo
July 10, 2007
Re: Associative parameters
Reply to Pragma,

> FWIW, ColdFusion script also offers named arguments, but it takes the
> all-or-nothing approach; if you name one arg, you must name all that
> you pass.  IMO, the python strategy (positional followed by named
> arguments) is much more intuitive.
> 

if we get named parameters, then we should also be able to get a tuple of 
parameter names.

maybe something like this:

is(typeof(fn) args = function);
is(fn argNames = names);

args val;
foreach(name; argNames)  val[name] = typeof(val[name]).init;



this would make my argument biding template(*) more robust.

static int fnc(int that, char has, bool lots, int[] of, float args)

// bind some args
alias Args!  (0,2,4).Become!(1,true,1e7).For!(fnc).Gives fn2;

vs.

alias Args!  (that,lots,args).Become!(1,true,1e7).For!(fnc).Gives fn2;



* http://www.dsource.org/projects/scrapple/browser/trunk/arg_bind/bind.d
July 11, 2007
Re: Associative parameters
Pragma wrote:
> Just my $0.02 here: Lately I have been doing a lot more python 
> programming and I've found it's named arguments to be a good substitute 
> for overloading.  It's not perfect replacement, but it does have its 
> advantages.  I have yet to find it
> problematic.

I think there's not much other way you could implement overloading in a 
language like Python where there are no declared types.

def foo(x):
   # do one thing
def foo(y):
   # do another thing

How's the interpreter supposed to decide which one you mean?  You could 
overload on the number of arguments I suppose, but by doing that you'd 
mostly just lose the ability to unambiguously refer to functions by name 
(which bites us even today in D2.0  -- callback=&foo;  ... but which 
foo?).  Variable numbers of arguments can be reasonably implemented 
using defaults.

But when you do have type info that you can overload on, it's a whole 
different thing.

> But from what I can tell, named arguments are no more or less 
> problematic than overloads mixed with default arguments. Right now, it's 
> possible to create two or more overloads that can be called the same 
> way, resulting in an ambiguity that is easily flagged by the compiler.
> Named arguments just provide another way to make the same kind of 
> mistake, so the developer must be no more aware than before.
> 
> void foobar(int d);
> void foobar(int a=0,int b=0,int c=0,int d=0);
> foobar(d=42); // which one?
> foobar(69);   // which one?

I like the idea of named parameters too, but the contrarian's argument 
is that even if the compiler can catch all the errors, it still adds a 
lot of complexity to the language.  Especially since there are already 3 
ways to overload functions (by arg types, by number of args, and with 
defaults).

To make it feasible I think we're first going to have to introduce a 
special syntax for keyword arguments.  Any D code that exists today 
should continue to behave the same as it does now.  Suddenly giving 
meaning to all parameter names would be a catastrophe.

In Lisp, for example, all keyword arguments follow a &key sigil:
   http://www.gigamonkeys.com/book/functions.html

(defun foo (bar &key (a 0) b c)
   (list bar a b c))
(foo)                   ==> ERROR missing required argument 'bar'
(foo 99)                ==> (99 0 NIL NIL)
(foo 99 :a 1)           ==> (99 1 NIL NIL)
(foo 99 :b 1)           ==> (99 0 1 NIL)

Something like that could probably be made to work for D.  I think Lisp 
also requires you to supply the keyword when you call it.  I.e.
(foo 3 2 1 0) doesn't work.  You have to name the keyword arguments. 
Even if that's not Lisp's rule, it makes sense for D, since it would cut 
down a lot on overload ambiguity issues.

In D you'd also be required to supply default values for all keyword 
args.  Be

So for D we could do something like:

void foo(int bar, :key: int a=0, int b=0, int c=0) {
   writefln("%s %s %s %s", bar,a,b,c};
}

The ":key:" token is just an example.  Could be any other unambiguous token.

--bb
Top | Discussion index | About this forum | D home