Re: "for" statement issue

2016-10-23 Thread Nick Treleaven via Digitalmars-d

On Saturday, 22 October 2016 at 17:11:26 UTC, ag0aep6g wrote:
How is it guaranteed that `a` doesn't have side effects? May be 
a function call, since empty parentheses can be omitted in 
calls.


I missed that case. (Insert grumble about non-UFCS parenthesis 
omission being allowed).



The lambda itself is a value, no?


int a() { import std.stdio; writeln("a"); return 1; }

void main()
{
int delegate(int) dg = (a, b => a + b);
}


OK. Though AIUI from 2.072 a() must return void for the comma 
expression to compile (then a+b wouldn't compile either).


Re: "for" statement issue

2016-10-22 Thread Timon Gehr via Digitalmars-d

On 22.10.2016 17:53, Nick Treleaven wrote:


[1,2,3].fold!{a, b => a + b}.writeln;


Probably (a, b => a + b) could be legal.


It is. (It means pass a and the lambda b => a + b.)


Re: "for" statement issue

2016-10-22 Thread ag0aep6g via Digitalmars-d

On 10/22/2016 05:53 PM, Nick Treleaven wrote:

Probably (a, b => a + b) could be legal. Reasoning:

1. a could be an existing symbol in scope, otherwise it's an undefined
identifier error.
2. If a was interpreted as an existing symbol which is followed by the
comma operator, the expression (a) wouldn't have side effects so should
be a compile error.


How is it guaranteed that `a` doesn't have side effects? May be a 
function call, since empty parentheses can be omitted in calls.



3. The bracketed comma expression would have to return the lambda b=>a+b
as a value expression, which cannot compile because there are no
arguments supplied for calling the lambda to obtain a value.


The lambda itself is a value, no?


int a() { import std.stdio; writeln("a"); return 1; }

void main()
{
int delegate(int) dg = (a, b => a + b);
}



Re: "for" statement issue

2016-10-22 Thread Marc Schütz via Digitalmars-d

On Friday, 21 October 2016 at 13:42:49 UTC, Adam D. Ruppe wrote:

On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:

It does create a lambda?
Hmm that should not happen.


Eh, that's exactly what the language rules say should happen, 
and it actually does make sense to me... you might even want to 
use an immediately-called lambda to group several statements 
together into one expression.




int j;
for({j=2; int d = 3; } j+d<7; {j++; d++;}) {
}

I'm more surprised by the fact that `d` is declared inside the 
first curly braces, but is evidently still in scope outside of 
it...


Re: "for" statement issue

2016-10-22 Thread Nick Treleaven via Digitalmars-d

On Friday, 21 October 2016 at 15:26:12 UTC, mogu wrote:

[1,2,3].fold!((a, b) => a + b).writeln;

=>

[1,2,3].fold!{a, b => a + b}.writeln;


Probably (a, b => a + b) could be legal. Reasoning:

1. a could be an existing symbol in scope, otherwise it's an 
undefined identifier error.
2. If a was interpreted as an existing symbol which is followed 
by the comma operator, the expression (a) wouldn't have side 
effects so should be a compile error.
3. The bracketed comma expression would have to return the lambda 
b=>a+b as a value expression, which cannot compile because there 
are no arguments supplied for calling the lambda to obtain a 
value.


So this syntax seems available as it isn't currently used for 
working code. A small change, maybe, but it's good to reduce 
bracket nesting to help with reading complex nested expressions.


Destroy.


Re: "for" statement issue

2016-10-21 Thread Vladimir Panteleev via Digitalmars-d
On Friday, 21 October 2016 at 16:46:08 UTC, Andrei Alexandrescu 
wrote:
Read the example again, the lambda is not evaluated as a bool. 
-- Andrei


My bad.

In that case, what Steven said.


Re: "for" statement issue

2016-10-21 Thread Andrei Alexandrescu via Digitalmars-d

On 10/21/2016 12:39 PM, Vladimir Panteleev wrote:

On Friday, 21 October 2016 at 12:34:58 UTC, Andrei Alexandrescu wrote:

What would be a good solution to forbid certain constructs in the
increment part of a for statement?


For this specific case, a clear solution would be to forbid evaluating
lambdas as a boolean expression, because they will always be true, and
thus almost always an error.


Read the example again, the lambda is not evaluated as a bool. -- Andrei




Re: "for" statement issue

2016-10-21 Thread Vladimir Panteleev via Digitalmars-d
On Friday, 21 October 2016 at 12:34:58 UTC, Andrei Alexandrescu 
wrote:
What would be a good solution to forbid certain constructs in 
the increment part of a for statement?


For this specific case, a clear solution would be to forbid 
evaluating lambdas as a boolean expression, because they will 
always be true, and thus almost always an error. Same as with 
assignments in if statements. If intended, it can be worked 
around with "!is null".




Re: "for" statement issue

2016-10-21 Thread mogu via Digitalmars-d

Allow new syntax makes codes simpler in some cases:

writeln({
int a = 5;
return a + 5;
}());

=>

writeln{
int a = 5;
return a + 5;
}();

[1,2,3].fold!((a, b) => a + b).writeln;

=>

[1,2,3].fold!{a, b => a + b}.writeln;


[Issue 16632] "for" statement issue

2016-10-21 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16632

Steven Schveighoffer <schvei...@yahoo.com> changed:

   What|Removed |Added

Summary|"for" statemenet issue  |"for" statement issue

--


Re: "for" statement issue

2016-10-21 Thread Steven Schveighoffer via Digitalmars-d

On 10/21/16 10:38 AM, mogu wrote:

On Friday, 21 October 2016 at 14:22:27 UTC, Steven Schveighoffer wrote:

On 10/21/16 10:12 AM, Temtaime wrote:

On Friday, 21 October 2016 at 13:42:49 UTC, Adam D. Ruppe wrote:

On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:

[...]


Eh, that's exactly what the language rules say should happen, and it
actually does make sense to me... you might even want to use an
immediately-called lambda to group several statements together into
one expression.

[...]


Please, no.
It's fully clear that { stmts } createa a lambda, just () is ommited.


No, it's not.

{ int x; x = 2; }

Is not a lambda. It's a scope.

So the meaning changes based on where it's used. I totally agree that
we should remove that feature.



{} in swift is a lambda too.


Swift doesn't have arbitrary scopes. So there is no ambiguity.


I think swift has better lambda syntax.
Maybe could help for a better syntax in d.


We likely are not going to change the lambda syntax. However, it's 
possible we could remove the ambiguous cases.



reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2 } )
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )


