Jump to page: 1 2
Thread overview
Default values for functions, and named parameters...
Aug 17, 2001
Taylor Gautier
Aug 17, 2001
Russ Lewis
Aug 17, 2001
Russ Lewis
Aug 20, 2001
Taylor Gautier
Aug 19, 2001
Walter
Aug 20, 2001
Taylor Gautier
Aug 25, 2001
Dan Hursh
Aug 31, 2001
Walter
Oct 23, 2001
Sean L. Palmer
Oct 23, 2001
Sean L. Palmer
Dec 30, 2001
Walter
Dec 31, 2001
Pavel Minayev
Dec 31, 2001
Walter
Dec 31, 2001
Pavel Minayev
Jan 01, 2002
Walter
Jan 01, 2002
Pavel Minayev
August 17, 2001
I scanned through the docs for D, looks pretty cool!  I didn't see a lot of documentation regarding functions so I'll ask one question, and make a suggestion too.  If these were already in the documenation, I apologize in advance!

1) Are there default values allowed for functions?  With the strong influence of C/C++ on D, I would imagine so.

2) After reading the following section regarding static initialization of structs in any order, a thought occurred to me about the usefulness of this construct:

~ D documentation
Static struct members are by default initialized to 0, and floating point
values to NAN. If a static initializer is supplied, the members are
initialized by the member name, colon, expression syntax. The members may be
initialized in any order.
 struct X { int a; int b; int c; int d = 7;}
 static X x = { a:1, b:2}; // c is set to 0, d to 7
 static X z = { c:4, b:5, a:2 , d:5};   // z.a = 2, z.b = 5, z.c = 4, d = 5
~

How many times have you written a function like (ok, this is c++ like
syntax, bear with me):

class foo
{
    ...
    void do_some_foo(int a, int b = DEFAULT_B_VAL, int c = DEFAULT_C_VAL);
};

