POV-Ray : Newsgroups : povray.general : CSDL: C-like Simulation Description Language Server Time
7 Aug 2024 05:15:14 EDT (-0400)
  CSDL: C-like Simulation Description Language (Message 46 to 55 of 65)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Warp
Subject: Re: CSDL alpha 1 release
Date: 23 Jan 2002 18:57:16
Message: <3c4f4ddc@news.povray.org>
Christopher James Huff <chr### [at] maccom> wrote:
: And how else am I supposed to get a copy?

  Needing to do this with just mere base class pointers is clear sign that
you haven't designed your object hierarchy well.

  For example in our project I have implemented a bitvector which has some
functionalities needed in our libraries that std::vector<bool> doesn't have,
and which implements the copy-on-write technique for efficiency (these
bitvectors are copied a lot and modified very seldom). (If you don't know
what the copy-on-write technique means, just ask.)
  It either allocates the bit array dynamically or uses a user-given memory
location (kind-of placement new functionality).
  Of course this is a very different situation than yours, but now I'm getting
to my point: Things are allocated dynamically, copied, freed and so on, but
all inside the bitvector class. The bitvector handles everything.
  From outside I only need to use instances of this bitvector. I can assign
this bitvector, give it as a value parameter, return it by value, everything
that can be done by value (ie, no pointers) and it still is efficient, no
matter how large the bitvector is. It itself takes care of everything related
to pointer and dynamic allocation *inside* itself, privately. I don't see what
it does from outside, and I don't even want to see it.
  That's the whole point of modularity.

  One of the main principles of modularity is that if a module reserves a
resource (eg. memory), the same module (moreover, with just a few exceptions,
the same instance of the module which made the allocation) takes care of
freeing this resource and that no leaks happen.
  A module which allocates a resource and then returns a handle to this
resource to the outside, to the upper level and *hopes* that it gets freed
somewhere else, is almost always a sign of a really, really bad module design.

  Designing a good, working and secure object hierarchy is not something to
be done lightly, not even in medium to small sized programs. If you make
a good design, you'll gain a lot later.

:> : Having to return void pointers and cast them to the 
:> : correct types.
:>   I never have to do this. It also breaks badly modular OO design.

: Which is why I don't like it.

  One of the reasons why so many people love Java and hate C++ is that
Java simply doesn't support "bad" features from C, while C++ does (for
compatibility). Usually people who learn C++ come from C, where they learnt
really bad habits, which they can't get rid of in C++ for long, long time
(unless they have very good teachers). The good thing in Java is that it just
doesn't have these bad ways of doing things, so you just can't use them.
  Personally I dislike Java because in my opinion it has gone just way too
far with its limitation of "bad" features (which really aren't). Java has
many good things, and many of the limitations are things that I don't really
miss (eg. "kludgy" pointer casts), but on the other hand it misses things
that are really useful in C++ and helps a lot in implementing modularity
(even though some of these things *might* be possible to use in a wrong way,
I don't, so removing them is a true limitation to me).

: In C++, if you have a derived object that implements a certain method 
: not in its base class, but only have a base-class pointer to it, you 
: can't call that method unless you cast to that type.

  I don't want to sound rude, but you should really study object orientedness
principles in more detail.
  In an object-oriented hierarchy a module/function which takes a base class
reference/pointer is only interested in the base class interface. It does
not know, and moreover it doesn't even want to know, if there's really a
derived class behind that reference or pointer. It just sees a base class
and period (the derived class *is a* base class by all practical means); it's
not interested in anything else.
  If this kind of module/function needs to know more, it's usually a sign
of bad OO design.

: I've been avoiding using references

  Bad idea. You should really use references instead of pointers whenever
possible (and *const* references whenever possible).
  It's much easier to shoot yourself in the foot with pointers than with
references.
  It's not a syntax thing (syntax is usually the least of your worries). It's
a higher level thing.

: And I have to use dynamic allocation because the objects are going to 
: stick around for an indefinite amount of time, they can't be deleted 
: when the function goes out of scope.

  That's where you should make a module (ie a class) to handle this and not
just leave the pointers float around and hope that they will sometime be
freed by something. That sounds a lot like what you want to do is a
container class (ie. a class that contains objects and takes care of creating
and destroying them).

:> : Templates.
:> 
:>   What about them?

: They make my head hurt. ;-)

  Templates are incredibly versatile. In fact, it has been proven that
templates (with C++ types) alone are a turing-strong language. You can
make loops, lists, trees, conditionals, etc. which are evaluated at
compilation time (ie. you can, for example, make a list of constant int
values, add values at the end of the list, remove values from the list,
join lists, traverse a list etc, all at compilation time).
  (This is actually a whole field of research, called "generative
programming".)

  Templates have saved me a lot of work in many places.

: They're fine unless there's a problem. If there's a problem, it's often 
: very difficult to figure out what it is from the error messages.

  Templates have their problems, and error messages are one of them (the
other is that no compiler yet has implemented export templates, which means
that your object files will be HUGE if you use lots of big templates).
  However, you get used to them with experience. (Also with experience you
just usually avoid the error messages completely :P )

-- 
#macro M(A,N,D,L)plane{-z,-9pigment{mandel L*9translate N color_map{[0rgb x]
[1rgb 9]}scale<D,D*3D>*1e3}rotate y*A*8}#end M(-3<1.206434.28623>70,7)M(
-1<.7438.1795>1,20)M(1<.77595.13699>30,20)M(3<.75923.07145>80,99)// - Warp -