(s1, s2) => s1 > s2

Seems pretty good to me


reversedNames = names.sorted(by: { $0 > $1 } )


With the original string lambdas, this was possible as "a > b". I'm not 
sure this case is worth much effort to add.



reversedNames = names.sorted(by: >)


Not sure if we'll ever get this in D :)



someFunctionThatTakesAClosure(closure: {
// closure's body goes here
})
someFunctionThatTakesAClosure() {
// trailing closure's body goes here
}


Yes, I've seen and used this. I think this is actually a little confusing.

-Steve


Re: "for" statement issue

2016-10-21 Thread Steven Schveighoffer via Digitalmars-d

On 10/21/16 10:28 AM, Kagamin wrote:

On Friday, 21 October 2016 at 14:16:26 UTC, Steven Schveighoffer wrote:

How about in general forbidding lambda statements that aren't called
or used anywhere?


How?

int main()
{
int a;
auto b = ()=>{a++;};
b();
assert(a==1);
return 0;
}


Oh, I see. This error that I didn't see right away wouldn't be 
prevented, but that's not what I was talking about. I just meant that 
the original problem shouldn't have happened, since the lambda is never 
used.


I totally agree that the above sucks and should be fixed.

-Steve




Re: "for" statement issue

2016-10-21 Thread Andrei Alexandrescu via Digitalmars-d

On 10/21/2016 09:42 AM, Adam D. Ruppe wrote:

I think deprecating `{ lambda }` is really the way to go.


Another possibility is to disallow an ExpressionStatement that consists 
solely of a lambda. There is precedent for that, e.g. the statement "1 + 
1;" is disallowed. -- Andrei




Re: "for" statement issue

2016-10-21 Thread Steven Schveighoffer via Digitalmars-d

On 10/21/16 10:28 AM, Kagamin wrote:

On Friday, 21 October 2016 at 14:16:26 UTC, Steven Schveighoffer wrote:

How about in general forbidding lambda statements that aren't called
or used anywhere?


How?

int main()
{
int a;
auto b = ()=>{a++;};
b();
assert(a==1);
return 0;
}


This lambda is both used in an assignment, and called.

If I do this:

10;

It's flagged as not having any effect. Similarly if I do:

() => 5;

Then it's not used/called. What is the point?

-Steve


Re: "for" statement issue

2016-10-21 Thread mogu via Digitalmars-d
On Friday, 21 October 2016 at 14:22:27 UTC, Steven Schveighoffer 
wrote:

On 10/21/16 10:12 AM, Temtaime wrote:
On Friday, 21 October 2016 at 13:42:49 UTC, Adam D. Ruppe 
wrote:

On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:

[...]


Eh, that's exactly what the language rules say should happen, 
and it
actually does make sense to me... you might even want to use 
an
immediately-called lambda to group several statements 
together into

one expression.

[...]


Please, no.
It's fully clear that { stmts } createa a lambda, just () is 
ommited.


No, it's not.

{ int x; x = 2; }

