Re: Flag proposal

2011-06-19 Thread KennyTM~

On Jun 20, 11 03:03, Nick Sabalausky wrote:

"KennyTM~"  wrote in message
news:it8f4s$1gve$1...@digitalmars.com...

On Jun 15, 11 00:45, so wrote:

On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~  wrote:


loc.x on the caller side, it has no idea about function signature, and
you don't know if it was 10th or 2nd argument in function.

// definition
fun(int x, int y) {
}

// call
fun(x, y) // you need to check the definition if you think something
wrong with parameters the second time you come here
fun(y, x) // same
fun(x:x, y:y) // you know there is nothing wrong with parameters
fun(y:y, x:x) // same



If you have no idea about the function signature, you have no idea
about the parameter names either.


I think you are just resisting here, if you write a call once with named
arguments, you documented it in place, the next time you visit this call
all you need to see is in the call site.



I'm just bringing up the fact. Why would you need to check the function
signature when reading

 MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
bRepaint:true);

? It's clear what each argument does.


Because it might be wrong.



If you feel the need of duplicating the same information, fine, write

 MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);

in your code. But don't make it mandatory, it's a waste of time and space
when the writer just wants to clarify that 'true' is a bRepaint.



I don't think anyone suggested named arguments should be manditory.



Right, no one suggested named arguments should be mandatory, but @so's 
original suggestion is either "all on" or "all off", which makes this 
example pretty much mandatory because of a 'bRepaint: true'.


Re: Flag proposal

2011-06-19 Thread Nick Sabalausky
"so"  wrote in message news:op.vw2s1b19mpw3zg@tan-pc...
> On Tue, 14 Jun 2011 16:01:20 +0300, KennyTM~  wrote:
>
>> On Jun 14, 11 19:11, so wrote:
>> [snip]
>>> Also i don't understand why some think allowing hybrid calls has any
>>> merit. Just search "named arguments" and first thing you'd see is calls
>>> with all arguments named, no exception. Allowing unnamed arguments and
>>> named arguments in one call doesn't make any sense to me, it is almost
>>> opposite to the reasons named arguments designed for, you don't even
>>> need to talk about its drawbacks like the complications and confusions.
>>
>> And if you think it's complicated, you're just thinking in a too 
>> complicated way. The rule is simple.
>>
>> Say there is a function
>>
>>  pure nothrow
>>  S parseString(S=const(char)[], C)
>> (ref C[] input,
>>  out ConversionResult result,
>>  char quote='"',
>>  bool recognizePrefix=true) if (...);
>>
>> and you call it as
>>
>>  string s = `"hello"`;
>>  ConversionResult detailResult;
>>  auto parsed = parseString(s, recognizePrefix:false, 
>> result:detailResult);
>>
>> The first step is identify all positional arguments ('s' here), and fill 
>> them in in-order.
>>
>>  input <- s
>>  result <- ...
>>  quote <- ...
>>  recognizePrefix <- ...
>>
>> next, we match the named args
>>
>>  input <- s
>>  result <- detailResult
>>  quote <- ...
>>  recognizePrefix <- false
>>
>> finally we fill in the optional parameters
>>
>>  input <- s
>>  result <- detailResult
>>  quote <- '"'
>>  recognizePrefix <- false
>>
>> what's so complicated? Actually, reordering creates more complication 
>> than hybrid (e.g. ambiguity in selecting an overload).
>
> So complicated because it took you this long to match the parameters with 
> the variables, you still need to check function definition because you 
> have parameters that have no match. These are the very things named 
> arguments needs to solve or am i missing something?
>

Simple rule for combining hybrid and reordering:

Look at the caller's args one at a time: as soon as one is reordered, the 
rest of the args must be named (otherwise you wouldn't know which param it's 
supposed to be).





Re: Flag proposal

2011-06-19 Thread Nick Sabalausky
"KennyTM~"  wrote in message 
news:it8f4s$1gve$1...@digitalmars.com...
> On Jun 15, 11 00:45, so wrote:
>> On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~  wrote:
>>
 loc.x on the caller side, it has no idea about function signature, and
 you don't know if it was 10th or 2nd argument in function.

 // definition
 fun(int x, int y) {
 }

 // call
 fun(x, y) // you need to check the definition if you think something
 wrong with parameters the second time you come here
 fun(y, x) // same
 fun(x:x, y:y) // you know there is nothing wrong with parameters
 fun(y:y, x:x) // same

>>>
>>> If you have no idea about the function signature, you have no idea
>>> about the parameter names either.
>>
>> I think you are just resisting here, if you write a call once with named
>> arguments, you documented it in place, the next time you visit this call
>> all you need to see is in the call site.
>>
>
> I'm just bringing up the fact. Why would you need to check the function 
> signature when reading
>
> MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
>bRepaint:true);
>
> ? It's clear what each argument does.

Because it might be wrong.


> If you feel the need of duplicating the same information, fine, write
>
> MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
>nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);
>
> in your code. But don't make it mandatory, it's a waste of time and space 
> when the writer just wants to clarify that 'true' is a bRepaint.
>

I don't think anyone suggested named arguments should be manditory.





Re: Flag proposal

2011-06-15 Thread Caligo
Named parameters are possible in C++ with Boost, so why can't we have
named parameters in D with Phobos?


Re: Flag proposal

2011-06-15 Thread KennyTM~

On Jun 16, 11 00:43, bearophile wrote:

so:


I didn't know they work this way, i agree it is a good argument (finally
we agree on something!)


To not waste all the good discussions I suggest to write down a DEP (D Enhancement 
Proposal), that tries to list what to do in all corner cases, even just a "?" 
where you don't know what to do (and including my Scala-style deprecated(oldArgName) 
idea). Even writing a pre-DEP will be a good starting point.
Even if in the end named arguments don't get added to D, having this DEP will 
be good to avoid further future discussions, or as starting point for a future 
desire to try adding them again.

Bye,
bearophile


You mean a DIP :)


Re: Flag proposal

2011-06-15 Thread bearophile
so:

> I didn't know they work this way, i agree it is a good argument (finally  
> we agree on something!)

To not waste all the good discussions I suggest to write down a DEP (D 
Enhancement Proposal), that tries to list what to do in all corner cases, even 
just a "?" where you don't know what to do (and including my Scala-style 
deprecated(oldArgName) idea). Even writing a pre-DEP will be a good starting 
point.
Even if in the end named arguments don't get added to D, having this DEP will 
be good to avoid further future discussions, or as starting point for a future 
desire to try adding them again.

Bye,
bearophile


Re: Flag proposal

2011-06-15 Thread so
I'm just bringing up the fact. Why would you need to check the function  
signature when reading


 MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
bRepaint:true);

? It's clear what each argument does. If you feel the need of  
duplicating the same information, fine, write


 MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);

in your code. But don't make it mandatory, it's a waste of time and  
space when the writer just wants to clarify that 'true' is a bRepaint.


Waste of time? so is writing docs and comments, so is checking the library  
everytime you have trouble understanding a call. It is designed to ease  
understanding your own or others code. I have no idea how you can think  
about writing a few chars more as if something bad. In programming we  
waste our times not when we are actually writing but while doing  
everything else!



Looks like i am just repeating myself but i don't understand how is
pssing constants meaningless and variables, and why do you even need
named arguments for those?

enum x=...
enum y=...
...
fun(x, y)



If you want to disregard named argument, why go the complicated route  
and define enums? You could do as well


 fun(/*x*/0, /*y*/0);


No, you are the one suggesting that, in your example you called  
MoveWindow(hwnd) and said it was all you need, then i gave this example to  
prove if all you need is that, you don't need NAs anyways since it is just  
so easy to treat other things as "hwnd".


(and yes I'm currently using it.) But the point is it's ugly. Heck why  
do we need to defend NA. My point is only "hybrid should be allowed if I  
want to".


It is ugly but it is not heck, it does nothing, it gives you no  
guaranties, compiler does no matching. It is no better than fun(0, 0). We  
came this far but we still don't think the NAs same way, and i am starting  
to lose my hope explaining myself.



Yet all well-known languages that support named arguments that support
reordering also support hybrid. (C# 4, VB 6, Python, CLisp, ...)


This is not an argument.


Neither is 'Just search "named arguments" and first thing you'd see is  
calls with all arguments named, no exception.'


Why not? first thing you would encounter is its prototype, its best usage  
that makes most sense, i told it because you seem to give its primary  
function no value at all.


Maybe another argument: D's static struct initializer already supports  
hybrid and reordering. Extending that to function arguments is natural.



struct S { int x; int y; }
void main() {
 S s0 = {4, 5};
 S s1 = {x:4, 5};
 S s2 = {4, y:5};
 S s3 = {x:4, y:5};
//  S s4 = {y:4, 5};// error
 S s5 = {y:5, x:4};
}



I didn't know they work this way, i agree it is a good argument (finally  
we agree on something!)

Though i have to say it looks quite confusing and verbose (rules).
Then again, it looks like i am alone on this one, quite possibly i am  
wrong :)


Re: Flag proposal

2011-06-14 Thread KennyTM~

On Jun 15, 11 01:18, so wrote:

On Tue, 14 Jun 2011 16:01:20 +0300, KennyTM~  wrote:


On Jun 14, 11 19:11, so wrote:
[snip]

Also i don't understand why some think allowing hybrid calls has any
merit. Just search "named arguments" and first thing you'd see is calls
with all arguments named, no exception. Allowing unnamed arguments and
named arguments in one call doesn't make any sense to me, it is almost
opposite to the reasons named arguments designed for, you don't even
need to talk about its drawbacks like the complications and confusions.


And if you think it's complicated, you're just thinking in a too
complicated way. The rule is simple.

Say there is a function

pure nothrow
S parseString(S=const(char)[], C)
(ref C[] input,
out ConversionResult result,
char quote='"',
bool recognizePrefix=true) if (...);

and you call it as

string s = `"hello"`;
ConversionResult detailResult;
auto parsed = parseString(s, recognizePrefix:false, result:detailResult);

The first step is identify all positional arguments ('s' here), and
fill them in in-order.

input <- s
result <- ...
quote <- ...
recognizePrefix <- ...

next, we match the named args

input <- s
result <- detailResult
quote <- ...
recognizePrefix <- false

finally we fill in the optional parameters

input <- s
result <- detailResult
quote <- '"'
recognizePrefix <- false

what's so complicated? Actually, reordering creates more complication
than hybrid (e.g. ambiguity in selecting an overload).


So complicated because it took you this long to match the parameters
with the variables, you still need to check function definition because
you have parameters that have no match. These are the very things named
arguments needs to solve or am i missing something?

You could just drop it and go read the function signature everytime,
it'd save you time :P


What you're missing may be that what I'm outlining is how the /compiler/ 
matches the parameters. The /compiler/ of course needs to check the 
function definition every time, otherwise how could it emit errors when 
you give a wrong name? :)





Re: Flag proposal

2011-06-14 Thread KennyTM~

On Jun 15, 11 00:45, so wrote:

On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~  wrote:


loc.x on the caller side, it has no idea about function signature, and
you don't know if it was 10th or 2nd argument in function.

// definition
fun(int x, int y) {
}

// call
fun(x, y) // you need to check the definition if you think something
wrong with parameters the second time you come here
fun(y, x) // same
fun(x:x, y:y) // you know there is nothing wrong with parameters
fun(y:y, x:x) // same



If you have no idea about the function signature, you have no idea
about the parameter names either.


I think you are just resisting here, if you write a call once with named
arguments, you documented it in place, the next time you visit this call
all you need to see is in the call site.



I'm just bringing up the fact. Why would you need to check the function 
signature when reading


MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
   bRepaint:true);

? It's clear what each argument does. If you feel the need of 
duplicating the same information, fine, write


MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
   nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);

in your code. But don't make it mandatory, it's a waste of time and 
space when the writer just wants to clarify that 'true' is a bRepaint.



You see the difference between variables and generic constants?

RECT bounds;
GetWindowRect(hWnd, &bounds);

writeln("Please enter the coordinates.");
auto x = readln().chomp().to!int();
auto y = readln().chomp().to!int();
auto width = bounds.right - bounds.left;
auto height = bounds.bottom - bounds.top;

MoveWindow(hWnd, x, y, width, height, bRepaint:true);
vs.

writeln("Resetting window dimensions");
...
MoveWindow(hWnd, X:0, Y:0, nWidth:800, nHeight:600, bRepaint:true);

Named arguments provides clarification when the argument itself (e.g.
0, false, true) is meaningless. But with a variable which itself
provides a meaning, forcing named argument on _every_argument_passed_
is just annoying.


Looks like i am just repeating myself but i don't understand how is
pssing constants meaningless and variables, and why do you even need
named arguments for those?

enum x=...
enum y=...
...
fun(x, y)



If you want to disregard named argument, why go the complicated route 
and define enums? You could do as well


fun(/*x*/0, /*y*/0);

