Thread overview
How to use map?
Nov 11, 2014
Lemonfiend
Nov 11, 2014
bearophile
Nov 11, 2014
Lemonfiend
Nov 11, 2014
Lemonfiend
Nov 11, 2014
Marc Schütz
Nov 11, 2014
Lemonfiend
November 11, 2014
I'm trying to do something simple like creating an array of struct S from a float array via map:

---
void main()
{
	float[] vals = [1.1, 2.1, 3.1, 4.1];

	import std.algorithm: map;
	auto arr = vals.map!`S(a)`.array;
	writeln(arr);
}

struct S(T)
{
	T t;
}
---

But I get:
---
C:\D\dmd2\windows\bin\..\..\src\phobos\std\functional.d-mixin-49(49): Error: undefined identifier S
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(480): Error: template instance std.functional.unaryFun!("S(a)", "a").unaryFun!float error instantiating
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(427):        instantiated from here: MapResult!(unaryFun, float[])
src\app.d(28):        instantiated from here: map!(float[])
---

If I instead do ie. map!`cast(int)a` it works fine.
What am I missing?
November 11, 2014
Lemonfiend:

> If I instead do ie. map!`cast(int)a` it works fine.
> What am I missing?

Generally don't use casts, unless you know what you are doing (and often you don't).

The code you were trying to write:

struct Foo(T) {
    T t;
}

void main() {
    import std.stdio, std.algorithm, std.array;

    float[] vals = [1.1, 2.1, 3.1, 4.1];
    auto arr = vals.map!(Foo!float).array;
    arr.writeln;
}

Bye,
bearophile
November 11, 2014
> The code you were trying to write:
>
> struct Foo(T) {
>     T t;
> }
>
> void main() {
>     import std.stdio, std.algorithm, std.array;
>
>     float[] vals = [1.1, 2.1, 3.1, 4.1];
>     auto arr = vals.map!(Foo!float).array;
>     arr.writeln;
> }

Sorry, my example had an unneeded template. Simply this (and also your code)
---
struct S
{
    float f;
}
---
still results in an undefined identifier.
November 11, 2014
Oh, no it doesn't. My bad.

It was all about !(Foo) vs !(`Foo(a)`). Is there somewhere I can read more about this?

November 11, 2014
On Tuesday, 11 November 2014 at 14:09:43 UTC, Lemonfiend wrote:
> Oh, no it doesn't. My bad.
>
> It was all about !(Foo) vs !(`Foo(a)`). Is there somewhere I can read more about this?

Don't know whether it's documented, but it's a consequence of using string mixins.

unaryFun (which is used internally by map) is implemented this way:

    auto unaryFun(ElementType)(auto ref ElementType __a)
    {
        mixin("alias " ~ parmName ~ " = __a ;");
        return mixin(fun);
    }

where `fun` is `Foo(a)`. Of course, `Foo` is not visible in std.functional. When you pass in a symbol, the lookup work because it takes place at the point of instantiation.
November 11, 2014
On Tuesday, 11 November 2014 at 15:53:37 UTC, Marc Schütz wrote:
> Don't know whether it's documented, but it's a consequence of using string mixins.
>
> unaryFun (which is used internally by map) is implemented this way:
>
>     auto unaryFun(ElementType)(auto ref ElementType __a)
>     {
>         mixin("alias " ~ parmName ~ " = __a ;");
>         return mixin(fun);
>     }
>
> where `fun` is `Foo(a)`. Of course, `Foo` is not visible in std.functional. When you pass in a symbol, the lookup work because it takes place at the point of instantiation.

That makes sense, thanks.