Is not a lambda. It's a scope.

So the meaning changes based on where it's used. I totally 
agree that we should remove that feature.


-Steve


{} in swift is a lambda too. I think swift has better lambda 
syntax. Maybe could help for a better syntax in d.



reversedNames = names.sorted(by: { (s1: String, s2: String) -> 
Bool in

return s1 > s2
})
reversedNames = names.sorted(by: { (s1: String, s2: String) -> 
Bool in return s1 > s2 } )

reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
reversedNames = names.sorted(by: { $0 > $1 } )
reversedNames = names.sorted(by: >)

someFunctionThatTakesAClosure(closure: {
// closure's body goes here
})
someFunctionThatTakesAClosure() {
// trailing closure's body goes here
}
let strings = numbers.map {
(number) -> String in
var number = number
var output = ""
repeat {
output = digitNames[number % 10]! + output
number /= 10
} while number > 0
return output
}


Re: "for" statement issue

2016-10-21 Thread Kagamin via Digitalmars-d

http://ideone.com/KBf8k9


Re: "for" statement issue

2016-10-21 Thread Kagamin via Digitalmars-d
On Friday, 21 October 2016 at 14:16:26 UTC, Steven Schveighoffer 
wrote:
How about in general forbidding lambda statements that aren't 
called or used anywhere?


How?

int main()
{
int a;
auto b = ()=>{a++;};
b();
assert(a==1);
return 0;
}


Re: "for" statement issue

2016-10-21 Thread Steven Schveighoffer via Digitalmars-d

On 10/21/16 10:12 AM, Temtaime wrote:

On Friday, 21 October 2016 at 13:42:49 UTC, Adam D. Ruppe wrote:

On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:

[...]


Eh, that's exactly what the language rules say should happen, and it
actually does make sense to me... you might even want to use an
immediately-called lambda to group several statements together into
one expression.

[...]


Please, no.
It's fully clear that { stmts } createa a lambda, just () is ommited.


No, it's not.

{ int x; x = 2; }

Is not a lambda. It's a scope.

So the meaning changes based on where it's used. I totally agree that we 
should remove that feature.


-Steve


Re: "for" statement issue

2016-10-21 Thread Steven Schveighoffer via Digitalmars-d

On 10/21/16 8:34 AM, Andrei Alexandrescu wrote:

I got a question about what happens with this code:

int j;
for({j=2; int d = 3; } j+d<7; {j++; d++;}) {
}

My first instinct was that that won't compile but it surprisingly does.
And it loops forever.

So the grammar according to
https://dlang.org/spec/grammar.html#ForStatement is:

ForStatement:
for ( Initialize Testopt ; Incrementopt ) ScopeStatement

Initialize:
;
NoScopeNonEmptyStatement

NoScopeNonEmptyStatement:
NonEmptyStatement
BlockStatement

NonEmptyStatement goes over a bunch of odd places such as case statement
and default statement. And then BlockStatement is the matched case:

BlockStatement:
{ }
{ StatementList }

So it seems we have another case in which "{" "}" do not introduce a
scope. Fine. The real problem is with the increment part, which is an
expression. The code { j++; d++; } is... a lambda expression that never
gets used, which completes a very confusing sample.

What would be a good solution to forbid certain constructs in the
increment part of a for statement?


How about in general forbidding lambda statements that aren't called or 
used anywhere?


-Steve


Re: "for" statement issue

2016-10-21 Thread Temtaime via Digitalmars-d

On Friday, 21 October 2016 at 13:42:49 UTC, Adam D. Ruppe wrote:

On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:

[...]


Eh, that's exactly what the language rules say should happen, 
and it actually does make sense to me... you might even want to 
use an immediately-called lambda to group several statements 
together into one expression.


[...]


Please, no.
It's fully clear that { stmts } createa a lambda, just () is 
ommited.


foo({ code; }); is always OK and we shouldn't deprecate it.


Re: "for" statement issue

2016-10-21 Thread Stefan Koch via Digitalmars-d

On Friday, 21 October 2016 at 13:42:49 UTC, Adam D. Ruppe wrote:

On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:

It does create a lambda?
Hmm that should not happen.


I think deprecating `{ lambda }` is really the way to go. It'd 
fix this as well at that other FAQ at pretty low cost.


Yes lets make it happen!
{ } has too many meanings.
Lets deprecate this one.




Re: "for" statement issue

2016-10-21 Thread Adam D. Ruppe via Digitalmars-d

On Friday, 21 October 2016 at 13:33:26 UTC, Stefan Koch wrote:

It does create a lambda?
Hmm that should not happen.


Eh, that's exactly what the language rules say should happen, and 
it actually does make sense to me... you might even want to use 
an immediately-called lambda to group several statements together 
into one expression.


