Thread overview
Forwarding arguments through a std.algorithm.map
Mar 10, 2018
Nordlöw
Mar 10, 2018
ag0aep6g
Mar 16, 2018
Nordlöw
Mar 16, 2018
Nordlöw
Mar 16, 2018
Nordlöw
Mar 11, 2018
crimaniak
Mar 11, 2018
Seb
Mar 11, 2018
Stefan Koch
March 10, 2018
If I have a function

    bool f(Rs...)(Rs rs)

is it somehow possible to map and forward all its arguments `rs` to another function

    bool g(Rs...)(Rs rs);

through a call to some map-and-forward-like-function `forwardMap` in something like

    bool f(Rs...)(Rs rs)
    {
        alias someArbitraryFun = _ => _;
        return g(forwardMap!(someArbitraryFun)(rs));
    }

?

What should the definition of forwardMap look like?

Does Phobos contain something like this already?
March 10, 2018
On 03/10/2018 09:48 PM, Nordlöw wrote:
> If I have a function
> 
>      bool f(Rs...)(Rs rs)
> 
> is it somehow possible to map and forward all its arguments `rs` to another function
> 
>      bool g(Rs...)(Rs rs);
> 
> through a call to some map-and-forward-like-function `forwardMap` in something like
> 
>      bool f(Rs...)(Rs rs)
>      {
>          alias someArbitraryFun = _ => _;
>          return g(forwardMap!(someArbitraryFun)(rs));
>      }
> 
> ?

Not with that syntax, as far as I know. A function can't return an alias seq like that.

But it can return a std.typecons.Tuple. You'd have to add `.expand` then:

    return g(forwardMap!someArbitraryFun(rs).expand);

> What should the definition of forwardMap look like?

Not tested beyond `f(1, 2.3, "foo")`:

----
auto forwardMap(alias fun, Ts ...)(Ts things)
{
    import std.meta: aliasSeqOf, staticMap;
    import std.range: iota;
    import std.typecons: Tuple;
    alias NewType(size_t i) = typeof(fun(things[i]));
    alias NewTypes = staticMap!(NewType,
        aliasSeqOf!(iota(things.length)));
    Tuple!NewTypes results;
    static foreach (i, thing; things) results[i] = fun(thing);
    return results;
}
----

I wouldn't call it "forwardMap". "tupleMap" or "seqMap" maybe?

> Does Phobos contain something like this already?

Not that I know of.
March 11, 2018
On Saturday, 10 March 2018 at 20:48:06 UTC, Nordlöw wrote:
> If I have a function
>
>     bool f(Rs...)(Rs rs)
>
> is it somehow possible to map and forward all its arguments `rs` to another function
>
>     bool g(Rs...)(Rs rs);

docs:
 https://dlang.org/phobos/std_traits.html#.Parameters
usage example:
 https://github.com/crimaniak/d-vision/blob/master/src/vision/eventbus.d#L173
March 11, 2018
On Saturday, 10 March 2018 at 20:48:06 UTC, Nordlöw wrote:
> If I have a function
>
>     bool f(Rs...)(Rs rs)
>
> is it somehow possible to map and forward all its arguments `rs` to another function
>
>     bool g(Rs...)(Rs rs);
>
> through a call to some map-and-forward-like-function `forwardMap` in something like
>
>     bool f(Rs...)(Rs rs)
>     {
>         alias someArbitraryFun = _ => _;
>         return g(forwardMap!(someArbitraryFun)(rs));
>     }
>
> ?
>
> What should the definition of forwardMap look like?
>
> Does Phobos contain something like this already?

Not sure whether I understand what you are looking for, but std.functional is your friend here I think pipe/compose is the function you are searching for.

https://dlang.org/phobos/std_functional.html#forward
https://dlang.org/phobos/std_functional.html#partial
https://dlang.org/phobos/std_functional.html#pipe
March 11, 2018
On Saturday, 10 March 2018 at 20:48:06 UTC, Nordlöw wrote:
> If I have a function
>
>     bool f(Rs...)(Rs rs)
>
> is it somehow possible to map and forward all its arguments `rs` to another function
>
>     bool g(Rs...)(Rs rs);
>
> through a call to some map-and-forward-like-function `forwardMap` in something like
>
>     bool f(Rs...)(Rs rs)
>     {
>         alias someArbitraryFun = _ => _;
>         return g(forwardMap!(someArbitraryFun)(rs));
>     }
>
> ?
>
> What should the definition of forwardMap look like?
>
> Does Phobos contain something like this already?

