www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - const main args?

reply bearophile <bearophileHUGS lycos.com> writes:
Currently the accepted signatures for the D main are (it also works if you use
"pure main"):

void main();
int main();
void main(string[] args);
int main(string[] args);

But why instead isn't the args argument const when present?
int main(in string[] args);

Bye,
bearophile
Aug 12 2011
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 12 Aug 2011 16:16:45 -0400, bearophile <bearophileHUGS lycos.com>  
wrote:

 Currently the accepted signatures for the D main are (it also works if  
 you use "pure main"):

 void main();
 int main();
 void main(string[] args);
 int main(string[] args);

 But why instead isn't the args argument const when present?
 int main(in string[] args);

What would be the purpose of this? -Steve
Aug 12 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 int main(in string[] args);

What would be the purpose of this?

Why do you use "in" in function arguments? To make sure you will not modify the given array. I think it's not good practice to change the length of the input strings of the main or replace it with another dynamic array at runtime. On the other hand in D const is transitive, and currently you can't do many things on a const array (like several std.algorithms). So currently that "in" restricts too much the things you are allowed to do with args. This is why I have asked for an opinion, to understand the balance of the pros and cons. Bye, bearophile
Aug 12 2011
next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, August 12, 2011 15:51 Andrej Mitrovic wrote:
 That's pretty stupid, of course you want to modify the arguments.
 
 Classic example:
 
 void main(string[] args)
 {
 args.popFront; // get rid of name
 
 foreach (arg; args)
 {
 }
 }

getopt alters the arguments too. I'm not sure that it should be disallowed to use void main(in string[] args) but I'd argue that doing that is generally incredibly counter-productive. Of course, I'm against the use of in with arrays in general. const(T)[] maybe, but as soon as you use in, you can't use any range functions. A totally const or immutable array is generally useless IMHO. - Jonathan M Davis
Aug 12 2011
parent reply Adam Ruppe <destructionator gmail.com> writes:
Jonathan M Davis wrote:
 const(T)[] maybe,
 but as soon as you use in, you can't use any range functions.

That is, to me, the biggest problem with range functions and something that should be fixed. There's no defense for it aside from being the status quo. It's just a shortcoming of the current implementation, not a principled limitation.
Aug 12 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/13/2011 01:04 AM, Adam Ruppe wrote:
 Jonathan M Davis wrote:
 const(T)[] maybe,
 but as soon as you use in, you can't use any range functions.

That is, to me, the biggest problem with range functions and something that should be fixed. There's no defense for it aside from being the status quo. It's just a shortcoming of the current implementation, not a principled limitation.

+1. Maybe the impact on Phobos of fixing this can be kept small by a well thought-out language change.
Aug 12 2011
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 void main(string[] args)
 {
     args.popFront;  // get rid of name
 
     foreach (arg; args)
     {
     }
 }

If I see code like that I probably rewrite it like this: void main(in string[] args) { foreach (arg; args[1..$]) { } } ;-) Bye, bearophile
Aug 12 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, August 13, 2011 02:10:35 Andrej Mitrovic wrote:
 On 8/13/11, bearophile <bearophileHUGS lycos.com> wrote:
 Andrej Mitrovic:
 void main(string[] args)
 {
 
     args.popFront;  // get rid of name
     
     foreach (arg; args)
     {
     }
 
 }

If I see code like that I probably rewrite it like this: void main(in string[] args) { foreach (arg; args[1..$]) { } }

And what benefit is there to that? I pop the argument and then don't have to worry about it ever again. Whereas you're using [1..$], and later on in your argument parsing code you might introduce a bug like: auto userArgumentCount = args.length; // woops, you'll get 1 extra here due to app name.