(and yes I'm currently using it.) But the point is it's ugly. Heck why 
do we need to defend NA. My point is only "hybrid should be allowed if I 
want to".



Yet all well-known languages that support named arguments that support
reordering also support hybrid. (C# 4, VB 6, Python, CLisp, ...)


This is not an argument.


Neither is 'Just search "named arguments" and first thing you'd see is 
calls with all arguments named, no exception.'


Maybe another argument: D's static struct initializer already supports 
hybrid and reordering. Extending that to function arguments is natural.



struct S { int x; int y; }
void main() {
S s0 = {4, 5};
S s1 = {x:4, 5};
S s2 = {4, y:5};
S s3 = {x:4, y:5};
//  S s4 = {y:4, 5};// error
S s5 = {y:5, x:4};
}



Re: Flag proposal

2011-06-14 Thread Nick Sabalausky
"Michel Fortin"  wrote in message 
news:it7kq2$26ha$1...@digitalmars.com...
>
> Also, with reordering, if you have two overloaded functions of this form:
>
> void fun(int a, string b) {}
> void fun(string b, int a) {}
>
> which one does this calls:
>
> fun(a: 1, b: "hello");
>
> ? Does the call become ambiguous when using named arguments?

I'd say "yes". But even if you said "no, the winner is whichever matches the 
order given, if there is a perfect match", that would be fine too.

I'd further argue that either way it's not a significant problem, because it 
seems that situation would be extremely rare. And the only realistic case I 
can think of where it would might occur is if the callee wants to allow 
re-ordered params. But that would already solved by re-orderable names 
arguments anyway.

> It wouldn't be ambiguous if reordering wasn't allowed. What does C# does 
> with this?
>




Re: Flag proposal

2011-06-14 Thread so

On Tue, 14 Jun 2011 16:01:20 +0300, KennyTM~  wrote:


On Jun 14, 11 19:11, so wrote:
[snip]

Also i don't understand why some think allowing hybrid calls has any
merit. Just search "named arguments" and first thing you'd see is calls
with all arguments named, no exception. Allowing unnamed arguments and
named arguments in one call doesn't make any sense to me, it is almost
opposite to the reasons named arguments designed for, you don't even
need to talk about its drawbacks like the complications and confusions.


And if you think it's complicated, you're just thinking in a too  
complicated way. The rule is simple.


Say there is a function

 pure nothrow
 S parseString(S=const(char)[], C)
(ref C[] input,
 out ConversionResult result,
 char quote='"',
 bool recognizePrefix=true) if (...);

and you call it as

 string s = `"hello"`;
 ConversionResult detailResult;
 auto parsed = parseString(s, recognizePrefix:false,  
result:detailResult);


The first step is identify all positional arguments ('s' here), and fill  
them in in-order.


 input <- s
 result <- ...
 quote <- ...
 recognizePrefix <- ...

next, we match the named args

 input <- s
 result <- detailResult
 quote <- ...
 recognizePrefix <- false

finally we fill in the optional parameters

 input <- s
 result <- detailResult
 quote <- '"'
 recognizePrefix <- false

what's so complicated? Actually, reordering creates more complication  
than hybrid (e.g. ambiguity in selecting an overload).


So complicated because it took you this long to match the parameters with  
the variables, you still need to check function definition because you  
have parameters that have no match. These are the very things named  
arguments needs to solve or am i missing something?


You could just drop it and go read the function signature everytime, it'd  
save you time :P


Re: Flag proposal

2011-06-14 Thread so
On Tue, 14 Jun 2011 15:34:53 +0300, Michel Fortin  
 wrote:


There's much more to named arguments as it first appears. Have you  
thought about:


1. variadic arguments?


There is already a syntax for this in the language.

fun(a:1, var:{3,5,7})


2. named template arguments?


Do we need this?

3. template variadic arguments (tuples) and how they expand as function  
parameters?


This one is a bit tricky but wouldn't 1 also apply here?


Also, with reordering, if you have two overloaded functions of this form:

void fun(int a, string b) {}
void fun(string b, int a) {}


Only solution i can think of to this would be changing argument names,  
otherwise an error.


Re: Flag proposal

2011-06-14 Thread so

On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~  wrote:


loc.x on the caller side, it has no idea about function signature, and
you don't know if it was 10th or 2nd argument in function.

// definition
fun(int x, int y) {
}

// call
fun(x, y) // you need to check the definition if you think something
wrong with parameters the second time you come here
fun(y, x) // same
fun(x:x, y:y) // you know there is nothing wrong with parameters
fun(y:y, x:x) // same



If you have no idea about the function signature, you have no idea about  
the parameter names either.


I think you are just resisting here, if you write a call once with named  
arguments, you documented it in place, the next time you visit this call  
all you need to see is in the call site.



You see the difference between variables and generic constants?

  RECT bounds;
  GetWindowRect(hWnd, &bounds);

  writeln("Please enter the coordinates.");
  auto x = readln().chomp().to!int();
  auto y = readln().chomp().to!int();
  auto width = bounds.right - bounds.left;
  auto height = bounds.bottom - bounds.top;

  MoveWindow(hWnd, x, y, width, height, bRepaint:true);
vs.

  writeln("Resetting window dimensions");
  ...
  MoveWindow(hWnd, X:0, Y:0, nWidth:800, nHeight:600, bRepaint:true);

Named arguments provides clarification when the argument itself (e.g. 0,  
false, true) is meaningless. But with a variable which itself provides a  
meaning, forcing named argument on _every_argument_passed_ is just  
annoying.


Looks like i am just repeating myself but i don't understand how is pssing  
constants meaningless and variables, and why do you even need named  
arguments for those?


enum x=...
enum y=...
...
fun(x, y)

Yet all well-known languages that support named arguments that support  
reordering also support hybrid. (C# 4, VB 6, Python, CLisp, ...)


This is not an argument.


Re: Flag proposal

2011-06-14 Thread KennyTM~

On Jun 14, 11 20:34, Michel Fortin wrote:

On 2011-06-13 21:36:01 -0400, so  said:


IMO named arguments in D at least should do:

- Reordering (since we got default parameters, even better)

- It is enabled only if we have access to the function declaration.

- In a function call we either use named arguments for all the
non-default arguments or call it with the usual syntax. No hybrid
stuff, no confusion.

fun(int a, int b, int c=3)

fun(1, 2, 3) // fine - current
fun(1, 2) // fine - current

fun(a:1, b:3, c:5) // fine
fun(a:1, b:3) // fine
fun(b:1, c:3, a:5) // fine
fun(b:1, a:3) // fine
fun(b:1) // error
fun(c:1) // error
fun(2, b:1) // error
fun(2, c:1) // error
fun(2, c:2, 3) // error


There's much more to named arguments as it first appears. Have you
thought about:

1. variadic arguments?
2. named template arguments?


partition!(ss:SwapStrategy.stable,
   predicate:"a>0")
  (r:[1,2,3,4]);

Variadic is a real problem though. IIRC C# doesn't allow it.


3. template variadic arguments (tuples) and how they expand as function
parameters?

Also, with reordering, if you have two overloaded functions of this form:

void fun(int a, string b) {}
void fun(string b, int a) {}

which one does this calls:

fun(a: 1, b: "hello");

? Does the call become ambiguous when using named arguments? It wouldn't
be ambiguous if reordering wasn't allowed. What does C# does with this?




Looks like the last one get the precedence. At least for Mono (see 
http://ideone.com/REXC0). MSDN says



Use of named and optional arguments affects overload resolution in the 
following ways:


- A method, indexer, or constructor is a candidate for execution if each 
of its parameters either is optional or corresponds, by name or by 
position, to a single argument in the calling statement, and that 
argument can be converted to the type of the parameter.


- If more than one candidate is found, overload resolution rules for 
preferred conversions are applied to the arguments that are explicitly 
specified. Omitted arguments for optional parameters are ignored.


- If two candidates are judged to be equally good, preference goes to a 
candidate that does not have optional parameters for which arguments 
were omitted in the call. This is a consequence of a general preference 
in overload resolution for candidates that have fewer parameters.



It doesn't cover your case. Of course this is bad. But this isn't much 
different from another solved problem...



void f(float s){}
void f(double s){}

void main() {
f(3);
}

x.d(5): Error: function x.f called with argument types:
((int))
matches both:
x.f(float s)
and:
x.f(double s)


We could do the same for named arguments.


void fun(int a, string b) {}
void fun(string b, int a) {}

void main() {
fun(a: 1, b: "hello");
}

x.d(5): Error: function x.fun called with argument names and types:
((int a, string b))
matches both:
x.f(int a, string b)
and:
x.f(string b, int a)



Re: Flag proposal

2011-06-14 Thread KennyTM~

On Jun 14, 11 19:11, so wrote:
[snip]

Also i don't understand why some think allowing hybrid calls has any
merit. Just search "named arguments" and first thing you'd see is calls
with all arguments named, no exception. Allowing unnamed arguments and
named arguments in one call doesn't make any sense to me, it is almost
opposite to the reasons named arguments designed for, you don't even
need to talk about its drawbacks like the complications and confusions.


And if you think it's complicated, you're just thinking in a too 
complicated way. The rule is simple.


Say there is a function

pure nothrow
S parseString(S=const(char)[], C)
   (ref C[] input,
out ConversionResult result,
char quote='"',
bool recognizePrefix=true) if (...);

and you call it as

string s = `"hello"`;
ConversionResult detailResult;
auto parsed = parseString(s, recognizePrefix:false, 
result:detailResult);


The first step is identify all positional arguments ('s' here), and fill 
them in in-order.


input <- s
result <- ...
quote <- ...
recognizePrefix <- ...

next, we match the named args

input <- s
result <- detailResult
quote <- ...
recognizePrefix <- false

finally we fill in the optional parameters

input <- s
result <- detailResult
quote <- '"'
recognizePrefix <- false

what's so complicated? Actually, reordering creates more complication 
than hybrid (e.g. ambiguity in selecting an overload).


Re: Flag proposal

2011-06-14 Thread Andrei Alexandrescu

On 6/14/11 1:58 AM, so wrote:

Tell me this is not true! :)
So ruby don't have named arguments and the community came up with a
solution which is by the look of it heavily influenced by language
capabilities. No offense and please no kicking butts but... This is
madness!!!


Ha! My Flag chef d'oeuvre would enjoy appreciation, just in another 
language.


Andrei


Re: Flag proposal

2011-06-14 Thread Michel Fortin

On 2011-06-13 21:36:01 -0400, so  said:


IMO named arguments in D at least should do:

- Reordering (since we got default parameters, even better)

- It is enabled only if we have access to the function declaration.

- In a function call we either use named arguments for all the 
non-default  arguments or call it with the usual syntax. No hybrid 
stuff, no confusion.


   fun(int a, int b, int c=3)

   fun(1, 2, 3) // fine - current
   fun(1, 2) // fine - current

   fun(a:1, b:3, c:5) // fine
   fun(a:1, b:3) // fine
   fun(b:1, c:3, a:5) // fine
   fun(b:1, a:3) // fine
   fun(b:1) // error
   fun(c:1) // error
   fun(2, b:1) // error
   fun(2, c:1) // error
   fun(2, c:2, 3) // error


There's much more to named arguments as it first appears. Have you 
thought about:


1. variadic arguments?
2. named template arguments?
3. template variadic arguments (tuples) and how they expand as function 
parameters?


Also, with reordering, if you have two overloaded functions of this form:

void fun(int a, string b) {}
void fun(string b, int a) {}

which one does this calls:

fun(a: 1, b: "hello");

? Does the call become ambiguous when using named arguments? It 
wouldn't be ambiguous if reordering wasn't allowed. What does C# does 
with this?



--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Flag proposal

2011-06-14 Thread KennyTM~

On Jun 14, 11 19:11, so wrote:

On Tue, 14 Jun 2011 12:58:30 +0300, KennyTM~  wrote:


And yet, with loc.x, myWin.width etc, you don't need to check the
definition to know those should be coordinates and widths.


loc.x on the caller side, it has no idea about function signature, and
you don't know if it was 10th or 2nd argument in function.

// definition
fun(int x, int y) {
}

// call
fun(x, y) // you need to check the definition if you think something
wrong with parameters the second time you come here
fun(y, x) // same
fun(x:x, y:y) // you know there is nothing wrong with parameters
fun(y:y, x:x) // same



If you have no idea about the function signature, you have no idea about 
the parameter names either.



You don't need to abandon hybrid to enable reordering. Ary's
suggestion, for example, allows positional and named arguments to
coexist.


Allows reordering by introducing two new order restrictions which i
still had trouble understanding, sorry Ary :)


Why do you need to check the function definition when you see
'moveTo(x, y)'?


Same question, why do you need named arguments?



You see the difference between variables and generic constants?

 RECT bounds;
 GetWindowRect(hWnd, &bounds);

 writeln("Please enter the coordinates.");
 auto x = readln().chomp().to!int();
 auto y = readln().chomp().to!int();
 auto width = bounds.right - bounds.left;
 auto height = bounds.bottom - bounds.top;

 MoveWindow(hWnd, x, y, width, height, bRepaint:true);

vs.

 writeln("Resetting window dimensions");
 ...
 MoveWindow(hWnd, X:0, Y:0, nWidth:800, nHeight:600, bRepaint:true);

Named arguments provides clarification when the argument itself (e.g. 0, 
false, true) is meaningless. But with a variable which itself provides a 
meaning, forcing named argument on _every_argument_passed_ is just annoying.



enum bRepaint=true;
MoveWindow(... bRepaint)


Non sequitur. In my MoveWindow example hWnd, loc and myWin are assumed
to be variables you got from elsewhere. The names of these variables
already provide the semantics to the readers, making NA for those
arguments redundant. If they were constants it's nothing wrong with

MoveWindow(hWnd, X:0, Y:0, nWidth:200, nHeight:200, bRepaint:true);


Again, they are variables you get on the caller side, they got no idea
about function signature.


See above.


Also i don't understand why some think allowing hybrid calls has any
merit. Just search "named arguments" and first thing you'd see is calls
with all arguments named, no exception. Allowing unnamed arguments and
named arguments in one call doesn't make any sense to me, it is almost
opposite to the reasons named arguments designed for, you don't even
need to talk about its drawbacks like the complications and confusions.


Yet all well-known languages that support named arguments that support 
reordering also support hybrid. (C# 4, VB 6, Python, CLisp, ...)


Re: Flag proposal

2011-06-14 Thread so

On Tue, 14 Jun 2011 12:58:30 +0300, KennyTM~  wrote:

And yet, with loc.x, myWin.width etc, you don't need to check the  
definition to know those should be coordinates and widths.


loc.x on the caller side, it has no idea about function signature, and you  
don't know if it was 10th or 2nd argument in function.


// definition
fun(int x, int y) {
}

// call
fun(x, y) // you need to check the definition if you think something wrong  
with parameters the second time you come here

fun(y, x) // same
fun(x:x, y:y) // you know there is nothing wrong with parameters
fun(y:y, x:x) // same

You don't need to abandon hybrid to enable reordering. Ary's suggestion,  
for example, allows positional and named arguments to coexist.


Allows reordering by introducing two new order restrictions which i still  
had trouble understanding, sorry Ary :)


Why do you need to check the function definition when you see 'moveTo(x,  
y)'?


Same question, why do you need named arguments?


enum bRepaint=true;
MoveWindow(... bRepaint)


Non sequitur. In my MoveWindow example hWnd, loc and myWin are assumed  
to be variables you got from  elsewhere. The names of these variables  
already provide the semantics to the readers, making NA for those  
arguments redundant.  If they were constants it's nothing wrong with


 MoveWindow(hWnd, X:0, Y:0, nWidth:200, nHeight:200, bRepaint:true);


Again, they are variables you get on the caller side, they got no idea  
about function signature.
Also i don't understand why some think allowing hybrid calls has any  
merit. Just search "named arguments" and first thing you'd see is calls  
with all arguments named, no exception. Allowing unnamed arguments and  
named arguments in one call doesn't make any sense to me, it is almost  
opposite to the reasons named arguments designed for, you don't even need  
to talk about its drawbacks like the complications and confusions.


Re: Flag proposal

2011-06-14 Thread KennyTM~

On Jun 14, 11 16:39, so wrote:

On Tue, 14 Jun 2011 11:23:12 +0300, KennyTM~  wrote:


On Jun 14, 11 14:46, so wrote:

On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~  wrote:


I'd rather have no reordering and allow hybrid call. Named argument is
useful for specifying the nature of an argument. If the type is clear
for all but one argument, the rest is just noisy redundant info.


fun(bool, bool, bool, bool, bool...)
Isn't the type clear for every argument here?



By "type" I mean the purpose of an argument, e.g. the first 'int' in
MoveWindow is an x-coordinate, the second is a y-coordinate, etc.
Sorry I don't know of a better term. When what one argument does is
clear for the caller, forcing NA on it just annoys the programmer.


This is the whole point of NAs, it is not clear, you need to check the
function definition whenever you read the call.



And yet, with loc.x, myWin.width etc, you don't need to check the 
definition to know those should be coordinates and widths.



e.g.

MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
bRepaint:true);

is no worse than

MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);


Reordering is important an example:

fun(int a, int b=2, int c=3)
If you want to name c but not b what are you going to do?



That's skipping, not really reordering. 'a' still precedes 'c'. Also,
I'm not against reordering, but I'm against using reordering as a
reason to abandon hybrid.


It is not a reason to abandon hybrid, it is a consequence of abandoning it.



You don't need to abandon hybrid to enable reordering. Ary's suggestion, 
for example, allows positional and named arguments to coexist.



Named arguments isn't something to save typing.
Also the first version of the MoveWindow indeed worse than the second,
which again i think requires no explanation.


No, please explain. What does the extra hWnd, X, Y, nWidth, nHeight
buy, when the respective arguments already show what they are?'


Matching, with fun(x:x, y:y) or fun(y:y, x:x) you are done, you don't
ever need to check function definition again.
With your reasoning you don't need named arguments at all.



Why do you need to check the function definition when you see 'moveTo(x, 
y)'?



enum bRepaint=true;
MoveWindow(... bRepaint)


Non sequitur. In my MoveWindow example hWnd, loc and myWin are assumed 
to be variables you got from  elsewhere. The names of these variables 
already provide the semantics to the readers, making NA for those 
arguments redundant.  If they were constants it's nothing wrong with


MoveWindow(hWnd, X:0, Y:0, nWidth:200, nHeight:200, bRepaint:true);




Re: Flag proposal

2011-06-14 Thread so

On Tue, 14 Jun 2011 11:23:12 +0300, KennyTM~  wrote:


On Jun 14, 11 14:46, so wrote:

On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~  wrote:


I'd rather have no reordering and allow hybrid call. Named argument is
useful for specifying the nature of an argument. If the type is clear
for all but one argument, the rest is just noisy redundant info.


fun(bool, bool, bool, bool, bool...)
Isn't the type clear for every argument here?



By "type" I mean the purpose of an argument, e.g. the first 'int' in  
MoveWindow is an x-coordinate, the second is a y-coordinate, etc. Sorry  
I don't know of a better term. When what  one argument does is clear for  
the caller, forcing NA on it just annoys the programmer.


This is the whole point of NAs, it is not clear, you need to check the  
function definition whenever you read the call.



e.g.

MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
bRepaint:true);

is no worse than

MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);


Reordering is important an example:

fun(int a, int b=2, int c=3)
If you want to name c but not b what are you going to do?



