www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Structs and Variadic Functions

reply Xinok <xknnet gmail.com> writes:
I think combining structs with variadic functions can introduce some new
interesting possibilities.

struct SS{
	int a, b, c;
}
static SS obj = {10, 20, 30}; // Full initalization
static SS obj = {a : 15, c : 35}; // Partial initalization


Apply this to a variadic function:
void func(SS arg ...){
	writefln(arg.a);
	writefln(arg.b);
	writefln(arg.c);
}

int main(){
	func(15, 30, 45); // Full initalization
	func(b : 45, c : 30); // Partial initalization
}



In response to my last two suggestions:
Using aliases for constants - I greatly misunderstood how 'const' works in D.
As long as you initalize the variable, D forces the expression to be constant.
static int a;
const int* ptr = &a; // OK
const int* ptr = new int; // Error: non-constant expression new int

Virtual Import - I didn't think this was a great idea anyways. I was just
trying to suggest a way to define aliases for modules.
Dec 17 2006
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Xinok" <xknnet gmail.com> wrote in message 
news:em4ctn$hhu$1 digitaldaemon.com...
I think combining structs with variadic functions can introduce some new
 interesting possibilities.

 struct SS{
 int a, b, c;
 }
 static SS obj = {10, 20, 30}; // Full initalization
 static SS obj = {a : 15, c : 35}; // Partial initalization


 Apply this to a variadic function:
 void func(SS arg ...){
 writefln(arg.a);
 writefln(arg.b);
 writefln(arg.c);
 }

 int main(){
 func(15, 30, 45); // Full initalization
 func(b : 45, c : 30); // Partial initalization
 }
I really like that. It also wouldn't impose any extra overhead, since the size of the structure on the stack would be the same size as if you were to pass those parameters, and accessing those struct members in the function would also be virtually the same as accessing parameters.
Dec 17 2006
prev sibling next sibling parent reply Kenny <seriousmoose yahoo.com> writes:
I would also like to see this. One of my favourite things about js, is that I
can
send it an assoc array of whatever I want... functions, floats, strings,
integers,
and the ones I don't send are null. having that for functions would be
AMAZING...
I think it's not that hard to implement either. I suppose one could push on the
stack a list of pointers in the order they appear in the struct... the null ones
being uninitialized. then, inside of the function, the values will have to be
loaded, grabbing the value of a pointer. Technically, you can already do
something
similar though, by setting default values for all params to the function.

1. but, you can't call them unordered, referencing only the names.
2. if you know you want the first and third argument initialized, then it's
weird
to skip the second.

hmmmmm. this is a really good idea.
Dec 19 2006
parent Xinok <xnknet gmail.com> writes:
The main use I saw for this feature was passing properties to a function. Take
for
example, a file class:

class File{
	private struct FProp{
		string path; // Path to the file to open
		bool read, write; // Open file to read or write
		int cache; // File cache
		bool temp; // Temporary file?
		bool binary; // Open file in binary mode?
	}

	this(FProp prop ...); // Constructor
}


int main(){
	File ifile(path : "C:\\in.dat", read : true, cache : 4096);
	File ofile(path : "C:\\out.dat", write : true, cache : 0, temp : true);
}


You only set the properties you need, and in any order you want.
Dec 19 2006
prev sibling parent reply Reiner Pope <xxxxxx xxx.xx> writes:
Xinok wrote:
 I think combining structs with variadic functions can introduce some new
 interesting possibilities.
 
 struct SS{
 	int a, b, c;
 }
 static SS obj = {10, 20, 30}; // Full initalization
 static SS obj = {a : 15, c : 35}; // Partial initalization
 
 
 Apply this to a variadic function:
 void func(SS arg ...){
 	writefln(arg.a);
 	writefln(arg.b);
 	writefln(arg.c);
 }
 
 int main(){
 	func(15, 30, 45); // Full initalization
 	func(b : 45, c : 30); // Partial initalization
 }
 
