Re: [Vala] Final / Sealed classes in Vala



On Fri, 2009-09-25 at 20:52 +0200, Jan Hudec wrote:
But in the end it comes down to language design and in
vala's case, enforcing compile time errors instead of deferring
critical
errors and misbehavior at runtime. (just like abstract classes are
not
instantiatable, even if they don't contain abstract or pure virtual
methods)

Programmers should be given enough rope to shoot themselves in the
 feet.

Abstract classes are different thing, because they prevent
 instantiating them by mistake. But do you think you would inherit a
 class by *mistake*?

On the other hand I had problems with things being declared private
 when they were needed outside the class many times, either by mistake
 or because the author didn't realize they were actually needed by the
 user. 

The idea of a sealed/final class can be used to mean a few things:

 * It can be part of a contract between a library-writer and an
application developer.  For example, the library contains a great deal
of classes, some of which are never intended to be derived for whatever
reason.  Classes might even be sealed by default (because it is harder
to go from not restrictive to less restrictive in an API, for example,
but not the inverse), but I'd call that an abuse.

 * It can be used to make guarantees with known-fragile code by
preventing the subclassing of trees that contain virtual methods that
should never be overridden.  I'd argue that this usage constitutes a
"patch" on the code, a "TODO" sign saying "I need to be better-written."
But it's then an option.  By this argument, it can also speed up code
development by enabling more fragility, though.

 * It can be used to say "there is no reason that you should ever
subclass this," and make that an official statement.  Simple as that.

Perhaps the best benefit is that you can _write_ sealed by default,
because it's easy to remove later on if you find out you do in fact need
it to be unsealed (say your users do need to subclass it, or whatever).
But it is much harder to not write sealed and realize "I should have
sealed that," because once you release an API that is not
permission-restricted, if you permission-restrict it, you break the
assumptions that code that used the API previously made.  That's why we
write "private" by default in class definitions.

In other words, it's an extension of the concept of encapsulation.
Instead of hiding class implementation details, we're just hiding the
whole class by making it "sealed".  Though, if there are libraries that
do things that way, they should have a way to create something
analogous.

As a fictitious example, let's say that a library has an HTTP class, it
is sealed, and it is derived from a tree of abstract classes from Socket
down to TCPApplication.  You should still be able to derive from the
same tree as the HTTP class so that you can implement FTP, or telnet, or
whatever.  At that point, if you wanted to write a WebRequest class or a
SOAP class that implemented protocols on top of HTTP or in a raw
fashion, you'd use the HTTP class (or maybe its parent class,
TCPApplication) as a private variable.  This also lends itself to the
idea that you can design your new class to be portable to any underlying
transport protocol implementation.  Maybe you can use SOAP (with long
latency) over Internet mail, or (more likely) a raw socket or a telnet
server, just because you aren't limited to the HTTP connector anyway.

So, there is a real use-case (and I'm sure it can be pretty easy to
think of more).  It just shouldn't be overused, lest we have problems
going too far.  If a library sealed every single class, that would limit
its usefulness considerably.  I think what we do currently, effectively
sealing no classes, is just the other end of the spectrum.

Again, though, this is a lower-level discussion, I think.  Does glib and
glib-gobject have maintainers anymore, anyone know?

        --- Mike

-- 
Blog:  http://mike.trausch.us/blog/
Misc. Software:  http://mike.trausch.us/software/

“The greater danger for most of us lies not in setting our aim too
high and falling short; but in setting our aim too low, and achieving
our mark.” —Michelangelo



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]