Though I have become convinced recently that we should deprecate 
the `{ lambdas }` in favor of `() { lambdas }`. This is the same 
mistake as `() => {xxx}` that we see a bunch of newbies make. If 
the syntax was changed to require the empty parens for the args, 
`() {}`, people would be a lot less likely to mess this up... and 
the rest of us don't seriously lose anything, adding `()` is easy 
enough if they aren't already there.


I think deprecating `{ lambda }` is really the way to go. It'd 
fix this as well at that other FAQ at pretty low cost.


Re: "for" statement issue

2016-10-21 Thread Stefan Koch via Digitalmars-d

On Friday, 21 October 2016 at 13:18:19 UTC, RazvanN wrote:
On Friday, 21 October 2016 at 12:34:58 UTC, Andrei Alexandrescu 
wrote:

[...]


I am the one who raised the question. I am n00b when it comes 
to D language (I just started reading about it a couple of days 
ago) and I tried the above mentioned code expecting that either 
the variables j and d get incremented accordingly or at least
I would get a compilation error. Instead, the program compiles 
and when run it sticks
into an infinite loop. I haven't read anything about lambda 
functions in D, but the

current outcome is very confusing for a beginner like myself.

Thanks,
RazvanN

Ah.
It does create a lambda?
Hmm that should not happen.

I agree this is confusing and unwanted.
Please feel free to post this to bugzilla.

I will take a look next month. If nobody resolves it before then.




Re: "for" statement issue

2016-10-21 Thread RazvanN via Digitalmars-d
On Friday, 21 October 2016 at 12:34:58 UTC, Andrei Alexandrescu 
wrote:

I got a question about what happens with this code:

int j;
for({j=2; int d = 3; } j+d<7; {j++; d++;}) {
}

My first instinct was that that won't compile but it 
surprisingly does. And it loops forever.


So the grammar according to 
https://dlang.org/spec/grammar.html#ForStatement is:


ForStatement:
for ( Initialize Testopt ; Incrementopt ) ScopeStatement

Initialize:
;
NoScopeNonEmptyStatement

NoScopeNonEmptyStatement:
NonEmptyStatement
BlockStatement

NonEmptyStatement goes over a bunch of odd places such as case 
statement and default statement. And then BlockStatement is the 
matched case:


BlockStatement:
{ }
{ StatementList }

So it seems we have another case in which "{" "}" do not 
introduce a scope. Fine. The real problem is with the increment 
part, which is an expression. The code { j++; d++; } is... a 
lambda expression that never gets used, which completes a very 
confusing sample.


What would be a good solution to forbid certain constructs in 
the increment part of a for statement?



Thanks,

Andrei


I am the one who raised the question. I am n00b when it comes to 
D language (I just started reading about it a couple of days ago) 
and I tried the above mentioned code expecting that either the 
variables j and d get incremented accordingly or at least
I would get a compilation error. Instead, the program compiles 
and when run it sticks
into an infinite loop. I haven't read anything about lambda 
functions in D, but the

current outcome is very confusing for a beginner like myself.

Thanks,
RazvanN


Re: "for" statement issue

2016-10-21 Thread Stefan Koch via Digitalmars-d
On Friday, 21 October 2016 at 12:34:58 UTC, Andrei Alexandrescu 
wrote:

I got a question about what happens with this code:

int j;
for({j=2; int d = 3; } j+d<7; {j++; d++;}) {
}

[...]
We could restrict the initialze part to assignments only. But I 
am unsure of the implications.

How did you find this case?


"for" statement issue

2016-10-21 Thread Andrei Alexandrescu via Digitalmars-d

I got a question about what happens with this code:

int j;
for({j=2; int d = 3; } j+d<7; {j++; d++;}) {
}

My first instinct was that that won't compile but it surprisingly does. 
And it loops forever.


So the grammar according to 
https://dlang.org/spec/grammar.html#ForStatement is:


ForStatement:
for ( Initialize Testopt ; Incrementopt ) ScopeStatement

Initialize:
;
NoScopeNonEmptyStatement

NoScopeNonEmptyStatement:
NonEmptyStatement
BlockStatement

NonEmptyStatement goes over a bunch of odd places such as case statement 
and default statement. And then BlockStatement is the matched case:


BlockStatement:
{ }
{ StatementList }

So it seems we have another case in which "{" "}" do not introduce a 
scope. Fine. The real problem is with the increment part, which is an 
expression. The code { j++; d++; } is... a lambda expression that never 
gets used, which completes a very confusing sample.


What would be a good solution to forbid certain constructs in the 
increment part of a for statement?



Thanks,

Andrei


$250 bounty placed on D with statement issue

2014-08-08 Thread Andrei Alexandrescu via Digitalmars-d

https://www.bountysource.com/issues/3635875-the-with-statement-does-not-observe-temporary-object-lifetime

Andrei