Unless I misunderstand you, it seems you are suggesting named parameters. Some other languages have this already (for example, OCaml), but it doesn't require structs to do this. You can pick up the names of parameters from the prototype, and we already have support for default parameters. All you need now is support for naming parameters at the call-site, for which your syntax seems perfectly suitable. Then, you could avoid variadic functions and structs and just write: FilePtr openFile(char[] filename, bool read=true, bool write=true, bool append=false, bool anotherParam=false) {...} int main(){ openFile(filename : "asdf.txt", append : true); // Equivalent to openFile("asdf.txt", true, true, true, false); } Which is certainly a nice syntax feature to have. Cheers, Reiner
Dec 20 2006
next sibling parent "Kristian Kilpi" <kjkilpi gmail.com> writes:
On Thu, 21 Dec 2006 07:46:14 +0200, Reiner Pope <xxxxxx xxx.xx> wrote:
[snip]
 Unless I misunderstand you, it seems you are suggesting named  =
 parameters. Some other languages have this already (for example, OCaml=
), =
 but it doesn't require structs to do this. You can pick up the names o=
f =
 parameters from the prototype, and we already have support for default=
=
 parameters. All you need now is support for naming parameters at the  =
 call-site, for which your syntax seems perfectly suitable. Then, you  =
 could avoid variadic functions and structs and just write:

    FilePtr openFile(char[] filename, bool read=3Dtrue, bool write=3Dtr=
ue, =
 bool append=3Dfalse, bool anotherParam=3Dfalse) {...}

 int main(){
      openFile(filename : "asdf.txt", append : true);
      // Equivalent to openFile("asdf.txt", true, true, true, false);
 }

 Which is certainly a nice syntax feature to have.

 Cheers,

 Reiner
Yes, indeed. I guess named parameters have been suggested before (in thi= s = NG)? Does Walter see it as a potential 2.0+ feature?
Dec 21 2006
prev sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Reiner Pope wrote:
 Xinok wrote:
 I think combining structs with variadic functions can introduce some new
 interesting possibilities.

 struct SS{
     int a, b, c;
 }
 static SS obj = {10, 20, 30}; // Full initalization
 static SS obj = {a : 15, c : 35}; // Partial initalization


 Apply this to a variadic function:
 void func(SS arg ...){
     writefln(arg.a);
     writefln(arg.b);
     writefln(arg.c);
 }

 int main(){
     func(15, 30, 45); // Full initalization
     func(b : 45, c : 30); // Partial initalization
 }
Unless I misunderstand you, it seems you are suggesting named parameters. Some other languages have this already (for example, OCaml), but it doesn't require structs to do this. You can pick up the names of parameters from the prototype, and we already have support for default parameters. All you need now is support for naming parameters at the call-site, for which your syntax seems perfectly suitable. Then, you could avoid variadic functions and structs and just write: FilePtr openFile(char[] filename, bool read=true, bool write=true, bool append=false, bool anotherParam=false) {...} int main(){ openFile(filename : "asdf.txt", append : true); // Equivalent to openFile("asdf.txt", true, true, true, false); } Which is certainly a nice syntax feature to have.
This has been suggested several times. It may be possible. But I recall Walter was uncomfortable with parameter names in prototypes becoming significant all the sudden when they aren't in C/C++. Prototypes currently don't require a parameter to have a name at all. Then there's the added difficulty of figuring out overloading. If you have two functions with a parameter called 'foo' which one do you call for func(foo:23). Some new rules for what's the best match are probably needed. I don't think the issues are insurmountable, but they do require some work. And a willingness on everyone's part to accept that the _name_ of a parameter is now part of the public interface and thus changing a parameter name can break code. I don't recall about OCaml, but Python at least has keyword arguments but doesn't have overloading, so it doesn't have to deal with the overload/keyword interaction. Also I'd say that if regular functions get call-by keyword capability, then I would hope that templates get it too. So that may have some implications on the syntax used. If "keyword : value" is used for functions, then probably something different would have to be used for templates, since : already means specialization there. It would be nice if the same syntax could be used for both. Here are some links -- Thread started by Chris Sauls Jun 2005: http://www.digitalmars.com/d/archives/digitalmars/D/25835.html Thread started by me May 2005: http://www.digitalmars.com/d/archives/digitalmars/D/23172.html Thread started by Norbert Nemec, June 2004 http://www.digitalmars.com/d/archives/digitalmars/D/4543.html Thread started by Eric Shumard, May 2004 http://www.digitalmars.com/d/archives/digitalmars/D/752.html And this one's not about keyword args, but about default parameters and function pointers in general. Started by Don Clugston. http://www.digitalmars.com/d/archives/digitalmars/D/27291.html --bb
Dec 22 2006
parent reply Don Clugston <dac nospam.com.au> writes:
Bill Baxter wrote:
 And this one's not about keyword args, but about default parameters and 
 function pointers in general. Started by Don Clugston.
 http://www.digitalmars.com/d/archives/digitalmars/D/27291.html