there is staticMap.
March 16, 2018
On Saturday, 10 March 2018 at 21:31:41 UTC, ag0aep6g wrote:
> Not tested beyond `f(1, 2.3, "foo")`:
>
> auto forwardMap(alias fun, Ts ...)(Ts things)
> {
>     import std.meta: aliasSeqOf, staticMap;
>     import std.range: iota;
>     import std.typecons: Tuple;
>     alias NewType(size_t i) = typeof(fun(things[i]));
>     alias NewTypes = staticMap!(NewType,
>         aliasSeqOf!(iota(things.length)));
>     Tuple!NewTypes results;
>     static foreach (i, thing; things) results[i] = fun(thing);
>     return results;
> }

Thanks! I'll try to put together something...
March 16, 2018
On Saturday, 10 March 2018 at 21:31:41 UTC, ag0aep6g wrote:
> auto forwardMap(alias fun, Ts ...)(Ts things)
> {
>     import std.meta: aliasSeqOf, staticMap;
>     import std.range: iota;
>     import std.typecons: Tuple;
>     alias NewType(size_t i) = typeof(fun(things[i]));
>     alias NewTypes = staticMap!(NewType,
>         aliasSeqOf!(iota(things.length)));
>     Tuple!NewTypes results;
>     static foreach (i, thing; things) results[i] = fun(thing);
>     return results;
> }

Found a slightly compacter way without `iota` and `aliasSeqOf` and with (deprecated) string-lambda support and single-pass initialization using `= void` and `emplace`:

/** Returns: `xs` forwarded through calls to `fun`.
 *
 * See also: https://forum.dlang.org/post/zjxmreegqkxgdzvihvyk@forum.dlang.org
 */
auto forwardMap(alias fun, Ts...)(Ts xs)
{
    import std.meta : staticMap;
    alias MappedTypeOf(T) = typeof(fun(T.init));
    alias NewTypes = staticMap!(MappedTypeOf, Ts);

    import std.typecons : Tuple;
    Tuple!NewTypes ys = void;
    import std.conv : emplace;

    import std.functional : unaryFun;
    alias fun_ = unaryFun!(fun);

    static foreach (immutable i, x; xs)
    {
        emplace(&ys[i], fun_(x));
    }
    return ys;
}

I believe this should go into Phobos somewhere. Into std.typecons, std.meta or std.algorithm?
March 16, 2018
On 03/16/2018 03:52 PM, Nordlöw wrote:
> On Saturday, 10 March 2018 at 21:31:41 UTC, ag0aep6g wrote:
>> auto forwardMap(alias fun, Ts ...)(Ts things)
>> {
>>     import std.meta: aliasSeqOf, staticMap;
>>     import std.range: iota;
>>     import std.typecons: Tuple;
>>     alias NewType(size_t i) = typeof(fun(things[i]));
>>     alias NewTypes = staticMap!(NewType,
>>         aliasSeqOf!(iota(things.length)));
>>     Tuple!NewTypes results;
>>     static foreach (i, thing; things) results[i] = fun(thing);
>>     return results;
>> }
> 
> Found a slightly compacter way without `iota` and `aliasSeqOf` and with (deprecated) string-lambda support and single-pass initialization using `= void` and `emplace`:
> 
> /** Returns: `xs` forwarded through calls to `fun`.
>   *
>   * See also: https://forum.dlang.org/post/zjxmreegqkxgdzvihvyk@forum.dlang.org
>   */
> auto forwardMap(alias fun, Ts...)(Ts xs)
> {
>      import std.meta : staticMap;
>      alias MappedTypeOf(T) = typeof(fun(T.init));
>      alias NewTypes = staticMap!(MappedTypeOf, Ts);
> 
>      import std.typecons : Tuple;
>      Tuple!NewTypes ys = void;
>      import std.conv : emplace;
> 
>      import std.functional : unaryFun;
>      alias fun_ = unaryFun!(fun);
> 
>      static foreach (immutable i, x; xs)
>      {
>          emplace(&ys[i], fun_(x));
>      }
>      return ys;
> }
> 
> I believe this should go into Phobos somewhere. Into std.typecons, std.meta or std.algorithm?

My knee-jerk reaction is that's a rather peculiar primitive to add to the standard library. -- Andrei
March 16, 2018
On Friday, 16 March 2018 at 20:39:33 UTC, Andrei Alexandrescu wrote:
> My knee-jerk reaction is that's a rather peculiar primitive to add to the standard library. -- Andrei

I'm needing it for variadic equal...I'll put it as a private member in `equal`s template declaration for now.