Jump to page: 1 2 3
Thread overview
API
May 06, 2014
Adam D. Ruppe
May 06, 2014
Adam D. Ruppe
May 06, 2014
bearophile
May 06, 2014
Adam D. Ruppe
May 06, 2014
bearophile
May 06, 2014
Adam D. Ruppe
May 06, 2014
Orvid King
May 06, 2014
bearophile
May 06, 2014
H. S. Teoh
May 06, 2014
Brian Schott
May 06, 2014
Idan Arye
May 06, 2014
Walter Bright
May 06, 2014
MattCoder
May 06, 2014
Walter Bright
May 07, 2014
monarch_dodra
May 06, 2014
Brad Anderson
May 06, 2014
bearophile
May 06, 2014
ed
May 06, 2014
Yota
May 06, 2014
Dmitry Olshansky
May 07, 2014
Byron
May 07, 2014
Xiaoxi
May 06, 2014
So I'm looking at creation functions and in particular creation functions for arrays.

1. Follow the new int[n] convention:

auto a = allok.make!(int[])(42);
assert(a.length == 42);
assert(a.equal(repeat(0, 42));

2. Follow the [ literal ] convention:

auto a = allok.make!(int[])(42);
assert(a.length == 1);
assert(a[0] == 42);

For the second option, to create longer arrays:

auto a = allok.make!(int[])(42, 43, 44);
assert(a.length == 3);
assert(a.equal(iota(42, 45));

Nice ways to repeat things:

auto a = allok.make!(int[])(42, repeat(43, 5), 44);

And even nice ways to create holes for efficiency:

auto a = allok.make!(int[])(42, uninitialized(5), 44);


Destroy.

Andrei
May 06, 2014
On Tuesday, 6 May 2014 at 00:10:36 UTC, Andrei Alexandrescu wrote:
> 1. Follow the new int[n] convention:
> 2. Follow the [ literal ] convention:

We could combine these pretty easily:

struct Length { size_t length; }

allok.make!(int[])(Length(42)); // #1
allok.make!(int[])(1,2,3); // #2 btw could also use IFTI here which is nice

This also potentially gives a third option:

allok.make!(Length(42), 5); // length == 42, all elements == 5, typeof(return) == typeof(args[1])[]


I kinda like that, though I'm not sure if I'd still like it if I used it regularly. Then, of course, we can also take other ranges to initialize too.
May 06, 2014
I guess if it takes an input range with lengths though it could just as well do alloc.make(repeat(0).take(45))
May 06, 2014
Andrei Alexandrescu:

> So I'm looking at creation functions and in particular creation functions for arrays.
>
> 1. Follow the new int[n] convention:
>
> auto a = allok.make!(int[])(42);
> assert(a.length == 42);
> assert(a.equal(repeat(0, 42));
>
> 2. Follow the [ literal ] convention:
>
> auto a = allok.make!(int[])(42);
> assert(a.length == 1);
> assert(a[0] == 42);

Both cases are needed. Unfortunately we don't have named arguments in D, otherwise you can use the same name for both operations, using different arguments.

Also keep in mind that in std.array we have functions like assocArray, uninitializedArray, and minimallyInitializedArray.


I suggest to take a look at a similar function in Scala and especially in Lisp. Lisp has decades of experience to steal from.

A common desire is to create an array based on a given function of its indexes:

immutable a = allok.make!(int[][])(tuple(2, 3), (r, c) => r * 10 + c);
==>
[[0, 1, 2], [10, 11, 12]]

This is rather handy when you want to create immutable arrays.


> auto a = allok.make!(int[])(42, uninitialized(5), 44);

From my experience this is a very uncommon situation, I don't remember if I have ever had such need. (In most cases you want an initialized or an unitialized array. More rarely you want to initialize the first N items and leave M items not initialized).

Bye,
bearophile
May 06, 2014
Adam D. Ruppe:

> I guess if it takes an input range with lengths though it could just as well do alloc.make(repeat(0).take(45))

This is OK if "make" recognizes the repeat.take type statically and uses this information to allocate the array efficiently. In general such pattern recognition tricks should be more present in Phobos (in Haskell there is even a syntax to add them).

Bye,
bearophile
May 06, 2014
On Tuesday, 6 May 2014 at 00:10:36 UTC, Andrei Alexandrescu wrote:
> So I'm looking at creation functions and in particular creation functions for arrays.
>
> 1. Follow the new int[n] convention:

I prefer this one.
May 06, 2014
On Tue, May 06, 2014 at 12:28:19AM +0000, bearophile via Digitalmars-d wrote:
> Andrei Alexandrescu:
> 
> >So I'm looking at creation functions and in particular creation functions for arrays.
> >
> >1. Follow the new int[n] convention:
> >
> >auto a = allok.make!(int[])(42);
> >assert(a.length == 42);
> >assert(a.equal(repeat(0, 42));
> >
> >2. Follow the [ literal ] convention:
> >
> >auto a = allok.make!(int[])(42);
> >assert(a.length == 1);
> >assert(a[0] == 42);
> 
> Both cases are needed. Unfortunately we don't have named arguments in D, otherwise you can use the same name for both operations, using different arguments.
[...]

Adam's trick with a Length struct neatly solves this problem. :-)

	struct Length { size_t n; }
	auto a = allok.make!(int[])(Length(42), 1);
	... // etc

It's a very clever idea, and I like it!


T

-- 
In theory, software is implemented according to the design that has been carefully worked out beforehand. In practice, design documents are written after the fact to describe the sorry mess that has gone on before.
May 06, 2014
On Tuesday, 6 May 2014 at 00:31:04 UTC, bearophile wrote:
> This is OK if "make" recognizes the repeat.take type statically and uses this information to allocate the array efficiently.

I don't think it needs any special beyond hasLength!T so it can allocate it all in one go, so it wouldn't be specialized on Take specifically, just anything with an explicit length property.
May 06, 2014
Adam D. Ruppe:

> I don't think it needs any special beyond hasLength!T so it can allocate it all in one go, so it wouldn't be specialized on Take specifically, just anything with an explicit length property.

If you know that the item is always the same (coming from a repeat) can't you optimize the memory filling better?

Bye,
bearophile
May 06, 2014
On Tuesday, 6 May 2014 at 00:39:44 UTC, bearophile wrote:
> If you know that the item is always the same (coming from a repeat) can't you optimize the memory filling better?

Oh yeah, that's a good point, you can similarly optimize if you know the size of the copy that's needed at compile time (generate better inline memcpy code).
« First   ‹ Prev
1 2 3