That's skipping, not really reordering. 'a' still precedes 'c'. Also,  
I'm not against reordering, but I'm against using reordering as a reason  
to abandon hybrid.


It is not a reason to abandon hybrid, it is a consequence of abandoning it.


Named arguments isn't something to save typing.
Also the first version of the MoveWindow indeed worse than the second,
which again i think requires no explanation.


No, please explain. What does the extra hWnd, X, Y, nWidth, nHeight buy,  
  when the respective arguments already show what they are?'


Matching, with fun(x:x, y:y) or fun(y:y, x:x) you are done, you don't ever  
need to check function definition again.

With your reasoning you don't need named arguments at all.

enum bRepaint=true;
MoveWindow(... bRepaint)


Re: Flag proposal

2011-06-14 Thread KennyTM~

On Jun 14, 11 14:46, so wrote:

On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~  wrote:


I'd rather have no reordering and allow hybrid call. Named argument is
useful for specifying the nature of an argument. If the type is clear
for all but one argument, the rest is just noisy redundant info.


fun(bool, bool, bool, bool, bool...)
Isn't the type clear for every argument here?



By "type" I mean the purpose of an argument, e.g. the first 'int' in 
MoveWindow is an x-coordinate, the second is a y-coordinate, etc. Sorry 
I don't know of a better term. When what  one argument does is clear for 
the caller, forcing NA on it just annoys the programmer.



e.g.

MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
bRepaint:true);

is no worse than

MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);


Reordering is important an example:

fun(int a, int b=2, int c=3)
If you want to name c but not b what are you going to do?



That's skipping, not really reordering. 'a' still precedes 'c'. Also, 
I'm not against reordering, but I'm against using reordering as a reason 
to abandon hybrid.



Named arguments isn't something to save typing.
Also the first version of the MoveWindow indeed worse than the second,
which again i think requires no explanation.


No, please explain. What does the extra hWnd, X, Y, nWidth, nHeight buy, 
 when the respective arguments already show what they are?'


Re: Flag proposal

2011-06-14 Thread so

Reordering is important an example:

fun(int a, int b=2, int c=3)
If you want to name c but not b what are you going to do?


In fact, i was wrong on this one, you'd simply call fun(a, c:4).
Reordering is nice because if you remove hybrid calls you no longer need  
an order, you are free to change priority.


Re: Flag proposal

2011-06-14 Thread Ary Manzana

On 6/14/11 1:58 PM, so wrote:

On Tue, 14 Jun 2011 09:48:14 +0300, Ary Manzana 
wrote:


Well, that's the way Ruby works :-)

In fact, in Ruby there are no named arguments. So people came up with
this idea.

def some_function(param_a, param_b, options = {})
param_c = options['param_c'] || default_for_c
param_d = options['param_d'] || default_for_d
end

The last argument is a hash (a dictionary) with a default value of an
empty hash.

So you can call it:

some_function(1, 2)
some_function(1, 2, {'param_c' => 3})
some_function(1, 2, {'param_c' => 3, 'param_d' => 4})

But in Ruby there's a rule: you can skip parenthesis. And you can skip
the brackets for a hash if it's the last argument. And instead of
strings symbols are much nicer and efficient. So...

some_function 1, 2
some_function 1, 2, :param_c => 3
some_function 1, 3, :param_c => 3, :param_d => 4

Of course this won't work in D because passing hashes all the time
would be very inneficcient. But I think positional arguments first,
named arguments last is a simple rule that's easy to follow and
probably implement (maybe when I'll go back to my country I'll try to
implement it).


Tell me this is not true! :)


:-P


So ruby don't have named arguments and the community came up with a
solution which is by the look of it heavily influenced by language
capabilities. No offense and please no kicking butts but... This is
madness!!!


Well, in fact I don't know if the community came up with this or if the 
creators came up with this. But I'm sure at some point they agreed on 
this because it's supported on the syntax level.


Re: Flag proposal

2011-06-14 Thread so
On Tue, 14 Jun 2011 09:48:14 +0300, Ary Manzana   
wrote:



Well, that's the way Ruby works :-)

In fact, in Ruby there are no named arguments. So people came up with  
this idea.


def some_function(param_a, param_b, options = {})
   param_c = options['param_c'] || default_for_c
   param_d = options['param_d'] || default_for_d
end

The last argument is a hash (a dictionary) with a default value of an  
empty hash.


So you can call it:

some_function(1, 2)
some_function(1, 2, {'param_c' => 3})
some_function(1, 2, {'param_c' => 3, 'param_d' => 4})

But in Ruby there's a rule: you can skip parenthesis. And you can skip  
the brackets for a hash if it's the last argument. And instead of  
strings symbols are much nicer and efficient. So...


some_function 1, 2
some_function 1, 2, :param_c => 3
some_function 1, 3, :param_c => 3, :param_d => 4

Of course this won't work in D because passing hashes all the time would  
be very inneficcient. But I think positional arguments first, named  
arguments last is a simple rule that's easy to follow and probably  
implement (maybe when I'll go back to my country I'll try to implement  
it).


Tell me this is not true! :)
So ruby don't have named arguments and the community came up with a  
solution which is by the look of it heavily influenced by language  
capabilities. No offense and please no kicking butts but... This is  
madness!!!


Re: Flag proposal

2011-06-14 Thread Ary Manzana

On 6/14/11 1:38 PM, so wrote:

On Tue, 14 Jun 2011 09:33:54 +0300, Ary Manzana 
wrote:


On 6/14/11 12:58 PM, so wrote:

On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky  wrote:


I think Ary's suggestion is very simple and easy to understand. Hybrid
calls
are *only* confusing when an unnamed parameter comes after a named one.


An example to it.

fun(int a, int b, int c, int d)

Say we want to name only c:

fun(2, 3, 1, c:5)

// error: c assigned twice

Remember, the third argument is positional so it's assigned to c. Then
you are trying to assign c again. It's an error.


Sorry i don't understand, what should i do?


You can't only name c. You can name arguments from the end to the beginning:

fun(2, 3, 1, d: 99)
fun(2, 3, c: 98, d:99)
fun(2, 3, d: 98, c:99)
fun(2, c: 97, b: 98, d:99)
etc.


Re: Flag proposal

2011-06-13 Thread so

On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~  wrote:

I'd rather have no reordering and allow hybrid call. Named argument is  
useful for specifying the nature of an argument. If the type is clear  
for all but one argument, the rest is just noisy redundant info.


fun(bool, bool, bool, bool, bool...)
Isn't the type clear for every argument here?


e.g.

 MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
bRepaint:true);

is no worse than

 MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);


Reordering is important an example:

fun(int a, int b=2, int c=3)
If you want to name c but not b what are you going to do?

Named arguments isn't something to save typing.
Also the first version of the MoveWindow indeed worse than the second,  
which again i think requires no explanation.


Re: Flag proposal

2011-06-13 Thread Ary Manzana

On 6/14/11 12:32 PM, Nick Sabalausky wrote:

"so"  wrote in message news:op.vw1msqy0mpw3zg@so-pc...

On Tue, 14 Jun 2011 04:46:54 +0300, Ary Manzana
wrote:


On 6/14/11 8:36 AM, so wrote:

On Mon, 13 Jun 2011 20:19:15 +0300, bearophile<
  wrote:


Andrei:


If we all get convinced that named parameters are worth it,


I think this is not going to happen because some people (two?) don't
want this feature.


I think they worth it and it is the right time to talk extensively why
people think they don't.
And reasoning should not be about its failure or success in another
language, we better have our own rules.

IMO named arguments in D at least should do:

- Reordering (since we got default parameters, even better)

- It is enabled only if we have access to the function declaration.

- In a function call we either use named arguments for all the
non-default arguments or call it with the usual syntax. No hybrid stuff,
no confusion.


A different rule can be:
   - Named arguments come last.
   - Any previous arguments match the order.


IMO the main that makes NAs confusing is allowing hybrid calls.
I don't think allowing reordering then introducing two new rules on
ordering is a good idea.


I think Ary's suggestion is very simple and easy to understand. Hybrid calls
are *only* confusing when an unnamed parameter comes after a named one.


Well, that's the way Ruby works :-)

In fact, in Ruby there are no named arguments. So people came up with 
this idea.


def some_function(param_a, param_b, options = {})
  param_c = options['param_c'] || default_for_c
  param_d = options['param_d'] || default_for_d
end

The last argument is a hash (a dictionary) with a default value of an 
empty hash.


So you can call it:

some_function(1, 2)
some_function(1, 2, {'param_c' => 3})
some_function(1, 2, {'param_c' => 3, 'param_d' => 4})

But in Ruby there's a rule: you can skip parenthesis. And you can skip 
the brackets for a hash if it's the last argument. And instead of 
strings symbols are much nicer and efficient. So...


some_function 1, 2
some_function 1, 2, :param_c => 3
some_function 1, 3, :param_c => 3, :param_d => 4

Of course this won't work in D because passing hashes all the time would 
be very inneficcient. But I think positional arguments first, named 
arguments last is a simple rule that's easy to follow and probably 
implement (maybe when I'll go back to my country I'll try to implement it).


Re: Flag proposal

2011-06-13 Thread so
On Tue, 14 Jun 2011 09:33:54 +0300, Ary Manzana   
wrote:



On 6/14/11 12:58 PM, so wrote:

On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky  wrote:


I think Ary's suggestion is very simple and easy to understand. Hybrid
calls
are *only* confusing when an unnamed parameter comes after a named one.


An example to it.

fun(int a, int b, int c, int d)

Say we want to name only c:

fun(2, 3, 1, c:5)

// error: c assigned twice

Remember, the third argument is positional so it's assigned to c. Then  
you are trying to assign c again. It's an error.


Sorry i don't understand, what should i do?


Re: Flag proposal

2011-06-13 Thread Ary Manzana

On 6/14/11 12:58 PM, so wrote:

On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky  wrote:


I think Ary's suggestion is very simple and easy to understand. Hybrid
calls
are *only* confusing when an unnamed parameter comes after a named one.


An example to it.

fun(int a, int b, int c, int d)

Say we want to name only c:

fun(2, 3, 1, c:5)

// error: c assigned twice

Remember, the third argument is positional so it's assigned to c. Then 
you are trying to assign c again. It's an error.


Re: Flag proposal

2011-06-13 Thread KennyTM~

On Jun 14, 11 09:36, so wrote:

On Mon, 13 Jun 2011 20:19:15 +0300, bearophile <
 wrote:


Andrei:


If we all get convinced that named parameters are worth it,


I think this is not going to happen because some people (two?) don't
want this feature.


I think they worth it and it is the right time to talk extensively why
people think they don't.
And reasoning should not be about its failure or success in another
language, we better have our own rules.

IMO named arguments in D at least should do:

- Reordering (since we got default parameters, even better)

- It is enabled only if we have access to the function declaration.

- In a function call we either use named arguments for all the
non-default arguments or call it with the usual syntax. No hybrid stuff,
no confusion.

fun(int a, int b, int c=3)

fun(1, 2, 3) // fine - current
fun(1, 2) // fine - current

fun(a:1, b:3, c:5) // fine
fun(a:1, b:3) // fine
fun(b:1, c:3, a:5) // fine
fun(b:1, a:3) // fine
fun(b:1) // error
fun(c:1) // error
fun(2, b:1) // error
fun(2, c:1) // error
fun(2, c:2, 3) // error

Thanks.


I'd rather have no reordering and allow hybrid call. Named argument is 
useful for specifying the nature of an argument. If the type is clear 
for all but one argument, the rest is just noisy redundant info.


e.g.

MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
   bRepaint:true);

is no worse than

MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
   nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);



Re: Flag proposal

2011-06-13 Thread so

On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky  wrote:

I think Ary's suggestion is very simple and easy to understand. Hybrid  
calls

are *only* confusing when an unnamed parameter comes after a named one.


An example to it.

fun(int a, int b, int c, int d)

Say we want to name only c:

fun(2, 3, 1, c:5)

Ary's rules and function signature in mind, after you glance the call  
you'd do some calculations and eventually find out the caller meant:


fun(a:2, b:3, d:1, c:5)

This is only 4 parameters and i named only one. Now NAs supposed to ease  
to process of self-documenting, not complicate it even further.
I'm in favor of keeping it as simple as possible without creating any  
confusion.


Re: Flag proposal

2011-06-13 Thread Nick Sabalausky
"so"  wrote in message news:op.vw1msqy0mpw3zg@so-pc...
> On Tue, 14 Jun 2011 04:46:54 +0300, Ary Manzana  
> wrote:
>
>> On 6/14/11 8:36 AM, so wrote:
>>> On Mon, 13 Jun 2011 20:19:15 +0300, bearophile <
>>>  wrote:
>>>
 Andrei:

> If we all get convinced that named parameters are worth it,

 I think this is not going to happen because some people (two?) don't
 want this feature.
>>>
>>> I think they worth it and it is the right time to talk extensively why
>>> people think they don't.
>>> And reasoning should not be about its failure or success in another
>>> language, we better have our own rules.
>>>
>>> IMO named arguments in D at least should do:
>>>
>>> - Reordering (since we got default parameters, even better)
>>>
>>> - It is enabled only if we have access to the function declaration.
>>>
>>> - In a function call we either use named arguments for all the
>>> non-default arguments or call it with the usual syntax. No hybrid stuff,
>>> no confusion.
>>
>> A different rule can be:
>>   - Named arguments come last.
>>   - Any previous arguments match the order.
>
> IMO the main that makes NAs confusing is allowing hybrid calls.
> I don't think allowing reordering then introducing two new rules on 
> ordering is a good idea.

I think Ary's suggestion is very simple and easy to understand. Hybrid calls 
are *only* confusing when an unnamed parameter comes after a named one.





Re: Flag proposal

2011-06-13 Thread so
On Tue, 14 Jun 2011 04:46:54 +0300, Ary Manzana   
wrote:



On 6/14/11 8:36 AM, so wrote:

On Mon, 13 Jun 2011 20:19:15 +0300, bearophile <
 wrote:


Andrei:


If we all get convinced that named parameters are worth it,


I think this is not going to happen because some people (two?) don't
want this feature.


I think they worth it and it is the right time to talk extensively why
people think they don't.
And reasoning should not be about its failure or success in another
language, we better have our own rules.

IMO named arguments in D at least should do:

- Reordering (since we got default parameters, even better)

- It is enabled only if we have access to the function declaration.

- In a function call we either use named arguments for all the
non-default arguments or call it with the usual syntax. No hybrid stuff,
no confusion.


A different rule can be:
  - Named arguments come last.
  - Any previous arguments match the order.


IMO the main that makes NAs confusing is allowing hybrid calls.
I don't think allowing reordering then introducing two new rules on  
ordering is a good idea.


Re: Flag proposal

2011-06-13 Thread Ary Manzana

On 6/14/11 8:36 AM, so wrote:

On Mon, 13 Jun 2011 20:19:15 +0300, bearophile <
 wrote:


Andrei:


If we all get convinced that named parameters are worth it,


I think this is not going to happen because some people (two?) don't
want this feature.


I think they worth it and it is the right time to talk extensively why
people think they don't.
And reasoning should not be about its failure or success in another
language, we better have our own rules.

IMO named arguments in D at least should do:

- Reordering (since we got default parameters, even better)

- It is enabled only if we have access to the function declaration.

- In a function call we either use named arguments for all the
non-default arguments or call it with the usual syntax. No hybrid stuff,
no confusion.


A different rule can be:
 - Named arguments come last.
 - Any previous arguments match the order.




fun(int a, int b, int c=3)

fun(1, 2, 3) // fine - current
fun(1, 2) // fine - current

fun(a:1, b:3, c:5) // fine
fun(a:1, b:3) // fine
fun(b:1, c:3, a:5) // fine
fun(b:1, a:3) // fine
fun(b:1) // error

// error: missing a


fun(c:1) // error

// error: missing a and b

fun(2, b:1) // error

// ok, a is 2, b is 1, c is 3


fun(2, c:1) // error

// error: missing b


fun(2, c:2, 3) // error

// error, 3 after named arguments


Re: Flag proposal

