May 29, 2015
On Friday, 29 May 2015 at 11:16:27 UTC, Mike wrote:
> But, if you'll forgive my ignorance, what is the primary motivation for migrating to a library AA?

- The current implementation uses runtime type information (TypeInfo) to compute hashes and compare keys. That's at least 2 virtual non-inlineable calls to lookup a value by an int key. Speedup is likely in the 1.5x-2x range.

- The runtime interface is incorrectly attributed.

- Small-key/value optimizations are hardly possible without statically knowing the types.
May 29, 2015
On Friday, 29 May 2015 at 11:17:00 UTC, Martin Nowak wrote:
> On Wednesday, 27 May 2015 at 17:16:53 UTC, IgorStepanov wrote:
>> Foo f;
>> f[5][3] = Foo(42); translates to
>>    f.opIndex!(true)(5).opIndex!(true)(3) = Foo(42);
>>
>> auto x = f[5][4]; translates to
>>    auto x = f.opIndex!(false)(5).opIndex!(false)(3);
>
> We shouldn't replace opIndexAssign though, b/c default construction + assignment is more expensive than constructing in-place.

Sorry, I meant
f.opIndex!(true)(5).opIndexAssign(Foo(42), 3);
May 29, 2015
On Friday, 29 May 2015 at 11:22:53 UTC, IgorStepanov wrote:
> Sorry, I meant
> f.opIndex!(true)(5).opIndexAssign(Foo(42), 3);

Added to the ER.
https://issues.dlang.org/show_bug.cgi?id=7753#c6
May 29, 2015
On Friday, 29 May 2015 at 12:52:29 UTC, Martin Nowak wrote:
> On Friday, 29 May 2015 at 11:22:53 UTC, IgorStepanov wrote:
>> Sorry, I meant
>> f.opIndex!(true)(5).opIndexAssign(Foo(42), 3);
>
> Added to the ER.
> https://issues.dlang.org/show_bug.cgi?id=7753#c6

Thanks, but unfortunately, writing enhacement request to bugzilla is equals to writing to /dev/null :)
I'll create a DIP about this, when I'll have a free time.
What do you want about this syntax? Maybe you may suggest a better solution?
May 29, 2015
On Friday, 29 May 2015 at 13:12:58 UTC, IgorStepanov wrote:
> Thanks, but unfortunately, writing enhacement request to bugzilla is equals to writing to /dev/null :)

No it's not, it keeps us from rediscussing the same stuff over and over.

> I'll create a DIP about this, when I'll have a free time.

As the amount of DIPs grows, DIPs become the new ER.
The problem is that this enhancement is of low priority and there is nothing you can do to change that, except for making a convincing case and a backward compatible implementation.

> What do you want about this syntax? Maybe you may suggest a better solution?

A separate opIndexCreate might be better, b/c it allows you to have a ref return for one and an rvalue return for the other function. It also allows to use those operands as polymorphic functions in classes.
May 29, 2015
On Friday, 29 May 2015 at 13:12:58 UTC, IgorStepanov wrote:
> What do you want about this syntax? Maybe you may suggest a better solution?

The discussion drifts a little OT, if we have opIndexCreate, then the library AA can be more compatible, but it still won't be a drop-in replacement.
May 29, 2015
On Friday, 29 May 2015 at 17:52:58 UTC, Martin Nowak wrote:
> On Friday, 29 May 2015 at 13:12:58 UTC, IgorStepanov wrote:
>> What do you want about this syntax? Maybe you may suggest a better solution?
>
> The discussion drifts a little OT, if we have opIndexCreate, then the library AA can be more compatible, but it still won't be a drop-in replacement.

We went a long way in this direction and if we don't come to the result yet, that, I think, we haven't thought-out plan.

I suggest you to answer to the following two question:
1. What way to transit to the new AA would be acceptable?
You rejects my way (and I could not continue to work in the winter), and AFAIR you principial objection was: "aaLiteral is non-@safe for the unsafe code and it is breakage". However, aaLiteral attributes hasn't checked by compiler, because it was used in e2ir. _d_assocarrayliteralTX is not @safe or pure, but aa can be used in @safe pure code. We may insert additional checks, see aaLiteral attributes, and raise deprecation message, if attributes are inacceptable.
If it is the last objection, we may repeat compiler-side part for the new AA template. Othrewice, lets invent another way.

2. What issues disallows us to implement full library AA? Except .stringof, .mangleof, and other compiler magic.
I see only two issues: opIndexCreate and building aa from literals.
May 29, 2015
On Friday, 29 May 2015 at 21:58:16 UTC, IgorStepanov wrote:
> I suggest you to answer to the following two question:
> 1. What way to transit to the new AA would be acceptable?

One that doesn't break any code, carefully deprecates necessary semantic changes, and provides an improved implementation.

> You rejects my way (and I could not continue to work in the winter), and AFAIR you principial objection was: "aaLiteral is non-@safe for the unsafe code and it is breakage".

The objection was too much code breakage for an inferior implementation.
https://github.com/D-Programming-Language/druntime/pull/934#issuecomment-66888409

> We may insert additional checks, see aaLiteral attributes, and raise deprecation message, if attributes are inacceptable.

Maybe we can hack around the attribute incompatibilities in the compiler, we'll have to add deprecations at some point anyhow.

> 2. What issues disallows us to implement full library AA? Except .stringof, .mangleof, and other compiler magic.
> I see only two issues: opIndexCreate and building aa from literals.

