On 06/02/2013 10:44 PM, Jonathan M Davis wrote:
On Sunday, June 02, 2013 12:37:38 Andrei Alexandrescu wrote:
On 6/2/13 9:59 AM, Manu wrote:
I've never said that virtuals are bad. The key function of a class is
polymorphism.
But the reality is that in non-tool or container/foundational classes
(which are typically write-once, use-lots; you don't tend to write these
daily), a typical class will have a couple of virtuals, and a whole
bunch of properties.

I've argued if no dispatch is needed just make those free functions.
_Everything_ in a class is supposed to be overridable, unless inherited
and explicitly "final"ized. It's sort of a historical accident that
things got the way they are. But in D we know better because we have the
module-level privacy model and UFCS. So we should break clean from history.

There are four problems with that:

1. Very few programmers think that way. The normal thing in most every OO
language is to put all of the functions on the class, so pretty much no one is
going to make them free functions. Do you really expect people to put
properties (what would have been getters and setters in other languages)
outside the class? It's not going to happen. And by default, everyone takes a
performance hit as a result (folks like Manu and Don wcare about that
performance hit more than many of us, but it's still there).
...

Yup.

2. The class' functions are no longer encapsulated inside the class. For some
programmers, this is a big deal. They want all of the class' functionality on
the class where it's easy to find. Having UFCS makes using free functions less
of a problem, but many programmers will absolutely hate the idea of putting
their non-virtual functions outside of the class, so they won't do it, and
they (and everyone using their code) will end up with virtual functions when
the functions shouldn't be virtual.


This is 1. again. (The unit of encapsulation in D is a module.)

3. In many cases, putting a function outside of the class is a royal pain.
This is particularly true with templated classes. If you have

class C(T)
{
    private T _var;
}

and you want a property to give you var, you end up with something ugly like

@property auto var(U)(U this_)
     if(is(U V == C!W, W))
{
     return this_._var;
}

Do you really expect many programmers to be able to pull off complicated is
expressions like that? _I_ have to look it up every time I use it. Sure, using
free functions might work in simple cases, but it starts falling apart when
you have to deal with stuff like templated types.


1. Just do

@property auto var(T)(C!T this_){ return this_._var; }

2. The is-expression is not that complicated. The latest release finally fixes the issue that you needed to specify a redundant identifier to make it work:

@property auto var(U)(U this_)if(is(U==C!T,T)){ return this_._var; }


4. It causes more ambiguities and compilation errors. If a function is on the
class, it always wins. If it's a free function, then you potentially have
ambiguities due to overload sets. Making sure that the function takes the
exact type significantly reduces the problem, but someone else could easily
create a function with the same signature which now conflicts with the one
which is effectively supposed to be a member function.
...

Well, yes, but I think this will not be a huge problem in practise.
(The private symbol clash stupidity may exacerbate the problem when it occurs though.)

I wouldn't mind if the default changed. (But I currently cannot update my compiler anyway, because of hard-to-reduce forward reference bugs.)

Reply via email to