July 05, 2013
On Thursday, 4 July 2013 at 23:52:35 UTC, bearophile wrote:
> Andrei Alexandrescu:
>
>> Where does the whole "stronger typing" comes in? This is poppycock. We need real arguments here.
>
> Maybe it's a matter of definitions, for me having "null" as literal for empty array, null pointer, empty associative array, and more is more weakly typed compared to having a literal like [] usable only for empty dynamic arrays (and strings), a literal as [:] usable only for empty associative arrays, and null for pointers, class references (and little else like a Nullable).
>
> Bye,
> bearophile

[] and [:] aren't even remotely close to be strongly typed. I still don't see any reason to have a distinction.
July 05, 2013
On Thursday, 4 July 2013 at 23:25:38 UTC, Andrei Alexandrescu wrote:
> Where does the whole "stronger typing" comes in? This is poppycock. We need real arguments here.
>
> Andrei

More values typeof([]) can be implicitly converted to - weaker typing, that simple. Actually I'd love to be able to specify precisely typed empty array literal, like [uint] or [uint:bool] but can't find a good syntax to propose. Currently array literals are very special and is does harm the type system.
July 05, 2013
On Thursday, 4 July 2013 at 23:52:35 UTC, bearophile wrote:
> Andrei Alexandrescu:
>
>> Where does the whole "stronger typing" comes in? This is poppycock. We need real arguments here.
>
> Maybe it's a matter of definitions, for me having "null" as literal for empty array, null pointer, empty associative array, and more is more weakly typed compared to having a literal like [] usable only for empty dynamic arrays (and strings), a literal as [:] usable only for empty associative arrays, and null for pointers, class references (and little else like a Nullable).
>
> Bye,
> bearophile

While I agree with the need to have a literal for non-initialized arrays and another one for initialized but empty arrays, that is null and [] respectively, I can't see the necessity for [:]. The literal should be used to mark the difference between null and empty, not the difference between plain or associative, shouldn't it?
For me, having to type
  int[string] foo = [:];
instead of
  int[string] foo = []; // same semantic
would just be a source of confusion.
July 05, 2013
On Friday, 5 July 2013 at 08:15:35 UTC, Nicolas Sicard wrote:
> On Thursday, 4 July 2013 at 23:52:35 UTC, bearophile wrote:
>> Andrei Alexandrescu:
>>
>>> Where does the whole "stronger typing" comes in? This is poppycock. We need real arguments here.
>>
>> Maybe it's a matter of definitions, for me having "null" as literal for empty array, null pointer, empty associative array, and more is more weakly typed compared to having a literal like [] usable only for empty dynamic arrays (and strings), a literal as [:] usable only for empty associative arrays, and null for pointers, class references (and little else like a Nullable).
>>
>> Bye,
>> bearophile
>
> While I agree with the need to have a literal for non-initialized arrays and another one for initialized but empty arrays, that is null and [] respectively, I can't see the necessity for [:]. The literal should be used to mark the difference between null and empty, not the difference between plain or associative, shouldn't it?
> For me, having to type
>   int[string] foo = [:];
> instead of
>   int[string] foo = []; // same semantic
> would just be a source of confusion.

Keep in mind that arrays are value that *look* like reference types. You can get an array that's non-null with no allocations.

Associative arrays, on the other hand, are true reference types. This means initialization *necessarily* implies allocating a payload. Having "[]" "maybe"/"maybe not" allocate is not that good of an idea. Using "[:]", on the other hand, really stresses the fact that "this AA needs to be empty but initialized, and I know I'm going to allocate for it".
July 05, 2013
On Thu, 04 Jul 2013 20:15:08 +0100, Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:

> 04-Jul-2013 19:00, Regan Heath пишет:
>> In fact, you can generalise further.
>>
>> The meaning of if(x) is "compare the value of x with 0" (in C, C++, .. ).
>>
>> The value of x for a pointer is the address to which it points.
>> The value of x for a class reference is the address of the class to
>> which it refers.
>>
>> If D's arrays are reference types,
>
> They are not. It's a half-reference no wonder it has a bit of schizophrenia now and then.

True.  The struct which contains the ptr and length is actually a value type.  I think conceptually however we should be thinking of them as reference types, because.. the array struct is effectively a lightweight wrapper (adding length) around a reference type (ptr).

>   then IMO they should exhibit the same
>> behaviour.
>>
>
> The behavior should be the most useful and since arr.length != 0 is what 99% of time a programmer wants to check.

IMO, the behaviour should be consistent.  If you code if (x) then the compiler will compare 'x' (not a property of x) to 0.  Doing anything else would be inconsistent and unexpected to anyone from a C background.

If you mean to check arr.length, then code that explicitly.  Coding if (arr) and having it check arr.length hides details which really should be visible for the programmer to see.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
July 05, 2013
On Thursday, 4 July 2013 at 19:15:09 UTC, Dmitry Olshansky wrote:
> 04-Jul-2013 19:00, Regan Heath пишет:
>> In fact, you can generalise further.
>>
>> The meaning of if(x) is "compare the value of x with 0" (in C, C++, .. ).
>>
>> The value of x for a pointer is the address to which it points.
>> The value of x for a class reference is the address of the class to
>> which it refers.
>>
>> If D's arrays are reference types,
>
> They are not. It's a half-reference no wonder it has a bit of schizophrenia now and then.

