www.digitalmars.com         C & C++   DMDScript  

D - final - statement

reply "Immanuel Scholz" <digitals-mars kutzsche.net> writes:
Is there a final - statement in D? I saw it on the list of identifiers, but
not hint how to use it with classes...

final class X {..}    // ok?

class X : final Y {...}   // ok?

class X
{
  final int foo();  // ok?
  int foo() final;  // ok?
}

final MyClass c;  // ok?
final MyClass* c = createMyClass();   // ok?


Imi
Mar 12 2002
parent reply "Walter" <walter digitalmars.com> writes:
"Immanuel Scholz" <digitals-mars kutzsche.net> wrote in message
news:a6l6hd$n9u$1 digitaldaemon.com...
 Is there a final - statement in D? I saw it on the list of identifiers,

 not hint how to use it with classes...

 final class X {..}    // ok?

 class X : final Y {...}   // ok?

 class X
 {
   final int foo();  // ok?
   int foo() final;  // ok?
 }

 final MyClass c;  // ok?
 final MyClass* c = createMyClass();   // ok?

No, there isn't a final statement. I need to fix the doc.
Mar 12 2002
parent reply Immanuel Scholz <news kutzsche.net> writes:
Walter wrote:

 No, there isn't a final statement. I need to fix the doc.

too bad. Why there isn't one? I thought "final" is a good idea (since it offers compiler-optimizations) -- Immanuel Scholz, PGP: (Work 0x9216F1E7, Home 0x3B5DC02D)
Mar 12 2002
parent reply "Walter" <walter digitalmars.com> writes:
"Immanuel Scholz" <news kutzsche.net> wrote in message
news:a6m0h2$12ns$1 digitaldaemon.com...
 Walter wrote:

 No, there isn't a final statement. I need to fix the doc.

too bad. Why there isn't one? I thought "final" is a good idea (since it offers compiler-optimizations)

The compiler shouldn't need it to do the optimizations.
Mar 12 2002
parent reply Immanuel Scholz <news kutzsche.net> writes:
Walter wrote:

 
 "Immanuel Scholz" <news kutzsche.net> wrote in message
 news:a6m0h2$12ns$1 digitaldaemon.com...
 Walter wrote:

 No, there isn't a final statement. I need to fix the doc.

too bad. Why there isn't one? I thought "final" is a good idea (since it offers compiler-optimizations)

The compiler shouldn't need it to do the optimizations.

Yes. I remember the section in the draft... but I wanted to complain anyway: class foo { export int function_with_needs_to_be_fast_called (); } How to decide here whether the compiler can static link the function? I assume, the compiler can't decide and will link dynamic via vpt, because it could be overwritten within another dll, linked at runtime. However: class foo { export final int function_with_are_static_linked (); } This is good, because the compiler knows, that the function may not be overwritten anywhere. My second consideration about final is, that you can clearly state as a class designer, that a user MUST NOT overwrite some function: class base_class_for_all_other_classes { final long get_id(); } As example, this function must not be overwritten (either accidentally or intentional), since each gid should be calculated the same way. This provide a way to say clear design-decisions, IMHO much better than comments like: class base_class_for_all_other_classes { // I beg you, dear programmer, do not overwrite, please, please... long get_id(); } (If really somebody read documentation? ;) It is a really mess that within C++ you CAN overwrite non-virtual functions, but there are really no use of this bug, er, feature. I think it should be possible to get an invariant of subclassing, but it should be IMpossible, to violate this invariant. -- Immanuel Scholz, PGP: (Work 0x9216F1E7, Home 0x3B5DC02D)
Mar 13 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Immanuel Scholz" <news kutzsche.net> wrote in message
news:a6ndb2$1kam$1 digitaldaemon.com...

 How to decide here whether the compiler can static link
 the function? I assume, the compiler can't decide and will
 link dynamic via vpt, because it could be overwritten within
 another dll, linked at runtime. However:

 class foo
 {
   export final int function_with_are_static_linked ();
 }

 This is good, because the compiler knows, that the function
 may not be overwritten anywhere.

Agreed.
 My second consideration about final is, that you can clearly
 state as a class designer, that a user MUST NOT overwrite
 some function:

 class base_class_for_all_other_classes
 {
   final long get_id();
 }

 As example, this function must not be overwritten (either
 accidentally or intentional), since each gid should be
 calculated the same way.

