August 09, 2009
Walter Bright, el  9 de agosto a las 13:29 me escribiste:
> D has a number of subtle problems (performance and semantic) that arise when arrays are resized. The solution is to separate resizeable array types from slices. Slices will retain the old:
> 
>    T[] slice;
> 
> syntax. Resizeable arrays will be declared as:
> 
>    T[new] array;
> 
> The new expression:
> 
>    new T[10]
> 
> will return a T[new].
> 
> T[new] will implicitly convert to T[], but not the other way.
> 
> slice.length will become read-only.
> 
> Under the hood, a T[new] will be a single pointer to a library defined type. This library defined type will likely contain three properties:
> 
>     size_t length;
>     T* ptr;
>     size_t capacity;
> 
> The usual array operations will work on T[new] as well as T[].
> 
> Doing this change will:
> 
> 1. fix many nasties at the edges of array semantics
> 
> 2. make arrays implementable on .net
> 
> 3. make clear in function signatures if the function can resize the array or not

What about writing a DIP? ;)

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
VECINOS RESCATARON A CABALLITO ATROPELLADO
	-- Crónica TV
August 09, 2009
On 2009-08-09 16:29:21 -0400, Walter Bright <newshound1@digitalmars.com> said:

> D has a number of subtle problems (performance and semantic) that arise when arrays are resized. The solution is to separate resizeable array types from slices. Slices will retain the old:
> 
>     T[] slice;
> 
> syntax. Resizeable arrays will be declared as:
> 
>     T[new] array;
> 
> The new expression:
> 
>     new T[10]
> 
> will return a T[new].

I have nothing against the concept of container, but I dislike like the syntax. Is this really better than Array!T ?


> T[new] will implicitly convert to T[], but not the other way.
> 
> slice.length will become read-only.

All fine by me.


> Doing this change will:
> 
> 1. fix many nasties at the edges of array semantics

Unfortunatly, not all. Solving them all could be done with unique semantics (unique slices can be expanded with no side effect).


> 2. make arrays implementable on .net
> 
> 3. make clear in function signatures if the function can resize the array or not

Unique and ref unique slices would be perfectly fine for that (assuming slices can be resized when unique).

But I know, unique isn't easy to implement to fit all the use cases we'd like to solve. I'm just sharing a dream.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

August 09, 2009
Michel Fortin wrote:
> But I know, unique isn't easy to implement to fit all the use cases we'd like to solve. I'm just sharing a dream.

We explored unique at length, and trying to make it work would render the rest of the language nearly unusably complex.
August 09, 2009
Walter Bright wrote:

>> But I know, unique isn't easy to implement to fit all the use cases we'd like to solve. I'm just sharing a dream.
> 
> We explored unique at length, and trying to make it work would render the rest of the language nearly unusably complex.

I've heard 'unique' mentioned on this group now and then. What does it mean in the context of programming languages?

-- 
Michiel Helvensteijn

August 10, 2009
On Sun, 09 Aug 2009 14:21:31 -0700, Walter Bright <newshound1@digitalmars.com> wrote:

> bearophile wrote:
>>> 2. make arrays implementable on .net
>>  I don't care of such thing. dotnet already has C# and C# is probably
>> better than D, and it's similar anyway. So I don't think people will
>> use D on dotnet. So even if creating a D for dotnet can be positive,
>> I don't want D2 to change its design to allow a better implementation
>> on dotnet.
>
> Even if you're correct that D.net is pointless, and I don't agree with that assessment, I think the problems implementing D arrays on .net will show up elsewhere in attempts to support other targets. So I think it's a "canary" issue rather than a .net one.

But (IIRC) it's not actually a canary. .NET has slices and there's no 'self-contained' implementation problem. The issue was that the .NET library wasn't written with slices (.NET, D or otherwise) in mind, so conversions to/from slices were required.
August 10, 2009
Mon, 10 Aug 2009 01:56:35 +0200, Michiel Helvensteijn wrote:

> Walter Bright wrote:
> 
>>> But I know, unique isn't easy to implement to fit all the use cases we'd like to solve. I'm just sharing a dream.
>> 
>> We explored unique at length, and trying to make it work would render the rest of the language nearly unusably complex.
> 
> I've heard 'unique' mentioned on this group now and then. What does it mean in the context of programming languages?