- error messages
- attributes
- literals (especially polysemous initializers, i.e. ubyte[ubyte] aa = [0:1, 1:2])
- implicit tail const conversion Val[Key] -> const(Val)[Key]
- lots of magic around making Key const
- delete aa[key]
- lots of other small details (grep for Taarray in src/expression.c)

This is a heavily used built-in type, we can't risk a rewrite that breaks lots of code.
May 30, 2015
On 5/29/15 4:41 PM, Martin Nowak wrote:
> On Friday, 29 May 2015 at 21:58:16 UTC, IgorStepanov wrote:
>> I suggest you to answer to the following two question:
>> 1. What way to transit to the new AA would be acceptable?
>
> One that doesn't break any code, carefully deprecates necessary semantic
> changes, and provides an improved implementation.

I suggest first we build a library AA that sits beside real AA, even if it doesn't . Then we create a test suite to prove that the library AA can be a drop in replacement. Then replace it :)

Put it in code.dlang or std.experimental. It's better to have code to play with and test than it is to do everything at once.

-Steve



May 30, 2015
On Friday, 29 May 2015 at 22:41:13 UTC, Martin Nowak wrote:
> On Friday, 29 May 2015 at 21:58:16 UTC, IgorStepanov wrote:
>> I suggest you to answer to the following two question:
>> 1. What way to transit to the new AA would be acceptable?
>
> One that doesn't break any code, carefully deprecates necessary semantic changes, and provides an improved implementation.
>
>> You rejects my way (and I could not continue to work in the winter), and AFAIR you principial objection was: "aaLiteral is non-@safe for the unsafe code and it is breakage".
>
> The objection was too much code breakage for an inferior implementation.
> https://github.com/D-Programming-Language/druntime/pull/934#issuecomment-66888409
>
>> We may insert additional checks, see aaLiteral attributes, and raise deprecation message, if attributes are inacceptable.

I recall a list of your demands.

------------------------------------------------------------
1. open addressing
2. efficient construction, insertion and assignment (no extra copies or postblits)
3. fully CTFEable (includes storing literals in the data segment)
4. type and attribute correctness
5. get's rid of TypeInfo methods (toHash, opEquals, tsize)
6. GC NO_SCAN for values
------------------------------------------------------------

1. It depends only on library AA implementation, not on dmd-druntime interaction.
2. This goal was achieved in my last AA version. Open addressing edition may get us troubles with it, but I think this troubles are solvable.
3. Storing CTFE literals was implemented in that implementation. Maybe not quite right, but the problem is also solvable.
4. This solution follows directly from template implementation.
5. Was done.
6. This problem is also solvable.

Now about backward compatibility:
AFAIR you pointed to the one breakage: the forced checking of attribute correctness.
I then entered into an argument with you, but I forgot, that the forced  attribute checking was disabled in the last edition:
Yes, aaLiteral gets attributes from the underlying code, and if AA constructor was unsafe, aaLiteral was unsafe too.
However, AssocArrayLiteralExp::toElem doesn't check the attribute correctness and constructing of unsafe or non-throwable AA from safe or throwable code was allowed.
Or I forgot about some other breakage cases?

>> 2. What issues disallows us to implement full library AA? Except .stringof, .mangleof, and other compiler magic.
>> I see only two issues: opIndexCreate and building aa from literals.
>
> - error messages
> - attributes
> - literals (especially polysemous initializers, i.e. ubyte[ubyte] aa = [0:1, 1:2])
> - implicit tail const conversion Val[Key] -> const(Val)[Key]
> - lots of magic around making Key const
> - delete aa[key]
> - lots of other small details (grep for Taarray in src/expression.c)
>
> This is a heavily used built-in type, we can't risk a rewrite that breaks lots of code.

>- error messages
Is it a significant problem? If compiler allows correct code, disallows incorrect code and gets a clear error messages there there is no problem, I think. Of cource, we will need to write pretty error messages, implement correct .stringof in dmd (to writting type name as V[K], not as AA!(K, V).

> - attributes
We will able to deprecate attribute violations in transitional version (with vtbl).

> - literals (especially polysemous initializers, i.e. ubyte[ubyte] aa = [0:1, 1:2])
Yes, this is the first main trouble.

> - implicit tail const conversion Val[Key] -> const(Val)[Key]
May be we may add "alias this"-es for all all those variants?
Something like ...
struct AA(K, V)
{
    alias getCKeyMval this;
    alias getMKeyCval this;
    alias getCKeyCval this;
    @property {
    ref AA!(const(K), V) getCKeyMval() { return *cast(typeof(return)*)&this; }
    ref AA!(K, const(V)) getMKeyCval() { return *cast(typeof(return)*)&this; }
    ref AA!(const(K), const(V)) getCKeyCval() { return *cast(typeof(return)*)&this; }
    }
}

> - lots of magic around making Key const
The most count of them may be solved without language modifying.

> - delete aa[key]
This case has gone one or two years ago.
Now for the following code...
int[int] aa;
delete aa[5];
... compiler writes me "Error: cannot delete type int"

> - lots of other small details (grep for Taarray in src/expression.c)
We should start to try to find and solve them.
As I see, we now we need only two language change requirements: opIndexCreate and AA literal overloading.
The rest of the problems can be identified at the stage of parallel operation of both implementations.