Post a reply to this message

From: Warp
Subject: Re: CSDL alpha 1 release
Date: 23 Jan 2002 19:05:22
Message: <3c4f4fc2@news.povray.org>
Lutz Kretzschmar <lut### [at] stmuccom> wrote:
: Why? That's the standard way of cloning an object (standard in the
: sense of widely used). Simply invoke the copy constructor on the
: current instance. How else would you write a Clone() or Copy()
: function?

  It may be a standard way in Java. In C++ it's a standard way of getting
sure that you will get a high chance of a memory leak (specially if there's
more than one person using the library which does that). (And no, the way
Java handles object allocation and freeing is not always good.)

  As I already said in another article, one of the basic principles of
modularity is that if a module (class, whatever) allocates a resource, the
same module takes care that the resource gets freed (and gets freed only
once).
  Making a module which allocates a resource, returns a handle to this
resource outside and hopes that someone else will hopefully free it somewhere,
is a *really* bad module design (and OO design).

  The whole class hierarchy should be designed so that this kind of copying
is not needed (ie. not in this way). This usually can be done much better
and much more nicely (and specially much more safely).
  Making efforts for a good design now can save you a lot of trouble later.

-- 
#macro N(D)#if(D>99)cylinder{M()#local D=div(D,104);M().5,2pigment{rgb M()}}
N(D)#end#end#macro M()<mod(D,13)-6mod(div(D,13)8)-3,10>#end blob{
N(11117333955)N(4254934330)N(3900569407)N(7382340)N(3358)N(970)}//  - Warp -


Post a reply to this message

From: Warp
Subject: Re: CSDL alpha 1 release
Date: 23 Jan 2002 19:11:30
Message: <3c4f5132@news.povray.org>
Thorsten Froehlich <tho### [at] trfde> wrote:
: Apart from this, without dynamic_cast<>, multiple inheritance would be far
: more difficult to use.

  I have used multiple inheritance. I haven't needed dynamic_cast<> (nor
any other cast for that matter).

  dynamic_cast<> is one of those casts which you just shouldn't use (ok,
not that; what I mean is that you should almost never use downcasting;
downcasting is generally bad).
  The other casts you should never use are const_cast<> (used just as a hack
for dealing with old bad-designed libraries) and reinterpret_cast<> (which
is mainly used for low-level hacking).

-- 
#macro M(A,N,D,L)plane{-z,-9pigment{mandel L*9translate N color_map{[0rgb x]
[1rgb 9]}scale<D,D*3D>*1e3}rotate y*A*8}#end M(-3<1.206434.28623>70,7)M(
-1<.7438.1795>1,20)M(1<.77595.13699>30,20)M(3<.75923.07145>80,99)// - Warp -


Post a reply to this message

From: Thorsten Froehlich
Subject: Re: CSDL alpha 1 release
Date: 23 Jan 2002 19:11:34
Message: <3c4f5136@news.povray.org>
In article <chr### [at] netplexaussieorg> , 
Christopher James Huff <chr### [at] maccom>  wrote:

> I'm not sure quite what you mean...though if no compilers support it
> yet, I guess it doesn't really matter.

Imagine

list<MyClassA> lista;
list<MyClassB> listb;

where MyClassA and MyClassB have no common base.

Compilers right now just copy the code for all functions.  Later the linker
will only strip unused functions, but that is all.

However, if the compiler collects the requirements (the misc operator member
functions, i.e. constructors, destructors, comparison operators) in advance,
it could exploit this advance knowledge.  For example then the function to
insert an element would be the same, it would only have to know what class
the user wishes to insert and then call the constructor of that class
dynamically.

To understand why this isn't possible without "export" is that the compiler
only looks at one translation unit (a source file) at a time.  The "export"
keyword basically tells the compiler that there is shared code.  Of course,
onyl could simply parse all translation units and treat them as one, but
doing so would require so much memory for a mid-sized project, we cannot
dream about for decades to come! *

    Thorsten

