Jump to page: 1 2
Thread overview
Range Construction Pattern
Feb 22, 2014
Nordlöw
Feb 22, 2014
Tobias Pankrath
Feb 22, 2014
Nordlöw
Feb 22, 2014
Tobias Pankrath
Feb 22, 2014
Nordlöw
Feb 22, 2014
Philippe Sigaud
Feb 22, 2014
Nordlöw
Feb 22, 2014
Tobias Pankrath
Feb 22, 2014
Philippe Sigaud
Feb 22, 2014
Nordlöw
Feb 22, 2014
Philippe Sigaud
Feb 22, 2014
Nordlöw
Feb 22, 2014
Nordlöw
February 22, 2014
Assumed I have the following code

    SysTime[] times;
    const n = 3;
    foreach (i; 0..n) times ~= Clock.currTime;

is there a simpler, perhaps functional, higher order pattern with which to achieve the same goal?
February 22, 2014
On Saturday, 22 February 2014 at 12:29:11 UTC, Nordlöw wrote:
> Assumed I have the following code
>
>     SysTime[] times;
>     const n = 3;
>     foreach (i; 0..n) times ~= Clock.currTime;
>
> is there a simpler, perhaps functional, higher order pattern with which to achieve the same goal?

What's Clock.currTime exactly, a function?
--
times = iota(3).map!(x => Clock.currTime).array;
--

February 22, 2014
On Saturday, 22 February 2014 at 12:40:42 UTC, Tobias Pankrath wrote:
> On Saturday, 22 February 2014 at 12:29:11 UTC, Nordlöw wrote:
>> Assumed I have the following code
>>
>>    SysTime[] times;
>>    const n = 3;
>>    foreach (i; 0..n) times ~= Clock.currTime;
>>
>> is there a simpler, perhaps functional, higher order pattern with which to achieve the same goal?
>
> What's Clock.currTime exactly, a function?
> --
> times = iota(3).map!(x => Clock.currTime).array;
> --

Great!

See also: https://stackoverflow.com/questions/21954381/range-construction-pattern/21954416?noredirect=1#21954416
February 22, 2014
> times = iota(3).map!(x => Clock.currTime).array;
> --

Ok here's my try so far:

auto create(alias fun)(size_t n)
{
    import std.range: iota, map;
    return n.iota.map!(n => fun);
}

Now what remains is to retstrict create to only take a fun with *no* input arguments and a non-void return.

How do I do that?
February 22, 2014
> Great!
>
> See also: https://stackoverflow.com/questions/21954381/range-construction-pattern/21954416?noredirect=1#21954416

I don't think that 'create' is a good name for a function, that basically lazily evaluates another function foo n times. Maybe std.range.repeat should have an overload that takes an alias to a callable, so you don't need this rather awkward use of iota.




February 22, 2014
> Now what remains is to retstrict create to only take a fun with *no*
input arguments and a non-void return.
>
> How do I do that?

With a template contraint.
Not tested:

import std.traits: isCallable, ParameterTypeTuple, ReturnType;

auto create(alias fun)(size_t n)
if (isCallable!fun && ParameterTypeTuple!(fun).length == 0
&& !is(ReturnType!fun == void))
{
    import std.range: iota, map;
    return n.iota.map!(n => fun);
}


February 22, 2014
On Saturday, 22 February 2014 at 14:03:11 UTC, Philippe Sigaud wrote:
>> Now what remains is to retstrict create to only take a fun with *no*
> input arguments and a non-void return.
>>
>> How do I do that?
>
> With a template contraint.
> Not tested:
>
> import std.traits: isCallable, ParameterTypeTuple, ReturnType;
>
> auto create(alias fun)(size_t n)
> if (isCallable!fun && ParameterTypeTuple!(fun).length == 0
> && !is(ReturnType!fun == void))
> {
>     import std.range: iota, map;
>     return n.iota.map!(n => fun);
> }

Your solution with

   ParameterTypeTuple!(fun).length == 0

doesn't work here because currTime takes a defaulted argument.

I believe we need a new std.trait, say arityMin, for this.
Any ideas on how to implement that? Perhaps using __traits(compiles...?

See also my update at:
https://stackoverflow.com/questions/21954381/range-construction-pattern/21954416?noredirect=1#21954416
February 22, 2014
>
> I believe we need a new std.trait, say arityMin, for this.
> Any ideas on how to implement that? Perhaps using __traits(compiles...?
>
> See also my update at:
> https://stackoverflow.com/questions/21954381/range-construction-pattern/21954416?noredirect=1#21954416

In the meantime you can use an is-expression:
--
int foo()  { return 12; }
void bar() { }
void baz(int x) { }
void main()
{
	pragma(msg, is(typeof(foo()) == void));
	pragma(msg, is(typeof(bar()) == void));
        pragma(msg, is(typeof(baz()) == void));
}
--

You can check if arbitrary code compiles with the "if-typeof-delegate-trick":
--
static if(is(typeof({ <code>}))))
{
// code compiles
}
--
February 22, 2014
> You can check if arbitrary code compiles with the
"if-typeof-delegate-trick":
> --
> static if(is(typeof({ <code>}))))
> {
> // code compiles
> }
> --

Or with __traits(compiles, <code>), which better documents the intent.


February 22, 2014
My try so far:

import std.traits: isCallable, ReturnType, arity, ParameterTypeTuple;

enum arityMin0(alias fun) = __traits(compiles, fun()); // new syntax in 2.064

auto repeat(alias fun)(size_t n) if (isCallable!fun &&
                                     arityMin0!fun &&
                                     !is(ReturnType!fun == void))
{
    import std.range: iota, map;
    return n.iota.map!(n => fun);
}
« First   ‹ Prev
1 2