Wow! That was my third ever D post!
Jan 09 2007
parent reply Xinok <xnknet gmail.com> writes:
Don Clugston Wrote:

 Bill Baxter wrote:
 And this one's not about keyword args, but about default parameters and 
 function pointers in general. Started by Don Clugston.
 http://www.digitalmars.com/d/archives/digitalmars/D/27291.html
Wow! That was my third ever D post!
While this post is still here, I'd like to make this suggestion: We have the 'default' keyword, let's use it! void func(int a = 15, int b = 30, int c = 45); func(45, default, 60);
Jan 09 2007
next sibling parent David L. Davis <SpottedTiger yahoo.com> writes:
I like this idea...it makes a lot of sense to me.

David L.
Jan 09 2007
prev sibling next sibling parent Pragma <ericanderton yahoo.removeme.com> writes:
Xinok wrote:
 Don Clugston Wrote:
 
 Bill Baxter wrote:
 And this one's not about keyword args, but about default parameters and 
 function pointers in general. Started by Don Clugston.
 http://www.digitalmars.com/d/archives/digitalmars/D/27291.html
Wow! That was my third ever D post!
While this post is still here, I'd like to make this suggestion: We have the 'default' keyword, let's use it! void func(int a = 15, int b = 30, int c = 45); func(45, default, 60);
Neat. I suppose 'default' could be used for non default args as well? void foo(int x); foo(default); // x = int.init -- - EricAnderton at yahoo
Jan 09 2007
prev sibling parent Xinok <xnknet gmail.com> writes:
Xinok Wrote:

 
 While this post is still here, I'd like to make this suggestion:
 We have the 'default' keyword, let's use it!
 
 void func(int a = 15, int b = 30, int c = 45);
 func(45, default, 60);
Just one more thing I'd like to add, this could propose a slight problem with overloading functions: void func(int a = 15, int b = 30, int c = 45); void func(int a = 15, string b = "Thirty", int c = 45); func(45, default, 60); // Error - Cannot overload default argument A simple suggestion for this: func(45, default int, 60); func(45, default string, 60); To the original post, perhaps we could introduce a new kind of default parameter to D? Something like a 'static default argument'.
 PROPOSAL
 The solution is really very simple.
 
 int afunc(int x, int y=3)
 {
 ..dosomething
 }
 
 should be *identical* to declaring TWO functions:
 
 int afunc(int x)
 {
 afunc(x, 3);
 }
 
 int afunc(int x, int y)
 {
 .. dosomething
 }
I know nothing about assembly, but would it be possible to simply put all the initalizers into a single function, and depending on the type of the function pointer, it jumps to the proper location in the function to initalize the rest of the parameters? int func(int a = 15, int b = 30, int c = 45){ a = 15; // int func() b = 30; // int func(int) c = 45; // int func(int, int) return a + b + c; // int func(int, int, int) } IAW, if you were to create a pointer to this function: int delegate(int, int) ptr = &func; This delegate would point directly to the address of the code where you see 'c = 45' This would eliminate any performance issues and 'ghost functions'.
Jan 09 2007