* Just imagine that with optimizations, CW needs over 100 MB of memory for
some source files in POV-Ray.  Now consider there are 100 of those files,
and you fill 5-10 GB quickly!  Of course, POV-Ray can be considered a
"small" project compared to most commercial applications these days...

____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trfde

Visit POV-Ray on the web: http://mac.povray.org


Post a reply to this message

From: Thorsten Froehlich
Subject: Re: CSDL alpha 1 release
Date: 23 Jan 2002 19:26:21
Message: <3c4f54ad@news.povray.org>
In article <3c4f3a4c@news.povray.org> , Warp <war### [at] tagpovrayorg>  wrote:

> Thorsten Froehlich <tho### [at] trfde> wrote:
> : return new SubClass(*this);
>
>   Uh. That hurts my eyes.

So I assume you don't read "The C++ Programming Language" from Stroustrup?

Well, at least you will have to stop reading it now that I direct your
attention to p. 424  (in the 3rd edition paperback of the book) aka section
15.6.2 "Virtual Constructors".  After all, you should really not hurt your
eyes intentionally! ;-)

    Thorsten

PS: I am sorry, but it looks like you lost this argument...

____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trfde

Visit POV-Ray on the web: http://mac.povray.org


Post a reply to this message

From: Thorsten Froehlich
Subject: Re: CSDL alpha 1 release
Date: 23 Jan 2002 19:45:35
Message: <3c4f592f$1@news.povray.org>
In article <3c4f5132@news.povray.org> , Warp <war### [at] tagpovrayorg>  wrote:

>   I have used multiple inheritance. I haven't needed dynamic_cast<> (nor
> any other cast for that matter).
>
>   dynamic_cast<> is one of those casts which you just shouldn't use (ok,
> not that; what I mean is that you should almost never use downcasting;
> downcasting is generally bad).
>   The other casts you should never use are const_cast<> (used just as a hack
> for dealing with old bad-designed libraries) and reinterpret_cast<> (which
> is mainly used for low-level hacking).

Not sure if you can access it, but if you have access to the
/povray/tools/povdocgen/ directory in Perforce, could you explain to me how
to design classes so that they can contain and access an HTML (or XML to be
more general) parse tree - or (almost) any parse tree for that matter -
without having to use casting?

Or, to be more precise, you have two kinds of classes that have nothing in
common expect that they can be turned into text and back (thus those
functions are in the common base class).

However, one class only stores plain text while the other class has
attributes and stores no plain text at all. Yet objects can be nested inside
the class with attributes, which needs to store a list with any number of
objects of either class.

So one either uses casting or one class which contains a list and a string
and only uses either.  The first way is the proper design, the second is the
worst possible design.

    Thorsten

____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trfde

Visit POV-Ray on the web: http://mac.povray.org


Post a reply to this message

From: Lutz Kretzschmar
Subject: Re: CSDL alpha 1 release
Date: 24 Jan 2002 03:16:01
Message: <kagv4ukggo8ht4b09dsr08ff1kou8j335k@4ax.com>
Hi Warp, you recently wrote in povray.general:

>   It may be a standard way in Java. 
I wouldn't know, I've never written any. I've been doing C++ the last
7 years.

>   Making a module which allocates a resource, returns a handle to this
> resource outside and hopes that someone else will hopefully free it somewhere,
> is a *really* bad module design (and OO design).
Generally, I agree, but not in this case. And you failed to answer my
question. How do create a copy of an object to which you have a base
class pointer. As Thorsten said, since there are no virtual
constructors, you can't do it any other way. The design of the module
has nothing to do with this. The way the return value (the new object)
is handled is part of the module design. To make sure there are no
leaks.

> The whole class hierarchy should be designed so that this kind of copying
> is not needed (ie. not in this way). 
Very funny. There is no amount of design that can avoid this.

> Making efforts for a good design now can save you a lot of trouble later.
Now that I agree with :-)

- Lutz
  email : lut### [at] stmuccom
  Web   : http://www.stmuc.com/moray


Post a reply to this message

From: Ole Laursen
Subject: Re: Licensing, Was: Re: CSDL Update
Date: 24 Jan 2002 03:30:57
Message: <87hepc9mms.fsf@bach.composers>
Christopher James Huff <chr### [at] maccom> writes:
> >   3. Demand that all use of foobar-0.1 comply with the new license.
> > 
> > As long as you're only doing 1 & 2 there's no problem (well, depending
> > on your point of view there might be some moral problems, and people
> > are likely to complain...), but you can't legally do 3.
> 
> If I understand things properly, #3 is legal if the old license 
> specifically stated that the license could be changed, so anyone using 
> the software has warning.

