July 12, 2012
On 12/07/2012 19:51, Andrei Alexandrescu wrote:
>> 2. Provide a class modifier that makes immutable(_) illegal, so the
>> class uses "logical const" instead of "physical const".
>
> I think this would be considerably trickier.
>

This is orthogonal to what we are dealing here.
July 12, 2012
On 2012-07-12 14:58:28 +0000, deadalnix <deadalnix@gmail.com> said:

> I think this is not a problem as big as it is stated.
> 
> Most of that code will be executed close to never, and 60Mb isn't a big deal for any modern computer, not even for most cell phones now.

60Mb was only with bindings to the most fundamentals parts of Cocoa. It scales linearly with the number of classes and functions you add bindings for. It's just crazy.

That's pretty much a moot point now though. The new approach, hacking the compiler, is so much better on so many levels that the old bridge looks like a joke now (even though it was impressive). I only wish I had time to dedicate to it. Perhaps next year I will.

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

July 12, 2012
On 7/12/2012 2:51 AM, Jonathan M Davis wrote:
> On Thursday, July 12, 2012 02:43:09 Walter Bright wrote:
>> A main motivation for going this route is to avoid breaking existing code.
>
> Except that it's _guaranteed_ to break code, because anything which relies on
> Object having opEquals, opCmp, toHash, or toString is going to break. We can
> provide an appropriate deprecation path to ease the transition, but this
> _will_ break code.

Which is why we'll be leaving those members in Object for the foreseeable future.


July 12, 2012
On Thursday, 12 July 2012 at 17:51:32 UTC, Andrei Alexandrescu wrote:
> On 7/12/12 1:40 PM, David Piepgrass wrote:
>> 1. Most importantly, the C++ template approach is a big pain for
>> large-scale systems, because in such systems you want to create DLLs/SOs
>> and C++ has neither a standard ABI nor a safe way to pass around
>> template instantiations between DLLs (in the presence of changes to
>> internal implementation details). Similar problems exist for D, yes?
>> It's a lot easier to define a standard ABI for classes than to solve the
>> cross-DLL template problem.
>
> The thing is, that can be done in an opt-in manner. People who want methods in the root of the hierarchy can define a root that defines them. But there's no way to opt out of inheriting Object. Basically it's nice to not force people to buy into a constrained environment without necessity.

But is the constrained environment we're talking about really all that constrained?

- 'const' is not overly harsh if the user has machanisms to make that mean 'logical const'.
- regarding the 5 vtable entries (destructor, toString, toHash, opEquals, opCmp), well, that's only 20/40 bytes per process, and maybe we don't need opCmp that much.

Although having these in Object seems constraining in one way, removing them is constraining in a different way: you can no longer provide collection classes for "any" object without involving templates.

Wait a minute, though. Keeping in mind the problem of DLL interoperability, and the constraints on using templated + many DLLs together, what if D introduced the feature that Go and Rust have, the ability to adapt any object to a compatible interface?

interface IComparable {
   bool opEquals(IComparable rhs);
   int opCmp(IComparable rhs);
}

class Foo { /* could contain anything */ }

So let's say we remove all the methods from Object, but we still want people to be able to make a collection of "any object", such as Foo, and pass this collection between DLLs safely. Moreover we want only be a single instance of the collection class, defined in a single DLL (so this collection cannot be a template class).

Since a class Foo does not declare that it implements IComparable, and it might not even contain opCmp() and opEquals(), we can't just cast to IObject. Not in the current D, anyway.

But now add interface adaptation from Go/Rust. Foo might not define opEquals and opCmp itself, but any client can add those via UFCS, and the standard library would probably define opEquals via UFCS as reference equality already. Thus it is possible for any client to pretend that any class implements IComparable, by adding the missing pieces (if any) and casting to IComparable.

July 12, 2012
On 2012-07-12 15:39, Steven Schveighoffer wrote:

> I think if we want a solution that allows old code to work, why not what
> Timon suggested? Have a base class for Object (RawObject was suggested)
> that does not implement the opFunctions.  It would still break code, but
> would be easy to fix (just specify your class derives from Object, not
> RawObject).

Wouldn't the default be to inherit from Object?

Like this:

class RawObject {}
class Object : RawObject {}
class Foo {} // inherits from Object by default.

Most people would not need to change anything, they can continue to use Object. If they want to avoid the methods declared in Object they need to explicitly inherit from RawObject.

