On Wednesday, 14 March 2012 at 23:51:30 UTC, H. S. Teoh wrote:
On Thu, Mar 15, 2012 at 12:20:43AM +0100, Jakob Bornecrantz
wrote:
[...]
struct AAver1(K, V)
{
K[] tbl; V[] tlb2; uint size;
}
struct AAver2(K, V)
{
K[] tbl; V[] tbl2; V[] optimizationTbl;
}
Would break if a AAver1 table was ever passed to code that
was compiled against a AAver2 table. In sort you could never
add anything to the AA struct. Without going in roundabout
ways of making sure you never access outside of any struct
version ever out there.
Or for that matter change how the internal tables are
populated by add and remove.
[...]
How is this different from any other templates in
druntime/phobos?
Its not, I at least like to see it being possible to keep a
stable ABI in druntime, and as such making it possible to
share inbuilt language features like AA across libraries,
phobos is a lost cause.
And FYI, the current AA implementation *already* suffers
from this problem, because the Range interface already
assumes a specific implementation behind the opaque pImpl
pointer (see object_.d -- it *duplicates* the struct
definitions from aaA.d and casts the void* into pointers to
those structs). If aaA.d were to change its implementation
today, the Range stuff in struct AssociativeArray would break
horribly.
The motivation behind my rewriting AA's is to fix this
schizophrenic mess. The internal aaA.d structs should *not*
be duplicated in object_.d, but currently they are. So there
are two options, either (1) we move everything back into aaA.d
(and introduce a whole bunch more void* pImpl and C-linkage
functions for the structs that Range support requires), or
(2) we move everything out of aaA.d.
Yes that is bad, I of course would like to see (2). I don't
feel that just because I wasn't around to hit people over
the head when this was introduced as reason for losing the
ability of D libraries, or making it even harder for people
to do them.
Personally, I feel the second option is better. If we want
to improve or add to AA's API, we can just change it in
object_.d. Key and value types are directly accessible, so
we never have to play around with typeinfos and pointer
arithmetic to do simple stuff.
If we go with the first option, every little change will
require changes to aaA.d, and trying to add new functionality
will constantly introduce new C-linkage functions in aaA.d,
new void* pImpl's in object_.d, with the associated hacks
using typeinfos (because Key/Value types are essentially
opaque to aaA.d, so you have to rely on typeinfos and pointer
arithmetic instead of letting the compiler figure it out for
you). This is very hard to maintain, and much more bug-prone.
I'm assuming you mean "changes to aaA.d and _object.d".
I'm glad you listed cons of doing it as a opaque pointer,
I don't agree completely that it will be that much more
difficult to maintain or be that much more buggy.
Yes the current one of doing it in DMD, _object.d and in
druntime is bad and can be improved. Did you see my response
to Don? What do you think of that?
Yes there will be a cost to doing it the second way, but
we as a language provider are taking that cost so that
our users don't have to take it via being locked to the
exact same druntime/compiler version between libraries.
Yes doing a stable ABI isn't easy and free, so I think we
need to weigh the pros and cons of supporting language
level primitives easily (for users) across library
boundaries. I think we should just htfu[1] and provide
this feature.
I just wanted to make sure people understand what they are
loosing and what this means. And that they should't have
any illusions of things just magically working. I don't see
me changing my view on thism I want this feature, if I don't
get sure I'll be sad and D will be less attractive to me but
it isn't the end of the world. I want to thank you again for
taking the time to explain everything to me and taking the
time to respond.
What I really want to get to is: Do we really want to do this?
Cheers, Jakob.
[1] http://www.youtube.com/watch?v=unkIVvjZc9Y