2011-06-13 Thread so
On Mon, 13 Jun 2011 20:19:15 +0300, bearophile <  
 wrote:



Andrei:


If we all get convinced that named parameters are worth it,


I think this is not going to happen because some people (two?) don't  
want this feature.


I think they worth it and it is the right time to talk extensively why  
people think they don't.
And reasoning should not be about its failure or success in another  
language, we better have our own rules.


IMO named arguments in D at least should do:

- Reordering (since we got default parameters, even better)

- It is enabled only if we have access to the function declaration.

- In a function call we either use named arguments for all the non-default  
arguments or call it with the usual syntax. No hybrid stuff, no confusion.


  fun(int a, int b, int c=3)

  fun(1, 2, 3) // fine - current
  fun(1, 2) // fine - current

  fun(a:1, b:3, c:5) // fine
  fun(a:1, b:3) // fine
  fun(b:1, c:3, a:5) // fine
  fun(b:1, a:3) // fine
  fun(b:1) // error
  fun(c:1) // error
  fun(2, b:1) // error
  fun(2, c:1) // error
  fun(2, c:2, 3) // error

Thanks.


Re: turtles features (Was: Flag proposal)

2011-06-13 Thread bearophile
Timon Gehr:

> Will this be fixed too?

Mutually recursive inner functions are not so common, and there is a 
workaround, making one of them a delegate defined before.

But what about this?

auto foo()()
out(result) {
} body {
return 0;
}
void main() {
foo();
}


test.d(1): Error: function test.foo!().foo post conditions are not supported if 
the return type is inferred
test.d(7): Error: template instance test.foo!() error instantiating
test.d(7): Error: forward reference to inferred return type of function call foo

This is a common problem for my code, is it possible to fix (support) this? (In 
functional-style code auto return values are sometimes almost necessary).

Bye,
bearophile


turtles features (Was: Flag proposal)

2011-06-13 Thread Timon Gehr
Andrei Alexandrescu wrote:
> module my_module;
>
> void fun()
> {
>  import std.random;
>  return uniform(0, 100);
> }
>
> int gun()
> {
>  import std.stdio;
>  writeln(fun());
> }
>
> This module won't compile in today's D, but not for a matter of
> principles; it's just a random limitation of the language. (It does work
> if you import from within a class or struct.) You can insert most
> declarations in a scope, so the ones you can't insert are just awkward
> exceptions, unless there's a good reason to actively disable them. Any
> code should work if you just wrap another scope around it.


//void main(){
immutable a = b;
immutable b = 1;

int foo(int n){
if(n==1) return 1;
return 1+bar(n);
}

int bar(int n){
if(n&1) return foo(3*n+1);
return foo(n/2);
}
//}

Will this be fixed too?

Timon


Re: Flag proposal

2011-06-13 Thread Timon Gehr
> On 6/13/11 4:02 PM, Nick Sabalausky wrote:
>> "Andrei Alexandrescu"  wrote in message
>> news:it3ne2$1g2f$1...@digitalmars.com...
>>> That actually does help, but not for enums used by more than one function.
>>> The other issues remain too.
>>>
>>
>> I would think that an enum used by more than one function *should* be listed
>> separately.
>
> Actually, not necessarily, if the definition is self explanatory. By the
> same argument a named argument with the same name and meaning in several
> functions doesn't necessarily have to be defined separately.
>
>
> Andrei

What about just not documenting the enum itself? This elegantly resolves the
'certain' vs. 'an' debate too :o).


Timon


Re: Flag proposal

2011-06-13 Thread Andrei Alexandrescu

On 6/13/11 4:02 PM, Nick Sabalausky wrote:

"Andrei Alexandrescu"  wrote in message
news:it3ne2$1g2f$1...@digitalmars.com...

That actually does help, but not for enums used by more than one function.
The other issues remain too.



I would think that an enum used by more than one function *should* be listed
separately.


Actually, not necessarily, if the definition is self explanatory. By the 
same argument a named argument with the same name and meaning in several 
functions doesn't necessarily have to be defined separately.



Andrei


Re: Flag proposal

2011-06-13 Thread Nick Sabalausky
"Andrei Alexandrescu"  wrote in message 
news:it3ne2$1g2f$1...@digitalmars.com...
> On 6/12/11 2:19 PM, Nick Sabalausky wrote:
>> "Andrei Alexandrescu"  wrote in message
>> news:it32j8$2gfq$1...@digitalmars.com...
>>> On 6/12/11 1:45 PM, Nick Sabalausky wrote:
 "Andrei Alexandrescu"   wrote in message
 news:it1c0f$1uup$1...@digitalmars.com...
> On 06/11/2011 03:52 PM, Nick Sabalausky wrote:
>> "Andrei Alexandrescu"wrote in 
>> message
>> news:it07ni$1pvj$1...@digitalmars.com...
>>>
>>> Anyway, that was the first thing "grep yes std/*" found. Let's see 
>>> the
>>> next one:
>>>
>>> /**
>>> Specifies whether the output of certain algorithm is desired in 
>>> sorted
>>> format.
>>> */
>>> enum SortOutput {
>>>no,  /// Don't sort output
>>>yes, /// Sort output
>>> }
>>>
>>> This already is very unpleasant because "certain" is as imprecise as
>>> it
>>> gets. Plus one for Flag, I hope you agree.
>>>
>>
>> Flag -= 1
>> s/output of certain algorithm/output of an algorithm/ += 1
>>
>> That one-word doc change makes it all perfectly clear.
>
> Not at all. The typo in the original text must have confused you: it
> should be "certain algorithms" because SortOutput is used in four
> distinct
> algorithms (one of which has two overloads). Grep std/algorithm.d.
>
> Flag += 2
>

 Not that I consider quibbling over small English wording differences a
 major
 thing, but I fail to see how:

 "Specifies whether the output of an algorithm is desired in sorted
 format."

 is significantly different from:

 "Specifies whether the output of certain algorithms are desired in 
 sorted
 format."

 In either case, I don't see anything problematically imprecise.
>>>
>>> Still means I need to jump back and forth in the documentation.
>>>
>>
>> And you don't like the "///ditto" suggestion for handling that?
>
> That actually does help, but not for enums used by more than one function. 
> The other issues remain too.
>

I would think that an enum used by more than one function *should* be listed 
separately.




Re: Flag proposal

2011-06-13 Thread Nick Sabalausky
"bearophile" < bearophileh...@lycos.com> wrote in message 
news:it5gqj$a1g$1...@digitalmars.com...
> Andrei:
>
>> If we all get convinced that named parameters are worth it,
>
> I think this is not going to happen because some people (two?) don't want 
> this feature.
>
> I am for it, if it's well implemented. The reordering is one important 
> part of this feature.
> An optional sub-feature is a way to deprecate argument names. Thankfully 
> in D there is already the deprecated keyword; a first idea:
>
> void foo(int deprecated(y) x) {}
> Or:
> void foo(int deprecated{y} x) {}
>

I like it!




Re: Flag proposal

2011-06-13 Thread bearophile
Andrei:

> If we all get convinced that named parameters are worth it,

I think this is not going to happen because some people (two?) don't want this 
feature.

I am for it, if it's well implemented. The reordering is one important part of 
this feature.
An optional sub-feature is a way to deprecate argument names. Thankfully in D 
there is already the deprecated keyword; a first idea:

void foo(int deprecated(y) x) {}
Or:
void foo(int deprecated{y} x) {}

Bye,
bearophile


Re: Flag proposal

2011-06-13 Thread Lars T. Kyllingstad
On Sun, 12 Jun 2011 14:59:57 -0400, Nick Sabalausky wrote:

> "Andrei Alexandrescu"  wrote in message
> news:it1cvf$21d4$1...@digitalmars.com...
>>
>> It's the namespace pollution and the non-self-containedness of the
>> function that's most troublesome. Also see Steve's point about methods.
>> It's just untenable - to use the idiom with a class/struct method, you
>> need to go all the way _outside_ of it an plant a symbol there.
>>
>>
> You can't put an enum in a class/struct?

Yes, but then you have to qualify it with the name of the class/struct 
when using it.  See Steve's post:

http://www.digitalmars.com/webnews/newsgroups.php?
art_group=digitalmars.D&article_id=138281

-Lars


Re: Flag proposal [OT]

2011-06-13 Thread Alix Pexton

On 13/06/2011 02:31, Paul D. Anderson wrote:

Alix Pexton Wrote:


On 12/06/2011 16:11, Steven Schveighoffer wrote:

On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton
  wrote:


On 12/06/2011 02:40, Steven Schveighoffer wrote:

On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic
  wrote:


On 6/11/11, Alix Pexton  wrote:

On 11/06/2011 06:18, Andrej Mitrovic wrote:

We should rename Yes and No to Yay and Nay to make them alignable,
and
even more importantly to make us appear as old Englishmen!


"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not
actually a old English word :) A more correct alternative would be
"Aye" (pronounced the same as "eye"), which (along with "Nay") is
still
used for some voting actions (such as councillors deciding where to go
for lunch). I myself say it al least 20 times a day :)

A...



Oh damn, yay is what teenage girls would say, not old Englishmen. My
bad, it really is "Aye". :p


You were phonetically right :) It's yea or nay.

http://dictionary.cambridge.org/dictionary/british/yea-or-nay

My son's most recent birthday (3 years old) was a farm-themed birthday,
and we asked people to RSVP yay or neigh :P

So I guess there's all kinds of kooky fun you can have with flags...

-Steve


Nope, its definitely Aye when used for voting, (at least it is round
here) as in "all those in favour, say aye", "ayes to the right" and
"the ayes have it". Maybe southerners say this "yea" word of which you
speak, we don't hold with their strange customs in these parts ^^


I don't deny that aye is used frequently for voting. All I was saying
is, the correct expression is yea or nay, not yay or nay. Andrej thought
it was actually aye or nay, which I've never heard as an expression.

I'm not sure it's used anymore, but it's definitely an expression that
was used for voting (see my dictionary reference).

-Steve


True, "yea-or-nay" is quite a common, if old fashioned phrase, but "yea"
on its own is exceptionally rare (to the point where I doubt ever
hearing anyone make such a noise and mean it to indicate the affirmative).

A...


Then you must not have heard the King James Version of the Bible read aloud, or 
been to a Shakespeare play.

Admittedly the KJV and Shakespeare's works don't count as modern English, but I doubt 
you've never "heard such a noise"!  :-)

p.s. The word appears 209 times in Shakespeare's plays. There's a website for 
everything!



Aye, I did mean people using their own words and not someone else's. for 
such a prolific writer, 209 doesn't seem like a lot, and I can't help 
wondering how many times the bard used "aye".


Mind you, he was a southerner!

A...



Re: Flag proposal [OT]

2011-06-12 Thread Paul D. Anderson
Alix Pexton Wrote:

> On 12/06/2011 16:11, Steven Schveighoffer wrote:
> > On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton
> >  wrote:
> >
> >> On 12/06/2011 02:40, Steven Schveighoffer wrote:
> >>> On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic
> >>>  wrote:
> >>>
>  On 6/11/11, Alix Pexton  wrote:
> > On 11/06/2011 06:18, Andrej Mitrovic wrote:
> >> We should rename Yes and No to Yay and Nay to make them alignable,
> >> and
> >> even more importantly to make us appear as old Englishmen!
> >
> > "Yay" and "Nay" are too similar looking, but luckily, "Yay" is not
> > actually a old English word :) A more correct alternative would be
> > "Aye" (pronounced the same as "eye"), which (along with "Nay") is
> > still
> > used for some voting actions (such as councillors deciding where to go
> > for lunch). I myself say it al least 20 times a day :)
> >
> > A...
> >
> 
>  Oh damn, yay is what teenage girls would say, not old Englishmen. My
>  bad, it really is "Aye". :p
> >>>
> >>> You were phonetically right :) It's yea or nay.
> >>>
> >>> http://dictionary.cambridge.org/dictionary/british/yea-or-nay
> >>>
> >>> My son's most recent birthday (3 years old) was a farm-themed birthday,
> >>> and we asked people to RSVP yay or neigh :P
> >>>
> >>> So I guess there's all kinds of kooky fun you can have with flags...
> >>>
> >>> -Steve
> >>
> >> Nope, its definitely Aye when used for voting, (at least it is round
> >> here) as in "all those in favour, say aye", "ayes to the right" and
> >> "the ayes have it". Maybe southerners say this "yea" word of which you
> >> speak, we don't hold with their strange customs in these parts ^^
> >
> > I don't deny that aye is used frequently for voting. All I was saying
> > is, the correct expression is yea or nay, not yay or nay. Andrej thought
> > it was actually aye or nay, which I've never heard as an expression.
> >
> > I'm not sure it's used anymore, but it's definitely an expression that
> > was used for voting (see my dictionary reference).
> >
> > -Steve
> 
> True, "yea-or-nay" is quite a common, if old fashioned phrase, but "yea" 
> on its own is exceptionally rare (to the point where I doubt ever 
> hearing anyone make such a noise and mean it to indicate the affirmative).
> 
> A...

Then you must not have heard the King James Version of the Bible read aloud, or 
been to a Shakespeare play.

Admittedly the KJV and Shakespeare's works don't count as modern English, but I 
doubt you've never "heard such a noise"!  :-)

p.s. The word appears 209 times in Shakespeare's plays. There's a website for 
everything!



Re: Flag proposal

2011-06-12 Thread Andrei Alexandrescu

On 6/12/11 2:19 PM, Nick Sabalausky wrote:

"Andrei Alexandrescu"  wrote in message
news:it32j8$2gfq$1...@digitalmars.com...

On 6/12/11 1:45 PM, Nick Sabalausky wrote:

"Andrei Alexandrescu"   wrote in message
news:it1c0f$1uup$1...@digitalmars.com...

On 06/11/2011 03:52 PM, Nick Sabalausky wrote:

"Andrei Alexandrescu"wrote in message
news:it07ni$1pvj$1...@digitalmars.com...


Anyway, that was the first thing "grep yes std/*" found. Let's see the
next one:

/**
Specifies whether the output of certain algorithm is desired in sorted
format.
*/
enum SortOutput {
   no,  /// Don't sort output
   yes, /// Sort output
}

This already is very unpleasant because "certain" is as imprecise as
it
gets. Plus one for Flag, I hope you agree.



Flag -= 1
s/output of certain algorithm/output of an algorithm/ += 1

That one-word doc change makes it all perfectly clear.


Not at all. The typo in the original text must have confused you: it
should be "certain algorithms" because SortOutput is used in four
distinct
algorithms (one of which has two overloads). Grep std/algorithm.d.

Flag += 2



Not that I consider quibbling over small English wording differences a
major
thing, but I fail to see how:

"Specifies whether the output of an algorithm is desired in sorted
format."

is significantly different from:

"Specifies whether the output of certain algorithms are desired in sorted
format."

In either case, I don't see anything problematically imprecise.


Still means I need to jump back and forth in the documentation.



And you don't like the "///ditto" suggestion for handling that?


That actually does help, but not for enums used by more than one 
function. The other issues remain too.


Andrei


Re: Flag proposal [OT]

2011-06-12 Thread Alix Pexton

On 12/06/2011 16:11, Steven Schveighoffer wrote:

On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton
 wrote:


On 12/06/2011 02:40, Steven Schveighoffer wrote:

On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic
 wrote:


On 6/11/11, Alix Pexton  wrote:

On 11/06/2011 06:18, Andrej Mitrovic wrote:

We should rename Yes and No to Yay and Nay to make them alignable,
and
even more importantly to make us appear as old Englishmen!


"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not
actually a old English word :) A more correct alternative would be
"Aye" (pronounced the same as "eye"), which (along with "Nay") is
still
used for some voting actions (such as councillors deciding where to go
for lunch). I myself say it al least 20 times a day :)

A...



Oh damn, yay is what teenage girls would say, not old Englishmen. My
bad, it really is "Aye". :p


You were phonetically right :) It's yea or nay.

http://dictionary.cambridge.org/dictionary/british/yea-or-nay

My son's most recent birthday (3 years old) was a farm-themed birthday,
and we asked people to RSVP yay or neigh :P

