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

Re: Funny situation (was: Re: Serialization et al)



> > > You had a good start in that implementation, I just didn't have enough
> > > time to completely cover it this time. Some things were still off-base.
> >
> > My english isn't perfect. Off-base means ... ? Sub optimal?
> 
> Means missing the target, missing the goal (not by not going far enough,
> but by straying from it). I think this comes from baseball.
>
Ahh, well, perhaps. It wasn't like a "this is the way it's going to be",
more like "something sorta like this". The specifics, like the actual
methods to declare, were only listed to get an idea what objects of the
contained class should be able to do.

> > > I don't exactly see why it is a template. The entries should be
> > > abstracted as well, so no need to make this class generic, it will take
> > > entries of the abstract class.
> >
> > You lost me here. It will take entries of the abstract class? You mean
> > like it will "take" (i.e., contain) the abstract class for a file or a
> > directory? If you do, then, that's possible within the scheme.
> >
> > The reason the FileSystemEntityContainer is a template, is that there
> > are two basic kinds of file system entities (i.e., dirs and files), and
> > these two are kept separately in two *different* containers.
> 
> Why not a single container? This is a case of the composite container (I
> think this is the name, not sure) pattern. This pattern is for cases
> where you have a tree of items where nodes and leaves share a lot of
> functionality (nodes would be directory and leaves would be files, and
> they are almost the same). You simply make the node class inherit the
> leave class and have the pointer to the root of the tree be a pointer to
> a leave. The node class would add a few content manipulation methods
> (addEntry, removeEntry) and whatever else is specific to the node.
>
That's actually quite clever. Still, I don't like Directory being a
derivative of File. Directories are not files (atleast, not on all
OSes), and you don't do the same things to or with them.

Getting the size (or compressed size) of a file makes no sense for a
Directory. You can't open a directory. Or, well, actually you can
(getting a directory stream, which is very counterintuitive to me (the
name)), but the return type is not the same.

Some of the attribute flags (just one?) doesn't mean the same for a file
as for a directory.

File has 20 methods. The stuff I mention above makes up 5 of those.
That's one quarter of the interface of File that does not make sense for
Directory.

Also, whenever I'm passed a File pointer, I don't want to be wondering
(and in some cases having to check) wheter its really a Directory.

> > Of course, it would be possible to devise an interface and
> > implementation for FileSystemEntityContainer that would make it possible
> > for it to meet the requirements of both being a container for dirs and
> > files, without being a template. However, that would require
> > compromising compile time type safety in favor of runtime type safety.
> > This is bad both in terms of efficiency and bug tracking.
> >
> > FileSystemEntityContainer being a template isn't all that bad, as we'll
> > probably only be making two different instantiations of it (one for
> > File, and one for Directory).
> 
> It isn't that bad. Correct me if I'm wrong, but that means a file
> container won't be able to contain directories and vice-versa? And
> FileSystemEntityContainer isn't a directory itself?
>
Yes and yes.

> Consider this:
> 
> class File {
> public:
>   int open(...);
>   [ other File methods ]
> };
> 
> class Directory: public File {
> public:
>   [ implementation of inherited methods from File ]
>   int addEntry(File*);
>   int removeEntry(File*);
> };
>
All things that make sense for File doesn't make sense for Directory.

> This makes for one simple system. There could be a asDirectory() method
> to get a properly casted Directory* or a NULL if the File is really only
> a File (similar to the S_ISDIR macro applied to the POSIX structure
> equivalent to those classes, struct stat). Or dynamic_cast could be
> used.
>
Dynamic cast is *evil*. Atleast, it is in my world. Sometimes, you have
to use RTTI, but often enough, you don't. To me, its like a goto, just
with more proper utilizations.

To quote Bjarne Stroustrup (in an article about library design):

"The C++ class concept and type system is the primary focus for all C++
library design. The strengths and weaknesses [of this system] determine
the shape of C++ libraries. My main recommendation to library builders
and users is simple: don't fight the type system."

"However, not all checking can be done at compile time. Trying to do so
is a good design and implementation strategy, but if taken to excess it
can lead to inflexibility and inconvinience."

[About RTTI] "Was this facility added to encourage the use of runtime
type checking? No!" [Goes on to say it was for stopping vendor specific
solutions, and it does have it uses]

"The basic rule is as ever: Use static (compile-time checked) mechanisms
wherever possible - such mechanisms are feasible and superior to the
runtime mechanisms in more cases than most programmers are aware of."