What do you mean by D's dynamic arrays being half-reference types? And what kind of "schizophrenia" do exhibit?
July 05, 2013
On Thu, 04 Jul 2013 18:26:09 +0100, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Why do you want so much an empty array that's not null? I can't make sense of this entire argument.

Suppose you have a web page, suppose it has a text field on it called "comment".  Suppose you load a pre-existing record from your database and populate the page, suppose it had a value for comment, suppose you want to set that comment to be blank.  you edit and click save.

The code backing this page is going to get a string for "comment", that string should be empty but not null.

Why?  Because if it were null it would have a different meaning.  It would mean that the comment field was not present on the page at all, and should not be altered.

There are many such examples.  All of them can be worked around by various means but these are all more complex and require additional containers or variables to represent state.

null  - does not exist, was not specified.
empty - exists and was intentionally set to be empty.

I think arrays will be most useful if we can treat them like safe reference types - this wrappers around the unsafe ptr reference type.  To do that, we need null/empty to be stable/reliable states.

If not, then array becomes like 'int' and we have to invent a special value to represent the null case (or use other containers/variables to represent null) like we do for int.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
July 05, 2013
05-Jul-2013 13:01, TommiT пишет:
> On Thursday, 4 July 2013 at 19:15:09 UTC, Dmitry Olshansky wrote:
>> 04-Jul-2013 19:00, Regan Heath пишет:
>>> In fact, you can generalise further.
>>>
>>> The meaning of if(x) is "compare the value of x with 0" (in C, C++,
>>> .. ).
>>>
>>> The value of x for a pointer is the address to which it points.
>>> The value of x for a class reference is the address of the class to
>>> which it refers.
>>>
>>> If D's arrays are reference types,
>>
>> They are not. It's a half-reference no wonder it has a bit of
>> schizophrenia now and then.
>
> What do you mean by D's dynamic arrays being half-reference types? And
> what kind of "schizophrenia" do exhibit?

For instance passing a slice by value means passing length by value and data pointed to by pointer (hence half-ref):

void messWith(int[] slice)
{
	slice[0] = 45; //changes data pointed to, reference semantics
	slice.length = 0; //doesn't, length is not part of 'reference semantic'
}

void main(){
	auto test = [1, 2, 3];
	messWith(test);
	assert(test.length == 3);
	assert(test[0] == 45);
}

-- 
Dmitry Olshansky
July 05, 2013
05-Jul-2013 12:55, Regan Heath пишет:
> On Thu, 04 Jul 2013 20:15:08 +0100, Dmitry Olshansky
> <dmitry.olsh@gmail.com> wrote:
>
>> 04-Jul-2013 19:00, Regan Heath пишет:
>>> In fact, you can generalise further.
>>>
>>> The meaning of if(x) is "compare the value of x with 0" (in C, C++,
>>> .. ).
>>>
>>> The value of x for a pointer is the address to which it points.
>>> The value of x for a class reference is the address of the class to
>>> which it refers.
>>>
>>> If D's arrays are reference types,
>>
>> They are not. It's a half-reference no wonder it has a bit of
>> schizophrenia now and then.
>
> True.  The struct which contains the ptr and length is actually a value
> type.  I think conceptually however we should be thinking of them as
> reference types, because.. the array struct is effectively a lightweight
> wrapper (adding length) around a reference type (ptr).
>
>>   then IMO they should exhibit the same
>>> behaviour.
>>>
>>
>> The behavior should be the most useful and since arr.length != 0 is
>> what 99% of time a programmer wants to check.
>
> IMO, the behaviour should be consistent.  If you code if (x) then the
> compiler will compare 'x' (not a property of x) to 0.  Doing anything
> else would be inconsistent and unexpected to anyone from a C background.

Then since slices compared to null by your logic means both ptr and length equal 0. Completely broken idea hence I'd simply propose to disable it.


-- 
Dmitry Olshansky
July 05, 2013
On Friday, July 05, 2013 11:01:17 TommiT wrote:
> On Thursday, 4 July 2013 at 19:15:09 UTC, Dmitry Olshansky wrote:
> > 04-Jul-2013 19:00, Regan Heath пишет:
> >> In fact, you can generalise further.
> >> 
> >> The meaning of if(x) is "compare the value of x with 0" (in C,
> >> C++, .. ).
> >> 
> >> The value of x for a pointer is the address to which it points.
> >> The value of x for a class reference is the address of the
> >> class to
> >> which it refers.
> >> 
> >> If D's arrays are reference types,
> > 
> > They are not. It's a half-reference no wonder it has a bit of schizophrenia now and then.
> 
> What do you mean by D's dynamic arrays being half-reference types? And what kind of "schizophrenia" do exhibit?

Okay. Take this function.

void foo(T)(T bar)
{
    bar.mutateMe();
}

If T is a reference type, then the argument passed to foo will be mutated. If T is a value type, it won't be. But with arrays, it depends. If you alter bar's length in any way, it won't have any effect on the array that you passed to foo. However, if you alter any of bar's elements, then it _will_ alter the array that was passed in. So, arrays are sort of a half-reference type rather than a reference type or a value type.

- Jonathan M Davis