It depends on what you're doing. If all you're doing is iterating over the arguments once, then there's no reason to pop an element off. It's more code and is slightly less efficient. However, if you're going to do more than that with the arguments, then it may very well just be better to pop off the front before doing anything else with them. Either approach could be better depending on what else you're doing in your code. - Jonathan M Davis
Aug 12 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I don't recall the last time `void main()` was a bottleneck in my apps. :p
Maybe it would actually make a big difference in CGI apps though.
Aug 13 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 int main(string[] _args)
 {
     const args = _args;  // not modifiable copy
 }

Currently DMD accepts code like: int main(in string[] args) { return 0; } void main(in string[] args) {} int main() { return 0; } void main() {} What I have asked is if it's worth changing D/DMD so it only accepts such two four forms.
 D cannot always be perfect, and I'd rather we  
 spend more time on the meaty parts of the language.

The topic of this thread is surely a minor thing, I agree there are far more important things to work on. But on the base of my experience I don't agree with you. Little things are little, but they pile up. Little wrong things don't make a language unusable, but many little things done right reduce programming stress and improve how much you like your language (sometimes they avoid some bugs in your code). At its base Python is not a big deal, its implementation sucks, it contains no new ideas, and even its basic syntax is like C. But hundreds of well thought out and carefully designed "user-interface" details in the core language and its standard library make its usage pleasurable. Bye, bearophile
Aug 15 2011
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/15/2011 03:47 PM, Steven Schveighoffer wrote:
 On Fri, 12 Aug 2011 17:51:50 -0400, bearophile
 <bearophileHUGS lycos.com> wrote:

 Steven Schveighoffer:

 int main(in string[] args);

What would be the purpose of this?

Why do you use "in" in function arguments? To make sure you will not modify the given array. I think it's not good practice to change the length of the input strings of the main or replace it with another dynamic array at runtime.

int main(string[] _args) { const args = _args; // not modifiable copy } It's a very easy problem to solve, and it's not really worth changing the compiler for IMO. In other words, it's one of those "features" that's so trivial that it's not worth implementing. D cannot always be perfect, and I'd rather we spend more time on the meaty parts of the language. -Steve

This is a place where D trivially could be perfect ;). I agree that this issue has a very low priority. But it should be fixed eventually.
Aug 15 2011
parent reply Brad Roberts <braddr slice-2.puremagic.com> writes:
On Mon, 15 Aug 2011, Timon Gehr wrote:

 On 08/15/2011 03:47 PM, Steven Schveighoffer wrote:
 On Fri, 12 Aug 2011 17:51:50 -0400, bearophile
 <bearophileHUGS lycos.com> wrote:
 
 Steven Schveighoffer:
 
 int main(in string[] args);

What would be the purpose of this?

Why do you use "in" in function arguments? To make sure you will not modify the given array. I think it's not good practice to change the length of the input strings of the main or replace it with another dynamic array at runtime.

int main(string[] _args) { const args = _args; // not modifiable copy } It's a very easy problem to solve, and it's not really worth changing the compiler for IMO. In other words, it's one of those "features" that's so trivial that it's not worth implementing. D cannot always be perfect, and I'd rather we spend more time on the meaty parts of the language. -Steve

This is a place where D trivially could be perfect ;). I agree that this issue has a very low priority. But it should be fixed eventually.

Only if there was actual uniformity in agreement on what perfect is. There isn't in this case.
Aug 15 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/15/2011 11:53 PM, Brad Roberts wrote:
 On Mon, 15 Aug 2011, Timon Gehr wrote:

 On 08/15/2011 03:47 PM, Steven Schveighoffer wrote:
 On Fri, 12 Aug 2011 17:51:50 -0400, bearophile
 <bearophileHUGS lycos.com>  wrote:

 Steven Schveighoffer:

 int main(in string[] args);

What would be the purpose of this?

Why do you use "in" in function arguments? To make sure you will not modify the given array. I think it's not good practice to change the length of the input strings of the main or replace it with another dynamic array at runtime.