But then, you wanted to call do_some_foo() with the value a, and the value c, but use the default value for b.  It turns out that in practice, functions with more than 1 default value are generally not as useful as functions with 1 default value, because with 2 or more default values, you generally end up wanting to specify each of the two values independently while leaving the other to be the default value in different places in your code, yet this is not possible. (it get's worse with more defaults)

Combining this wish (to have independent default values) with a nice little perl-ism that allows for named parameters [ala lincoln stein's CGI.pm and probably others] *and* with D's static struct initialization syntax, couldn't the calling syntax for functions be enhanced in general to allow for the arbitrary ordering of parameters, so long as you named them?

This would allow you to call:

int main()
{
    foo f;

    f.do_some_foo(a:12, c:6);

   // which should be equivalent to:

   f.do_some_foo(12, c:6);
}


August 17, 2001
Taylor Gautier wrote:

> I scanned through the docs for D, looks pretty cool!  I didn't see a lot of documentation regarding functions so I'll ask one question, and make a suggestion too.  If these were already in the documenation, I apologize in advance!
>
> 1) Are there default values allowed for functions?  With the strong influence of C/C++ on D, I would imagine so.
>
> 2) After reading the following section regarding static initialization of structs in any order, a thought occurred to me about the usefulness of this construct:
>
> ~ D documentation
> Static struct members are by default initialized to 0, and floating point
> values to NAN. If a static initializer is supplied, the members are
> initialized by the member name, colon, expression syntax. The members may be
> initialized in any order.
>  struct X { int a; int b; int c; int d = 7;}
>  static X x = { a:1, b:2}; // c is set to 0, d to 7
>  static X z = { c:4, b:5, a:2 , d:5};   // z.a = 2, z.b = 5, z.c = 4, d = 5
> ~
>
> How many times have you written a function like (ok, this is c++ like
> syntax, bear with me):
>
> class foo
> {
>     ...
>     void do_some_foo(int a, int b = DEFAULT_B_VAL, int c = DEFAULT_C_VAL);
> };
>
> But then, you wanted to call do_some_foo() with the value a, and the value c, but use the default value for b.  It turns out that in practice, functions with more than 1 default value are generally not as useful as functions with 1 default value, because with 2 or more default values, you generally end up wanting to specify each of the two values independently while leaving the other to be the default value in different places in your code, yet this is not possible. (it get's worse with more defaults)
>
> Combining this wish (to have independent default values) with a nice little perl-ism that allows for named parameters [ala lincoln stein's CGI.pm and probably others] *and* with D's static struct initialization syntax, couldn't the calling syntax for functions be enhanced in general to allow for the arbitrary ordering of parameters, so long as you named them?
>
> This would allow you to call:
>
> int main()
> {
>     foo f;
>
>     f.do_some_foo(a:12, c:6);
>
>    // which should be equivalent to:
>
>    f.do_some_foo(12, c:6);
> }

I would think that a call like

    f.do_some_foo(a,,c)

would be more readable, but I'm not sure that it is worth it.  Too much possibility of syntax errors or bugs from hitting , too many times.  What about:

    f.do_some_foo(a,default,c)

I dunno if I really like it.  Just brainstorming...thoughts, anyone?


August 17, 2001
My mistake.  Used wrong values in my previous post...

>     f.do_some_foo(a,,c)

should be:   f.do_some_foo(12,,6)

>     f.do_some_foo(a,default,c)

should be:   f.do_some_foo(12,default,6)

August 18, 2001
Taylor Gautier wrote:

> class foo
> {
>     ...
>     void do_some_foo(int a, int b = DEFAULT_B_VAL, int c = DEFAULT_C_VAL);
> };

> This would allow you to call:
>
> int main()
> {
>     foo f;
>
>     f.do_some_foo(a:12, c:6);
>
>    // which should be equivalent to:
>
>    f.do_some_foo(12, c:6);
> }

I believe you meant

    f.do_some_foo(12, DEFAULT_B_VAL, 6)


First point: LX has that very feature:

[localhost:~/Development/mozart/lx] ddd% cat test.lx function f(integer A := 0, B := 1, C := 2) return integer

integer A := f()
integer B := f(1)
integer C := f(2, 3)
integer D := f(C: 4)
integer E := f(B: 1, C: 2, A: 0)


[localhost:~/Development/mozart/lx] ddd% ./lx -parse test.lx -run_semantics
-stdout
-- Generated by LX using lx-text.stylesheet
import  LX_BUILTINS
using LX_BUILTINS

constant  function f( in _integer A := 0;  in _integer B := 1;
                      in _integer C := 2) return _integer
variable  _integer A := f (0, 1, 2)
variable  _integer B := f (1, 1, 2)
variable  _integer C := f (2, 3, 2)
variable  _integer D := f (0, 1, 4)
variable  _integer E := f (0, 1, 2)
-- Thank you for using LX.
[localhost:~/Development/mozart/lx] ddd%



Second point: did you know that a little known "feature" of C++ in that space allows you to write code that becomes invalid if you _include_ a header file (not that most C++ compiler care...) The C++ rules are that default arguments from multiple declarations combine, but that they must not overlap. And also, there must be a default for argument for arg[N+1] if there is one for arg[N]. So:

// file1.C
int f(int x = 0, int y);    // NO: default required for y

// file2.C
int f(int x, int y = 0);
int f(int x = 0, int y);    // OK: both have defaults

// file3.C
int f(int x = 0, int y = 0);
int f(int x = 0, int y);    // NO: two defaults for x


Notice how the _EXACT SAME DEFINITION_ becomes invalid depending on the context. If you have a compiler that cares about these rules, you can misuse them for really great "mysterious error of the day" jokes. In particular, have declarations that compile either only when the header is included, or alternatively, only when the header is _NOT_ included, or even combinations where some headers have to be included in a very specific order. All this without even using the preprocessor.

Conclusion: beware of the exact rules in D :-)


Christophe





August 19, 2001
Taylor Gautier wrote in message <9ljqh1$25ki$1@digitaldaemon.com>...
>I scanned through the docs for D, looks pretty cool!  I didn't see a lot of
>documentation regarding functions so I'll ask one question, and make a
>suggestion too.  If these were already in the documenation, I apologize in
>advance!
>1) Are there default values allowed for functions?  With the strong
>influence of C/C++ on D, I would imagine so.


