May 30, 2013
On Thursday, 30 May 2013 at 05:41:06 UTC, Maxim Fomin wrote:
> On Wednesday, 29 May 2013 at 23:45:04 UTC, Ali Çehreli wrote:
>> On 05/29/2013 03:59 PM, Peter Williams wrote:
>>
>> > I've been trying to find out how non ref array arguments are
>> passed to
>> > functions in D but can't find any documentation on it.
>>
>> The following concepts are relevant:
>>
>> - Dynamic array: Maintained by the D runtime
>
> Generally yes, but not always http://dpaste.dzfl.pl/ffbcb449

That's not a dynamic array, it's a slice of a static array.

>
>> - Fixed-length array (aka static array): Can be on the stack
>>
>> - Slice: An efficient tool to access a range of elements (of any type of array)
>>
>> Usually, it is the slice that gets passed:
>>
>>  void foo(int[] slice);
>
> Isn't it a dynamic array? I don't understand listing slice as separate type of arrays or mixing meaning of slice and dynamic array. As far as D spec is concerned, slice is a SliceExpression which produces dynamic array for array types.

You can't directly access dynamic arrays in D, you can only manipulate views of them using slices. "new int[5]" creates a new dynamic array internally but only returns a slice of that array.
May 30, 2013
On Thursday, 30 May 2013 at 05:44:43 UTC, Diggory wrote:
> On Thursday, 30 May 2013 at 05:41:06 UTC, Maxim Fomin wrote:
>> On Wednesday, 29 May 2013 at 23:45:04 UTC, Ali Çehreli wrote:
>>> On 05/29/2013 03:59 PM, Peter Williams wrote:
>>>
>>> > I've been trying to find out how non ref array arguments are
>>> passed to
>>> > functions in D but can't find any documentation on it.
>>>
>>> The following concepts are relevant:
>>>
>>> - Dynamic array: Maintained by the D runtime
>>
>> Generally yes, but not always http://dpaste.dzfl.pl/ffbcb449
>
> That's not a dynamic array, it's a slice of a static array.