So I guess there's all kinds of kooky fun you can have with flags...

-Steve


Nope, its definitely Aye when used for voting, (at least it is round
here) as in "all those in favour, say aye", "ayes to the right" and
"the ayes have it". Maybe southerners say this "yea" word of which you
speak, we don't hold with their strange customs in these parts ^^


I don't deny that aye is used frequently for voting. All I was saying
is, the correct expression is yea or nay, not yay or nay. Andrej thought
it was actually aye or nay, which I've never heard as an expression.

I'm not sure it's used anymore, but it's definitely an expression that
was used for voting (see my dictionary reference).

-Steve


True, "yea-or-nay" is quite a common, if old fashioned phrase, but "yea" 
on its own is exceptionally rare (to the point where I doubt ever 
hearing anyone make such a noise and mean it to indicate the affirmative).


A...


Re: Flag proposal

2011-06-12 Thread Walter Bright

On 6/12/2011 1:54 PM, Andrei Alexandrescu wrote:

On 06/12/2011 03:55 PM, foobar wrote:

People here already noted most advantages and disadvantages of this proposal
so I'll just add one more: KISS.
I too am against this proposal since it's very unKISS.


I agree that KISS is important and that Flag is failing it.


Set phasers to "vaporize".


Re: Flag proposal

2011-06-12 Thread Andrei Alexandrescu

On 06/12/2011 03:55 PM, foobar wrote:

People here already noted most advantages and disadvantages of this proposal so 
I'll just add one more: KISS.
I too am against this proposal since it's very unKISS.


I agree that KISS is important and that Flag is failing it.

Andrei


Re: Flag proposal

2011-06-12 Thread foobar
People here already noted most advantages and disadvantages of this proposal so 
I'll just add one more: KISS.
I too am against this proposal since it's very unKISS. 
I think, that either you really need a separate enum type to document the 
different values and hence use *should* define the enum or you don't really 
need it and hence KISS it with a plain boolean. 
I see zero benefit from adding so much complexity here. Are we trying to kill a 
fly with a hammer (and by that i mean the vehicle)?

I see no benefit in adding redundant "Yes" / "No" values.

Regarding named arguments, I don't like this "feature" and believe that it's 
more trouble than its worth. For example, Ruby managed to live without it and 
Rails uses AAs instead. 

And finally, Andrei's complain about scrolling up and down because of this so 
called boilerplate (7 lines of code in all of phobos): 
Even though D has a far superior module system compared to c++ (which has no 
such system whatsoever) you still chose to implement library-in-a-file. You 
even went so far as to add "groups" to DDoc. Is there some sort of weird metric 
at Facebook that gives you a bigger bonus if you manage to cram more code per 
file? Are you getting deducted per the amount of files you've added? 


Re: Flag proposal

2011-06-12 Thread Nick Sabalausky
"Timon Gehr"  wrote in message 
news:it0oee$ehu$1...@digitalmars.com...
> Jonathan M Davis wrote:
>> ...
>> The complaints about this generally seem to be one of these:
>>
>> 1. Dislike of the yes/no enum idiom in the first place. Regardless of how 
>> Flag
>> does it, it's a problem, because it's promoting an idiom that the poster
>> dislikes in the first place.
>>
>> 2. Flag!"enumName".yes and Flag!"enumName".no are ugly.
>>
>> 3. The use of a template such as Flag results in ugly error messages when 
>> it's
>> mistyped. EnumName.yes gets _much_ better errors when mistyped than
>> Flag!"enumName".yes.
>>
>> 4. Flag is seen as a narrow attempt at named arguments which would be far
>> better served by actually implementing named arguments.
>> [snip.]
>
> 5. The approach is too sophisticated and does not pull its own weight.
> Imagine what you would have to explain to somebody new to the language who
> wondered how Yes.sortOutput works... instant turn-off!
>

Not only that, but just simply trying to explain why you sometimes do 
"enumName.value" and sometimes do "value.enumName". It introduces a big 
inconsistency for callers, just for the sake of a trivial decrease in 
boilerplate for the callee.

Also, one thing I'm unclear on:

If you do:

   void foo(Flag!"bar" a) {}

Can the caller do something like this?:

   bar barValue = yes.bar;
   foo(barValue);







Re: Flag proposal

2011-06-12 Thread Nick Sabalausky
"Andrei Alexandrescu"  wrote in message 
news:it32kq$2gfq$2...@digitalmars.com...
> On 6/12/11 1:59 PM, Nick Sabalausky wrote:
>> "Andrei Alexandrescu"  wrote in message
>> news:it1cvf$21d4$1...@digitalmars.com...
>>>
>>> It's the namespace pollution and the non-self-containedness of the
>>> function that's most troublesome. Also see Steve's point about methods.
>>> It's just untenable - to use the idiom with a class/struct method, you
>>> need to go all the way _outside_ of it an plant a symbol there.
>>>
>>
>> You can't put an enum in a class/struct?
>>
>>> What I find most interesting is that the lack of strong counterarguments
>>> has not stood in the way of a strong emotional response.
>>
>> Correction: Andrei's staunch dismissal of all counterarguments has not 
>> stood
>> in the way of a strong emotional response.
>>
>>> This mood has made it difficult for exchange of rational arguments. 
>>> Funny
>>> thing is, the change is tiny.
>>>
>>> "Here, I'll add a handful of yes/no enums here and there in the standard
>>> library, just to help some algorithms. More to come."
>>>
>>> "Yeah, sure, whatevs."
>>>
>>> "Here, there's a way to define them once so we don't need to define them
>>> everywhere."
>>>
>>
>> Correction: "Here, there's a way to solve a barely-existant problem by
>> botching up syntax (and error messages) for the user."
>>
>>> "Gaa!!!"
>>>
>
> I'm not sure, but I think I see a sarcasm in there.
>

I guess it could be taken that way, but it wasn't really my point to be 
sarcastic. My intent was just to summarize the way I see the situation.





Re: Flag proposal

2011-06-12 Thread Nick Sabalausky
"Andrei Alexandrescu"  wrote in message 
news:it32j8$2gfq$1...@digitalmars.com...
> On 6/12/11 1:45 PM, Nick Sabalausky wrote:
>> "Andrei Alexandrescu"  wrote in message
>> news:it1c0f$1uup$1...@digitalmars.com...
>>> On 06/11/2011 03:52 PM, Nick Sabalausky wrote:
 "Andrei Alexandrescu"   wrote in message
 news:it07ni$1pvj$1...@digitalmars.com...
>
> Anyway, that was the first thing "grep yes std/*" found. Let's see the
> next one:
>
> /**
> Specifies whether the output of certain algorithm is desired in sorted
> format.
>*/
> enum SortOutput {
>   no,  /// Don't sort output
>   yes, /// Sort output
> }
>
> This already is very unpleasant because "certain" is as imprecise as 
> it
> gets. Plus one for Flag, I hope you agree.
>

 Flag -= 1
 s/output of certain algorithm/output of an algorithm/ += 1

 That one-word doc change makes it all perfectly clear.
>>>
>>> Not at all. The typo in the original text must have confused you: it
>>> should be "certain algorithms" because SortOutput is used in four 
>>> distinct
>>> algorithms (one of which has two overloads). Grep std/algorithm.d.
>>>
>>> Flag += 2
>>>
>>
>> Not that I consider quibbling over small English wording differences a 
>> major
>> thing, but I fail to see how:
>>
>> "Specifies whether the output of an algorithm is desired in sorted 
>> format."
>>
>> is significantly different from:
>>
>> "Specifies whether the output of certain algorithms are desired in sorted
>> format."
>>
>> In either case, I don't see anything problematically imprecise.
>
> Still means I need to jump back and forth in the documentation.
>

And you don't like the "///ditto" suggestion for handling that?





Re: Flag proposal

2011-06-12 Thread Nick Sabalausky
"Andrei Alexandrescu"  wrote in message 
news:it1cd7$1vv2$1...@digitalmars.com...
> On 06/11/2011 04:58 PM, Timon Gehr wrote:
>> Jonathan M Davis wrote:
>>> ...
>>> The complaints about this generally seem to be one of these:
>>>
>>> 1. Dislike of the yes/no enum idiom in the first place. Regardless of 
>>> how Flag
>>> does it, it's a problem, because it's promoting an idiom that the poster
>>> dislikes in the first place.
>>>
>>> 2. Flag!"enumName".yes and Flag!"enumName".no are ugly.
>>>
>>> 3. The use of a template such as Flag results in ugly error messages 
>>> when it's
>>> mistyped. EnumName.yes gets _much_ better errors when mistyped than
>>> Flag!"enumName".yes.
>>>
>>> 4. Flag is seen as a narrow attempt at named arguments which would be 
>>> far
>>> better served by actually implementing named arguments.
>>> [snip.]
>>
>> 5. The approach is too sophisticated and does not pull its own weight.
>> Imagine what you would have to explain to somebody new to the language 
>> who
>> wondered how Yes.sortOutput works... instant turn-off!
>>
>>
>> What about allowing anonymous enums in parameter lists? Unfortunately 
>> that would
>> be a language feature. :)
>>
>> T someAlgorithm(..., enum {unsorted, sorted} sortOutput);
>>
>> To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);

I like the basic idea, and it's a change that falls into the "removing 
restrictions" category.

But the issue "so" brought up with this about not being able to pass in a 
variable would need to be solved for the general case. It's trivial in the 
case of two options:

   bool useSorted = ...;
   someAlgorithm(..., useSorted? sorted : unsorted);

Although, really, that just shifts the boilerplate from the callee to the 
caller, so it's really a net loss.

You could maybe do:

   T someAlgorithm(..., enum Sorted {yes, no} sortOutput);

Which would be equivalent to:

   enum Sorted {yes, no}
   T someAlgorithm(..., Sorted sortOutput);

But I don't now if Andrei would like that (it makes the func signature kinda 
verbose, too).

>
> I proposed this to Walter some years ago, around the time I was 
> anticipating the nascent yes/no enum proliferation. The problem with this 
> is it defines a type in a function parameter specification, which is 
> unprecedented and therefore surprising.
>

Your Flag idiom essentially defines a type in a function parameter 
specification.





Re: Flag proposal

2011-06-12 Thread Andrei Alexandrescu

On 6/12/11 1:59 PM, Nick Sabalausky wrote:

"Andrei Alexandrescu"  wrote in message
news:it1cvf$21d4$1...@digitalmars.com...


It's the namespace pollution and the non-self-containedness of the
function that's most troublesome. Also see Steve's point about methods.
It's just untenable - to use the idiom with a class/struct method, you
need to go all the way _outside_ of it an plant a symbol there.



You can't put an enum in a class/struct?


What I find most interesting is that the lack of strong counterarguments
has not stood in the way of a strong emotional response.


Correction: Andrei's staunch dismissal of all counterarguments has not stood
in the way of a strong emotional response.


This mood has made it difficult for exchange of rational arguments. Funny
thing is, the change is tiny.

"Here, I'll add a handful of yes/no enums here and there in the standard
library, just to help some algorithms. More to come."

"Yeah, sure, whatevs."

"Here, there's a way to define them once so we don't need to define them
everywhere."



Correction: "Here, there's a way to solve a barely-existant problem by
botching up syntax (and error messages) for the user."


"Gaa!!!"



I'm not sure, but I think I see a sarcasm in there.

Andrei


Re: Flag proposal

2011-06-12 Thread Nick Sabalausky
"Andrei Alexandrescu"  wrote in message 
news:it1cvf$21d4$1...@digitalmars.com...
>
> It's the namespace pollution and the non-self-containedness of the 
> function that's most troublesome. Also see Steve's point about methods. 
> It's just untenable - to use the idiom with a class/struct method, you 
> need to go all the way _outside_ of it an plant a symbol there.
>

You can't put an enum in a class/struct?

> What I find most interesting is that the lack of strong counterarguments 
> has not stood in the way of a strong emotional response.

Correction: Andrei's staunch dismissal of all counterarguments has not stood 
in the way of a strong emotional response.

> This mood has made it difficult for exchange of rational arguments. Funny 
> thing is, the change is tiny.
>
> "Here, I'll add a handful of yes/no enums here and there in the standard 
> library, just to help some algorithms. More to come."
>
> "Yeah, sure, whatevs."
>
> "Here, there's a way to define them once so we don't need to define them 
> everywhere."
>

Correction: "Here, there's a way to solve a barely-existant problem by 
botching up syntax (and error messages) for the user."

> "Gaa!!!"
>





Re: Flag proposal

2011-06-12 Thread Andrei Alexandrescu

On 6/12/11 1:45 PM, Nick Sabalausky wrote:

"Andrei Alexandrescu"  wrote in message
news:it1c0f$1uup$1...@digitalmars.com...

On 06/11/2011 03:52 PM, Nick Sabalausky wrote:

"Andrei Alexandrescu"   wrote in message
news:it07ni$1pvj$1...@digitalmars.com...


Anyway, that was the first thing "grep yes std/*" found. Let's see the
next one:

/**
Specifies whether the output of certain algorithm is desired in sorted
format.
   */
enum SortOutput {
  no,  /// Don't sort output
  yes, /// Sort output
}

This already is very unpleasant because "certain" is as imprecise as it
gets. Plus one for Flag, I hope you agree.



Flag -= 1
s/output of certain algorithm/output of an algorithm/ += 1

That one-word doc change makes it all perfectly clear.


Not at all. The typo in the original text must have confused you: it
should be "certain algorithms" because SortOutput is used in four distinct
algorithms (one of which has two overloads). Grep std/algorithm.d.

Flag += 2



Not that I consider quibbling over small English wording differences a major
thing, but I fail to see how:

"Specifies whether the output of an algorithm is desired in sorted format."

is significantly different from:

"Specifies whether the output of certain algorithms are desired in sorted
format."

In either case, I don't see anything problematically imprecise.


Still means I need to jump back and forth in the documentation.

Andrei


Re: Flag proposal

2011-06-12 Thread Nick Sabalausky
"Andrei Alexandrescu"  wrote in message 
news:it1c0f$1uup$1...@digitalmars.com...
> On 06/11/2011 03:52 PM, Nick Sabalausky wrote:
>> "Andrei Alexandrescu"  wrote in message
>> news:it07ni$1pvj$1...@digitalmars.com...
>>>
>>> Anyway, that was the first thing "grep yes std/*" found. Let's see the
>>> next one:
>>>
>>> /**
>>> Specifies whether the output of certain algorithm is desired in sorted
>>> format.
>>>   */
>>> enum SortOutput {
>>>  no,  /// Don't sort output
>>>  yes, /// Sort output
>>> }
>>>
>>> This already is very unpleasant because "certain" is as imprecise as it
>>> gets. Plus one for Flag, I hope you agree.
>>>
>>
>> Flag -= 1
>> s/output of certain algorithm/output of an algorithm/ += 1
>>
>> That one-word doc change makes it all perfectly clear.
>
> Not at all. The typo in the original text must have confused you: it 
> should be "certain algorithms" because SortOutput is used in four distinct 
> algorithms (one of which has two overloads). Grep std/algorithm.d.
>
> Flag += 2
>

Not that I consider quibbling over small English wording differences a major 
thing, but I fail to see how:

"Specifies whether the output of an algorithm is desired in sorted format."

is significantly different from:

"Specifies whether the output of certain algorithms are desired in sorted 
format."

In either case, I don't see anything problematically imprecise.




Re: Flag proposal

2011-06-12 Thread Nick Sabalausky
"Jonathan M Davis"  wrote in message 
news:mailman.841.1307850316.14074.digitalmar...@puremagic.com...
> but the
> difference between EnumName.yes and Yes.EnumName for the user is pretty 
> much
> nonexistant except for the fact that Yes.EnumName will have worse error
> messages.

It also creates an awkward inconsistency. Most enums are X.Y, but then 
callint certain functions it's Y.X




Re: Flag proposal [OT]

2011-06-12 Thread Andrej Mitrovic
TBH I've only ever heard it used in Ali G Indahouse, so what do I know.. :p


Re: Flag proposal

2011-06-12 Thread Andrei Alexandrescu

On 6/11/11 8:49 PM, Steven Schveighoffer wrote:

On Sat, 11 Jun 2011 17:32:56 -0400, David Nadlinger 
wrote:


On 6/11/11 11:20 PM, Jonathan M Davis wrote:

1. Programmers following this idiom (including the Phobos devs) end up
creating enums with yes and no values and are effectively identical
to other
enums except for their names. So, we end up with a fair bit of
boilerplate
code just to pass a strict boolean value.


s/fair/tiny/, imho:

---
/// ditto.
enum SomeFlag { enable, disable }
---


A big problem with this (and enums in general), what if your flag
function is defined inside a struct or class?

struct MyStruct
{
/// This function ROCKS!
void someKickAssFunction(MoreBitchin moreBitchin) {}
/// ditto
enum MoreBitchin { yes, no }
}

// the call, not so much.
s.someKickAssFunction(MyStruct.MoreBitchin.yes);

In other words, in order for your doc trick to work, member functions
have to require an additional namespace to the enum.

IMO, however, we need a better way to access the enum values without
specifying the entire namespace. The difficult part is to do it in a way
which doesn't conflict with normal symbols.

Of course, such an improvement would pull the rug from this Flag
proposal...

-Steve


Thanks, Steve, this is an excellent point - as are all you made in this 
discussion (pro and con)!


Andrei


Re: Flag proposal

2011-06-12 Thread Andrei Alexandrescu

On 6/12/11 7:26 AM, so wrote:

My take on this is that we shouldn't try to reinvent the boolean in the
standard library.


I think this characterization is wrong. Let me replace the meaningless
Abc with an actual example, e.g. OpenRight in std.algorithm.

OpenRight is not a Boolean. Its *representation* is Boolean. It is
categorical data with two categories. You can represent it with an
unstructured Boolean the same way you can represent an automaton state
with an unstructured integer or temperature with an unstructured
double, but then you'd have the disadvantages that dimensional
analysis libraries are solving.


Quite contrary i think it is pretty much spot on, if it is not but just
its representation is boolean so is every other usage of boolean.

The only reason we use an enum instead of simple bool is self
documentation "fun(OpenRight.yes)". You simply can't deny the named
arguments solve not only this particular issue but the entire area
nicely "fun(openRight:true, width:4, height:3, depth:5)".


Never did.

Andrei


Re: Flag proposal [OT]

2011-06-12 Thread Steven Schveighoffer
On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton  
 wrote:



On 12/06/2011 02:40, Steven Schveighoffer wrote:

On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic
 wrote:


On 6/11/11, Alix Pexton  wrote:

On 11/06/2011 06:18, Andrej Mitrovic wrote:
We should rename Yes and No to Yay and Nay to make them alignable,  
and

even more importantly to make us appear as old Englishmen!


"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not
actually a old English word :) A more correct alternative would be
"Aye" (pronounced the same as "eye"), which (along with "Nay") is  
still

used for some voting actions (such as councillors deciding where to go
for lunch). I myself say it al least 20 times a day :)

A...



Oh damn, yay is what teenage girls would say, not old Englishmen. My
bad, it really is "Aye". :p


You were phonetically right :) It's yea or nay.

http://dictionary.cambridge.org/dictionary/british/yea-or-nay

My son's most recent birthday (3 years old) was a farm-themed birthday,
and we asked people to RSVP yay or neigh :P

So I guess there's all kinds of kooky fun you can have with flags...

-Steve


Nope, its definitely Aye when used for voting, (at least it is round  
here) as in "all those in favour, say aye", "ayes to the right" and "the  
ayes have it". Maybe southerners say this "yea" word of which you speak,  
we don't hold with their strange customs in these parts ^^


I don't deny that aye is used frequently for voting.  All I was saying is,  
the correct expression is yea or nay, not yay or nay.  Andrej thought it  
was actually aye or nay, which I've never heard as an expression.


I'm not sure it's used anymore, but it's definitely an expression that was  
used for voting (see my dictionary reference).


-Steve


Re: Flag proposal

2011-06-12 Thread bearophile
so:

> Quite contrary i think it is pretty much spot on, if it is not but just  
> its representation is boolean so is every other usage of boolean.

This is an unusual teacher that use functional languages, the blog post is 
about booleans and related matters:
http://existentialtype.wordpress.com/2011/03/15/boolean-blindness/

(Often I don't agree with this author, but I try to read some of his posts.)

Bye,
bearophile


Re: Flag proposal

2011-06-12 Thread so
On Sun, 12 Jun 2011 15:33:00 +0300, Daniel Murphy  
 wrote:



"Timon Gehr"  wrote in message
news:it0oee$ehu$1...@digitalmars.com...


What about allowing anonymous enums in parameter lists? Unfortunately  
that

would
be a language feature. :)

T someAlgorithm(..., enum {unsorted, sorted} sortOutput);

To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);



Wow - I actually really like this!  It would provide an even _better_
solution than named arguments for this type of thing!

The best part is that it could degrade to the enum's base type when  
taking a

function pointer, mangling the function's name and even inside the
function's body!

void myfunction(enum : int { option1, option2, option3 } options)
{
static assert(is(typeof(options) == int));
}
static assert(is(typeof(&myfunction) == void function(int));

myfunction(option2);


This also means you can use it only once. Not knowing the type, you can't  
pass as a variable either.

The loss is too big compared to the gain.

fun_step_one(enum whatever)
fun_step_two(enum?)

enum type? val
fun(val)


Re: Flag proposal

2011-06-12 Thread Daniel Murphy
"Timon Gehr"  wrote in message 
news:it0oee$ehu$1...@digitalmars.com...
>
> What about allowing anonymous enums in parameter lists? Unfortunately that 
> would
> be a language feature. :)
>
> T someAlgorithm(..., enum {unsorted, sorted} sortOutput);
>
> To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);
>

Wow - I actually really like this!  It would provide an even _better_ 
solution than named arguments for this type of thing!

The best part is that it could degrade to the enum's base type when taking a 
function pointer, mangling the function's name and even inside the 
function's body!

void myfunction(enum : int { option1, option2, option3 } options)
{
static assert(is(typeof(options) == int));
}
static assert(is(typeof(&myfunction) == void function(int));

myfunction(option2); 




Re: Flag proposal

2011-06-12 Thread so

My take on this is that we shouldn't try to reinvent the boolean in the
standard library.


I think this characterization is wrong. Let me replace the meaningless  
Abc with an actual example, e.g. OpenRight in std.algorithm.


OpenRight is not a Boolean. Its *representation* is Boolean. It is  
categorical data with two categories. You can represent it with an  
unstructured Boolean the same way you can represent an automaton state  
with an unstructured integer or temperature with an unstructured double,  
but then you'd have the disadvantages that dimensional analysis  
libraries are solving.


Quite contrary i think it is pretty much spot on, if it is not but just  
its representation is boolean so is every other usage of boolean.


The only reason we use an enum instead of simple bool is self  
documentation "fun(OpenRight.yes)". You simply can't deny the named  
arguments solve not only this particular issue but the entire area nicely  
"fun(openRight:true, width:4, height:3, depth:5)".


Re: Flag proposal

2011-06-12 Thread so
It's the namespace pollution and the non-self-containedness of the  
function that's most troublesome. Also see Steve's point about methods.  
It's just untenable - to use the idiom with a class/struct method, you  
need to go all the way _outside_ of it an plant a symbol there.


What I find most interesting is that the lack of strong counterarguments  
has not stood in the way of a strong emotional response. This mood has  
made it difficult for exchange of rational arguments. Funny thing is,  
the change is tiny.


"Here, I'll add a handful of yes/no enums here and there in the standard  
library, just to help some algorithms. More to come."


"Yeah, sure, whatevs."

"Here, there's a way to define them once so we don't need to define them  
everywhere."


"Gaa!!!"


Andrei


(Trying the 3rd time, something wrong with newsreader)

As you might know i prefer library solutions to language changes any day  
even the change is additive, yet this one i don't like.
Library solutions, especially those affect user must be IMO both elegant  
and generic, this one is not. I think we are agree on this.


There might be 7 in only std.algorithm but it is after all belongs to the  
std library, with the importance of phobos we can't change anything that  
is not accepted by majority. These are i think pretty strong arguments,  
though i believe it is you that needs to come up with strong arguments and  
i can't see any from you either :)


Introducing an idiom to phobos means it is the D way, there should be many  
other frameworks that would use such a solution much more frequently. They  
will either dismiss this solution (most likely) or populate it. The former  
means the failure of the change, the latter is ugly code (again, when it  
is used more frequently).


Named arguments both clean and generic.
On one drawback (?) that variable names being part of library definition,  
i don't see how it is a drawback.


Re: Flag proposal [OT]

2011-06-12 Thread Alix Pexton

On 12/06/2011 02:40, Steven Schveighoffer wrote:

On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic
 wrote:


On 6/11/11, Alix Pexton  wrote:

On 11/06/2011 06:18, Andrej Mitrovic wrote:

We should rename Yes and No to Yay and Nay to make them alignable, and
even more importantly to make us appear as old Englishmen!


"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not
actually a old English word :) A more correct alternative would be
"Aye" (pronounced the same as "eye"), which (along with "Nay") is still
used for some voting actions (such as councillors deciding where to go
for lunch). I myself say it al least 20 times a day :)

A...



Oh damn, yay is what teenage girls would say, not old Englishmen. My
bad, it really is "Aye". :p


You were phonetically right :) It's yea or nay.

http://dictionary.cambridge.org/dictionary/british/yea-or-nay

My son's most recent birthday (3 years old) was a farm-themed birthday,
and we asked people to RSVP yay or neigh :P

So I guess there's all kinds of kooky fun you can have with flags...

-Steve


Nope, its definitely Aye when used for voting, (at least it is round 
here) as in "all those in favour, say aye", "ayes to the right" and "the 
ayes have it". Maybe southerners say this "yea" word of which you speak, 
we don't hold with their strange customs in these parts ^^


A...


Re: Flag proposal

2011-06-12 Thread Dmitry Olshansky

On 12.06.2011 10:31, KennyTM~ wrote:

On Jun 12, 11 11:18, Andrei Alexandrescu wrote:

On 06/11/2011 04:20 PM, Jonathan M Davis wrote:

2. He proposed a template wrapper which would allow you to type
yes!"enumName"
and no!"enumName" instead of the full Flag!"enumName".yes and
Flag!"enumName".no. Some people feel that this resolves complaint #2.
Others
think that it's still quite ugly.


Those were since replaced with No.enumName and Yes.enumName by Dmitry's
idea:

https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330 





Andrei


Yes.X and No.X looks grammatically wrong. In D you usually have 
'Aggregate.member', not 'Member.aggregate'.

Well, you can do only as much staying within the language.
Personally, I think the biggest stumbling block is error messages, maybe 
we can do something about them.
Like make Flag struct with alias this and provide this(Flag!s) 
constructor, opAssign etc. that static assert something sensible on 
mismatch.


--
Dmitry Olshansky



Re: Flag proposal

2011-06-11 Thread KennyTM~

On Jun 12, 11 11:18, Andrei Alexandrescu wrote:

On 06/11/2011 04:20 PM, Jonathan M Davis wrote:

2. He proposed a template wrapper which would allow you to type
yes!"enumName"
and no!"enumName" instead of the full Flag!"enumName".yes and
Flag!"enumName".no. Some people feel that this resolves complaint #2.
Others
think that it's still quite ugly.


Those were since replaced with No.enumName and Yes.enumName by Dmitry's
idea:

https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330



Andrei


Yes.X and No.X looks grammatically wrong. In D you usually have 
'Aggregate.member', not 'Member.aggregate'.


Re: Flag proposal

2011-06-11 Thread Andrej Mitrovic
On 6/12/11, Andrei Alexandrescu  wrote:
> Funny thing is,
> the change is tiny.

You seem to be forgetting that there are library writers and then
there are library *users*. :)

Seeing Flag!"foo".yes in the calling code scared people. So naturally
people wanted to nuke it from orbit. If the proposal was yes.foo from
the beginning things would much quieter around here, methinks.


Re: Flag proposal

2011-06-11 Thread Andrei Alexandrescu

On 06/11/2011 10:45 PM, Jonathan M Davis wrote:

Yes, though there is a distinct difference between having to create a functor
elswhere to just to call an STL function and creating an extra enum next to
your function definition for one of its parameters. The parameter issue is far
smaller IMHO.


Absolutely. The proposed solution is also much smaller than e.g. lambda 
libraries and ultimately the language feature.


Andrei


Re: Flag proposal

2011-06-11 Thread Jonathan M Davis
On 2011-06-11 20:50, Jonathan M Davis wrote:
> On 2011-06-11 20:44, Andrei Alexandrescu wrote:
> > On 06/11/2011 04:42 PM, Jonathan M Davis wrote:
> > > On 2011-06-11 14:32, David Nadlinger wrote:
> > >> On 6/11/11 11:20 PM, Jonathan M Davis wrote:
> > >>> 1. Programmers following this idiom (including the Phobos devs) end
> > >>> up creating enums with yes and no values and are effectively
> > >>> identical to other enums except for their names. So, we end up with
> > >>> a fair bit of boilerplate code just to pass a strict boolean value.
> > >> 
> > >> s/fair/tiny/, imho:
> > >> 
> > >> ---
> > >> /// ditto.
> > >> enum SomeFlag { enable, disable }
> > >> ---
> > > 
> > > It's a fair bit only insomuch as the same code is duplicated in several
> > > places. The code itself in each instance is small. But if you do that
> > > enough times, it adds up. Whether it's enough to matter is debatable,
> > > but there is definitely boilerplate code there which could be reduced.
> > > 
> > > - Jonathan M Davis
> > 
> > It's the namespace pollution and the non-self-containedness of the
> > function that's most troublesome. Also see Steve's point about methods.
> > It's just untenable - to use the idiom with a class/struct method, you
> > need to go all the way _outside_ of it an plant a symbol there.
> > 
> > What I find most interesting is that the lack of strong counterarguments
> > has not stood in the way of a strong emotional response. This mood has
> > made it difficult for exchange of rational arguments. Funny thing is,
> > the change is tiny.
> > 
> > "Here, I'll add a handful of yes/no enums here and there in the standard
> > library, just to help some algorithms. More to come."
> > 
> > "Yeah, sure, whatevs."
> > 
> > "Here, there's a way to define them once so we don't need to define them
> > everywhere."
> > 
> > "Gaa!!!"
> 
> Honestly, at this point, I think that your proposal is pretty good, but I'm
> not sure that it's worth the degradation in error messages that the added
> templatization causes. But for a lot of people, I think that it's simply a
> combination of them not liking the yes/no enum idiom in the first place
> and/or feeling like what they really want is named parameters and that
> this really should be solved by named parameters. So, they don't like it.
> Personally, I'm a bit ambivalent towards yes/no enums, but I'm fine with
> having them. At this point, I'm just concerned about the worse error
> messages that the use of Flag will create and whether that pain is worth
> the added benefit that Flag brings.

Yikes! How did that get posted three times?! I wonder if my mail client is on 
the fritz...

- Jonathan M Davis


Re: Flag proposal

2011-06-11 Thread Jonathan M Davis
On 2011-06-11 20:44, Andrei Alexandrescu wrote:
> On 06/11/2011 04:42 PM, Jonathan M Davis wrote:
> > On 2011-06-11 14:32, David Nadlinger wrote:
> >> On 6/11/11 11:20 PM, Jonathan M Davis wrote:
> >>> 1. Programmers following this idiom (including the Phobos devs) end up
> >>> creating enums with yes and no values and are effectively identical to
> >>> other enums except for their names. So, we end up with a fair bit of
> >>> boilerplate code just to pass a strict boolean value.
> >> 
> >> s/fair/tiny/, imho:
> >> 
> >> ---
> >> /// ditto.
> >> enum SomeFlag { enable, disable }
> >> ---
> > 
> > It's a fair bit only insomuch as the same code is duplicated in several
> > places. The code itself in each instance is small. But if you do that
> > enough times, it adds up. Whether it's enough to matter is debatable,
> > but there is definitely boilerplate code there which could be reduced.
> > 
> > - Jonathan M Davis
> 
> It's the namespace pollution and the non-self-containedness of the
> function that's most troublesome. Also see Steve's point about methods.
> It's just untenable - to use the idiom with a class/struct method, you
> need to go all the way _outside_ of it an plant a symbol there.
> 
> What I find most interesting is that the lack of strong counterarguments
> has not stood in the way of a strong emotional response. This mood has
> made it difficult for exchange of rational arguments. Funny thing is,
> the change is tiny.
> 
> "Here, I'll add a handful of yes/no enums here and there in the standard
> library, just to help some algorithms. More to come."
> 
> "Yeah, sure, whatevs."
> 
> "Here, there's a way to define them once so we don't need to define them
> everywhere."
> 
> "Gaa!!!"