No. The behavior can be duplicated with:

    void foo(int x, int y) { ... }
    void foo(int x) { foo(x, 3); }

so there's no need for it or all the weird consequences of it.



>Combining this wish (to have independent default values) with a nice little perl-ism that allows for named parameters [ala lincoln stein's CGI.pm and probably others] *and* with D's static struct initialization syntax, couldn't the calling syntax for functions be enhanced in general to allow for the arbitrary ordering of parameters, so long as you named them?


I've needed the named initialization thing with structs because I've dealt with structs with dozens of members. While function parameters are technically the same concept, I just don't come across functions with dozens of parameters.


August 20, 2001
"Christophe de Dinechin" <descubes@earthlink.net> wrote in message news:3B7E2161.C752432D@earthlink.net...
> Taylor Gautier wrote:
>
> > class foo
> > {
> >     ...
> >     void do_some_foo(int a, int b = DEFAULT_B_VAL, int c =
DEFAULT_C_VAL);
> > };
>
> > This would allow you to call:
> >
> > int main()
> > {
> >     foo f;
> >
> >     f.do_some_foo(a:12, c:6);
> >
> >    // which should be equivalent to:
> >
> >    f.do_some_foo(12, c:6);
> > }
>
> I believe you meant
>
>     f.do_some_foo(12, DEFAULT_B_VAL, 6)

You missed my point.  I did NOT mean

f.do_some_foo(12, DEFAULT_B_VAL, 6);

I wrote:

f.do_some_foo(12, c:6)

on purpose for precisely the reason that I DON'T want to have to know what DEFAULT_B_VAL is defined to be.  (Sure if it's a constant, that's nice, but what if it isn't?)

I don't want D to have C++ semantics, I would like for D to have something more advanced than that.

I understand the rules surrounding default values that you mention in your response.  It is precisely these rules that are limiting and confusing.  I would like, for instance, a way to specify all 9 parameters to a function to have some reasonable defaults, and to be able to call that function specifying values for say any 2 input parameters. This type of thing is simply not possible with C++ rules/syntax.

-t


August 20, 2001
Hmmm :(

Well, I imagine one day in D you might see:

class foo
{
    struct bar_args { int a; int b; int c; int d = 7;};
    void bar(bar_args args);
};

void main()
{
    bar(foo::bar_args{a:1, b:2});
}

Or something equivalent (not sure if that's 100% syntactically correct) hehe
:)

I've seen the need for a lot of parameters when building CGI/HTML programming aids (which is why I mentioned CGI.pm) where tons of input parameters can abound, generally with reasonable defaults to all of them.

You can always design around functions with a lot of parameters, but I don't think a language should force you to design around anything, yes? (I assume it's why you started D)

-t