Unique reference is a reference which is statically known to be the only reference to the underlying data.  They have some interesting properties:

- Modification of underlying data does not cause side effects
- Can be implicitly cast to immutable
- Can be implicitly cast to mutable

They prove to be rather tricky both to specify and to implement though.
August 10, 2009
"Andrei Alexandrescu" <SeeWebsiteForEmail@erdani.org> wrote in message news:h5ndt0$1blj$1@digitalmars.com...
> bearophile wrote:
>> Walter Bright:
>>> Under the hood, a T[new] will be a single pointer to a library defined type. This library defined type will likely contain three properties:
>>
>> I have another question: are there some performance penalities in using such arrays for normal random access operations?
>
> One extra indirection, usually nearby.
>
> Andrei

If the size and capacity get added to the begining of the memory block containing the data, only an extra offset is needed. The compiler could emit "mov eax, [esi*4 + 8]" or something. Look ma, no extra indirection :)

In fact, this is what .NET does as well, if I'm not mistaken. But then, .NET always has an extra indirection because of the movable GC stuff, right?

L. 

August 10, 2009
== Quote from bearophile (bearophileHUGS@lycos.com)'s article
> Walter Bright:
> > Under the hood, a T[new] will be a single pointer to a library defined type. This library defined type will likely contain three properties:
> I have another question: are there some performance penalities in using such
arrays for normal random access operations?
> Bye,
> bearophile

import std.stdio, std.perf;

final class TNew {
    uint* foo;
    uint length;

    this(uint size) {
        foo = (new uint[size]).ptr;
        length = size;
    }

    ref uint opIndex(uint index) {
        return foo[index];
    }
}

void main() {
    auto pc = new PerformanceCounter;

    uint[] array = new uint[1];
    pc.start;
    foreach(i; 0..100_000_000) {
        array.ptr[0]++;
    }
    pc.stop;
    writeln("Direct:  ", pc.milliseconds);

    auto tnew = new TNew(1);
    pc.start;
    foreach(i; 0..100_000_000) {
        tnew[0]++;
    }
    pc.stop;
    writeln("Indirect:  ", pc.milliseconds);
}

Results:

Direct:  226
Indirect:  229
August 10, 2009
Lionello Lunesu wrote:
> 
> "Andrei Alexandrescu" <SeeWebsiteForEmail@erdani.org> wrote in message news:h5ndt0$1blj$1@digitalmars.com...
>> bearophile wrote:
>>> Walter Bright:
>>>> Under the hood, a T[new] will be a single pointer to a library defined type. This library defined type will likely contain three properties:
>>>
>>> I have another question: are there some performance penalities in using such arrays for normal random access operations?
>>
>> One extra indirection, usually nearby.
>>
>> Andrei
> 
> If the size and capacity get added to the begining of the memory block containing the data, only an extra offset is needed. The compiler could emit "mov eax, [esi*4 + 8]" or something. Look ma, no extra indirection :)

I wish too. The problem is that when you resize the array, the control block will not refer to the adjacent chunk.


Andrei
August 10, 2009
bearophile Wrote:

> grauzone:
> 
> > I see two things a dotnet implementation of D could have over native D: - better garbage collector (the D one barely does its job...)
> 
> The dotnet GC is probably better than the current D GC, but I think it's designed for mostly movable objects. Currently most (or all) D objects are pinned (they can't be moved around in memory), so I don't know if the dotnet GC will do much good.
> D needs a GC designed for its peculiar characteristics. And I believe D will also need some extra semantics to allow the creation of such efficient half-movable half-pinned GC (I have explained such ideas one time in the past).
> 
> Bye,
> bearophile

I just finished reading about Bartosz's early entry about the shared qualifier and how it could lead to per-thead memory heaps (as only shared allocations should use the shared heap). This means the GC can maintain different heaps per thread, and perform collection locally without pausing the world, and the entire heap can just be trashed when the thread exits.

I think it could be much more efficient than a moving GC (as maintaining different shared heaps and moving memory between them is a slow process). I am really tempted to modify my custom GC to do just that heh.