Honestly, at this point, I think that your proposal is pretty good, but I'm 
not sure that it's worth the degradation in error messages that the added 
templatization causes. But for a lot of people, I think that it's simply a 
combination of them not liking the yes/no enum idiom in the first place and/or 
feeling like what they really want is named parameters and that this really 
should be solved by named parameters. So, they don't like it. Personally, I'm 
a bit ambivalent towards yes/no enums, but I'm fine with having them. At this 
point, I'm just concerned about the worse error messages that the use of Flag 
will create and whether that pain is worth the added benefit that Flag brings.

- Jonathan M Davis


Re: Flag proposal

2011-06-11 Thread Jonathan M Davis
On 2011-06-11 20:27, Andrei Alexandrescu wrote:
> On 06/11/2011 03:52 PM, Nick Sabalausky wrote:
> > "Andrei Alexandrescu"  wrote in message
> > news:it07ni$1pvj$1...@digitalmars.com...
> > 
> >> Anyway, that was the first thing "grep yes std/*" found. Let's see the
> >> next one:
> >> 
> >> /**
> >> Specifies whether the output of certain algorithm is desired in sorted
> >> format.
> >> 
> >>   */
> >> 
> >> enum SortOutput {
> >> 
> >>  no,  /// Don't sort output
> >>  yes, /// Sort output
> >> 
> >> }
> >> 
> >> This already is very unpleasant because "certain" is as imprecise as it
> >> gets. Plus one for Flag, I hope you agree.
> > 
> > Flag -= 1
> > s/output of certain algorithm/output of an algorithm/ += 1
> > 
> > That one-word doc change makes it all perfectly clear.
> 
> Not at all. The typo in the original text must have confused you: it
> should be "certain algorithms" because SortOutput is used in four
> distinct algorithms (one of which has two overloads). Grep std/algorithm.d.
> 
> Flag += 2
> 
> > Also, since you're in favor of Flag, I think you'd agree with me that the
> > doc comments on the "no" and "yes" values are unnecessary and can be
> > ditched. Which makes the whole idiom this:
> > 
> > enum SortOutput { no, yes }
> 
> This exact kind of argument has been made in 1995 in favor of STL
> algorithms that require defining a struct outside the current context.
> The cost of adding one extra symbol turned out to be a fair amount more
> unpleasant than it was initially though.
> 
> Assessing that the boilerplate in this case is one line would be missing
> that important aspect.

Yes, though there is a distinct difference between having to create a functor 
elswhere to just to call an STL function and creating an extra enum next to 
your function definition for one of its parameters. The parameter issue is far 
smaller IMHO. It only comes up when defining functions, and particularly if we 
created a mixin for creating such an enum, the overhead would be fairly 
minimal - certainly far less than creating a functor for every call to an STL 
algorithm function (which pratically destroys the usefulness of the STL's 
algorithms for most people). So, I don't think that the cost involved is 
altogether comparable. However, you do bring up a very valid point. Flag 
definitely lowers the bar for the usage of such enums.

Ultimately, my main concern with using Flag like this is the error messages. 
Given the templates involved, I'd expect them to be pretty bad. D's template 
error messages are certainly better than C++'s (primarily thanks to template 
constraints), but they're still pretty bad - especially for newbies - and this 
particular use case effectively is simplifying the library developer's life 
slightly at the cost of nastier error messages for everyone who mistypes one 
of these enums. So, we save pain in one area and move it over to another which 
arguably has a higher impact. And I'm just not sure whether that's worth it or 
not. The fact that you've gotten to Yes.EnumName and eliminated all of the 
obvious template stuff from the user's perspective makes the code much 
cleaner, and it's fine as long as they don't have any typos, but the 
difference between EnumName.yes and Yes.EnumName for the user is pretty much 
nonexistant except for the fact that Yes.EnumName will have worse error 
messages. So, from the user's perspective, the situation is worse.

I don't know. I think that this proposal has reached the point where it might 
be reasonable to include it, but I just don't know if the gain in development 
is worth the pain for everyone who uses the functions which have Flag enums. 
If the error messages weren't worse, then it wouldn't be a problem, but as 
soon as you include templates, the error messages are pretty much always 
significantly worse. If there were a significant gain from this proposal, then 
I'd say that it would be worth it, but the gain seems pretty minor to me. So, 
I just don't know.

- Jonathan M Davis


Re: Flag proposal

2011-06-11 Thread Andrei Alexandrescu

On 06/11/2011 04:42 PM, Jonathan M Davis wrote:

On 2011-06-11 14:32, David Nadlinger wrote:

On 6/11/11 11:20 PM, Jonathan M Davis wrote:

1. Programmers following this idiom (including the Phobos devs) end up
creating enums with yes and no values and are effectively identical to
other enums except for their names. So, we end up with a fair bit of
boilerplate code just to pass a strict boolean value.


s/fair/tiny/, imho:

---
/// ditto.
enum SomeFlag { enable, disable }
---


It's a fair bit only insomuch as the same code is duplicated in several
places. The code itself in each instance is small. But if you do that enough
times, it adds up. Whether it's enough to matter is debatable, but there is
definitely boilerplate code there which could be reduced.

- Jonathan M Davis


It's the namespace pollution and the non-self-containedness of the 
function that's most troublesome. Also see Steve's point about methods. 
It's just untenable - to use the idiom with a class/struct method, you 
need to go all the way _outside_ of it an plant a symbol there.


What I find most interesting is that the lack of strong counterarguments 
has not stood in the way of a strong emotional response. This mood has 
made it difficult for exchange of rational arguments. Funny thing is, 
the change is tiny.


"Here, I'll add a handful of yes/no enums here and there in the standard 
library, just to help some algorithms. More to come."


"Yeah, sure, whatevs."

"Here, there's a way to define them once so we don't need to define them 
everywhere."


"Gaa!!!"


Andrei


Re: Flag proposal

2011-06-11 Thread Andrei Alexandrescu

On 06/11/2011 10:05 PM, Walter Bright wrote:

On 6/11/2011 12:58 PM, Andrei Alexandrescu wrote:

On 6/11/11 1:59 PM, Michel Fortin wrote:

On 2011-06-11 13:08:48 -0400, Andrei Alexandrescu
 said:


With named parameters, we'd have something along the lines of:

topNIndex(a, sortOutput : true);

which is nice, but not present in the language (and I can tell after
talking to Walter it won't be anytime soon).


The funny thing is that named arguments are not that difficult to
implement as long as you don't allow reordering. Much easier than
const(Object)ref actually.





Took
me less time than what I took arguing about Flag!"".


Love the attitude!! Let's see what Don and Walter think.


I think it's clever and insightful how Michel's solution is implemented.
It does not allow, however, for named arguments to be not in the same
positions as unnamed ones.

In other words, unlike struct field initializations, named arguments
cannot appear in any order. I think people will find it an odd difference.


If we all get convinced that named parameters are worth it, I'm 
convinced Michel would be sufficiently motivated to address this 
limitation. I personally am lukewarm regarding the feature but I think 
many people would find it quite convenient.


Andrei


Re: Flag proposal

2011-06-11 Thread Andrei Alexandrescu

On 06/11/2011 04:58 PM, Timon Gehr wrote:

Jonathan M Davis wrote:

...
The complaints about this generally seem to be one of these:

1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag
does it, it's a problem, because it's promoting an idiom that the poster
dislikes in the first place.

2. Flag!"enumName".yes and Flag!"enumName".no are ugly.

3. The use of a template such as Flag results in ugly error messages when it's
mistyped. EnumName.yes gets _much_ better errors when mistyped than
Flag!"enumName".yes.

4. Flag is seen as a narrow attempt at named arguments which would be far
better served by actually implementing named arguments.
[snip.]


5. The approach is too sophisticated and does not pull its own weight.
Imagine what you would have to explain to somebody new to the language who
wondered how Yes.sortOutput works... instant turn-off!


What about allowing anonymous enums in parameter lists? Unfortunately that would
be a language feature. :)

T someAlgorithm(..., enum {unsorted, sorted} sortOutput);

To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);


I proposed this to Walter some years ago, around the time I was 
anticipating the nascent yes/no enum proliferation. The problem with 
this is it defines a type in a function parameter specification, which 
is unprecedented and therefore surprising.


There's a closely related slide in our D 2007 conference talk.


Andrei


Re: Flag proposal

2011-06-11 Thread Andrei Alexandrescu

On 06/11/2011 03:52 PM, Nick Sabalausky wrote:

"Andrei Alexandrescu"  wrote in message
news:it07ni$1pvj$1...@digitalmars.com...


Anyway, that was the first thing "grep yes std/*" found. Let's see the
next one:

/**
Specifies whether the output of certain algorithm is desired in sorted
format.
  */
enum SortOutput {
 no,  /// Don't sort output
 yes, /// Sort output
}

This already is very unpleasant because "certain" is as imprecise as it
gets. Plus one for Flag, I hope you agree.



Flag -= 1
s/output of certain algorithm/output of an algorithm/ += 1

That one-word doc change makes it all perfectly clear.


Not at all. The typo in the original text must have confused you: it 
should be "certain algorithms" because SortOutput is used in four 
distinct algorithms (one of which has two overloads). Grep std/algorithm.d.


Flag += 2


Also, since you're in favor of Flag, I think you'd agree with me that the
doc comments on the "no" and "yes" values are unnecessary and can be
ditched. Which makes the whole idiom this:

enum SortOutput { no, yes }


This exact kind of argument has been made in 1995 in favor of STL 
algorithms that require defining a struct outside the current context. 
The cost of adding one extra symbol turned out to be a fair amount more 
unpleasant than it was initially though.


Assessing that the boilerplate in this case is one line would be missing 
that important aspect.



Andrei


Re: Flag proposal

2011-06-11 Thread Andrei Alexandrescu

On 06/11/2011 04:20 PM, Jonathan M Davis wrote:

2. He proposed a template wrapper which would allow you to type yes!"enumName"
and no!"enumName" instead of the full Flag!"enumName".yes and
Flag!"enumName".no. Some people feel that this resolves complaint #2. Others
think that it's still quite ugly.


Those were since replaced with No.enumName and Yes.enumName by Dmitry's 
idea:


https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330


Andrei


Re: Flag proposal

2011-06-11 Thread Walter Bright

On 6/11/2011 12:58 PM, Andrei Alexandrescu wrote:

On 6/11/11 1:59 PM, Michel Fortin wrote:

On 2011-06-11 13:08:48 -0400, Andrei Alexandrescu
 said:


With named parameters, we'd have something along the lines of:

topNIndex(a, sortOutput : true);

which is nice, but not present in the language (and I can tell after
talking to Walter it won't be anytime soon).


The funny thing is that named arguments are not that difficult to
implement as long as you don't allow reordering. Much easier than
const(Object)ref actually.




Took
me less time than what I took arguing about Flag!"".


Love the attitude!! Let's see what Don and Walter think.


I think it's clever and insightful how Michel's solution is implemented. It does 
not allow, however, for named arguments to be not in the same positions as 
unnamed ones.


In other words, unlike struct field initializations, named arguments cannot 
appear in any order. I think people will find it an odd difference.




Re: Flag proposal

2011-06-11 Thread Steven Schveighoffer
On Sat, 11 Jun 2011 17:32:56 -0400, David Nadlinger   
wrote:



On 6/11/11 11:20 PM, Jonathan M Davis wrote:

1. Programmers following this idiom (including the Phobos devs) end up
creating enums with yes and no values and are effectively identical to  
other
enums except for their names. So, we end up with a fair bit of  
boilerplate

code just to pass a strict boolean value.


s/fair/tiny/, imho:

---
/// ditto.
enum SomeFlag { enable, disable }
---


A big problem with this (and enums in general), what if your flag function  
is defined inside a struct or class?


struct MyStruct
{
   /// This function ROCKS!
   void someKickAssFunction(MoreBitchin moreBitchin) {}
   /// ditto
   enum MoreBitchin { yes, no }
}

// the call, not so much.
s.someKickAssFunction(MyStruct.MoreBitchin.yes);

In other words, in order for your doc trick to work, member functions have  
to require an additional namespace to the enum.


IMO, however, we need a better way to access the enum values without  
specifying the entire namespace.  The difficult part is to do it in a way  
which doesn't conflict with normal symbols.


Of course, such an improvement would pull the rug from this Flag  
proposal...


-Steve


Re: Flag proposal [OT]

2011-06-11 Thread Steven Schveighoffer
On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic  
 wrote:



On 6/11/11, Alix Pexton  wrote:

On 11/06/2011 06:18, Andrej Mitrovic wrote:

We should rename Yes and No to Yay and Nay to make them alignable, and
even more importantly to make us appear as old Englishmen!


"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not
actually a old English word :)  A more correct alternative would be
"Aye" (pronounced the same as "eye"), which (along with "Nay") is still
used for some voting actions (such as councillors deciding where to go
for lunch). I myself say it al least 20 times a day :)

A...



Oh damn, yay is what teenage girls would say, not old Englishmen. My
bad, it really is "Aye". :p


You were phonetically right :)  It's yea or nay.

http://dictionary.cambridge.org/dictionary/british/yea-or-nay

My son's most recent birthday (3 years old) was a farm-themed birthday,  
and we asked people to RSVP yay or neigh :P


So I guess there's all kinds of kooky fun you can have with flags...

-Steve


Re: Flag proposal

2011-06-11 Thread bearophile
Michel Fortin:

> 
> Took me less time than what I took arguing about Flag!"".

I don't know if Walter will appreciate this, or if this will need improvements, 
but you have done something better than my posts where I just talk :-)

Bye,
bearophile


Re: Flag proposal

2011-06-11 Thread Timon Gehr
Jonathan M Davis wrote:
> ...
> The complaints about this generally seem to be one of these:
>
> 1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag
> does it, it's a problem, because it's promoting an idiom that the poster
> dislikes in the first place.
>
> 2. Flag!"enumName".yes and Flag!"enumName".no are ugly.
>
> 3. The use of a template such as Flag results in ugly error messages when it's
> mistyped. EnumName.yes gets _much_ better errors when mistyped than
> Flag!"enumName".yes.
>
> 4. Flag is seen as a narrow attempt at named arguments which would be far
> better served by actually implementing named arguments.
> [snip.]

5. The approach is too sophisticated and does not pull its own weight.
Imagine what you would have to explain to somebody new to the language who
wondered how Yes.sortOutput works... instant turn-off!


What about allowing anonymous enums in parameter lists? Unfortunately that would
be a language feature. :)

T someAlgorithm(..., enum {unsorted, sorted} sortOutput);

To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);



Timon


Re: Flag proposal

2011-06-11 Thread Jonathan M Davis
On 2011-06-11 14:32, David Nadlinger wrote:
> On 6/11/11 11:20 PM, Jonathan M Davis wrote:
> > 1. Programmers following this idiom (including the Phobos devs) end up
> > creating enums with yes and no values and are effectively identical to
> > other enums except for their names. So, we end up with a fair bit of
> > boilerplate code just to pass a strict boolean value.
> 
> s/fair/tiny/, imho:
> 
> ---
> /// ditto.
> enum SomeFlag { enable, disable }
> ---

It's a fair bit only insomuch as the same code is duplicated in several 
places. The code itself in each instance is small. But if you do that enough 
times, it adds up. Whether it's enough to matter is debatable, but there is 
definitely boilerplate code there which could be reduced.

- Jonathan M Davis


Re: Flag proposal

2011-06-11 Thread David Nadlinger