"Walter" <walter@digitalmars.com> wrote in message news:9ln6rh$1b8b$2@digitaldaemon.com...
> Taylor Gautier wrote in message <9ljqh1$25ki$1@digitaldaemon.com>...
> >I scanned through the docs for D, looks pretty cool!  I didn't see a lot
of
> >documentation regarding functions so I'll ask one question, and make a suggestion too.  If these were already in the documenation, I apologize
in
> >advance!
> >1) Are there default values allowed for functions?  With the strong
> >influence of C/C++ on D, I would imagine so.
>
>
> No. The behavior can be duplicated with:
>
>     void foo(int x, int y) { ... }
>     void foo(int x) { foo(x, 3); }
>
> so there's no need for it or all the weird consequences of it.
>
>
>
> >Combining this wish (to have independent default values) with a nice
little
> >perl-ism that allows for named parameters [ala lincoln stein's CGI.pm and probably others] *and* with D's static struct initialization syntax, couldn't the calling syntax for functions be enhanced in general to allow for the arbitrary ordering of parameters, so long as you named them?
>
>
> I've needed the named initialization thing with structs because I've dealt with structs with dozens of members. While function parameters are technically the same concept, I just don't come across functions with
dozens
> of parameters.
>
>


August 25, 2001
Walter wrote:
> 
> Taylor Gautier wrote in message <9ljqh1$25ki$1@digitaldaemon.com>...
> >I scanned through the docs for D, looks pretty cool!  I didn't see a lot of
> >documentation regarding functions so I'll ask one question, and make a
> >suggestion too.  If these were already in the documenation, I apologize in
> >advance!
> >1) Are there default values allowed for functions?  With the strong
> >influence of C/C++ on D, I would imagine so.
> 
> No. The behavior can be duplicated with:
> 
>     void foo(int x, int y) { ... }
>     void foo(int x) { foo(x, 3); }
> 
> so there's no need for it or all the weird consequences of it.

	Mind if I ask what weirdness there is?  (aside from the possible
overlap of function declarations?)  I'm a novice, so if it's too complex
to explain in a meaningful way, don't worry.
	It's handy feature but your example demonstrated that it isn't that
handy by itself.  At least the default value is reflected in the
declaration of the function.  Some object browsers could use that.  But
it would probably be unpleasant to see if there is an f(int x = 0) and
an f().

> >Combining this wish (to have independent default values) with a nice little perl-ism that allows for named parameters [ala lincoln stein's CGI.pm and probably others] *and* with D's static struct initialization syntax, couldn't the calling syntax for functions be enhanced in general to allow for the arbitrary ordering of parameters, so long as you named them?
> 
> I've needed the named initialization thing with structs because I've dealt with structs with dozens of members. While function parameters are technically the same concept, I just don't come across functions with dozens of parameters.

If you had the above feature, this would be very beautiful.  Given named parameters and the ability to set defaults for a scope would be even nicer,


	import guiApi; // for the draw method

	// declare a local set of defaults
	return_t draw(window_t w = mywindow, color fg = myfg, color bg = mybg,
		      drawable d, position_t p, scale_t s = 1.0,
		      rotation_t r = 0.0);

	// draw a box
	draw(d:mybox p:here);

	// draw a diamond
	draw(d:mybox p:there r:(PI/4));


I will say that I wouldn't see named parameter as being too useful
without some sort of declared parameter defaults.  I supposed I should
shut up so you can spend more time on the compiler instead of dealing
with my odd suggestions.

Dan
August 31, 2001
The wierdness comes from how overloading works, and what happens when you inherit and override the function. You have to come up with some convoluted rules that wind up being confusing to many programmers.

-Walter

Dan Hursh wrote in message <3B873BB4.287DE4FA@infonet.isl.net>...
>Walter wrote:
>>
>> Taylor Gautier wrote in message <9ljqh1$25ki$1@digitaldaemon.com>...
>> >I scanned through the docs for D, looks pretty cool!  I didn't see a lot
of
>> >documentation regarding functions so I'll ask one question, and make a suggestion too.  If these were already in the documenation, I apologize
in
>> >advance!
>> >1) Are there default values allowed for functions?  With the strong
>> >influence of C/C++ on D, I would imagine so.
>>
>> No. The behavior can be duplicated with:
>>
>>     void foo(int x, int y) { ... }
>>     void foo(int x) { foo(x, 3); }
>>
>> so there's no need for it or all the weird consequences of it.
>
> Mind if I ask what weirdness there is?  (aside from the possible
>overlap of function declarations?)  I'm a novice, so if it's too complex to explain in a meaningful way, don't worry.
> It's handy feature but your example demonstrated that it isn't that
>handy by itself.  At least the default value is reflected in the declaration of the function.  Some object browsers could use that.  But it would probably be unpleasant to see if there is an f(int x = 0) and an f().
>
>> >Combining this wish (to have independent default values) with a nice
little
>> >perl-ism that allows for named parameters [ala lincoln stein's CGI.pm
and
>> >probably others] *and* with D's static struct initialization syntax, couldn't the calling syntax for functions be enhanced in general to
allow
>> >for the arbitrary ordering of parameters, so long as you named them?
>>
>> I've needed the named initialization thing with structs because I've
dealt
>> with structs with dozens of members. While function parameters are technically the same concept, I just don't come across functions with
dozens
>> of parameters.
>
>If you had the above feature, this would be very beautiful.  Given named parameters and the ability to set defaults for a scope would be even nicer,
>
>
> import guiApi; // for the draw method
>
> // declare a local set of defaults
> return_t draw(window_t w = mywindow, color fg = myfg, color bg = mybg,
>       drawable d, position_t p, scale_t s = 1.0,
>       rotation_t r = 0.0);
>
> // draw a box
> draw(d:mybox p:here);
>
> // draw a diamond
> draw(d:mybox p:there r:(PI/4));
>
>
>I will say that I wouldn't see named parameter as being too useful without some sort of declared parameter defaults.  I supposed I should shut up so you can spend more time on the compiler instead of dealing with my odd suggestions.
>
>Dan


