std.array.array and immutable elements

2014-11-07 Thread Jack Applegame via Digitalmars-d-learn

DMD64 D Compiler v2.066.1
Why second call doesn't compile?

import std.array;
import std.algorithm;

class Foo {
bool flag;
}
void main() {
  immutable(Foo)[] foos;
  foreach(i; 0..5) foos ~= new Foo;

  // compiles, typeof(bar1) == immutable(Foo)[]
  auto bar1 = array(foos.filter!(i = i.flag));

  // fails, expected typeof(bar2) == immutable(Foo)[]
  auto bar2 = array(foos.map!(i = i));
}

Error: cannot implicitly convert expression (arg) of type 
immutable(Foo) to test.Foo
Error: template instance 
std.conv.emplaceRef!(immutable(Foo)).emplaceRef!(immutable(Foo)) 
error instantiating
instantiated from here: array!(MapResult!(__lambda2, 
immutable(Foo)[]))


Re: std.array.array and immutable elements

2014-11-07 Thread ketmar via Digitalmars-d-learn
On Fri, 07 Nov 2014 14:32:57 +
Jack Applegame via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

ah, sorry, my bad, 'const' will not work to, for the same reason.


signature.asc
Description: PGP signature


Re: std.array.array and immutable elements

2014-11-07 Thread ketmar via Digitalmars-d-learn
On Fri, 07 Nov 2014 14:32:57 +
Jack Applegame via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 import std.array;
 import std.algorithm;
 
 class Foo {
   bool flag;
 }
 void main() {
immutable(Foo)[] foos;
foreach(i; 0..5) foos ~= new Foo;
   
// compiles, typeof(bar1) == immutable(Foo)[]
auto bar1 = array(foos.filter!(i = i.flag));
   
// fails, expected typeof(bar2) == immutable(Foo)[]
auto bar2 = array(foos.map!(i = i));
 }
`map` cannot return range with immutable elements, 'cause they are
obviously generated by program, and therefore aren't immutable.

i.e. map function can do alot of things which breaks immutability
promise for range elements, and filter function cannot (as it doesn't
return new element value).

but map can return 'const' ranges, so changing your `foos` to 'const'
will work.


signature.asc
Description: PGP signature


Re: std.array.array and immutable elements

2014-11-07 Thread anonymous via Digitalmars-d-learn

On Friday, 7 November 2014 at 14:57:56 UTC, ketmar via
Digitalmars-d-learn wrote:
`map` cannot return range with immutable elements, 'cause they 
are
obviously generated by program, and therefore aren't 
immutable.


That's not true. Runtime generated values can be immutable just
fine. And it's std.array.array that's choking here, not map.


Re: std.array.array and immutable elements

2014-11-07 Thread ketmar via Digitalmars-d-learn
On Fri, 07 Nov 2014 15:18:24 +
anonymous via Digitalmars-d-learn digitalmars-d-learn@puremagic.com
wrote:

 On Friday, 7 November 2014 at 14:57:56 UTC, ketmar via
 Digitalmars-d-learn wrote:
  `map` cannot return range with immutable elements, 'cause they 
  are
  obviously generated by program, and therefore aren't 
  immutable.
 
 That's not true. Runtime generated values can be immutable just
 fine. And it's std.array.array that's choking here, not map.
ah, sorry, maybe i'm too tired now and talking nonsense. it can have a
perfect sense for me, but still be nonsense. but don't blame me, it's
gdc bug which makes gdc segfaults on my code, it eats all my brains.


signature.asc
Description: PGP signature


Re: std.array.array and immutable elements

2014-11-07 Thread John Colvin via Digitalmars-d-learn

On Friday, 7 November 2014 at 14:33:00 UTC, Jack Applegame wrote:

DMD64 D Compiler v2.066.1
Why second call doesn't compile?

import std.array;
import std.algorithm;

class Foo {
bool flag;
}
void main() {
  immutable(Foo)[] foos;
  foreach(i; 0..5) foos ~= new Foo;

  // compiles, typeof(bar1) == immutable(Foo)[]
  auto bar1 = array(foos.filter!(i = i.flag));

  // fails, expected typeof(bar2) == immutable(Foo)[]
  auto bar2 = array(foos.map!(i = i));
}

Error: cannot implicitly convert expression (arg) of type 
immutable(Foo) to test.Foo
Error: template instance 
std.conv.emplaceRef!(immutable(Foo)).emplaceRef!(immutable(Foo)) 
error instantiating
instantiated from here: array!(MapResult!(__lambda2, 
immutable(Foo)[]))


I'm pretty sure that should work. Please file a bug report.

In the mean-time, either pre-allocate and std.algorithm.copy or - 
if you don't have the length - use std.array.appender and ~= the 
entire range in a single shot.