On 6/11/11 11:20 PM, Jonathan M Davis wrote:

1. Programmers following this idiom (including the Phobos devs) end up
creating enums with yes and no values and are effectively identical to other
enums except for their names. So, we end up with a fair bit of boilerplate
code just to pass a strict boolean value.


s/fair/tiny/, imho:

---
/// ditto.
enum SomeFlag { enable, disable }
---

David


Re: Flag proposal

2011-06-11 Thread Jonathan M Davis
On 2011-06-10 09:15, Andrei Alexandrescu wrote:
> https://github.com/D-Programming-Language/phobos/pull/94
> 
> Discuss!

Okay. Let's see if I can summarize this. Andrei thinks that have a categorized 
boolean type which is explicit about what it's used for is valuable. So, for 
instance, std.algorithm.until takes OpenRight.yes and OpenRight.no rather than 
bool so that it's explicit to the caller what the boolean value indicates and 
so that you don't accidentally pass a bool which means something else entirely 
to until. This currently requires declaring a separate enum with yes and no 
values for every function that does this with the occasional function which 
can reuse such an enum from another function, because it needs a boolean value 
for exactly the same thing. Andrei therefore have 2 problems with the status 
quo:

1. Programmers following this idiom (including the Phobos devs) end up 
creating enums with yes and no values and are effectively identical to other 
enums except for their names. So, we end up with a fair bit of boilerplate 
code just to pass a strict boolean value.

2. The documentation for these yes/no enums generally really should be with 
the function that they're using but ends up on the enum itself or in both 
places. Ideally, it would just go with the function.


So, Andrei created the Flag template in an attempt to do 3 things:

1. Be able to create the yes/no enum just by declaring the type of the 
function parameter - you eliminate boilerplate code.

2. The documentation is then clearly with the function that the yes/no enum 
goes with (it has nowhere else to go).

3. It promotes the yes/no idiom in a manner than seeing Flag!"enumName" as the 
type makes it immediately clear what the type in question is trying to do, and 
no one feels the need to go looking for the documentation for the enum because 
the use of the Flag idiom makes it clear what the type is.


The complaints about this generally seem to be one of these:

1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag 
does it, it's a problem, because it's promoting an idiom that the poster 
dislikes in the first place.

2. Flag!"enumName".yes and Flag!"enumName".no are ugly.

3. The use of a template such as Flag results in ugly error messages when it's 
mistyped. EnumName.yes gets _much_ better errors when mistyped than 
Flag!"enumName".yes.

4. Flag is seen as a narrow attempt at named arguments which would be far 
better served by actually implementing named arguments.


Andrei's response to each of these in turn is:

1. He argues for the yes/no enum idiom, citing issues with naked bool values 
and lack of clarity in code - how it saves you from having to look at the 
documentation to figure out what a particular boolean value means. It's 
essentially the same arguments he's made for the idiom ever since it was 
introduced into Phobos.

2. He proposed a template wrapper which would allow you to type yes!"enumName" 
and no!"enumName" instead of the full Flag!"enumName".yes and 
Flag!"enumName".no. Some people feel that this resolves complaint #2. Others 
think that it's still quite ugly.

3. He essentially says that the compiler's error messages for templates need 
to be improved. It's an inherent problem with templates.

4. He's not trying to solve anything with named arguments. He's trying to 
solve a much narrower problem of naked bool values being relatively 
meaningless for many function arguments and error-prone when you pass a 
boolean value which meant something else entirely. yes/no enums solve that 
specific problem. Named arguments would be a change to the language at a time 
when we should be looking at doing as much with the language as possible 
rather than looking to add new features to it. Features which solve 
restrictions and intrinsic problems in the language need to be looked at, but 
those which could be solved by using the existing language and creating a 
library-based solution should be first explored as library solutions.


Would you say that this is a fair summary of this debate so far?

- Jonathan M Davis


Re: Flag proposal

2011-06-11 Thread Nick Sabalausky
"Andrei Alexandrescu"  wrote in message 
news:it07ni$1pvj$1...@digitalmars.com...
>
> Anyway, that was the first thing "grep yes std/*" found. Let's see the 
> next one:
>
> /**
> Specifies whether the output of certain algorithm is desired in sorted
> format.
>  */
> enum SortOutput {
> no,  /// Don't sort output
> yes, /// Sort output
> }
>
> This already is very unpleasant because "certain" is as imprecise as it 
> gets. Plus one for Flag, I hope you agree.
>

Flag -= 1
s/output of certain algorithm/output of an algorithm/ += 1

That one-word doc change makes it all perfectly clear.

Also, since you're in favor of Flag, I think you'd agree with me that the 
doc comments on the "no" and "yes" values are unnecessary and can be 
ditched. Which makes the whole idiom this:

enum SortOutput { no, yes }

I hadn't noticed this before, but now that I'm actually looking directly at 
that, I don't see how that can be considered "boilerplate", or at least 
enough boilerplate to be worth having a utility template, adding Flag!"..." 
to function signatures in the code and documentation, and the inconsistency 
in changing the user's syntax away from how people expect to use an enum. 
And not only that, but all for the sake of a scenario that you've already 
argued is only rarely encountered. It's a clever use of templates, sure, but 
it's a little too clever for it's own good.





Re: Flag proposal

2011-06-11 Thread Robert Clipsham

On 11/06/2011 20:59, Andrei Alexandrescu wrote:

On 6/11/11 2:12 PM, Robert Clipsham wrote:


* No ugly templates
* Self documenting
* No overhead (dmd can inline it to myFunc(true, false))
* Caller decides if they want it


// Generate document in nook format
generatePdf("doc.pdf", Flag.nook);


Andrei



I'd call this a documentation issue. It's obvious you're passing true to 
the function. Of course, if you want to mitigate this somewhat, 
something like this could work:


struct FuncFlag(alias func)
{
// See code from above, but use typeof(&func).stringof to get
// a list of parameter names and make sure the passed name is valid
// of course, you can't check position, but the only way to get
// around that is named parameters or some sort of compiler support
}

alias FuncFlag!generatePdf PdfFlag;

// This now fails to compile
generatePdf("doc.pdf", PdfFlag.nook);

--
Robert
http://octarineparrot.com/


Re: Flag proposal

2011-06-11 Thread Robert Clipsham

On 11/06/2011 21:31, Robert Clipsham wrote:

On 11/06/2011 20:59, Andrei Alexandrescu wrote:

On 6/11/11 2:12 PM, Robert Clipsham wrote:


* No ugly templates
* Self documenting
* No overhead (dmd can inline it to myFunc(true, false))
* Caller decides if they want it


// Generate document in nook format
generatePdf("doc.pdf", Flag.nook);


Andrei



I'd call this a documentation issue. It's obvious you're passing true to
the function. Of course, if you want to mitigate this somewhat,
something like this could work:

struct FuncFlag(alias func)
{
// See code from above, but use typeof(&func).stringof to get
// a list of parameter names and make sure the passed name is valid
// of course, you can't check position, but the only way to get
// around that is named parameters or some sort of compiler support
}

alias FuncFlag!generatePdf PdfFlag;

// This now fails to compile
generatePdf("doc.pdf", PdfFlag.nook);




You can actually check the order! Add in a counter to FuncFlag, and each 
time opDispatch is called increment it. You can use this to check the 
position. The obvious downside is optional parameters, where the counter 
will be incorrect unless you reset it.



--
Robert
http://octarineparrot.com/


Re: Flag proposal

2011-06-11 Thread Andrei Alexandrescu

On 6/11/11 1:59 PM, Michel Fortin wrote:

On 2011-06-11 13:08:48 -0400, Andrei Alexandrescu
 said:


With named parameters, we'd have something along the lines of:

topNIndex(a, sortOutput : true);

which is nice, but not present in the language (and I can tell after
talking to Walter it won't be anytime soon).


The funny thing is that named arguments are not that difficult to
implement as long as you don't allow reordering. Much easier than
const(Object)ref actually.




Took
me less time than what I took arguing about Flag!"".


Love the attitude!! Let's see what Don and Walter think.

Andrei



Re: Flag proposal

2011-06-11 Thread Andrei Alexandrescu

On 6/11/11 2:12 PM, Robert Clipsham wrote:

On 11/06/2011 12:54, Andrei Alexandrescu wrote:

Consider two statements:

1. "I dislike Flag. It looks ugly to me."


This statement holds true for me.


2. "I dislike Flag. Instead I want named arguments."


This one is perhaps true. I've never needed named arguments.


There is little retort to (1) - it simply counts as a vote against. For
(2) the course of action is to point out the liabilities of changing the
language.

Andrei


So I had an idea.


struct Flag
{
static bool opDispatch(string n)()
{
static if (n[0..2] == "no")
{
return false;
}
else
{
return true;
}
}
}

void myFunc(bool foo, bool bar)
{
}

void main()
{
myFunc(Flag.foo, Flag.noBar);
}


* No ugly templates
* Self documenting
* No overhead (dmd can inline it to myFunc(true, false))
* Caller decides if they want it


// Generate document in nook format
generatePdf("doc.pdf", Flag.nook);


Andrei



Re: Flag proposal

2011-06-11 Thread Robert Clipsham

On 11/06/2011 12:54, Andrei Alexandrescu wrote:

Consider two statements:

1. "I dislike Flag. It looks ugly to me."


This statement holds true for me.


2. "I dislike Flag. Instead I want named arguments."


This one is perhaps true. I've never needed named arguments.


There is little retort to (1) - it simply counts as a vote against. For
(2) the course of action is to point out the liabilities of changing the
language.

Andrei


So I had an idea.


struct Flag
{
static bool opDispatch(string n)()
{
static if (n[0..2] == "no")
{
return false;
}
else
{
return true;
}
}
}

void myFunc(bool foo, bool bar)
{
}

void main()
{
myFunc(Flag.foo, Flag.noBar);
}


 * No ugly templates
 * Self documenting
 * No overhead (dmd can inline it to myFunc(true, false))
 * Caller decides if they want it

--
Robert
http://octarineparrot.com/


Re: Flag proposal

2011-06-11 Thread Michel Fortin
On 2011-06-11 13:08:48 -0400, Andrei Alexandrescu 
 said:



With named parameters, we'd have something along the lines of:

topNIndex(a, sortOutput : true);

which is nice, but not present in the language (and I can tell after 
talking to Walter it won't be anytime soon).


The funny thing is that named arguments are not that difficult to 
implement as long as you don't allow reordering. Much easier than 
const(Object)ref actually.




Took 


me less time than what I took arguing about Flag!"".


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Flag proposal

2011-06-11 Thread Ben Grabham

On 11/06/11 15:28, Andrei Alexandrescu wrote:

On 6/11/11 9:08 AM, David Nadlinger wrote:

On 6/11/11 1:54 PM, Andrei Alexandrescu wrote:

Consider two statements:

1. "I dislike Flag. It looks ugly to me."

2. "I dislike Flag. Instead I want named arguments."

There is little retort to (1) - it simply counts as a vote against. For
(2) the course of action is to point out the liabilities of changing the
language.


*And*, at least for me, still count it as an (informal) vote against
Flag.


Of course it does, but the point is there are arguments that might
convince the person.


You wrote about »The point is it [named arguments] would also have
disadvantages«, but at the same time, you seem to ignore that using a
non-obvious construct all over the standard library adds to perceived
the »language complexity« (from the user's perspective) just as well,
even more so if opDispatch or other »hacks« are used to beautify the
implementation.


I agree that implementation complexity has a cost. That would be
justified if the idiom becomes commonly used outside the library.


Yes, I do think named parameters would be a step forward and we should
definitely look into adding them to D. But independently, I don't think
that reinventing bool in Phobos is a good idea.


You may want to refer to my answer to Michel.


Andrei


Hey,

Don't know whether I can vote but I looked through it and I prefer using 
booleans over this. This just doesn't look very nice to me and if you 
*really* wanted to use this in a program, you could just use an enum but 
I don't see why flags is good (even after reading through all your 
counter-arguments).


Nebster


Re: Flag proposal

2011-06-11 Thread jdrewsen

Den 11-06-2011 03:26, David Nadlinger skrev:

On 6/11/11 3:21 AM, bearophile wrote:

Andrei:


This module won't compile in today's D, but not for a matter of
principles; it's just a random limitation of the language. (It does work
if you import from within a class or struct.) You can insert most
declarations in a scope, so the ones you can't insert are just awkward
exceptions, unless there's a good reason to actively disable them. Any
code should work if you just wrap another scope around it.

Walter and I call the above a "turtle feature", in allusion to the
"turtles all the way down" meme. Walter wants to fix this, and similar
limitations that act "unturtly". Imports inside a scope won't be visible
outside that scope, and importing the same module from several different
functions will come at no cost in compilation time.


You are allowed to import modules inside functions in Python too
(there is a just a minor restriction), but I have never asked for this
feature in D because this feature has a cost too. Putting all imports
at the top of the module is more tidy, it allows the person that reads
the code to find all the used imports very quickly. If they are spread
in the module they become less easy to find, you need to use your
editor/IDE to search for them.

Bye,
bearophile


At least allowing imports in unittests would be nice though – I
frequently find myself writing »version (unittest) {}« blocks before the
actual unit tests just to import some modules not needed during regular
builds (yeah, I suppose I'm somewhat pedantic about that).


+1




Re: Flag proposal

2011-06-11 Thread Andrei Alexandrescu

On 6/11/11 11:56 AM, Michel Fortin wrote:

On 2011-06-11 12:01:33 -0400, Andrei Alexandrescu
 said:


On 6/11/11 10:40 AM, Michel Fortin wrote:

On 2011-06-11 09:56:28 -0400, Andrei Alexandrescu
 said:

For representing categorical data with small sets, programming
languages use enumerated types. This is because in a small set you can
actually give name each element. That way you have a separate type for
the categorical data so you can enjoy good type checking. The mistake
I believe you are making is the conflation of a categorical data with
two categories with an unstructured Boolean. By making that conflation
you lose the advantages of good typechecking in one fell swoop.


I think you're misinterpreting. I don't like yes/no enums because I
don't find the value names meaningful, but I'm perfectly fine with
two-element enums if they are properly named.


What is meaningless about OpenRight.yes?


Choosing between "yes" and "no" is not meaningful. I'd rather choose
between "open" and "closed".


I don't see how "OpenRight.yes" is meaningless and "Openness.right" is 
meaningful.



Of course you'd have to pick a more fitting
name for the enum,


Name one.


preferably one that could work for all bounds, not
just the right one to make the category more useful.


Again, the charter of that particular category is only "open to the right".

Anyway, that was the first thing "grep yes std/*" found. Let's see the 
next one:


/**
Specifies whether the output of certain algorithm is desired in sorted
format.
 */
enum SortOutput {
no,  /// Don't sort output
yes, /// Sort output
}

This already is very unpleasant because "certain" is as imprecise as it 
gets. Plus one for Flag, I hope you agree.


Alright, so we have

void topNIndex(
alias less = "a < b",
SwapStrategy ss = SwapStrategy.unstable,
Range, RangeIndex)(Range r, RangeIndex index,
SortOutput sorted = SortOutput.no);

With Flag in tow, you'd delete SortOutput and you'd replace the 
definition with:


void topNIndex(
alias less = "a < b",
SwapStrategy ss = SwapStrategy.unstable,
Range, RangeIndex)(Range r, RangeIndex index,
Flag!"sortOutput" sorted = No.sortOutput);

Call:

auto a = [ 1, 2, 3 ];
topNIndex(a, Yes.sortOutput);

I understand you find the above meaningless and would advocate using a 
bool, which means:


topNIndex(a, true);

which would have even me running to the manual, and I wrote the darn thing.

With named parameters, we'd have something along the lines of:

topNIndex(a, sortOutput : true);

which is nice, but not present in the language (and I can tell after 
talking to Walter it won't be anytime soon).


With your choice of meaningful/less, you'd have something like:

enum HowToOutput { unsorted, sorted }
topNIndex(a, HowToOutput.sorted);

which is pretty much the same thing as yes/no, just more convoluted and 
less systematic. I mean you can't impose to yourself to choose any names 
except "yes" and "no" on account of them being meaningless.



Andrei



  1   2   3   >