Sometimes, you will want to iterate over only the files or only the
directories contained in a Directory. This is VERY ineffecient if those
two are put together. Of course, having them apart makes it a little
less effecient to iterate over all entries, but not nearly as badly.

Are you also suggesting moving functionality from
FileSystemEntityContainer to Directory? (I'm not sure) If you are, I
don't see the disadvantage of abstracting out the specific algorithm
used in a Directory derivative.

Am I totally missing the point here?

> Also, File and Directory themselves would only be abstract classes. File
> would have UnixFile, PakFile, ZipFile, and whatever else as childrens.
> Note that I blatantly reused the "PakFile" name for a different class,
> this clash would have to be fixed. The same would be done for
>
Actually, the name that is used is PakFileFile and PakFileDir. This
makes sense since a PakFile is a collection of something. UnixFile would
be ok, since Unix here would mean the Unix filesystem, which makes it up
for a collection of something. A file in a Zip-file would be a
ZipFileFile, as a Zip is a collection of something.

> 
> Simple API, maps quite nicely to the underlying concepts. 10% of the
> work, and easily fixable! ;-)
>
Here I have to disagree: The API is the same (Directory is not exposed).
Its not much easier to implement, and its less fixable, as there is less
abstraction. Its also more error prone, as you have to remember to check
the return type (or call AsDirectory()).

> > > There should be simply an abstract class with those methods as pure
> > > virtual, simple and straightforward.
> >
> > There is. FileSystemEntityContainer is both a template as well as an
> > abstract base class with all pure virtual methods. The template dictates
> > the interface, the pure virtual methods provide the implementation.
> 
> Yes, but can only contain one or the other of directories or file???
> What, each directory would have two FileSystemEntityContainer, one for
> the directories it contains and the other for the files it contains?
>
Yes. They are usually used apart, so having them apart makes sense. This
particular implementation is not exposed, so to clients, it won't
matter.

> You
> call that straightforward?
>
Why don't you find this to be so? Its perfectly intuitive to me...

> > > The LISP version, if it would be translated directly in C, would be
> > > recursive too, but why it is called iterative anyway is that a LISP
> > > compiler is normally smart enough to transform this into an iterative.
> > > C/C++ compilers don't optimize over function/method boundaries (except
> > > for inline stuff, of course).
> >
> > Isn't that a weakness in compilers rather than in the language of C/C++
> > itself? I get the hint that its more tricky implementing this in C/C++
> > (or compilers would do it), but still, I don't believe its impossible,
> > just very hard.
> 
> Yes, but there are some semantic requirements defined in the C++
> standard that prevents compilers from making all kinds of assumptions
> that could enable safe optimizations.
>
I've always wondered why compilers don't have options like "I promise
not to do this and that", and then the compiler would assume that you
haven't (giving you errors when you do, if it can check it).

Also, why nobody has thougth of creating #pragma's that means that this
or that specific variable or method or whatever doesn't do some specific
thing that it would otherwise be impossible for the compiler to know.

Those two things together should make C++ as optimizable as anything
else.

> My day job is in high performance computing, if I may recall you, and
> most amazingly, the reason a language that sucks like Fortran is so
> popular, is, err, *because* it sucks! The language is so primitive and
> so restrictive, while still mostly there and programmable (it *is* a
> pain in the ass, but not nearly as much as assembler, and a portable
> pain in the ass furthermore), that it is extremely optimizable!
>
I didn't know that. Worse is better ... :)

> My favorite example are pointers. Say you have a function that takes two
> int*. In C++, you simply cannot increment one of the int (not its
> pointer, but the int it points to) and assume the other didn't change,
> because they could both point to the same int! There is no such thing as
> pointers in Fortran, so compilers are free to assume one of the
> parameters is an invariant thru a loop and avoid doing any costly
> refetchs.
>
Hmm... That's smart. Must be annoying not to be able to pass by
reference, though.

> Even the best C/C++ compilers, like Kai's or Compaq's (previously
> Digital)
>
I believe Microsoft's is pretty good too.

> can't approach the level of performance many Fortran compilers
> can do. By the way, GCC/EGCS is not there at all when it comes to high
> performance computing (not enough support for things like vectors and
> specialized architectures and instructions).
>
Sadly so :(

> > I've noticed that when people really are trying to be rude over E-mail,
> > it'll be so blatantly obvious that its completely impossible to miss. It
> > usually goes something like "You suck", "man, you're a retard" or
> > "You're dumb as a door".
> 
> Yeah, that's a pretty good sign. :-)
> 
:)

There should be * * around that "are" there. My point is that people are
rarely very subtle over the internet when they don't like somebody.