-- 
/Jacob Carlborg


July 12, 2012
> we can't just cast to IObject.
Oops, I meant IComparable
July 12, 2012
On Thu, Jul 12, 2012 at 01:51:31PM -0400, Andrei Alexandrescu wrote:
> On 7/12/12 1:40 PM, David Piepgrass wrote:
> >1. Most importantly, the C++ template approach is a big pain for large-scale systems, [...]
> 
> The thing is, that can be done in an opt-in manner. People who want methods in the root of the hierarchy can define a root that defines them. But there's no way to opt out of inheriting Object. Basically it's nice to not force people to buy into a constrained environment without necessity.

Having a class RawObject as a superclass of Object is an equally good solution. Declare a class without a base class, and the base class defaults to Object.  Explicitly write "class MyClass : RawObject" and you get a class without the stuff in Object. If you want an entire hierarchy free of the stuff in Object, just write "class MyBaseClass : RawObject" and inherit everything from it.

This has the advantage of _not_ breaking any existing code, and the people who want to opt out of Object, can.


[...]
> >1. Provide a 'safe workaround' for const, for caching and lazy evaluation (implement it carefully to avoid breaking the guarantees of immutable)
> 
> We should explore this option in any case. At this point I'm starting to believe (a) we're doing the right thing by marginalizing the four methods aside from this issue, (b) caching is good for other things than this particular problem.
[...]

Please also remember that caching is only _one_ of the issues. Objects that exist over the network is another use case. Objects that are partially stored in (possibly remote) database. There are many other such cases. I hope we don't neglect these other cases by focusing only on caching.


T

-- 
Why are you blatanly misspelling "blatant"? -- Branden Robinson
July 12, 2012
On 2012-07-12 19:52, Michel Fortin wrote:

> I just don't have time to work on this right now -- I'm too busy working
> on other thing -- even though I'd like very much to work on that.

It would be so, so nice to have this finished and merged upstream.

-- 
/Jacob Carlborg


July 12, 2012
On Thursday, 12 July 2012 at 17:51:32 UTC, Andrei Alexandrescu wrote:
> On 7/12/12 1:40 PM, David Piepgrass wrote:
>> 1. Most importantly, the C++ template approach is a big pain for
>> large-scale systems, because in such systems you want to create DLLs/SOs
>> and C++ has neither a standard ABI nor a safe way to pass around
>> template instantiations between DLLs (in the presence of changes to
>> internal implementation details). Similar problems exist for D, yes?
>> It's a lot easier to define a standard ABI for classes than to solve the
>> cross-DLL template problem.
>
> The thing is, that can be done in an opt-in manner. People who want methods in the root of the hierarchy can define a root that defines them. But there's no way to opt out of inheriting Object. Basically it's nice to not force people to buy into a constrained environment without necessity.

+1

>> 4. Template bloat is no big deal on desktops but it becomes a bigger
>> problem as the target system gets smaller. Maybe some compromise should
>> be made to ensure D remains powerful and capable on small targets.
>
> I think virtuals are an equally, if not worse, problem in memory-constrained systems. The simple solution people choose for such - they use them judiciously. Here actually templates may be at an advantage because of their opt-in quality.

+1. Such seams give flexibility that otherwise would be extremely hard to achieve.

>> There were two proposals yesterday that I liked. Taken together, they
>> address all the problems that were raised with const functions in Object:
>>
>> 1. Provide a 'safe workaround' for const, for caching and lazy
>> evaluation (implement it carefully to avoid breaking the guarantees of
>> immutable)
>
> We should explore this option in any case. At this point I'm starting to believe (a) we're doing the right thing by marginalizing the four methods aside from this issue, (b) caching is good for other things than this particular problem.

+2 (Especially if it would be possible to redefine 'lazy', so that it would evaluate at most once.)
July 12, 2012
On Thursday, July 12, 2012 09:23:28 H. S. Teoh wrote:
> it's not fair to
> the community that the fate of such a vital component depends on the
> free time schedule of one person.

True, but it does happen all too often around here (e.g. Andrei with allocators and containers). The real problem is when the person working on it disappears (e.g. someone (Tomaz?) was working on a new std.xml which was supposedy coming along fairly well, but he hasn't posted about it (or anything, I think) since some time in 2010). Still, if the work on the AA redesign could be divided up among multiple individuals and appropriately coordinated, that would help.

- Jonathan M Davis