July 03, 2013
On 07/03/2013 07:53 PM, TommiT wrote:
> On Wednesday, 3 July 2013 at 14:33:02 UTC, bearophile wrote:
>> [..]
>
> I think it's a good idea to have [:] literal for associative arrays
> since there's [] literal for dynamic arrays.
>
> But I would expect [] to mean "empty dynamic array", not null. And the
> same for [:]. This is how I'd expect things to work:
>
> int[] nullArray;
> assert(nullArray is null);
>
> int[] emptyArray = [];
> assert(emptyArray !is null);
>
> int[string] nullAA;
> assert(nullAA is null);
>
> int[string] emptyAA = [:];
> assert(emptyAA !is null);
>
> Reasoning by extrapolation:
> int[] arr = [1, 2, 3]; // Array of 3 ints
> int[] arr = [1, 2]; // Array of 2 ints
> int[] arr = [1]; // Array of 1 ints
> int[] arr = []; // Array of 0 ints (not null)

+1.
July 03, 2013
On 07/03/2013 08:43 PM, TommiT wrote:
> On Wednesday, 3 July 2013 at 18:10:42 UTC, bearophile wrote:
>> TommiT:
>>> But I would expect [] to mean "empty dynamic array", not null. [..]
>> [..]
>>
>> This means you have to keep "null" in the language to represent an
>> empty associative array, because someone somewhere will surely want a
>> literal that avoids memory allocations. So lot of people will keep
>> using null, and the coding situation is improved about zero.
>
> Okay, I didn't realize an empty array would need to allocate.

Not necessarily if you allow the runtime to share the pointer for all empty arrays.
July 03, 2013
On 07/03/2013 08:10 PM, bearophile wrote:
> ...
>
> This means you have to keep "null" in the language to represent an empty
> associative array, because someone somewhere will surely want a literal
> that avoids memory allocations. So lot of people will keep using null,
> and the coding situation is improved about zero.
> ...

It would be improved.

Excerpt from my code:

private static Variant[VarDecl] parseContext(void[] mem,FunctionDef fd){
    // ...
    Variant[VarDecl] r;
    // (stupid built-in AAs)
    assert(fd !is null);
    r[cast(VarDecl)cast(void*)fd]=Variant(null);
    r.remove(cast(VarDecl)cast(void*)fd);
    // ...
}

That code using an allocating [:] literal:

private static Variant[VarDecl] parseContext(void[] mem, FunctionDef fd){
    // ...
    Variant[VarDecl] r = [:];
    // ...
}

Is there currently a better way to initialize AAs?
July 04, 2013
On 7/3/13 10:31 AM, Dicebot wrote:
> On Wednesday, 3 July 2013 at 16:55:59 UTC, bearophile wrote:
>> ...
>
> Has sounded convincing enough for me. Anything that enforces stronger
> typing is big win in my opinion.

typeof(null) has quite a few interesting properties. It's the closest type to the bottom of all types (we don't have an actual bottom type), and it subtypes many other types as mentioned.

Introducing yet another type works against that nice uniformity and is yet another arbitrary little thing that people who learn the language would need to know about.


Andrei
July 04, 2013
On 07/04/2013 02:28 AM, Andrei Alexandrescu wrote:
> On 7/3/13 10:31 AM, Dicebot wrote:
>> On Wednesday, 3 July 2013 at 16:55:59 UTC, bearophile wrote:
>>> ...
>>
>> Has sounded convincing enough for me. Anything that enforces stronger
>> typing is big win in my opinion.
>
> typeof(null) has quite a few interesting properties. It's the closest
> type to the bottom of all types (we don't have an actual bottom type),
> and it subtypes many other types as mentioned.
>
> Introducing yet another type works against that nice uniformity

What is that nice uniformity?

> and is yet another arbitrary little thing that people who learn the language
> would need to know about.
>...

A lot less arbitrary than having to initialize AAs into an empty state by adding and removing a mapping.

Also, I think [] should have a singleton type as well. Currently it is a void[] with special implicit conversion rules.
July 04, 2013
On Thursday, 4 July 2013 at 00:52:13 UTC, Timon Gehr wrote:
> Also, I think [] should have a singleton type as well. Currently it is a void[] with special implicit conversion rules.

+1
July 04, 2013
On 7/3/13 5:52 PM, Timon Gehr wrote:
> On 07/04/2013 02:28 AM, Andrei Alexandrescu wrote:
>> On 7/3/13 10:31 AM, Dicebot wrote:
>>> On Wednesday, 3 July 2013 at 16:55:59 UTC, bearophile wrote:
>>>> ...
>>>
>>> Has sounded convincing enough for me. Anything that enforces stronger
>>> typing is big win in my opinion.
>>
>> typeof(null) has quite a few interesting properties. It's the closest
>> type to the bottom of all types (we don't have an actual bottom type),
>> and it subtypes many other types as mentioned.
>>
>> Introducing yet another type works against that nice uniformity
>
> What is that nice uniformity?

That it "is the closest type to the bottom of all types" and "subtypes many other types as mentioned" :o).

>> and is yet another arbitrary little thing that people who learn the
>> language
>> would need to know about.
>> ...
>
> A lot less arbitrary than having to initialize AAs into an empty state
> by adding and removing a mapping.

Could be a function call. I find it unnecessary to just add new notation for every single little thing.

> Also, I think [] should have a singleton type as well. Currently it is a
> void[] with special implicit conversion rules.

Agreed.


Andrei
July 04, 2013
On Wednesday, July 03, 2013 22:00:39 Andrei Alexandrescu wrote:
> > A lot less arbitrary than having to initialize AAs into an empty state by adding and removing a mapping.
> 
> Could be a function call. I find it unnecessary to just add new notation for every single little thing.

True, but we should probably at least add something to the AA implementation to do this, since a function at that level can create an AA that's empty without having to add and remove an element. And actually, I might as well open an enhancement request for that:

http://d.puremagic.com/issues/show_bug.cgi?id=10535

- Jonathan M Davis
July 04, 2013
On Wednesday, 3 July 2013 at 16:55:59 UTC, bearophile wrote:
> deadalnix:
>
>> Why not simply [] ? After all, an array is just a very simple type of hashmap, with the identity as hash function.
>
> In a language it's very often handy for different data types to have different textual representations and different literals.
>

[] can be int[] or foo!bar[], so you'll have to justify why it is specifically good to make the difference in this case, while it is generally not needed.
July 04, 2013
On Wed, 03 Jul 2013 19:10:40 +0100, bearophile <bearophileHUGS@lycos.com> wrote:
> Telling apart the literal for an empty array from the literal of a empty but not null array is a bad idea that muds the language. And thankfully this currently fails:
>
> void main() {
>      int[] emptyArray = [];
>      assert(emptyArray !is null);
> }

As this comes up often you're probably aware that there are people (like myself) who find the distinction between a null (non-existant) array and an empty array useful.

Granted, it can complicate code but only if you want the distinction, in all other cases you should be checking array.length == 0 which is true for empty and null arrays.

Also, there are ways to get around the issue which all involve having a separate record of whether something exists or not - perhaps by placing items in a associative array and using 'contains' or having a separate existence boolean but they're all band aids over the issue of not having an actual reference type.

The humble char* pointer can represent null (non-existent) , "" empty, and "value" and I would find it useful if string could do the same, consistently (there are edge cases where arrays change from empty to null and vice-versa).

Tommi's suggestion that all empty arrays share a common pointer is a good one and more or less solves the "it has to allocate memory" complaint.

So, that just leaves arguments against complexity or arguments against the whole concept of null/empty being useful.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/