And this is a problem, because article about D slices encourages to call some raw memory (which almost never is directly manipulated and doesn't appear in source code) as a dynamic array, and dynamic array as a slice.

>>
>>> - Fixed-length array (aka static array): Can be on the stack
>>>
>>> - Slice: An efficient tool to access a range of elements (of any type of array)
>>>
>>> Usually, it is the slice that gets passed:
>>>
>>> void foo(int[] slice);
>>
>> Isn't it a dynamic array? I don't understand listing slice as separate type of arrays or mixing meaning of slice and dynamic array. As far as D spec is concerned, slice is a SliceExpression which produces dynamic array for array types.
>
> You can't directly access dynamic arrays in D, you can only manipulate views of them using slices. "new int[5]" creates a new dynamic array internally but only returns a slice of that array.

That's clear, issue here is misleading definitions used by D slices article.

typeof(slice) => int[]

From array page spec: type[] => dynamic array. So, int[] slice is a parameter of type 'dynamic array'.

From expression spec page what slice is:
SliceExpression:
   PostfixExpression [ ]
   PostfixExpression [ AssignExpression .. AssignExpression ]

and clearly 'slice' object is not an expression.
May 30, 2013
On Thursday, 30 May 2013 at 05:54:57 UTC, Maxim Fomin wrote:
> On Thursday, 30 May 2013 at 05:44:43 UTC, Diggory wrote:
>> On Thursday, 30 May 2013 at 05:41:06 UTC, Maxim Fomin wrote:
>>> On Wednesday, 29 May 2013 at 23:45:04 UTC, Ali Çehreli wrote:
>>>> On 05/29/2013 03:59 PM, Peter Williams wrote:
>>>>
>>>> > I've been trying to find out how non ref array arguments are
>>>> passed to
>>>> > functions in D but can't find any documentation on it.
>>>>
>>>> The following concepts are relevant:
>>>>
>>>> - Dynamic array: Maintained by the D runtime
>>>
>>> Generally yes, but not always http://dpaste.dzfl.pl/ffbcb449
>>
>> That's not a dynamic array, it's a slice of a static array.
>
> And this is a problem, because article about D slices encourages to call some raw memory (which almost never is directly manipulated and doesn't appear in source code) as a dynamic array, and dynamic array as a slice.

The article about slices on this site - http://dlang.org/d-array-article.html is perfectly correct.

>
>>>
>>>> - Fixed-length array (aka static array): Can be on the stack
>>>>
>>>> - Slice: An efficient tool to access a range of elements (of any type of array)
>>>>
>>>> Usually, it is the slice that gets passed:
>>>>
>>>> void foo(int[] slice);
>>>
>>> Isn't it a dynamic array? I don't understand listing slice as separate type of arrays or mixing meaning of slice and dynamic array. As far as D spec is concerned, slice is a SliceExpression which produces dynamic array for array types.
>>
>> You can't directly access dynamic arrays in D, you can only manipulate views of them using slices. "new int[5]" creates a new dynamic array internally but only returns a slice of that array.
>
> That's clear, issue here is misleading definitions used by D slices article.
>
> typeof(slice) => int[]
>
> From array page spec: type[] => dynamic array. So, int[] slice is a parameter of type 'dynamic array'.

Yep, it's misleading but the D documentation is misleading and wrong in a lot of places and I'd say here the problems are relatively minor. Still they should be fixed.

>
> From expression spec page what slice is:
> SliceExpression:
>    PostfixExpression [ ]
>    PostfixExpression [ AssignExpression .. AssignExpression ]
>
> and clearly 'slice' object is not an expression.

This is talking about the slice operator, not slices. The slice operator can be applied to any object which defines it.
May 30, 2013
On 05/29/2013 10:54 PM, Maxim Fomin wrote:

> And this is a problem, because article about D slices encourages to call
> some raw memory (which almost never is directly manipulated and doesn't
> appear in source code) as a dynamic array, and dynamic array as a slice.

An array is simply consecutive elements in memory. There are two types of arrays: static (aka fixed-length) and dynamic.

Slice is not an array itself: It is both an accessor to array elements (static or dynamic) and a tool that can spawn a new dynamic array when another element is appended to its view.

Documentations use "slice" and "dynamic array" synonymously because of the latter semantics.

Ali

May 30, 2013
On 05/29/2013 06:54 PM, Peter Williams wrote:

> On 30/05/13 10:49, Peter Williams wrote:
>> On 30/05/13 09:45, Ali Çehreli wrote:

>>>    http://dlang.org/d-array-article.html

> Thinking about this some more, it seems I still need the const even with
> pass by value to reassure the caller that his array won't be altered. So
> the problem doesn't go away it just changes slightly.

It is sensible that the parameter be const-element, non-const-slice:

    void foo(const(int)[] arr);

> I find the mechanism described in the article a little disconcerting and
> it certainly needs more publicity as it's a bug in waiting for the
> unwary.

It certainly is disconcerting. Performance have played a big role in the current semantics of slices.

> Wouldn't a better rule for pass by value be that any changes to
> the data part of the array (including assignment to an element) causes
> reallocation of the entire data portion.

The type of a slice parameter is not different than a local slice variable. Since we wouldn't want an entire copy of the elements due to an element mutation:

    int[] whole = // ...;
    int[] firstHalf = whole[0 .. $/2];
    firstHalf = 42;    // this should affect whole

Moving the last two lines to a new function should not change meaning:

    int[] whole = // ...;
    setFirstHalf(whole, 42);  // should still affect whole

Ali

May 30, 2013
On Thursday, 30 May 2013 at 06:08:09 UTC, Diggory wrote:
> On Thursday, 30 May 2013 at 05:54:57 UTC, Maxim Fomin wrote:
>> On Thursday, 30 May 2013 at 05:44:43 UTC, Diggory wrote:
>>> On Thursday, 30 May 2013 at 05:41:06 UTC, Maxim Fomin wrote:
>>>> On Wednesday, 29 May 2013 at 23:45:04 UTC, Ali Çehreli wrote:
>>>>> On 05/29/2013 03:59 PM, Peter Williams wrote:
>>>>>
>>>>> > I've been trying to find out how non ref array arguments are
>>>>> passed to
>>>>> > functions in D but can't find any documentation on it.
>>>>>
>>>>> The following concepts are relevant:
>>>>>
>>>>> - Dynamic array: Maintained by the D runtime
>>>>
>>>> Generally yes, but not always http://dpaste.dzfl.pl/ffbcb449
>>>
>>> That's not a dynamic array, it's a slice of a static array.
>>
>> And this is a problem, because article about D slices encourages to call some raw memory (which almost never is directly manipulated and doesn't appear in source code) as a dynamic array, and dynamic array as a slice.
>
> The article about slices on this site - http://dlang.org/d-array-article.html is perfectly correct.

No, the article is incorrect in vocabulary because it contradicts to the spec definitions, and spec incompletence is not a reason to dilute what is already defined. What actually happens is:
1) T[] is defined as dynamic array,  PostfixExpression [ ] is defined as SliceExpression.
2) Array article calls dynamic arrays as slices. Since notion of dynamic array is occupied, the article calls GC memory as dynamic array. This is a complete contradiction to spec.
3) Folks start using these misleading definitions.