Right! "final" is a good thing, why drop it?
Mar 13 2002
parent reply "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a6nr8m$1qrg$1 digitaldaemon.com...
 "final" is a good thing, why drop it?

The trouble with "final" was how it was used. To get efficiency, I'd run around marking everything not overridden as "final", i.e. everything at the bottom of the class heirarchy. Then, overriding a function means deleting "final" from its ancestor and adding it to the overriding function. A better way to achieve the same result is for the compiler to realize that nobody derives from class foo, therefore all its members are final for optimization purposes. This won't work for something intended to live in a library, but will for exe's. That's why I see the linker eventually merging into the compiler, so the compiler knows what the end result will be. The C++ way, where you take the "virtual" off of various functions, was in practice a disaster for me. There was always a case where some descended did a virtual derivation, and the wrong function would silently be called. This resulted in some of my worst bugs.
Mar 15 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a6tkgh$2tb2$1 digitaldaemon.com...

 The trouble with "final" was how it was used. To get efficiency, I'd run
 around marking everything not overridden as "final", i.e. everything at

 bottom of the class heirarchy. Then, overriding a function means deleting
 "final" from its ancestor and adding it to the overriding function.

final is not for the purpose of optimization - as you've stated for many times, it's the job of the compiler. final is used when you want to forbid the method from being overridden, or class from being inherited. Such cases happen quite often, why not provide a convenient way to control them? It's better than /* DON'T OVERRIDE THIS METHOD! */ anyhow...
Mar 15 2002
parent "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a6top4$31iu$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a6tkgh$2tb2$1 digitaldaemon.com...
 The trouble with "final" was how it was used. To get efficiency, I'd run
 around marking everything not overridden as "final", i.e. everything at

 bottom of the class heirarchy. Then, overriding a function means


 "final" from its ancestor and adding it to the overriding function.

times, it's the job of the compiler. final is used when you want to forbid the method from being overridden, or class from being inherited. Such cases happen quite often, why not provide a convenient way to control

 It's better than /* DON'T OVERRIDE THIS METHOD! */ anyhow...

It's not its purpose, you're right, but that's how it is used. It's how I used it, and how I've seen it used. (I'll probably add it in, though <g>.)
Mar 17 2002
prev sibling parent reply "Richard Krehbiel" <krehbiel3 comcast.net> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a6tkgh$2tb2$1 digitaldaemon.com...
 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:a6nr8m$1qrg$1 digitaldaemon.com...
 "final" is a good thing, why drop it?

The trouble with "final" was how it was used. To get efficiency, I'd run around marking everything not overridden as "final", i.e. everything at

 bottom of the class heirarchy. Then, overriding a function means deleting
 "final" from its ancestor and adding it to the overriding function.

 A better way to achieve the same result is for the compiler to realize

 nobody derives from class foo, therefore all its members are final for
 optimization purposes.

 This won't work for something intended to live in a library, but will for
 exe's. That's why I see the linker eventually merging into the compiler,

 the compiler knows what the end result will be.

So this means D will be bad for creating libraries? I don't think this is a good idea. I think you'd better have your language prepared to deal with the dumb linker for quite a while yet, and that means adding the "final" keyword. If you want to make your compiler smart enough, that's fine, but allow me to tell the compiler when I'm building a library. There's not a linker around that can decide when a class is final and inline it's small functions, the way some people (myself) hope it would work. Otherwise, you'll have us wishing for macros. (Oh, wait - I already do.)
Mar 17 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
"Richard Krehbiel" <krehbiel3 comcast.net> wrote in message
news:a72ou0$950$1 digitaldaemon.com...

 This won't work for something intended to live in a library, but will


 exe's. That's why I see the linker eventually merging into the compiler,

 the compiler knows what the end result will be.

So this means D will be bad for creating libraries? I don't think this is

 good idea.

 I think you'd better have your language prepared to deal with the dumb
 linker for quite a while yet, and that means adding the "final" keyword.

 you want to make your compiler smart enough, that's fine, but allow me to
 tell the compiler when I'm building a library.

I guess merging the linker with the compiler is the step to the right direction - Borland did it long ago with Pascal, and you can see the results now, build environment is much friendly than that of C. This, however, doesn't mean that D support for libraries is bad. It's just the compiler-linker is aware of every aspect of your library, and is able to make functions non-virtual and/or inline by itself. "final" is for other purposes, as I've stated in my previous post, and, well, seems like we'll see it quite soon in D.
Mar 17 2002