Hm, I wouldn't be too sure - I don't think it would stand in court.
But I don't really know, fortunately I'm not a lawyer. :-)

> But I worry about people *not* using it because it is GPL...some people 
> apparently don't like GPL, which is why I'm looking on information about 
> licensing.

Ah, see. I felt like that once too, but since I switched to Linux,
I've changed my mind. Richard Stallman's arguments begin to make sense. :-)
I'm beginning to like the fact that some of my code perhaps will be
able to persuade others to release their software as free software,
just like it was the case with me.

> If someone is willing to invest the time/money to make a product that 
> uses CSDL, I would have nothing against them charging for their product 
> or withholding the source code for their work, as long as they make any 
> changes/enhancements to CSDL available. People will only buy it if it is 
> better than the free stuff, and if the developer makes something better, 
> I'll thank them.

Follow your heart. :-)

But I think it would be wise to choose a GPL-compatible license.

-- 
Ole Laursen
http://sunsite.dk/olau/


Post a reply to this message

From: Alessandro Coppo
Subject: Re: CSDL alpha 1 release
Date: 24 Jan 2002 04:17:25
Message: <3c4fd125@news.povray.org>
Warp wrote:

>   It may be a standard way in Java. In C++ it's a standard way of getting
> sure that you will get a high chance of a memory leak (specially if
> there's more than one person using the library which does that). (And no,
> the way Java handles object allocation and freeing is not always good.)
> 
>   As I already said in another article, one of the basic principles of
> modularity is that if a module (class, whatever) allocates a resource, the
> same module takes care that the resource gets freed (and gets freed only
> once).
>   Making a module which allocates a resource, returns a handle to this
> resource outside and hopes that someone else will hopefully free it
> somewhere, is a *really* bad module design (and OO design).
> 
>   The whole class hierarchy should be designed so that this kind of
>   copying
> is not needed (ie. not in this way). This usually can be done much better
> and much more nicely (and specially much more safely).
>   Making efforts for a good design now can save you a lot of trouble
>   later.
> 

Well, the whole thing about garbage collection, reference counting, etc. 
etc. is just meant for NOT bothering about these details. I am working in 
Java since 2000 (and in C++ since 1990..) and I find myself 10 times more 
productive by just calling clone() on an object to create a copy than 
messing around with templetazied smart pointers, idioms to ensure correct 
destruction etc. etc.

ANY modern language (Java, C#, Perl, Python) and some not so modern 
(LISP...) have AT L:EAST reference counting.

Bye!!!
        Alessandro Coppo
        a.c### [at] REMOVE_MEiolit


Post a reply to this message

From: Warp
Subject: Re: CSDL alpha 1 release
Date: 24 Jan 2002 07:12:05
Message: <3c4ffa14@news.povray.org>
The main problem with downcasting is that it destroys abstraction quite
effectively.
  The whole idea of having a base class is abstraction: A base class describes
a general set of objects (in a more or less abstract way), and every inherited
class is by definition a base class as well.
  This means that if a function/method takes a base class handle (handle =
reference or pointer), this function/method is at the same abstraction level
as the base class itself. That is, this function/method works for *every*
object which has been inherited from the base class (the function/method
doesn't need to know any inherited object type and still work with them).
You can create new classes inherited from the base class (or from its children
classes), and this function/method will work fine with them.

  Now, if this function/method performs downcasting and relies on it in order
to function properly, this abstraction is effectively broken. Now you are
saying that this function/method works just for this, this and that inherited
object, and nothing else. If you later want to add a new inherited class,
you'll have to modify this function/method in order to support the new class
(and this might not always be even possible if you don't have access to its
source code). This is not very modular.
  If there's a functionality which is specific to a certain class, that
functionality should be implemented in that class. If several classes with
a common base class have similar functionalities (but which are implemented
in a different way), then there should be an abstract way of calling this
functionality in the base class.
  It's always better to do "downcasting" with a virtual function call instead
of doing it "by hand".

  (Yes, I know, there might be hundreds of exceptions to this generic rule,
but I have noticed in my work that they really are *exceptions*, and that they
are not common at all.)

-- 
#macro M(A,N,D,L)plane{-z,-9pigment{mandel L*9translate N color_map{[0rgb x]
[1rgb 9]}scale<D,D*3D>*1e3}rotate y*A*8}#end M(-3<1.206434.28623>70,7)M(
-1<.7438.1795>1,20)M(1<.77595.13699>30,20)M(3<.75923.07145>80,99)// - Warp -


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.