Re: Assigning to array of structs with custom constructor

2022-04-25 Thread Ali Çehreli via Digitalmars-d-learn

On 4/25/22 21:32, Salih Dincer wrote:

> So the problem is that the structure is not in the inter-module space

Nested structs carry an additional pointer to their containing context. 
When they don't need the context, we define them with 'static':


void foo() {
  static struct Bar { }
}

> If ```sruct Foo {}``` is not taken outside of ```main()``` it will fail
> for many possibilities!

Only if the struct needs the context. Otherwise, nested structs should 
be defined with 'static' and there is no issue with map...


Ali



Re: Assigning to array of structs with custom constructor

2022-04-25 Thread Salih Dincer via Digitalmars-d-learn



So the problem is that the structure is not in the inter-module 
space


On Monday, 25 April 2022 at 16:11:47 UTC, rassoc wrote:


This works:

```d
import std;

void main() {
struct Foo { string s; }
Foo[] arr = ["abc", "def", "ghi"].map!Foo.array;
arr.writeln; // => [Foo("abc"), Foo("def"), Foo("ghi")]
}
```


If ```sruct Foo {}``` is not taken outside of ```main()``` it 
will fail for many possibilities!


**For example:**

Error: cannot access frame pointer of `source.main.Foo`


SDB@79


Re: Assigning to array of structs with custom constructor

2022-04-25 Thread Ali Çehreli via Digitalmars-d-learn

On 4/25/22 19:37, Salih Dincer wrote:

> a lot of errors 

Hm. I can't reproduce any of that. I did two things:

1) Added necessary import directives

2) Moved all expressions into the main() function

I did not change anything else. The program below compiles and works 
with all these compilers:


- dmd 2.098.1
- dmd 2.099.1
- gdc 11.2.0
- ldc 1.28.1 (based on DMD v2.098.1 and LLVM 13.0.1)

Are you using a very old compiler?

import std.range;
import std.algorithm;
import std.conv;
import std.stdio;

struct Bar {
  string s;

  this(R)(R result) {
import std.conv : to;
this.s = result.to!string;
  }

  string toString() {
return s;
  }
}

void main() {
  auto parts = "abcdefghi".chunks(3);
  auto compiled = parts.map!(a => Bar(a));


  // NOTE: PLEASE IGNORE THE ERROR MESSAGES BELOW.
  //   EVERYTHING COMPILES AND WORKS.


  auto notCompile1 = parts.map!Bar;
  /* Error 1: instantiated from here: `map!(Chunks!string)`*/

  auto notCompile2 = parts.map!(c => c.to!string)
 .map!Bar;
  /* Error 1: 
/usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(604)

 : cannot access frame pointer of `source.main.Bar`

 Error 2: 
/usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(499)
 : template instance `std.algorithm.iteration.MapResult!(Bar, 
MapResult!(__lambda4, Chunks!string))` error instantiating


 Error 3: instantiated from here: `map!(MapResult!(__lambda4, 
Chunks!string))`

  */
  auto notCompile3 = parts.array.map!Bar;
  /* Error 1: 
/usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(604)

 : cannot access frame pointer of `source.main.Bar`

 Error 2: 
/usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(616)

 : cannot access frame pointer of `source.main.Bar`

 Error 3: 
/usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(499)
 : template instance `std.algorithm.iteration.MapResult!(Bar, 
Take!string[])` error instantiating


 Error 4: instantiated from here: `map!(Take!string
  */
  auto arr = compiled.array; /* [abc, def, ghi]

auto arr2 = str.chunks(3)
.map!(a => Bar(a))
.array;//*/

  arr.writeln(": ", typeof(arr).stringof);
}

Ali



Re: Assigning to array of structs with custom constructor

2022-04-25 Thread Salih Dincer via Digitalmars-d-learn

On Tuesday, 26 April 2022 at 00:57:54 UTC, Ali Çehreli wrote:

On 4/25/22 16:59, Salih Dincer wrote:

> Because it cannot be used with other possibilities such as
> ```chunks()``` and ```take()```.

There must be something wrong. map is commonly used with 
chunks(), take(), etc.


> Also it cannot be customized with
> ```toString()```.

Can you show examples of these please?


Of course, I have a few friends here:
and a lot of errors 

