May 06, 2014
On Mon, 05 May 2014 20:10:35 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> 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);

case 1. allok.arrayOf!int(42);

Yes, I know I got rid of the array type as the template parameter, but I don't think we want to duplicate the problem of not being able to allocate arrays on the heap that we have with 'new'.

case 2. allok.array(42); // Use IFTI

This mirrors std.array.array

In fact, 2 really should be in std.array:

array(Allocator, T...)(Allocator allok, T t) if (isAllocator!Allocator)

-Steve
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:
>
> 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);

I'm not a fan of the dual purposing at all.  When I see "a.make!T(x, y, z)",
I expect that to be identical to "new T(x, y, z)", whether T is an array type
or not.  The special case will cause more confusion than aid.  I'd much prefer
separate functions, as others had suggested. "a.zeroArray!int(dim1, dim2)"
May 06, 2014
On 5/5/14, 5:10 PM, Andrei Alexandrescu wrote:
> So I'm looking at creation functions and in particular creation
> functions for arrays.
[snip]

A few thoughts on the ideas so far (awesome ones, thanks!). Credit is implied to the respective posters.

> 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])[]

This is interesting, and may be used later in other places. The only problem I see it's not used in other places :o).

> alloc.make(repeat(0).take(45))

The problem here is it's unclear whether the intent is to allocate and initialize a range object, or an array of integers. There's no clarification an array is needed. alloc.make!(int[])(repeat(0).take(45)) or alloc.makeArray(repeat(0).take(45)) would work.

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

This is going a bit further from arrays into arrays of arrays, which would make array creation different when part of another array. That doesn't sit well, but then arrays of arrays may be special enough.

> 2. why "make" instead of "construct" or "factory"?
> Or "build" ?

The converse might be asked, too. One argument is std.container already uses "make", as does Go. "construct" is too specific because what really happens is allocation and construction, and "factory" is a bit unfortunate because it's a noun (yes, I know, Object has it).

> auto a = allok.make(42); // maybe require only() or don't use
> IFTI.

This lookes like making an integer, initializing it with 42, and returning a pointer to it.

> auto a = allok.make(iota(42, 45));

This allocates an iota object dynamically.

> One last thought. If array() accepted a second argument for an
> allocator you could just use a lot of existing code and slap an
> allocator into that final argument on your UFCS chain.
>
> auto arr = iota(1, 5).joiner(only(7, 13)).array(allok);

This is a really nice complement for the .array idiom used so often at the end of pipelines. It's currently around the top of my preferences. So the full signature would be:

auto array(R, A)(R range, auto ref A allok);

> Does it have to be one function?
>
> allok.makeLength!(int[])(42) as per new int[n] convention
> allok.makeUsing!(int[])(42, 43, 44) as per literal convention
>
> s/makeUsing/makeFilled -- or just makeFill
> s/makeUsing/makeFrom
> s/makeUsing/makeWith

This is down-to-earth but somewhat lacking in flexibility; every pattern needs its own function.

> I actually think this is a very elegant solution, but does open the
> question, should `allok.make!(42)` create an array initialized to 42,
> or an array with length of 42? Provided this is documented, I don't
> think the ambiguity should be an issue.

Neither, that should return an int* pointing to an int = 42.

> case 1. allok.arrayOf!int(42);

Noice.

> Yes, I know I got rid of the array type as the template parameter,
> but I don't think we want to duplicate the problem of not being able
> to allocate arrays on the heap that we have with 'new'.
>
> case 2. allok.array(42); // Use IFTI
>
> This mirrors std.array.array
>
> In fact, 2 really should be in std.array:
>
> array(Allocator, T...)(Allocator allok, T t) if
> (isAllocator!Allocator)

Yah.


Andrei


May 06, 2014
06-May-2014 04:10, 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));

Have this primitive to keep it simple.
(i.e. make => pass args to "ctor")
Especially in the case of int[][][] and such.

>
> 2. Follow the [ literal ] convention:
>
> auto a = allok.make!(int[])(42);
> assert(a.length == 1);
> assert(a[0] == 42);
>

This option is std.array.array in a disguise or rather the builder pattern. Would be nice to have it separately from allocator.

My argument is:
a) It should work for any container.
b) Is related not to an allocator but rather to the type of container (and its associated allocator). Arrays are unfortunately oblivious of allocators.

-- 
Dmitry Olshansky
May 06, 2014
On Tue, 06 May 2014 15:32:23 -0400, Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:

> 06-May-2014 04:10, 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));
>
> Have this primitive to keep it simple.
> (i.e. make => pass args to "ctor")
> Especially in the case of int[][][] and such.

I agree with the spirit of your idea, but not the implementation.

make!T(args) should build an instance of that type on the heap, and then call it's constructor.

In the case of T == int[], it should mean put an int[] on the heap, not allocate a block, and give me an int[] reference to it.

Array is a special case IMO, and deserves its own primitive.

-Steve
May 07, 2014
On Mon, 05 May 2014 17:10:35 -0700, Andrei Alexandrescu wrote:

> 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));

Why not use make for length only

> 
> 2. Follow the [ literal ] convention:
> 
> auto a = allok.make!(int[])(42);
> assert(a.length == 1);
> assert(a[0] == 42);
> 

And build here for building up the array
May 07, 2014
On Wednesday, 7 May 2014 at 16:12:15 UTC, Byron wrote:
> On Mon, 05 May 2014 17:10:35 -0700, Andrei Alexandrescu wrote:
>
>> 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));
>
> Why not use make for length only
>
>> 
>> 2. Follow the [ literal ] convention:
>> 
>> auto a = allok.make!(int[])(42);
>> assert(a.length == 1);
>> assert(a[0] == 42);
>> 
>
> And build here for building up the array

would have been cool if something like this worked:

template make(T : U[n], U, alias n)

i.e
int dim = 42;
make!int[dim]








May 07, 2014
On Tuesday, 6 May 2014 at 04:56:10 UTC, Walter Bright wrote:
> On 5/5/2014 7:51 PM, Andrei Alexandrescu wrote:
>> On 5/5/14, 5:54 PM, Walter Bright wrote:
>>> 2. why "make" instead of "construct" or "factory"?
>> Shorter.
>
> "Less" is 4 characters. I win!

There's a precedent for "make" in "std.container". For what it's worth.
1 2 3
Next ›   Last »