Re: More useful fixed-size array literals

2014-06-03 Thread bearophile via Digitalmars-d

Namespace:


Another attempt was also closed:
https://github.com/D-Programming-Language/dmd/pull/2958


There is a good hope:
https://github.com/D-Programming-Language/dmd/pull/3615

Bye,
bearophile


Re: More useful fixed-size array literals

2014-05-31 Thread Benjamin Thaut via Digitalmars-d

Am 31.05.2014 00:19, schrieb bearophile:

Code similar to this is not uncommon. Currently it's refused:


immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
 import std.algorithm: count;
 assert(data.count([1, 5]) == 3);
}


test.d(4,23): Error: array literal in @nogc function main may cause GC
allocation


The current workaround is not handy when you have conditionals, etc:

immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
 import std.algorithm: count;
 immutable static part = [1, 5];
 assert(data.count(part) == 3);
}


A language solution is a literal syntax for fixed-sized arrays (here I
slice it again because unfortunately count doesn't accept fixed-sized
arrays):


immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
 import std.algorithm: count;
 assert(data.count([1, 5]s[]) == 3);
}


I remember Kenji is not fond of this []s syntax, for reasons I don't
remember. Do you think there are other better/different solutions?

Bye,
bearophile



give scope a meaning for function arguments other then lambdas E.g:

size_t count(scope int[] heystack, scope int[] needle);

Now the compiler can allocate the literal [1, 5] on the stack without 
any special syntax because it knows that the array literal will not be 
escaped.


Kind Regards
Benjamin Thaut


Re: More useful fixed-size array literals

2014-05-31 Thread Namespace via Digitalmars-d
I remember Kenji is not fond of this []s syntax, for reasons I 
don't remember. Do you think there are other better/different 
solutions?


Bye,
bearophile


Read it on my closed Pull Request:
https://github.com/D-Programming-Language/dmd/pull/2952

Another attempt was also closed:
https://github.com/D-Programming-Language/dmd/pull/2958


Re: More useful fixed-size array literals

2014-05-31 Thread bearophile via Digitalmars-d

Benjamin Thaut:

give scope a meaning for function arguments other then 
lambdas E.g:


size_t count(scope int[] heystack, scope int[] needle);

Now the compiler can allocate the literal [1, 5] on the stack 
without any special syntax because it knows that the array 
literal will not be escaped.



With your suggestion this code should be accepted:

int foo(scope int[] items) @nogc {
int total = 0;
foreach (immutable x; items)
total += x;
return total;
}
void main() @nogc {
assert(foo([1, 5, 3, 1, 5, 1, 5]) == 21);
}



While this can't be accepted because 'items' escapes the body of 
'foo', so 'scope' forbids some valid code:


import std.algorithm: sum;
int foo(scope int[] items) @nogc {
return foo.sum;
}
void main() @nogc {
assert(foo([1, 5, 3, 1, 5, 1, 5]) == 21);
}



The []s syntax moves the control to the calling point, allowing 
more valid code to compile:


import std.algorithm: sum;
int foo(int[] items) @nogc {
return foo.sum;
}
void main() @nogc {
assert(foo([1, 5, 3, 1, 5, 1, 5]s) == 21);
}



A disadvantage of the []s syntax is that it's less safe than 
scope:


int[] global;
void foo() @nogc {
bar([1, 5, 3, 1, 5, 1, 5]s);
}
void bar(int[] b) @nogc {
global = b;
}
void main() {
import std.stdio;
foo();
writeln(global);
}



But that usage of []s is not much worse than this currently 
accepted code, the difference is that the []s syntax makes this 
problem a bit less visible:


int[] global;
void foo() @nogc {
int[7] a = [1, 5, 3, 1, 5, 1, 5];
bar(a); // Implicit slicing.
}
void bar(int[] b) @nogc {
global = b;
}
void main() {
import std.stdio;
foo();
writeln(global);
}


(I think Jonathan M Davis suggested to disallow such implicit 
slicing, and require a bar(a[]);.)



A possible way to increase the number of functions allowed by 
'scope' is to allow a reference to escape if it goes into another 
'scope':


int sum(scope int[] items) @nogc {
int total = 0;
foreach (immutable x; items)
total += x;
return total;
}
int foo(scope int[] items) @nogc {
return sum(items); // Allowed.
}
void main() @nogc {
assert(foo([1, 5, 3, 1, 5, 1, 5]) == 21); // Allowed.
}



(The problem with Scott Meyers' suggestion in the The Last Thing 
D Needs keynote is that to design a language/library feature 
that takes in account every other language/library part, you need 
a mind significantly larger than the average human one :-) ).