```d
struct Bar {
string s;

this(R)(R result) {
  import std.conv : to;
  this.s = result.to!string;
}

string toString() {
  return s;
}
  }
  auto parts = "abcdefghi".chunks(3);
  auto compiled = parts.map!(a => Bar(a));

  auto notCompile1 = parts.map!Bar;
  /* Error 1: instantiated from here: `map!(Chunks!string)`*/

  auto notCompile2 = parts.map!(c => c.to!string)
  .map!Bar;
  /* Error 1: 
/usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(604)

: cannot access frame pointer of `source.main.Bar`

 Error 2: 
/usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(499)
: template instance 
`std.algorithm.iteration.MapResult!(Bar, MapResult!(__lambda4, 
Chunks!string))` error instantiating


 Error 3: instantiated from here: `map!(MapResult!(__lambda4, 
Chunks!string))`

   */
  auto notCompile3 = parts.array.map!Bar;
  /* Error 1: 
/usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(604)

: cannot access frame pointer of `source.main.Bar`

 Error 2: 
/usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(616)

: cannot access frame pointer of `source.main.Bar`

 Error 3: 
/usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(499)
: template instance 
`std.algorithm.iteration.MapResult!(Bar, Take!string[])` error 
instantiating


 Error 4: instantiated from here: `map!(Take!string
   */
  auto arr = compiled.array; /* [abc, def, ghi]

  auto arr2 = str.chunks(3)
 .map!(a => Bar(a))
 .array;//*/

  arr.writeln(": ", typeof(arr).stringof);
```

SDB@79


Re: Assigning to array of structs with custom constructor

2022-04-25 Thread Ali Çehreli via Digitalmars-d-learn

On 4/25/22 16:59, Salih Dincer wrote:

> Because it cannot be used with other possibilities such as
> ```chunks()``` and ```take()```.

There must be something wrong. map is commonly used with chunks(), 
take(), etc.


> Also it cannot be customized with
> ```toString()```.

Can you show examples of these please?

> I guess even when ```this()``` constructor is added,
> ```map()``` explodes!

Ah! Now I tried *removing* Bar.this and the compilation failed. Perhaps 
you left the working code in? (?)


For others:

1) Remove Bar.this

2) The code will fail below:

  auto arr2 = "abcdefghi"
 .chunks(3)
 .map!(a => Bar(a))   <-- ERROR
 .array;

Error: cannot implicitly convert expression `a` of type `Take!string` to 
`string`


One confusing thing is the fact that we learn that chunks uses take in 
its implementation. I think it's cool but a newcomer may be confused 
with where that Take comes from. Let's put that aside.


Then the compilation error is easy to understdand because chunks returns 
a range itself but it is not possible to make a Bar from a range. I 
don't agree that this is a problem with map's usability. The type system 
doesn't know what to do.


Here is one way of fixing the issue, not surprisingly, with map itself. ;)

  import std.conv : to;
  auto arr2 = "abcdefghi"
 .chunks(3)
 .map!(c => c.to!string) // <-- ADDED
 .map!(a => Bar(a))
 .array;

Or, one can use a single map expression:

  auto arr2 = "abcdefghi"
 .chunks(3)
 .map!(a => Bar(a.to!string))  // <-- COMBINED
 .array;

Or, a function can be called, etc.

But to remove a misunderstanding, map can be used with most other range 
algorithms, in the standard library, provided by the programmer, etc.


Ali



Re: Assigning to array of structs with custom constructor

2022-04-25 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 25 April 2022 at 16:11:47 UTC, rassoc wrote:


```d
import std;

void main() {
struct Foo { string s; }
Foo[] arr = ["abc", "def", "ghi"].map!Foo.array;
arr.writeln; // => [Foo("abc"), Foo("def"), Foo("ghi")]
}
```


Thank you...

Very very nice and simple but not extensible!

Because it cannot be used with other possibilities such as 
```chunks()``` and ```take()```.  Also it cannot be customized 
with ```toString()```.  I guess even when ```this()``` 
constructor is added, ```map()``` explodes!  So it not to 
explode, it is necessary to move away from simplicity:


```d
import std.algorithm;
import std.range, std.stdio;

void main() {
  struct Foo {
string s; /*
string s;
string toString() {
  return s;
}//*/
  }
  auto arr1 = ["abc", "def", "ghi"]
  .map!Foo.array; /*
  .map!(a => Foo(a))
  .array;//*/

  typeof(arr1).stringof.writeln(": ", arr1);

  struct Bar {
string s;
//*
this(R)(R result) {
  import std.conv : to;
  this.s = result.to!string;
}//*/

string toString() {
  return s;
}
  }
  auto arr2 = "abcdefghi"
 .chunks(3)
 .map!(a => Bar(a))
 .array;

  typeof(arr2).stringof.writeln(": ", arr2);

} /* OUTPUT:
Foo[]: [Foo("abc"), Foo("def"), Foo("ghi")]
Bar[]: [abc, def, ghi]
*/
```
SDB@79


Re: Assigning to array of structs with custom constructor

2022-04-25 Thread cc via Digitalmars-d-learn

On Monday, 25 April 2022 at 15:23:12 UTC, Ali Çehreli wrote:

  auto arr = iota(10).map!(i => Foo(i.text)).array;


On Monday, 25 April 2022 at 16:11:47 UTC, rassoc wrote:

Foo[] arr = ["abc", "def", "ghi"].map!Foo.array;


Ahh that'll do it alright, thanks


Re: Assigning to array of structs with custom constructor

2022-04-25 Thread rassoc via Digitalmars-d-learn

On 4/25/22 16:36, cc via Digitalmars-d-learn wrote:

```d
struct Foo {
 string s;
 this(string s) { this.s = s; }
}
Foo foo = "a";
Foo[] foos = ["a"]; // Error: cannot implicitly convert expression `["a"]` of type `string[]` to 
`Foo[]`

Foo[] foos = cast(Foo[]) ["a"]; // Error: e2ir: cannot cast `"a"` of type 
`string` to type `Foo`
```

Was there a way to do this?  I thought I recalled seeing something like this before, but I can't 
seem to find it.


This works:

```d
import std;

void main() {
struct Foo { string s; }
Foo[] arr = ["abc", "def", "ghi"].map!Foo.array;
arr.writeln; // => [Foo("abc"), Foo("def"), Foo("ghi")]
}
```


Re: Assigning to array of structs with custom constructor

2022-04-25 Thread Ali Çehreli via Digitalmars-d-learn

On 4/25/22 07:36, cc wrote:
> ```d
> struct Foo {
>  string s;
>  this(string s) { this.s = s; }
> }
> Foo foo = "a";

I don't understand why that syntax exists. I always write it like this:

  auto foo = Foo("a");

> Foo[] foos = ["a"]; // Error: cannot implicitly convert expression
> `["a"]` of type `string[]` to `Foo[]`

This is a way:

  Foo[] foos = [Foo("a")];

Or:

  import std.stdio;
  import std.algorithm;
  import std.range;
  import std.conv;
  auto arr = iota(10).map!(i => Foo(i.text)).array;
  writeln(arr);

Ali



Re: Assigning to array of structs with custom constructor

2022-04-25 Thread cc via Digitalmars-d-learn

On Monday, 25 April 2022 at 15:13:51 UTC, Stanislav Blinov wrote:

Make it explicit:

```d
Foo[] foos = [Foo("a")];
```


There's that too, but I still have to iterate manually. e.g.:

```d
string[] ss = loadABunchOfStringsFromSomewhere();
//Foo[] foos = ss; //error
Foo[] foos;
foos.reserve(ss.length);
foreach (s; ss)
foos ~= Foo(s);
```

Was just hoping there was a way to streamline it within the 
struct definition.


Re: Assigning to array of structs with custom constructor

2022-04-25 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 25 April 2022 at 14:36:25 UTC, cc wrote:

```d
struct Foo {
string s;
this(string s) { this.s = s; }
}
Foo foo = "a";
Foo[] foos = ["a"]; // Error: cannot implicitly convert 
expression `["a"]` of type `string[]` to `Foo[]`
Foo[] foos = cast(Foo[]) ["a"]; // Error: e2ir: cannot cast 
`"a"` of type `string` to type `Foo`

```

Was there a way to do this?  I thought I recalled seeing 
something like this before, but I can't seem to find it.


Make it explicit:

```d
Foo[] foos = [Foo("a")];
```


Re: Assigning to array of structs with custom constructor

2022-04-25 Thread cc via Digitalmars-d-learn

On Monday, 25 April 2022 at 15:00:13 UTC, Alain De Vos wrote:

Not really an answer but this works,
```
void main(){
Foo foo = "a";
Foo[] foos;
foos ~=foo;
}%
```


Right, I can append individual elements, but can't assign or 
append a slice of a type that can be individually cast to the 
struct.


Re: Assigning to array of structs with custom constructor

2022-04-25 Thread Alain De Vos via Digitalmars-d-learn

Not really an answer but this works,
```
struct Foo {
string s;
this(string s) { this.s = s; }
}

void main(){
Foo foo = "a";
Foo[] foos;
foos ~=foo;
}%
```


Assigning to array of structs with custom constructor

2022-04-25 Thread cc via Digitalmars-d-learn

```d
struct Foo {
string s;
this(string s) { this.s = s; }
}
Foo foo = "a";
Foo[] foos = ["a"]; // Error: cannot implicitly convert 
expression `["a"]` of type `string[]` to `Foo[]`
Foo[] foos = cast(Foo[]) ["a"]; // Error: e2ir: cannot cast `"a"` 
of type `string` to type `Foo`

```

Was there a way to do this?  I thought I recalled seeing 
something like this before, but I can't seem to find it.