digitalmars.D - static parameters
- Bill Baxter (27/27) Aug 30 2007 On page 30 of WalterAndrei.pdf it talks about static function parameters...
- Robert Fraser (7/41) Aug 30 2007 As far as I understand it, it will allow overloading on constants for ma...
- Don Clugston (19/63) Aug 30 2007 Yes, means you can do compile-time regexps with identical syntax to run-...
- kris (3/37) Aug 30 2007 There appear to be a few features with the characteristics you describe....
- Reiner Pope (23/57) Aug 31 2007 I know it's far from the only way to do this, but static parameters
- Bruno Medeiros (14/48) Sep 01 2007 "this is just another way to do something we can already do" ?
- Bill Baxter (12/60) Sep 01 2007 By "do something we can already do" I meant the functionality, not the
- Bruno Medeiros (11/79) Sep 02 2007 That's the whole point of this functionality, just as described in
- Reiner Pope (5/13) Sep 02 2007 Yes, I assumed that. But I think there's a strong case for it, both in
- Jason House (7/40) Sep 01 2007 I think this style of functionality could be useful. Provided that I
- Bruno Medeiros (10/44) Sep 05 2007 The first thing that struck me with this change was this clear
- Robert Fraser (2/7) Sep 05 2007 Actually, I think this is a problem with the const and invariant termino...
On page 30 of WalterAndrei.pdf it talks about static function parameters. It says void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } And the reason given is it's supposed to make templates "easier for mortals". I don't really see how that makes anything easier. It's longer to type first of all. And you still have to be aware of the compile-time / runtime distinction, this just makes it a little harder to see. And it introduces issues like what to do if there are both template parameters and static arguments, and what to do with __traits for such functions, and what the parameters tuple should look like, and whether you can have foo(int i, static j), and whether you can still call it as foo!(7)(5), and if you can call foo(int i)(int j) as foo(3,x)? And if it is just like a template can you take &foo? If not, how do you take the address of a particular specialization of the function? Do you revert back to foo!(3) then? In short it seems like a classic case of a feature that adds little benefit, but a fair number of new rules that everyone will have to remember, and in the end it could very likely stomp on the toes of some other future features that would be much more useful. As far as I can tell, this is just another way to do something we can already do, and all we gain from it is the ability to save two characters on the calling side for functions that are only templated on const values. --bb
Aug 30 2007
Bill Baxter Wrote:On page 30 of WalterAndrei.pdf it talks about static function parameters. It says void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } And the reason given is it's supposed to make templates "easier for mortals". I don't really see how that makes anything easier. It's longer to type first of all. And you still have to be aware of the compile-time / runtime distinction, this just makes it a little harder to see. And it introduces issues like what to do if there are both template parameters and static arguments, and what to do with __traits for such functions, and what the parameters tuple should look like, and whether you can have foo(int i, static j), and whether you can still call it as foo!(7)(5), and if you can call foo(int i)(int j) as foo(3,x)? And if it is just like a template can you take &foo? If not, how do you take the address of a particular specialization of the function? Do you revert back to foo!(3) then? In short it seems like a classic case of a feature that adds little benefit, but a fair number of new rules that everyone will have to remember, and in the end it could very likely stomp on the toes of some other future features that would be much more useful. As far as I can tell, this is just another way to do something we can already do, and all we gain from it is the ability to save two characters on the calling side for functions that are only templated on const values. --bbAs far as I understand it, it will allow overloading on constants for manual constant folding & optimization. So if you have: void foo(static int i); void foo(int i); foo(3); // Calls the first foo(x); // Calls teh second (assuming x is not compile-time resolvable) That said, I do agree it's a bit of overkill.
Aug 30 2007
Robert Fraser wrote:Bill Baxter Wrote:Yes, means you can do compile-time regexps with identical syntax to run-time regexps. This was my proposal from the distant past, and I think someone else suggested it as well. But, with macros, most of the impetus is gone; you could get the same effect in another way: macro foo(i) { static if (__traits(compiletimeconst, i)) foo_template!(i); else foo_function(i); } One problem with the proposal, is that you can't currently accept any type as a template value parameter (only ints, floats, and strings). So struct Bar { int a; } foo(static Bar b); is not going to work. So it's not clear that it's a big win any more. I don't think we need it.On page 30 of WalterAndrei.pdf it talks about static function parameters. It says void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } And the reason given is it's supposed to make templates "easier for mortals". I don't really see how that makes anything easier. It's longer to type first of all. And you still have to be aware of the compile-time / runtime distinction, this just makes it a little harder to see. And it introduces issues like what to do if there are both template parameters and static arguments, and what to do with __traits for such functions, and what the parameters tuple should look like, and whether you can have foo(int i, static j), and whether you can still call it as foo!(7)(5), and if you can call foo(int i)(int j) as foo(3,x)? And if it is just like a template can you take &foo? If not, how do you take the address of a particular specialization of the function? Do you revert back to foo!(3) then? In short it seems like a classic case of a feature that adds little benefit, but a fair number of new rules that everyone will have to remember, and in the end it could very likely stomp on the toes of some other future features that would be much more useful. As far as I can tell, this is just another way to do something we can already do, and all we gain from it is the ability to save two characters on the calling side for functions that are only templated on const values. --bbAs far as I understand it, it will allow overloading on constants for manual constant folding & optimization. So if you have: void foo(static int i); void foo(int i); foo(3); // Calls the first foo(x); // Calls teh second (assuming x is not compile-time resolvable)
Aug 30 2007
Bill Baxter wrote:On page 30 of WalterAndrei.pdf it talks about static function parameters. It says void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } And the reason given is it's supposed to make templates "easier for mortals". I don't really see how that makes anything easier. It's longer to type first of all. And you still have to be aware of the compile-time / runtime distinction, this just makes it a little harder to see. And it introduces issues like what to do if there are both template parameters and static arguments, and what to do with __traits for such functions, and what the parameters tuple should look like, and whether you can have foo(int i, static j), and whether you can still call it as foo!(7)(5), and if you can call foo(int i)(int j) as foo(3,x)? And if it is just like a template can you take &foo? If not, how do you take the address of a particular specialization of the function? Do you revert back to foo!(3) then? In short it seems like a classic case of a feature that adds little benefit, but a fair number of new rules that everyone will have to remember, and in the end it could very likely stomp on the toes of some other future features that would be much more useful. As far as I can tell, this is just another way to do something we can already do, and all we gain from it is the ability to save two characters on the calling side for functions that are only templated on const values. --bbThere appear to be a few features with the characteristics you describe. I sure hope it's not feature-creep, yet some do bear that hallmark
Aug 30 2007
Bill Baxter wrote:On page 30 of WalterAndrei.pdf it talks about static function parameters. It says void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } And the reason given is it's supposed to make templates "easier for mortals". I don't really see how that makes anything easier. It's longer to type first of all. And you still have to be aware of the compile-time / runtime distinction, this just makes it a little harder to see. And it introduces issues like what to do if there are both template parameters and static arguments, and what to do with __traits for such functions, and what the parameters tuple should look like, and whether you can have foo(int i, static j), and whether you can still call it as foo!(7)(5), and if you can call foo(int i)(int j) as foo(3,x)? And if it is just like a template can you take &foo? If not, how do you take the address of a particular specialization of the function? Do you revert back to foo!(3) then? In short it seems like a classic case of a feature that adds little benefit, but a fair number of new rules that everyone will have to remember, and in the end it could very likely stomp on the toes of some other future features that would be much more useful. As far as I can tell, this is just another way to do something we can already do, and all we gain from it is the ability to save two characters on the calling side for functions that are only templated on const values. --bbI know it's far from the only way to do this, but static parameters should hopefully also allow static opIndex, allowing us to do nifty tuple-like behaviour: struct Tuple(T...) { T impl; T[i] opIndex(static int i) { return impl[i]; } T[i] opIndexAssign(T[i] val, static int i) { return (impl[i] = val); } } void main() { Tuple!(int, bool) t; t[1] = false; t[0] = 5; } -- Reiner
Aug 31 2007
Bill Baxter wrote:On page 30 of WalterAndrei.pdf it talks about static function parameters. It says void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } And the reason given is it's supposed to make templates "easier for mortals". I don't really see how that makes anything easier. It's longer to type first of all. And you still have to be aware of the compile-time / runtime distinction, this just makes it a little harder to see. And it introduces issues like what to do if there are both template parameters and static arguments, and what to do with __traits for such functions, and what the parameters tuple should look like, and whether you can have foo(int i, static j), and whether you can still call it as foo!(7)(5), and if you can call foo(int i)(int j) as foo(3,x)? And if it is just like a template can you take &foo? If not, how do you take the address of a particular specialization of the function? Do you revert back to foo!(3) then? In short it seems like a classic case of a feature that adds little benefit, but a fair number of new rules that everyone will have to remember, and in the end it could very likely stomp on the toes of some other future features that would be much more useful. As far as I can tell, this is just another way to do something we can already do, and all we gain from it is the ability to save two characters on the calling side for functions that are only templated on const values. --bb"this is just another way to do something we can already do" ? Are you sure that is the case? The presentation says: void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } However one will also be able to call foo as if it were a function: foo(3, 2); which is not at all possible currently for the template: void foo(int i)(int j) { ... } (or will that also change with the upcoming D features?) -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Sep 01 2007
Bruno Medeiros wrote:Bill Baxter wrote:No, I'm not at all sure. That's why I was asking.On page 30 of WalterAndrei.pdf it talks about static function parameters. It says void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } And the reason given is it's supposed to make templates "easier for mortals". I don't really see how that makes anything easier. It's longer to type first of all. And you still have to be aware of the compile-time / runtime distinction, this just makes it a little harder to see. And it introduces issues like what to do if there are both template parameters and static arguments, and what to do with __traits for such functions, and what the parameters tuple should look like, and whether you can have foo(int i, static j), and whether you can still call it as foo!(7)(5), and if you can call foo(int i)(int j) as foo(3,x)? And if it is just like a template can you take &foo? If not, how do you take the address of a particular specialization of the function? Do you revert back to foo!(3) then? In short it seems like a classic case of a feature that adds little benefit, but a fair number of new rules that everyone will have to remember, and in the end it could very likely stomp on the toes of some other future features that would be much more useful. As far as I can tell, this is just another way to do something we can already do, and all we gain from it is the ability to save two characters on the calling side for functions that are only templated on const values. --bb"this is just another way to do something we can already do" ? Are you sure that is the case?The presentation says: void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } However one will also be able to call foo as if it were a function: foo(3, 2); which is not at all possible currently for the template: void foo(int i)(int j) { ... } (or will that also change with the upcoming D features?)By "do something we can already do" I meant the functionality, not the syntax. We can already pass compile time integer parameters to functions, we just have to call it like foo!(3)(2) instead of foo(3,2). Robert and Reiner both pointed out some (mildly) interesting things it would allow. 1) seamlessly overloading on static/vs non-static. 2) allowing to make compile-time constant opIndex (and other operators too I suppose like opAddAssign). Neither of those is really knocking my socks off, though. --bb
Sep 01 2007
Bill Baxter wrote:Bruno Medeiros wrote:You had a statement, not a question. :PBill Baxter wrote:No, I'm not at all sure. That's why I was asking.On page 30 of WalterAndrei.pdf it talks about static function parameters. It says void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } And the reason given is it's supposed to make templates "easier for mortals". I don't really see how that makes anything easier. It's longer to type first of all. And you still have to be aware of the compile-time / runtime distinction, this just makes it a little harder to see. And it introduces issues like what to do if there are both template parameters and static arguments, and what to do with __traits for such functions, and what the parameters tuple should look like, and whether you can have foo(int i, static j), and whether you can still call it as foo!(7)(5), and if you can call foo(int i)(int j) as foo(3,x)? And if it is just like a template can you take &foo? If not, how do you take the address of a particular specialization of the function? Do you revert back to foo!(3) then? In short it seems like a classic case of a feature that adds little benefit, but a fair number of new rules that everyone will have to remember, and in the end it could very likely stomp on the toes of some other future features that would be much more useful. As far as I can tell, this is just another way to do something we can already do, and all we gain from it is the ability to save two characters on the calling side for functions that are only templated on const values. --bb"this is just another way to do something we can already do" ? Are you sure that is the case?That's the whole point of this functionality, just as described in Walter's slides (2 pages bellow where static function parameters are introduced). And that's why being able to call something foo(3,2) instead of foo!(3)(2) is not just a syntactical sugar.The presentation says: void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } However one will also be able to call foo as if it were a function: foo(3, 2); which is not at all possible currently for the template: void foo(int i)(int j) { ... } (or will that also change with the upcoming D features?)By "do something we can already do" I meant the functionality, not the syntax. We can already pass compile time integer parameters to functions, we just have to call it like foo!(3)(2) instead of foo(3,2). Robert and Reiner both pointed out some (mildly) interesting things it would allow. 1) seamlessly overloading on static/vs non-static.2) allowing to make compile-time constant opIndex (and other operators too I suppose like opAddAssign).That's assuming operator overloading will work with these functions, which we don't know for sure (unless it was mentioned in the conference).Neither of those is really knocking my socks off, though. --bb-- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Sep 02 2007
Bruno Medeiros wrote:Bill Baxter wrote:Yes, I assumed that. But I think there's a strong case for it, both in consistency and because it is required to emulate tuples. I sure hope it will work :-). -- Reiner2) allowing to make compile-time constant opIndex (and other operators too I suppose like opAddAssign).That's assuming operator overloading will work with these functions, which we don't know for sure (unless it was mentioned in the conference).
Sep 02 2007
Bill Baxter wrote:On page 30 of WalterAndrei.pdf it talks about static function parameters. It says void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } And the reason given is it's supposed to make templates "easier for mortals". I don't really see how that makes anything easier. It's longer to type first of all. And you still have to be aware of the compile-time / runtime distinction, this just makes it a little harder to see. And it introduces issues like what to do if there are both template parameters and static arguments, and what to do with __traits for such functions, and what the parameters tuple should look like, and whether you can have foo(int i, static j), and whether you can still call it as foo!(7)(5), and if you can call foo(int i)(int j) as foo(3,x)? And if it is just like a template can you take &foo? If not, how do you take the address of a particular specialization of the function? Do you revert back to foo!(3) then?Those are all good points!In short it seems like a classic case of a feature that adds little benefit, but a fair number of new rules that everyone will have to remember, and in the end it could very likely stomp on the toes of some other future features that would be much more useful.I think this style of functionality could be useful. Provided that I don't have to write lots of function definitions, having the compiler figure out what is or isn't compile-time values and optimizing based on that is a good thing. Personally, I think something like the return keyword could be helpful here tooAs far as I can tell, this is just another way to do something we can already do, and all we gain from it is the ability to save two characters on the calling side for functions that are only templated on const values. --bb
Sep 01 2007
Bill Baxter wrote:On page 30 of WalterAndrei.pdf it talks about static function parameters. It says void foo(static int i, int j) { ... } will become a synonym for the template void foo(int i)(int j) { ... } And the reason given is it's supposed to make templates "easier for mortals". I don't really see how that makes anything easier. It's longer to type first of all. And you still have to be aware of the compile-time / runtime distinction, this just makes it a little harder to see. And it introduces issues like what to do if there are both template parameters and static arguments, and what to do with __traits for such functions, and what the parameters tuple should look like, and whether you can have foo(int i, static j), and whether you can still call it as foo!(7)(5), and if you can call foo(int i)(int j) as foo(3,x)? And if it is just like a template can you take &foo? If not, how do you take the address of a particular specialization of the function? Do you revert back to foo!(3) then? In short it seems like a classic case of a feature that adds little benefit, but a fair number of new rules that everyone will have to remember, and in the end it could very likely stomp on the toes of some other future features that would be much more useful. As far as I can tell, this is just another way to do something we can already do, and all we gain from it is the ability to save two characters on the calling side for functions that are only templated on const values. --bbThe first thing that struck me with this change was this clear inconsistency: The static parameters are really compile time constants, but they are declared with 'static'. However, outside of function parameters, compile-time constants are declared with invariant and const (as "storage classes"). -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Sep 05 2007
Bruno Medeiros Wrote:The first thing that struck me with this change was this clear > inconsistency: The static parameters are really compile time constants, but they are declared with 'static'. However, outside of function parameters, compile-time constants are declared with invariant and const (as "storage classes").Actually, I think this is a problem with the const and invariant terminology. "const" doesn't mean compile-time constant, it means read-only reference. "invariant" means "constant after declaration, can be stored in ROM," but doesn't need to be compile-time resolvable. Plus, both these storage clases already exist, and "static" is a catch-all keyword for any feature not worth adding a real keyword for and doesn't really fit with anything else.
Sep 05 2007