Bye,
bearophile


Re: More useful fixed-size array literals

2014-05-31 Thread bearophile via Digitalmars-d

int foo(scope int[] items) @nogc {
return foo.sum;
}


That was:

return items.sum;

Bye,
bearophile


Re: More useful fixed-size array literals

2014-05-31 Thread Benjamin Thaut via Digitalmars-d

Am 31.05.2014 11:08, schrieb bearophile:

int foo(scope int[] items) @nogc {
return foo.sum;
}


That was:

return items.sum;

Bye,
bearophile


Well obviously the std.algorithm sum would also be annoted with scope. 
Because it doesn't escape it either. I don't see the problem here. And 
in case you really want to escape it, you need to .dup it.


A additional advantage of my solution is, that the compiler can prove it 
to be @safe. Your solution does not allow that.


Kind Regards
Benjamin Thaut


Re: More useful fixed-size array literals

2014-05-31 Thread bearophile via Digitalmars-d

Benjamin Thaut:

Well obviously the std.algorithm sum would also be annoted with 
scope. Because it doesn't escape it either. I don't see the 
problem here. And in case you really want to escape it, you 
need to .dup it.


A additional advantage of my solution is, that the compiler can 
prove it to be @safe. Your solution does not allow that.


You can see that the contents of this answer of yours are a 
strict subset of the contents of my last post :-)


A problem with that use of scope to solve this problem is that 
such feature interacts with several other things (like 
ownership), so it's a complex topic, so nearly everyone is afraid 
of touching and implementing it, so nothing will happen.


This phenomenon has happened even for more contained features the 
old (prestate) of contract programming, for built-in D tuple 
syntax, etc. And we keep having a language with holes, that lacks 
such basic features.


This means that sometimes designing a language in a less coherent 
way (in Scott Meyers' words) is better than having a language 
that lacks certain basic features.


I hope Walter or others will figure out this topic of ownership, 
etc.


Bye,
bearophile


Re: More useful fixed-size array literals

2014-05-30 Thread Meta via Digitalmars-d

On Friday, 30 May 2014 at 22:19:51 UTC, bearophile wrote:

Code similar to this is not uncommon. Currently it's refused:


immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
import std.algorithm: count;
assert(data.count([1, 5]) == 3);
}


test.d(4,23): Error: array literal in @nogc function main may 
cause GC allocation



The current workaround is not handy when you have conditionals, 
etc:


immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
import std.algorithm: count;
immutable static part = [1, 5];
assert(data.count(part) == 3);
}


A language solution is a literal syntax for fixed-sized arrays 
(here I slice it again because unfortunately count doesn't 
accept fixed-sized arrays):



immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
import std.algorithm: count;
assert(data.count([1, 5]s[]) == 3);
}


I remember Kenji is not fond of this []s syntax, for reasons I 
don't remember. Do you think there are other better/different 
solutions?


Bye,
bearophile


What about prepending the word static?

immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
import std.algorithm: count;
assert(data.count(static[1, 5]) == 3);
}

Or variadic template arguments. Aren't they allocated on the 
stack like static arrays?


immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
import std.algorithm: count;
//Assume count has a variadic template implementation
assert(data.count(1, 5) == 3);
}


Re: More useful fixed-size array literals

2014-05-30 Thread bearophile via Digitalmars-d

Meta:


What about prepending the word static?

immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
import std.algorithm: count;
assert(data.count(static[1, 5]) == 3);
}


This is about the same as appending the char 's'.


Or variadic template arguments. Aren't they allocated on the 
stack like static arrays?


immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
import std.algorithm: count;
//Assume count has a variadic template implementation
assert(data.count(1, 5) == 3);
}


Currently they are allocated on the stack. But count doesn't 
work like that. And I think this feature of D is bug-prone, and 
in bugzilla I've asked to change it (allocating on the heap on 
default).


Bye,
bearophile


Re: More useful fixed-size array literals

2014-05-30 Thread Mason McGill via Digitalmars-d

On Friday, 30 May 2014 at 22:19:51 UTC, bearophile wrote:
A language solution is a literal syntax for fixed-sized arrays 
(here I slice it again because unfortunately count doesn't 
accept fixed-sized arrays):



immutable data = [1, 5, 3, 1, 5, 1, 5];
void main() @nogc {
import std.algorithm: count;
assert(data.count([1, 5]s[]) == 3);
}


I would use this often. It's always seemed strange to me that 
static arrays are one of the few built-in data structures that 
don't have a dedicated literal form. `[1, 2, 3]s` nicely 
parallels the syntax for string and number literals.