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?
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;
--
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
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.
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?
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);
}
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
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
}
--
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.
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);
}
per.nordlow:
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);
}
For a nullary function, this solution is certainly OK: short and
understandable.
I found a way to parse an entire function param list, including default
args, but I don't remember right now how I did that. Maybe by parsing
'fun.stringof'
Maybe this exists in Phobos now?
btw, I'd call this template 'apply', because repeat already exists in
Phobos with a different use.
btw, I'd call this template 'apply', because repeat already
exists in
Phobos with a different use.
Good idea! I'll rename it.
I have a pile of extensions to std.algorithm, std.traits,
std.numeric, I'll pull some day when I get the time...
/Per
I have a pile of extensions to std.algorithm, std.traits,
std.numeric, I'll pull some day when I get the time...
I mean push...