This actually leads to incorrect assumptions, as was pointed out previously that dynamic array points only to runtime memory (which is not always the case).

>>
>>>>
>>>>> - Fixed-length array (aka static array): Can be on the stack
>>>>>
>>>>> - Slice: An efficient tool to access a range of elements (of any type of array)
>>>>>
>>>>> Usually, it is the slice that gets passed:
>>>>>
>>>>> void foo(int[] slice);
>>>>
>>>> Isn't it a dynamic array? I don't understand listing slice as separate type of arrays or mixing meaning of slice and dynamic array. As far as D spec is concerned, slice is a SliceExpression which produces dynamic array for array types.
>>>
>>> You can't directly access dynamic arrays in D, you can only manipulate views of them using slices. "new int[5]" creates a new dynamic array internally but only returns a slice of that array.
>>
>> That's clear, issue here is misleading definitions used by D slices article.
>>
>> typeof(slice) => int[]
>>
>> From array page spec: type[] => dynamic array. So, int[] slice is a parameter of type 'dynamic array'.
>
> Yep, it's misleading but the D documentation is misleading and wrong in a lot of places and I'd say here the problems are relatively minor. Still they should be fixed.

This is not a reason to confuse what exists.

>>
>> From expression spec page what slice is:
>> SliceExpression:
>>   PostfixExpression [ ]
>>   PostfixExpression [ AssignExpression .. AssignExpression ]
>>
>> and clearly 'slice' object is not an expression.
>
> This is talking about the slice operator, not slices. The slice operator can be applied to any object which defines it.

than please point out what else slice according to spec is (spec mentions slices in context of SliceExpressions and it is the only valid usage).
May 30, 2013
On Thursday, 30 May 2013 at 06:12:03 UTC, Ali Çehreli wrote:
> On 05/29/2013 10:54 PM, Maxim Fomin wrote:
>
> > And this is a problem, because article about D slices
> encourages to call
> > some raw memory (which almost never is directly manipulated
> and doesn't
> > appear in source code) as a dynamic array, and dynamic array
> as a slice.
>
> An array is simply consecutive elements in memory. There are two types of arrays: static (aka fixed-length) and dynamic.

As a general programming notion - yes, in D (array spec page):
"Dynamic arrays consist of a length and a pointer to the array data."

This actually kills two misinterpretations encouraged by array article that a) dynamic array is some kind of runtime memory b) that T[] data is not a dynamic array, it is a slice.

> Slice is not an array itself: It is both an accessor to array elements (static or dynamic) and a tool that can spawn a new dynamic array when another element is appended to its view.
>
> Documentations use "slice" and "dynamic array" synonymously because of the latter semantics.
>
> Ali

May 30, 2013
On Thursday, May 30, 2013 09:01:06 Maxim Fomin wrote:
> > The article about slices on this site - http://dlang.org/d-array-article.html is perfectly correct.
> 
> No, the article is incorrect in vocabulary because it contradicts
> to the spec definitions, and spec incompletence is not a reason
> to dilute what is already defined. What actually happens is:
> 1) T[] is defined as dynamic array,  PostfixExpression [ ] is
> defined as SliceExpression.
> 2) Array article calls dynamic arrays as slices. Since notion of
> dynamic array is occupied, the article calls GC memory as dynamic
> array. This is a complete contradiction to spec.
> 3) Folks start using these misleading definitions.
> 
> This actually leads to incorrect assumptions, as was pointed out previously that dynamic array points only to runtime memory (which is not always the case).

Much as I love that article, I really don't like the fact that it tries to claim that dynamic arrays and slices are two different things, since they aren't. T[] is a dynamic array _and_ a slice, and for the article to be completely correct in its terminology, it would actually be incorrect to refer to _anything_ in D as a dynamic array, as it would be something completely internal to the runtime. T[] would be only a slice, and the type system wouldn't have dynamic arrays in it anywhere.

The runtime holds the memory that dynamic arrays / slices refer to, but I really wish that that article had not referred to that underlying memory as being the dymanic array as opposed to simply a block of memory that the runtime gave slices to, letting the slices be referred to as dynamic arrays like they are.

