October 20, 2016 Re: Static Length Propagation of Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Thursday, 20 October 2016 at 13:05:05 UTC, Nordlöw wrote:
> On Thursday, 20 October 2016 at 12:38:40 UTC, Nordlöw wrote:
>> ElementType!R[n] arrayN(size_t n, R)(R r)
>> {
>> assert(r.length == n);
>> typeof(return) dst;
>> import std.algorithm.mutation : copy;
>> r.copy(dst[]);
>> return dst;
>> }
>
> Is there a place for part of this logic in Phobos?
>
> I'm thinking perhaps array{N,Exactly} should be added to std.array.
>
> The idea came to me after learning about dependent types in Idris:
>
> http://www.idris-lang.org/
There was a pull request awhile back for a small function that creates fixed-length arrays, but I think it was only intended to create them from dynamic arrays (such as `auto sarr = [1, 2, 3].staticArray`). Personally I think it would be nice to have a version of `array` that creates a static array, but I don't know how often it would be used or what the pitfalls are, if any.
|
October 20, 2016 Re: Static Length Propagation of Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Thursday, 20 October 2016 at 16:25:53 UTC, Meta wrote: > On Thursday, 20 October 2016 at 13:05:05 UTC, Nordlöw wrote: >> On Thursday, 20 October 2016 at 12:38:40 UTC, Nordlöw wrote: >>> ElementType!R[n] arrayN(size_t n, R)(R r) >>> { >>> assert(r.length == n); >>> typeof(return) dst; >>> import std.algorithm.mutation : copy; >>> r.copy(dst[]); >>> return dst; >>> } >> >> Is there a place for part of this logic in Phobos? >> >> I'm thinking perhaps array{N,Exactly} should be added to std.array. >> >> The idea came to me after learning about dependent types in Idris: >> >> http://www.idris-lang.org/ > > There was a pull request awhile back for a small function that creates fixed-length arrays, but I think it was only intended to create them from dynamic arrays (such as `auto sarr = [1, 2, 3].staticArray`). Personally I think it would be nice to have a version of `array` that creates a static array, but I don't know how often it would be used or what the pitfalls are, if any. I think you're talking about this PR: https://github.com/dlang/phobos/pull/4090. It handles range iteration, as well as opApply iteration. I also think that the addition is worth having, though Andrei seemed to disagree. The (other?) major obstacle is safe usage, which currently is not enforced by the compiler, see: https://issues.dlang.org/show_bug.cgi?id=8838 https://issues.dlang.org/show_bug.cgi?id=12625 On the bright side, it looks like one of Walter's PRs for DIP1000 should address those issues: https://github.com/dlang/dmd/pull/5972/files?diff=unified#diff-33b3e2fefc5298c0b9de67897929e7ceR89 |
October 21, 2016 Re: Static Length Propagation of Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Thursday, 20 October 2016 at 12:38:40 UTC, Nordlöw wrote:
> On Wednesday, 19 October 2016 at 19:39:46 UTC, Nordlöw wrote:
>> On Wednesday, 19 October 2016 at 19:01:50 UTC, Meta wrote:
>>> https://goo.gl/t9m3YK
>>>
>>> I'm actually pretty impressed that this kind of code can be written in D.
>>
>> Thanks! Add at
>>
>> https://github.com/nordlow/phobos-next/blob/master/src/algorithm_ex.d#L2234
>
> Made it even modular by factoring out arrayN at
>
> https://github.com/nordlow/phobos-next/blob/master/src/algorithm_ex.d#L2200
>
> and used at
>
> https://github.com/nordlow/phobos-next/blob/master/src/algorithm_ex.d#L2215
>
> Code:
>
>
> ElementType!R[n] arrayN(size_t n, R)(R r)
> {
> assert(r.length == n);
> typeof(return) dst;
> import std.algorithm.mutation : copy;
> r.copy(dst[]);
> return dst;
> }
>
> typeof(fun(E.init))[n] map(alias fun, E, size_t n)(const E[n] src)
> {
> import std.algorithm.iteration : map;
> return src[].map!fun.arrayN!n;
> }
>
> @safe pure nothrow unittest
> {
> import std.meta : AliasSeq;
> foreach (E; AliasSeq!(int, double))
> {
> enum n = 42;
> E[n] c;
> const result = map!(_ => _^^2)(c);
> static assert(c.length == result.length);
> static assert(is(typeof(result) == const(E)[n]));
> }
> }
Here's my variation on the theme. The main difference being that instead of eagerly evaluating the range I wrap it with additional static information. Unfortunately, (AFAIK) Phobos does not take advantage of ranges with statically known length, similarly to how it handles ranges with `enum bool empty = false`.
void main()
{
import std.stdio;
int[3] sarr = [1, 2, 3];
auto r1 = sarr.staticLengthRange;
static assert (isInputRange!(typeof(r1)));
static assert (r1.length == 3);
writeln(r1);
auto arr = [1, 2, 3, 4];
auto r2 = arr.map!(a => a * 2).staticLengthRange!4;
static assert (r2.length == 4);
writeln(r2);
}
import std.algorithm.iteration : map;
import std.range.primitives : hasLength, isInputRange;
// Note: this overload has questionable memory safety :(
// Would be quite cool if DIP1000 could support this use case
auto staticLengthRange(T, size_t n)(ref T[n] arr)
{
return .staticLengthRange!(n, T[])(arr[]);
}
auto staticLengthRange(size_t n, R)(R range)
if (isInputRange!R && hasLength!R)
{
struct Result
{
enum size_t length = n;
R _range;
alias _range this;
}
assert (range.length == n);
return Result(range);
}
auto staticLengthRange(size_t n, R)(R range)
if (isInputRange!R && hasLength!R)
{
struct Result
{
enum size_t length = n;
R _range;
alias _range this;
}
assert (range.length == n);
return Result(range);
}
|
Copyright © 1999-2021 by the D Language Foundation