int main(string[] _args) { const args = _args; // not modifiable copy } It's a very easy problem to solve, and it's not really worth changing the compiler for IMO. In other words, it's one of those "features" that's so trivial that it's not worth implementing. D cannot always be perfect, and I'd rather we spend more time on the meaty parts of the language. -Steve

This is a place where D trivially could be perfect ;). I agree that this issue has a very low priority. But it should be fixed eventually.

Only if there was actual uniformity in agreement on what perfect is. There isn't in this case.

Basically, disallowing it is just cutting the users freedom for no benefit to the language design and feels inconsistent.
Aug 15 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
That's pretty stupid, of course you want to modify the arguments.

Classic example:

void main(string[] args)
{
    args.popFront;  // get rid of name

    foreach (arg; args)
    {
    }
}
Aug 12 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, August 12, 2011 16:04 Adam Ruppe wrote:
 Jonathan M Davis wrote:
 const(T)[] maybe,
 but as soon as you use in, you can't use any range functions.

That is, to me, the biggest problem with range functions and something that should be fixed. There's no defense for it aside from being the status quo. It's just a shortcoming of the current implementation, not a principled limitation.

If it can be fixed so that a slice of a const/immutable range is tail-const, then they'll be in the same boat as static arrays and at least be usable with range-based functions when you slice them, but at this point, the only way to make it so that you could simply pass them without slicing them is if you overloaded _every_ range-based functions on arrays. And since you're going to have to slice containers to pass them to range-based functions anyway (dynamic arrays are actually kind of weird in that they can be passed directly to range-based functions without slicing them - it's just that they're the most common used of ranges and therefore what we're most used to). So, I don't think that it's unreasonable to require that static arrays and const or immutable dynamic arrays be sliced to be used with range-based functions. But until it's fixed so that slices of a dynamic range are tail-const/tail- immutable instead of exactly the same type, that doesn't work with const or immutable dynamic arrays, which definitely sucks. But if that can be fixed, I think that the situation will then be fairly reasonable. - Jonathan M Davis
Aug 12 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/13/11, bearophile <bearophileHUGS lycos.com> wrote:
 Andrej Mitrovic:

 void main(string[] args)
 {
     args.popFront;  // get rid of name

     foreach (arg; args)
     {
     }
 }

If I see code like that I probably rewrite it like this: void main(in string[] args) { foreach (arg; args[1..$]) { } }

And what benefit is there to that? I pop the argument and then don't have to worry about it ever again. Whereas you're using [1..$], and later on in your argument parsing code you might introduce a bug like: auto userArgumentCount = args.length; // woops, you'll get 1 extra here due to app name.
Aug 12 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, August 13, 2011 15:03:56 Andrej Mitrovic wrote:
 I don't recall the last time `void main()` was a bottleneck in my apps. :p
 Maybe it would actually make a big difference in CGI apps though.

I doubt that it will _ever_ make a difference performance-wise. It's obviously not in a loop, and with an application that you're running over and over again, the start up time for the runtime will outweigh any individual popFront. However, every bit of efficiency does count. So, if it's just as easy to do one thing as another, and one is more efficient, then generally speaking, it's better to pick the efficent one. And honestly, since popping the front off of an array is more verbose than slicing it, if you're only going to be operating on the array once, then slicing it is better IMHO. Regardless, it's not a big deal in this case. - Jonathan M Davis
Aug 13 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 12 Aug 2011 17:51:50 -0400, bearophile <bearophileHUGS lycos.com>  
wrote:

 Steven Schveighoffer:

 int main(in string[] args);

What would be the purpose of this?

Why do you use "in" in function arguments? To make sure you will not modify the given array. I think it's not good practice to change the length of the input strings of the main or replace it with another dynamic array at runtime.

int main(string[] _args) { const args = _args; // not modifiable copy } It's a very easy problem to solve, and it's not really worth changing the compiler for IMO. In other words, it's one of those "features" that's so trivial that it's not worth implementing. D cannot always be perfect, and I'd rather we spend more time on the meaty parts of the language. -Steve
Aug 15 2011