October 23, 2001
> 1) Are there default values allowed for functions?  With the strong influence of C/C++ on D, I would imagine so.

In fact I'd like to see the ability to default-initialize members at point of declaration, like so:

class Foo
{
  private:
    static int usage = 0;  // this assignment happens before main()
    int count = 1;           // this happens before any ctors are run (when
vtable is being initialized, probably)
    const char[] name = "unnamed"; // default ctor below won't use this
default value cuz compiler can tell name gets assigned before it gets read.
  public:
    Foo() { name = "Foo"; } // but count gets initialized to 1 first
}

Whaddya think, Walter?

> 2) After reading the following section regarding static initialization of structs in any order, a thought occurred to me about the usefulness of
this
> construct:
>
> ~ D documentation
> Static struct members are by default initialized to 0, and floating point
> values to NAN. If a static initializer is supplied, the members are
> initialized by the member name, colon, expression syntax. The members may
be
> initialized in any order.
>  struct X { int a; int b; int c; int d = 7;}
>  static X x = { a:1, b:2}; // c is set to 0, d to 7
>  static X z = { c:4, b:5, a:2 , d:5};   // z.a = 2, z.b = 5, z.c = 4, d =
5
> ~
>
> How many times have you written a function like (ok, this is c++ like
> syntax, bear with me):
>
> class foo
> {
>     ...
>     void do_some_foo(int a, int b = DEFAULT_B_VAL, int c = DEFAULT_C_VAL);
> };
>
> But then, you wanted to call do_some_foo() with the value a, and the value c, but use the default value for b.  It turns out that in practice, functions with more than 1 default value are generally not as useful as functions with 1 default value, because with 2 or more default values, you generally end up wanting to specify each of the two values independently while leaving the other to be the default value in different places in
your
> code, yet this is not possible. (it get's worse with more defaults)
>
> Combining this wish (to have independent default values) with a nice
little
> perl-ism that allows for named parameters [ala lincoln stein's CGI.pm and probably others] *and* with D's static struct initialization syntax, couldn't the calling syntax for functions be enhanced in general to allow for the arbitrary ordering of parameters, so long as you named them?
>
> This would allow you to call:
>
> int main()
> {
>     foo f;
>
>     f.do_some_foo(a:12, c:6);
>
>    // which should be equivalent to:
>
>    f.do_some_foo(12, c:6);
> }

I actually think this second point is a good idea too.

Just thought of something silly.  If you have  ? :  operators, you wouldn't need if or else keywords so long as you can treat a block as having a void value, and make  ? :  accept void values as its second and third arguments. Of course is one was void the other'd have to also be void.  Can't think of an equivalent for while.  ;)

I wonder what a language which didn't differentiate between a statement, block, or expression would be like?

Sean


« First   ‹ Prev
1 2