I would argue that all dynamic arrays are array slices and vice versa. And that's how std.traits.isDynamicArray treats them as well.

- Jonathan M Davis
May 30, 2013
On 05/30/2013 12:11 AM, Maxim Fomin wrote:

> On Thursday, 30 May 2013 at 06:12:03 UTC, Ali Çehreli wrote:
>> On 05/29/2013 10:54 PM, Maxim Fomin wrote:
>>
>> > And this is a problem, because article about D slices
>> encourages to call
>> > some raw memory (which almost never is directly manipulated
>> and doesn't
>> > appear in source code) as a dynamic array, and dynamic array
>> as a slice.
>>
>> An array is simply consecutive elements in memory. There are two types
>> of arrays: static (aka fixed-length) and dynamic.
>
> As a general programming notion - yes, in D (array spec page):
> "Dynamic arrays consist of a length and a pointer to the array data."

Then the spec is wrong because that is the definition of a slice. The reason is, there is no dynamic array is sight below but a static array and a slice:

    int[10] arr;
    int[] slice = arr;
    assert(slice.ptr == &arr[0]);  // (yes, same as arr.ptr)

Even though 'slice' above "consists of a length a pointer to the array data" despite the language of the spec, that is not a dynamic array:

    slice[0] = 42;

The static array's element is changed, not some dynamic array's.

The correct description is that the 'slice' variable above is a slice, having the ability to refer to elements of a dynamic array and a static array.

(I know I am repeating the article at this point but it happens to be the fact.) If there is no dynamic array to speak of above, what is a dynamic array then? The answer is, dynamic array is an entity that is owned and managed by the D runtime.

For the above code to finally involve a dynamic array, we can add an element to 'slice':

    slice ~= 7;
    assert(slice.ptr != &arr[0]);

Now there is a dynamic array but it is not our 'slice' that is the dynamic array. Here is the proof:

    slice = arr[5 .. $];
    assert(slice.ptr == &arr[5]);

Has 'slice' been a dynamic array until that last assignment and suddenly become a slice again? No, D does not involve type changes like that. It has always been a slice, which is not the same thing as a dynamic array.

> This actually kills two misinterpretations encouraged by array article
> that a) dynamic array is some kind of runtime memory

I still think so.

> b) that T[] data is not a dynamic array, it is a slice.

I still think so.

The spec must be outdated then; the array semantics have been finalized relatively recently (in 2009? or 2010?).

Ali

May 30, 2013
On Thursday, 30 May 2013 at 07:15:39 UTC, Jonathan M Davis wrote:
> On Thursday, May 30, 2013 09:01:06 Maxim Fomin wrote:
>> > The article about slices on this site -
>> > http://dlang.org/d-array-article.html is perfectly correct.
>> 
>> No, the article is incorrect in vocabulary because it contradicts
>> to the spec definitions, and spec incompletence is not a reason
>> to dilute what is already defined. What actually happens is:
>> 1) T[] is defined as dynamic array,  PostfixExpression [ ] is
>> defined as SliceExpression.
>> 2) Array article calls dynamic arrays as slices. Since notion of
>> dynamic array is occupied, the article calls GC memory as dynamic
>> array. This is a complete contradiction to spec.
>> 3) Folks start using these misleading definitions.
>> 
>> This actually leads to incorrect assumptions, as was pointed out
>> previously that dynamic array points only to runtime memory
>> (which is not always the case).
>
> Much as I love that article, I really don't like the fact that it tries to
> claim that dynamic arrays and slices are two different things, since they
> aren't. T[] is a dynamic array _and_ a slice, and for the article to be
> completely correct in its terminology, it would actually be incorrect to refer
> to _anything_ in D as a dynamic array, as it would be something completely
> internal to the runtime. T[] would be only a slice, and the type system
> wouldn't have dynamic arrays in it anywhere.
>
> The runtime holds the memory that dynamic arrays / slices refer to, but I
> really wish that that article had not referred to that underlying memory as
> being the dymanic array as opposed to simply a block of memory that the
> runtime gave slices to, letting the slices be referred to as dynamic arrays
> like they are.
>
> I would argue that all dynamic arrays are array slices and vice versa. And
> that's how std.traits.isDynamicArray treats them as well.
>
> - Jonathan M Davis

But it's clearly not the case that all slices are dynamic arrays... A dynamic array is already a well-established term to mean an array allocated on the heap. Slices can point to arrays on the stack.