 |
 |
|
 |
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On Sat, 21 Feb 2004 22:26:59 -0500, Christopher James Huff
<cja### [at] earthlink net> wrote:
>In article <403814c4$1@news.povray.org>, "Tek" <tek### [at] evilsuperbrain com>
>wrote:
>
>> Well, I know a good argument against it. So good in fact that it's the reason
>> why every games programmer I know doesn't use operator overloading: It hides
>> processing.
This might be a 'learning' problem if you aren't aware of the
operators 'hidden' complexity.
>So do functions.
Yes, same problem here. There's no correlation between length of
function name and complexity.
If you call a Trace() function you should know why.
May be to write a trace record to a log file, may be to start a render
that will be finished some months later.
>[...]
>> Of course, for less speed critical stuff like describing POV scenes, I'd
>> wholeheartedly support it. But I'm just saying there *is* a good argument
>> against it.
May be, but it isn't speed.
For example, I have rewritten POV-Ray's core using VECTOR, COLOUR and
some other classes (with appropriate operators).
It was as fast as the original version but shorter and IMHO much more
readable.
The macros required to do trivial colour/vector arithmetic are
'information hiding' in the worst sense. They blow up source code and
add visual noise which makes it sometimes almost impossible to see
what's going on.
OK, I'll stop now ;-)
>I still haven't heard one yet.
--
Andreas
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> >> Well, I know a good argument against it. So good in fact that it's the
reason
> >> why every games programmer I know doesn't use operator overloading: It
hides
> >> processing.
>
> This might be a 'learning' problem if you aren't aware of the
> operators 'hidden' complexity.
My point is that a+b takes a different length of time according to the types of
a and b, where as MyMatrixAddFunction(a,b) takes the same length of time always,
plus you can search for it to see where it's executed in the code, plus you can
stick a nice big comment on the prototype of it saying "//avoid calling this
unless really necessary, it's very slow" so that anyone who doesn't know how to
add these two things has to look up the function prototype and read the comment
and reconsider the code they're writing.
I'm not trying to suggest the source looks nicer with more function calls, it
certainly doesn't. I'd even say I like operator overloading a lot, it's
extremely useful in high-level programming applications. I'm merely saying that,
in practice, it makes it easier to write code that is much more complex to
execute than it is to read or write. This is both it's strongest and weakest
point.
> The macros required to do trivial colour/vector arithmetic are
> 'information hiding' in the worst sense. They blow up source code and
> add visual noise which makes it sometimes almost impossible to see
> what's going on.
As I said, I support using + for vectors since that's what it will compile to.
Although I don't really see your point about visual noise, function calls
certainly make it harder to write clearly readable code but since it's harder
all it takes is more effort. Programming isn't about making things easier for
the programmer, it's about making the end result better. In application software
or high level programming these two ideas are very compatible, but in time
critical stuff like game engines people like me have to give ourselves headaches
trying to optimize out one cycle in a render loop in order to improve the
performance of the game. Operator overloading hinders us in this quest.
Damn that made me sound so cool...
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Christopher James Huff <cja### [at] earthlink net> wrote:
> I am. I definitely would want operator overloading. I've never seen a
> good argument against it...
Ask Java worshippers. They know. ;)
I personally am all for operator overloading in the same way as you,
and it's one thing why I hate Java so much.
> > but interfaces are obsolete.
> > If you want to make an "interface", just make an abstract class.
> Interfaces are not obsolete. As for abstract classes...what are you
> talking about?
Interfaces are obsolete of you can make abstract classes. And why
wouldn't you (unless you want to make the language so that it does
not support virtual functions, which would limit its OO capabilities
by a whole lot).
A class is abstract if it has pure virtual functions (that is,
the class does not implement the virtual function(s) and thus cannot
be instantiated because of this; it can only be used through
inheritance so that the derived class implements the virtual
function(s) in question).
If every member function it has is purely virtual, then it's basically
the same thing as an interface. (This is how "interfaces" are done in C++
if you *really* need to make one.)
> > They are necessary, believe me... ;)
> Sorry, but I don't. I've never accidentally tried to access a private
> member.
That's right. *You*. But that's ok only for as long as you don't
distribute that library of yours containing public member variables...
Someone will inevitably use it in the wrong way and his code can then
break with an updated version of the library.
> They do serve a documentation purpose
That's not their purpose at all. Public and private parts have clear
maintainability, abstraction and safety purposes.
If you can't use the library in the wrong way (ie. the compiler does
not allow you to), then you will not use it in the wrong way.
> but IMO if a language has
> them, they should be defined in a separate place, with only the public
> interface in a header file.
Well, that's just a question of implementation of the interpreter/compiler.
If you can implement the interpreter so that the private part does not need
to be specified at the same place as the public part, good thing. (In C++
this is not possible for technical reasons, but in an interpreted
scripting language it may very well be possible.)
> But for POV, this would be too restrictive
> and complex, IMO.
What do you mean "restrictive"?
That's like saying #local is too restrictive. It doesn't make sense.
The private part of a class has the same visibility purpose as for
example #local has: It's safer to use #local whenever possible than
always using #declare.
> > I would even go so far that member variables are always private (ie.
> > you *can't* make them public).
> I wouldn't care for this. Think of vector member access...vec.x, vec.y,
> etc...vec.x() just adds more visual noise.
If you read my article completely I suggested adding support for calling
member functions without parentheses (supposing they don't take parameters).
There's nothing problematic with that.
--
#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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Tek <tek### [at] evilsuperbrain com> wrote:
> i.e. when you compile a+b, you expect it to compile to a simple add instruction,
> and these days most processors can do vector maths so I'd certainly support it
> being used for them. The problem is if you've defined your own type of data that
> has a "+" function, you incur the cost of a function call invisibly in your
> code. This is a very bad thing for time-critical applications like computer
> games. Things like this make optimising an absolute nightmare.
This may have been true 10 years ago.
Current compilers can usually optimize the overhead (eg. the function
call) away completely (supposing the operator function is inline).
If you make a class which uses operator overloading for simple tasks
(such as adding two internal values together) you should definitely
make them inline, after which the compiler will be able to optimize
all the overhead away.
For example, suppose you have this (in C++):
class MyInt
{
int value;
public:
MyInt(int init=0): value(init) {}
int operator+(const MyInt& rhs) const { return value+rhs.value; }
};
Now if you do something like this:
MyInt a=1, b=2, c;
c = a+b;
I would be very surprised if the code generated by a modern compiler
would be any different from the code which it would generate if you
replace the MyInt class with:
typedef int MyInt;
PS. In fact, I just tested this with gcc. I added the following
method to the MyInt class for easier usage:
operator int() { return value; }
and then made a code like this:
int foo()
{
MyInt a=1, b=2, c;
c = a+b;
return c;
}
Using the MyInt class or typedeffing MyInt to int resulted in identical
assembler code (when using optimizations):
.LLFB3:
!#PROLOGUE# 0
!#PROLOGUE# 1
retl
mov 3, %o0
This is sparc asm, and if we "translate" it back to C++ it means
the same thing as:
int foo()
{
return 3;
}
So using a class with operator overloading did not ask any overhead
*at all* to the code.
--
plane{-x+y,-1pigment{bozo color_map{[0rgb x][1rgb x+y]}turbulence 1}}
sphere{0,2pigment{rgbt 1}interior{media{emission 1density{spherical
density_map{[0rgb 0][.5rgb<1,.5>][1rgb 1]}turbulence.9}}}scale
<1,1,3>hollow}text{ttf"timrom""Warp".1,0translate<-1,-.1,2>}// - Warp -
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> This may have been true 10 years ago.
But I wasn't programming games 10 years ago.
> Current compilers can usually optimize the overhead (eg. the function
> call) away completely (supposing the operator function is inline).
Couldn't compilers inline functions 10 years ago?
Anyway, my point isn't just the function call overhead, it's the fact that it's
not an operator internally supported by the compiler with a bunch of rules, it's
a series of instructions of unspecified length elsewhere.
> If you make a class which uses operator overloading for simple tasks
> (such as adding two internal values together) you should definitely
> make them inline, after which the compiler will be able to optimize
> all the overhead away.
Well, it can lose the function call overhead, but not the overhead of it being a
function (i.e. several instructions) rather than a simple instruction (which is
really my point).
What I'm saying is I want "+" to produce the same amount of assembler code
whenever I use it.
> For example, suppose you have this (in C++):
Aha! but you'd never define an object for a type inherently supported by the
compiler, only for types which require something more complex. So you end up
with "+" becoming different amounts of compiled code depending on the context in
which it's used. This makes it harder to optimise code, since it is harder to
keep track of where the more complex + functions are being invoked.
Plus when someone is writing the code if they have to call
PerformReallySlowAndComplicatedAddition( a, b ) rather than a+b it tends to make
people more aware of what they're doing. It doesn't completely solve the problem
of writing optimised code, I'm just saying it makes it easier to keep track of
what's actually going on at the lowest level.
> So using a class with operator overloading did not ask any overhead
> *at all* to the code.
I think you've missed my point, I'm not saying operator overloading does
anything different to function calls, I'm saying addition functions for two
matrices are different to addition functions for the processor's inbuilt types,
and it is useful when optimising to keep track of this difference.
Operator overloading is great if you want to code at a higher level without
being bogged down by thinking about what's happening at the lowest level, but
when optimising code you want to do the opposite! Heck, if were even remotely
feasible we'd write everything in assembler...
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>>I wouldn't care for this. Think of vector member access...vec.x, vec.y,
>>etc...vec.x() just adds more visual noise.
>
> If you read my article completely I suggested adding support for calling
> member functions without parentheses (supposing they don't take parameters).
> There's nothing problematic with that.
Eiffel does this...
(Can be slightly confusing at times... but then, so can most things!)
Not sure what you do about vec.x := 7... (But then, for certain objects
it might be that you can't change one attribute without changing another
as well... can't think of a good example right now...)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Tek <tek### [at] evilsuperbrain com> wrote:
> Well, it can lose the function call overhead, but not the overhead of it being a
> function (i.e. several instructions) rather than a simple instruction (which is
> really my point).
The only alternative to operator overloading is to use a member function.
So how is that any different?
> > For example, suppose you have this (in C++):
> Aha! but you'd never define an object for a type inherently supported by the
> compiler, only for types which require something more complex. So you end up
> with "+" becoming different amounts of compiled code depending on the context in
> which it's used. This makes it harder to optimise code, since it is harder to
> keep track of where the more complex + functions are being invoked.
You missed my point completely.
I just gave a simple example and wanted to point out that using operator
overloading does not add any overhead whatsoever to regular function calls.
If you want to make, for example, a rational number type (which contains
two integers), then it doesn't matter if you use it with operators or with
regular member function calls: Using operators is not any slower.
> Plus when someone is writing the code if they have to call
> PerformReallySlowAndComplicatedAddition( a, b ) rather than a+b it tends to make
> people more aware of what they're doing.
So you are saying that even if the addition would be extremely fast you
still should not use operator overloading? Why?
Using operators makes the code cleaner and easier to read with complex
expressions.
(This is IMHO a true problem in Java. You can't make in Java things like
"a = b + c*(d*c-e);" with your own defined type.)
> Operator overloading is great if you want to code at a higher level without
> being bogged down by thinking about what's happening at the lowest level, but
> when optimising code you want to do the opposite! Heck, if were even remotely
> feasible we'd write everything in assembler...
If you don't know what operator+() does with the type you are using,
then you should seek another job, IMHO.
If you are making speed-critical code then you should know your tools.
--
#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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> IMHO this comes down to 'pov ain't oo' - I don't think anyone denies
> that oo capabilities in pov wouldn't be at the very least interesting,
> but that's not the issue....
POV sure ain't OO. No doubt about it ;-)
(...unless you start getting into an argument about what OO "is"... *sigh*)
Question: what IS the issue? (Maybe I'm just slow...)
Andrew @ home on Mozilla.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <403897c7$1@news.povray.org> , "Tek" <tek### [at] evilsuperbrain com>
wrote:
> Couldn't compilers inline functions 10 years ago?
Not as well, no.
> Anyway, my point isn't just the function call overhead, it's the fact that
> it's not an operator internally supported by the compiler with a bunch of
> rules, it's a series of instructions of unspecified length elsewhere.
There is no such difference.
> Well, it can lose the function call overhead, but not the overhead of it being
> a function (i.e. several instructions) rather than a simple instruction (which
> is really my point).
No, there won't be additional instructions if a function is inlined. For
any (not ten year old) compiler the overhead of inlining a function will be
exactly zero compared to direct insertion of the code.
Thorsten
____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trf de
Visit POV-Ray on the web: http://mac.povray.org
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Christopher James Huff <cja### [at] earthlink net> wrote:
> Pass everything by reference
That can be problematic.
Suppose you have something like this:
class ItemContainer
{
private:
Int numberOfItems;
public:
...
Int size() { return numberOfItems; } // <- returns a reference
...
};
...
ItemContainer container;
// add things to 'container'
Int foo = container.size(); // <- gets a *reference*
foo -= 100; // Ooops! The container breaks badly!
The thing is that in principle the code is not doing anything malign
on purpose. It's only natural that you take eg. the size of the container
to a variable and then use this variable for example as a loop counter
(eg. to go through all the items in the container).
The big problem is that since your variable is actually a reference
to the original 'numberOfItems' variable, you'll end up breaking the
container.
I don't know enough about Java to know how this problem is avoided
there.
--
#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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Andrew C on Mozilla <voi### [at] dev null> wrote:
> Question: what IS the issue? (Maybe I'm just slow...)
If I'm not completely mistaken, I think that the basic issue here
is which OO properties POV-Ray's scripting language would benefit from
and which would be unnecessary.
--
#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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> I just gave a simple example and wanted to point out that using operator
> overloading does not add any overhead whatsoever to regular function calls.
I never said it did.
Oh dear, oh dear, I seem to have confused you. I'll try to explain:
What I said is that if you have a + between two ints it compiles to less code
than if you have a + you've defined as an overload operator *for a more complex
type*.
i.e. the code looks the same, but it does more stuff (because the data it's
operating on is more complex). This is *good* from an OO point of view, because
you don't need to know about the implementation of the object in order to use
it, but bad from an optimisation point of view, because you do need to know
about the implementation in order to be able to use it *efficiently*.
> Using operators makes the code cleaner and easier to read with complex
> expressions.
So what if it's easier to read? A good programmer can deal with code that's hard
to read, it's good if it's readable but not if you've lost some information you
might want.
> If you don't know what operator+() does with the type you are using,
> then you should seek another job, IMHO.
> If you are making speed-critical code then you should know your tools.
Right, lets say your product ships in two weeks time, and you've discovered that
the physics guy who got sacked last week was a moron. Hey, it happens. You need
to go through his code and find everywhere that he's performing a matrix*vector
multiply, in order to replace it with a more efficient piece of code.
How do you do that?
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> > Anyway, my point isn't just the function call overhead, it's the fact that
> > it's not an operator internally supported by the compiler with a bunch of
> > rules, it's a series of instructions of unspecified length elsewhere.
>
> There is no such difference.
Okay, remove the word "elsewhere" and you might see what I mean.
> > Well, it can lose the function call overhead, but not the overhead of it
being
> > a function (i.e. several instructions) rather than a simple instruction
(which
> > is really my point).
>
> No, there won't be additional instructions if a function is inlined. For
> any (not ten year old) compiler the overhead of inlining a function will be
> exactly zero compared to direct insertion of the code.
ffs, I know that! I know what inline does! I'm talking with the premise that you
won't write a function to do something you can already do in one line of code.
i.e. if anyone, anywhere, ever writes a function:
add(a,b)
{
return a+b;
}
that person should be dragged out into the street and shot*. So, ON THAT
PREMISE, if you have decided to write an inline function there will be an
"overhead of it being a function (i.e. several instructions) rather than a
simple instruction", by which I mean you have decided to write a function that
is more than one instruction.
I just explained that *really* badly yet again...
What I'm saying is, quite simply, we like to make a distinction between "+" and
any more elaborate function. Because doing so prevents people writing lines like
a = b + 3*(c-d), which looks perfectly innocent, but could be a major
bottleneck.
I'm not saying overload operators are a bad thing, I'm just presenting the
reasons why we don't generally use them in game coding. I think for simple types
which are well suited to the compiler you could define some more (like vectors),
but I'd still make a distinction between that and a significantly greater amount
of processing.
We like the clunkier syntax *because* it is harder to use and requires more
thought from the programmer. In our situation this is a good thing.
--
Tek
www.evilsuperbrain.com
*I bet someone's now going to come up with a perfectly good reason why they
might do this, but it's 5:20am and I can't think of one!
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Warp" <war### [at] tag povray org> wrote in message news:4038a07d@news.povray.org...
> Andrew C on Mozilla <voi### [at] dev null> wrote:
> > Question: what IS the issue? (Maybe I'm just slow...)
>
> If I'm not completely mistaken, I think that the basic issue here
> is which OO properties POV-Ray's scripting language would benefit from
> and which would be unnecessary.
Well the original issue was me saying "I want to do some OO-style pov code. Has
anyone done this before?". Although the thread seems to have drifted away from
that... :)
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Tek <tek### [at] evilsuperbrain com> wrote:
> What I said is that if you have a + between two ints it compiles to less code
> than if you have a + you've defined as an overload operator *for a more complex
> type*.
Actually, that's not always so.
In my example the + between the two class instances generated no code
at all, while a + between two ints may generate an addition asm code
(when the compiler can't do it at compile time)... :)
> i.e. the code looks the same, but it does more stuff (because the data it's
> operating on is more complex). This is *good* from an OO point of view, because
> you don't need to know about the implementation of the object in order to use
> it, but bad from an optimisation point of view, because you do need to know
> about the implementation in order to be able to use it *efficiently*.
You need to know about how a library function is implemented anyways,
regardless of how it is called, if you want to make as optimal code as
possible.
If you are using class instances you know that calling the operator+
for them will (potentially) generate a function call. If you don't know
that, you don't have business making highly-optimized hacker code.
Besides, it's true what they say that optimization should firstly be
made at algorithmical level. Only when the algorithms and data containers
are as efficient as possible and the code still is too slow, then one should
try to look what is taking so long.
Optimizing a function call away won't help you if your algorithm is
a thousand times slower than a completely different algorithm which makes
the same thing. :)
> > Using operators makes the code cleaner and easier to read with complex
> > expressions.
> So what if it's easier to read?
If you make write-and-forget code then it doesn't matter. However, if
you make code which potentially needs to be enhanced/fixed in the future
(and specially by someone else than you), then clarity is a big plus.
> A good programmer can deal with code that's hard
> to read
Yes, after cursing you and your family for making it so hard to read.
--
#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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Tek <tek### [at] evilsuperbrain com> wrote:
> We like the clunkier syntax *because* it is harder to use and requires more
> thought from the programmer. In our situation this is a good thing.
Good luck trying to maintain and enhance such code in the future then.
--
#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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <4038bb04@news.povray.org> , Warp <war### [at] tag povray org> wrote:
> Good luck trying to maintain and enhance such code in the future then.
If you write games, you don't have to, I suppose. All you need is a few
patches later on when bad coding style produced plenty of bugs in the
initial release version ;-)
Thorsten
____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trf de
Visit POV-Ray on the web: http://mac.povray.org
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Warp" <war### [at] tag povray org> wrote in message
news:4037f302@news.povray.org...
> Patrick Elliott <sha### [at] hotmail com> wrote:
> > But it can happen.
>
> Of course it can happen. And it can also happen that a function
> named "multiply" calculates the square root. But that doesn't mean
> it's not avoidable. It just means the design of the program/library
> has a flaw.
Holy cow, this thread grew a lot. I was in bed all Saturday (not sick, just
very, very tired) and missed out on the fun. I have too much to do to catch
up.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <4038a02f@news.povray.org>, Warp <war### [at] tag povray org>
wrote:
> Christopher James Huff <cja### [at] earthlink net> wrote:
> > Pass everything by reference
>
> That can be problematic.
...snip...
> Int foo = container.size(); // <- gets a *reference*
No, that initializes an Int named foo to the object returned by
container.size. Not a problem.
This was a problem in Sapphire...not a major one, but it required
annoying additional code to create a copy. Now I have an additional
syntax for creating variables:
def foo: val; //defines a variable foo attached to the value val
def foo = val; //defines a variable foo attached to a copy of val
> The big problem is that since your variable is actually a reference
> to the original 'numberOfItems' variable, you'll end up breaking the
> container.
You could also introduce const references...not sure if its worth the
trouble.
> I don't know enough about Java to know how this problem is avoided
> there.
Java passes everything by value. Objects are only handled through
references, those references are passed by value. And it will break in
the way you describe above, but it isn't very common...in this case, you
would use the primitive int type instead of an integer object.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <403897c7$1@news.povray.org>, "Tek" <tek### [at] evilsuperbrain com>
wrote:
> Couldn't compilers inline functions 10 years ago?
Not as intelligently.
> Anyway, my point isn't just the function call overhead, it's the fact
> that it's not an operator internally supported by the compiler with a
> bunch of rules, it's a series of instructions of unspecified length
> elsewhere.
Which you have to call no matter what. It being done through an operator
function rather than through an explicit member function call makes
exactly zero difference.
> Well, it can lose the function call overhead, but not the overhead of
> it being a function (i.e. several instructions) rather than a simple
> instruction (which is really my point).
Zero overhead. None. Nada. Not one extra instruction.
> What I'm saying is I want "+" to produce the same amount of assembler code
> whenever I use it.
Well, you can't. Adding some things takes more work. Using member
functions doesn't help this at all.
> > For example, suppose you have this (in C++):
>
> Aha! but you'd never define an object for a type inherently supported by the
> compiler, only for types which require something more complex.
Actually, iterators often do exactly this, being a thin wrapper over a
pointer.
> So you end up with "+" becoming different amounts of compiled code
> depending on the context in which it's used. This makes it harder to
> optimise code, since it is harder to keep track of where the more
> complex + functions are being invoked.
Just be aware of what you're adding. It's no harder than keeping track
of a bunch of methods named add(), mult(), etc, and the code is much
easier to read.
> I think you've missed my point, I'm not saying operator overloading does
> anything different to function calls, I'm saying addition functions for two
> matrices are different to addition functions for the processor's inbuilt
> types, and it is useful when optimising to keep track of this difference.
How is this so? If you need to add two matrices, you need to add two
matrices. You can't do this with the same code for adding two integers.
> Operator overloading is great if you want to code at a higher level without
> being bogged down by thinking about what's happening at the lowest level, but
> when optimising code you want to do the opposite! Heck, if were even remotely
> feasible we'd write everything in assembler...
No...then you run into the "can't see the forest for the trees" problem.
You'll spend too much time optimizing tiny little things, and completely
miss larger optimizations that can have a huge impact. And I still
haven't seen an argument against including operator overloading in a
language...even if this were true, it would apply only to specific
projects.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <4038aea6$1@news.povray.org>, "Tek" <tek### [at] evilsuperbrain com>
wrote:
> that person should be dragged out into the street and shot*. So, ON THAT
> PREMISE, if you have decided to write an inline function there will be an
> "overhead of it being a function (i.e. several instructions) rather than a
> simple instruction", by which I mean you have decided to write a function
> that is more than one instruction.
__normal_iterator& operator++() { ++_M_current; return *this; }
That's the ++ operator for one of the STL iterators. And it does make
sense to do it this way...other operators have to do more complex
things, but it still makes sense to have a ++ operator.
> What I'm saying is, quite simply, we like to make a distinction
> between "+" and any more elaborate function. Because doing so
> prevents people writing lines like a = b + 3*(c-d), which looks
> perfectly innocent, but could be a major bottleneck.
All the coder has to do is look at the types being worked on. And this
still isn't an argument against the existance of operator overoading.
> We like the clunkier syntax *because* it is harder to use and requires more
> thought from the programmer. In our situation this is a good thing.
But it requires more thought about the wrong things...I don't see how it
can help.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <40388944@news.povray.org>, Warp <war### [at] tag povray org>
wrote:
> > Interfaces are not obsolete. As for abstract classes...what are you
> > talking about?
>
> Interfaces are obsolete of you can make abstract classes. And why
> wouldn't you (unless you want to make the language so that it does
> not support virtual functions, which would limit its OO capabilities
> by a whole lot).
Argh...forget about virtual functions. They are an artifact of C++,
which does everything statically by default. I specifically said no
static binding. No virtual functions, because everything is dynamically
bound.
> A class is abstract if it has pure virtual functions (that is,
> the class does not implement the virtual function(s) and thus cannot
> be instantiated because of this; it can only be used through
> inheritance so that the derived class implements the virtual
> function(s) in question).
Again, I'm talking about single inheritance. Multiple inheritance is not
necessary, and is needlessly complex. Abstract classes are not as useful
in single inheritance models, interfaces cover their functionality.
Interfaces render multiple inheritance + multiple abstract root classes
obsolete, not the other way around.
> > Sorry, but I don't. I've never accidentally tried to access a private
> > member.
>
> That's right. *You*. But that's ok only for as long as you don't
> distribute that library of yours containing public member variables...
> Someone will inevitably use it in the wrong way and his code can then
> break with an updated version of the library.
That's their fault for screwing around with stuff that's not documented
as the public interface. They could do the same thing with preliminary
code that may eventually be public interface, but which isn't nailed
down yet. But I've seen enough people trying really hard to do really
stupid things to get your point...fine if they are the only victims of
their stupidity, but if I have to work on their code or use their
software...
> Well, that's just a question of implementation of the interpreter/compiler.
> If you can implement the interpreter so that the private part does not need
> to be specified at the same place as the public part, good thing. (In C++
> this is not possible for technical reasons, but in an interpreted
> scripting language it may very well be possible.)
Oh, it's possible for C++, just more complex to compile. The compiler
would have to collect both definitions before it could compile anything
using more than a pointer or reference to the type. Probably be best to
have special directives specifying the files that have the
implementation and interface. Or tie the class names to the file names,
like Java.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <n8ag309hemfhpmj8jnt5j5s3k8gr66rm62@4ax.com>,
Andreas Kaiser <aka### [at] nurfuerspam de> wrote:
> This might be a 'learning' problem if you aren't aware of the
> operators 'hidden' complexity.
Only if the code is poorly designed. You shouldn't have to care about
the hidden complexity. It doesn't matter one bit how the = operator
copies a string, only that it does so.
> >So do functions.
>
> Yes, same problem here. There's no correlation between length of
> function name and complexity.
It's not a problem. It's a feature. Code written without functions is
called spaghetti code, it ain't pretty and it is very inefficient and
unmaintainable. Or should functions that do more have longer names? How
long should POV-Ray's main() function be?
> If you call a Trace() function you should know why.
> May be to write a trace record to a log file, may be to start a render
> that will be finished some months later.
And when it's in a raytracer, and when you're giving it ray information
and receiving a color from it, which do you think it is? This is an
English language issue, not a programming language one.
> The macros required to do trivial colour/vector arithmetic are
> 'information hiding' in the worst sense. They blow up source code and
> add visual noise which makes it sometimes almost impossible to see
> what's going on.
Agreed. They hide what the code is really doing by bloating up each
little operation.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <40389d5e$1@news.povray.org>,
Andrew C on Mozilla <voi### [at] dev null> wrote:
> > IMHO this comes down to 'pov ain't oo' - I don't think anyone denies
> > that oo capabilities in pov wouldn't be at the very least interesting,
> > but that's not the issue....
>
> POV sure ain't OO. No doubt about it ;-)
Actually, it comes close in many ways. You transform all shapes and
textures. You can texture all shapes. You can use the solid ones in CSG.
It's a fixed heirarchy, but you could express it in terms of objects.
object
transformable:object
shape:transformable
solid_shape:shape
finite_solid_shape:solid_shape
sphere:finite_solid_shape
box:finite_solid_shape
infinite_solid_shape:solid_shape
plane:infinite_solid_shape
patch_shape:shape
bicubic_patch:patch_shape
triangle:patch_shape
pigment:transformable
solid_pigment:pigment {color}
patterned_pigment:pigment {pattern, color_map}
texture:transformable
patterned_texture:texture {pattern, texture_map}
plain_texture:texture {pigment, finish, normal}
and so on...
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Which you have to call no matter what.
No you don't, there is always another way to write the code. That's my entire
point. If people have to think more when performing an operation which is more
complex than a simple "+" then hopefully they might some way to do something
simpler.
That is the nature of optimisation, doing the same things in a different way.
> Just be aware of what you're adding. It's no harder than keeping track
> of a bunch of methods named add(), mult(), etc, and the code is much
> easier to read.
The standards we use would be more like matrixAdd(), vectorAdd(), etc. That way
it is easier to keep track of because you are using different function names
according to what the back end is doing. This means you can search for them in
the code, which is a very useful feature.
> How is this so? If you need to add two matrices, you need to add two
> matrices.
Do you? What if you're adding two vectors? What if you're adding two vectors
before computing a dot product with another vector? it may be possible to do
this more efficiently by computing the dot product with each of the vectors and
then adding the results.
Code is malliable, nothing needs to be written a certain way. Our aim is to
write it in a more efficient way, and to write it in a way that makes it easier
to optimise later.
> > Heck, if were even remotely
> > feasible we'd write everything in assembler...
>
> No...then you run into the "can't see the forest for the trees" problem.
Uh, I did say "if it were remotely feasible". Obviously it isn't for the reason
you state there. However there is such a thing as too high level for any given
application, and the consensus amongst people I've worked with is that operator
overloading is a little too high level for the kind of code we write.
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Why is this harder than "your webmaster was a fool. How do you find all
> the links to pages that don't exist?"
It's not, but our way's easier than that: You just search for the name of the
function (thereby getting cases that the compiler might not complain about
because it gives up early or some code might depend on a #define'd switch)
--
Tek
www.evilsuperbrain.com
"Darren New" <dne### [at] san rr com> wrote in message
news:4038f420$1@news.povray.org...
> Tek wrote:
> > How do you do that?
>
> You use the right tools. Heck, the compiler can tell, can't it?
>
> The trivial method is to change the name of the matrix multiply routine
> and see all the places where the compiler complains of missing functions.
>
> Why is this harder than "your webmaster was a fool. How do you find all
> the links to pages that don't exist?"
>
> --
> Darren New, San Diego CA USA (PST)
> I am in geocentric orbit, supported by
> a quantum photon exchange drive....
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> You need to know about how a library function is implemented anyways,
> regardless of how it is called, if you want to make as optimal code as
> possible.
Which is easier to keep track of if it has a different name to all the other
library add functions. You can glance at the code and see what it's calling.
> If you are using class instances you know that calling the operator+
> for them will (potentially) generate a function call. If you don't know
> that, you don't have business making highly-optimized hacker code.
But if you're looking at unfamiliar code how do you know if you're looking at
class instances? They could just be typedeffed ints. You need to find the
definition of the class, which takes longer than simply seeing what function
it's calling.
However, I note you have dodged my question, which I think is the crux of the
issue:
Right, lets say your product ships in two weeks time, and you've discovered that
the physics guy who got sacked last week was a moron. Hey, it happens. You need
to go through his code and find everywhere that he's performing a matrix*vector
multiply, in order to replace it with a more efficient piece of code.
How do you do that?
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <4038f266$1@news.povray.org> , Darren New <dne### [at] san rr com>
wrote:
> And in real languages, you don't even have to tell the compiler to do
> that. ;-)
You don't need to do in C++ either. "inline" is only a hint to the compiler
just like the "register" keyword. Most modern compilers will inline
whatever they see fit, and some will even completely ignore the "inline"
keyword and find a better selection of functions to inline.
Thorsten
____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trf de
Visit POV-Ray on the web: http://mac.povray.org
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Warp" <war### [at] tag povray org> wrote in message news:4038bb04@news.povray.org...
> Tek <tek### [at] evilsuperbrain com> wrote:
> > We like the clunkier syntax *because* it is harder to use and requires more
> > thought from the programmer. In our situation this is a good thing.
>
> Good luck trying to maintain and enhance such code in the future then.
What the heck do you think I've been doing for the last 5 years?!
I'm not talking about some nice theory on a strategy for writing code, I'm
telling you the way that we actually do it. You can disagree all you like, but
this approach *does* work.
In terms of maintenance, this approach again makes it easier to optimise code
(even code you're not familiar with) because you can always see at a glance what
functions are being called where. This is ugly and confusing information if you
are thinking purely in terms of theoretical algorithms, but in our world the
reason you are looking at the code is precisely to see that very information! We
put this extra info there not because it clutters the code, but because it is of
use to us.
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Thorsten Froehlich" <tho### [at] trf de> wrote in message
news:4038be6e$1@news.povray.org...
> If you write games, you don't have to, I suppose. All you need is a few
> patches later on when bad coding style produced plenty of bugs in the
> initial release version ;-)
I write console games, so actually we have to release stuff with less bugs in
than people in most fields of development (possibly banking and military
applications need even less bugs, but most fields get away with shoddy code).
We use this coding style because it helps us, not hinders us.
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> __normal_iterator& operator++() { ++_M_current; return *this; }
>
> That's the ++ operator for one of the STL iterators. And it does make
> sense to do it this way...other operators have to do more complex
> things, but it still makes sense to have a ++ operator.
Damn, I'll grant you that's a good example :)
> > prevents people writing lines like a = b + 3*(c-d), which looks
> > perfectly innocent, but could be a major bottleneck.
>
> All the coder has to do is look at the types being worked on.
Which is not as easy as just looking at the name of the function being called. I
realise this sounds messy and cumbersome to you, but this "mess" is actually
information that we find useful for our application.
> And this
> still isn't an argument against the existance of operator overoading.
I never said it was!!!
I like operator overloading, I'm just explaining why we don't use it where I
work (or indeed at the last place I worked either).
> > We like the clunkier syntax *because* it is harder to use and requires more
> > thought from the programmer. In our situation this is a good thing.
>
> But it requires more thought about the wrong things...I don't see how it
> can help.
For us, these are not the wrong things, these are the things we want people to
think about. In most OO programming applications you want to free people to
think at a higher level, we do not. In fact we seldom even use objects and
inheritance, because we prefer to keep things at a lower level than that.
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Game coding and movie special-effects both have the advantage that once
> released, you're likely to never look at the code again. (Well, at least
> until they started doing MMORPGs and such.)
Not true, we do sequels. Every game I've worked on has used elements of an
engine from an earlier game, so we try to write code that helps us do that. For
our applications it is more useful to see which function is being called than to
see a simpler looking piece of code that has a complex back end.
I guess what I'm saying is normal people look at a piece of code to work out
what it does, games programmers look at it to see how it does it.
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <40391f1d$1@news.povray.org>, "Tek" <tek### [at] evilsuperbrain com>
wrote:
> > All the coder has to do is look at the types being worked on.
>
> Which is not as easy as just looking at the name of the function
> being called. I realise this sounds messy and cumbersome to you, but
> this "mess" is actually information that we find useful for our
> application.
I've written a raytracer using vectors that use operator overloading. It
was much easier to see what the code did than it is in POV, which uses
macros for the vector operations.
> > And this
> > still isn't an argument against the existance of operator overoading.
>
> I never said it was!!!
Yes you did...in a reply to one of my earlier messages:
> > I am. I definitely would want operator overloading. I've never seen a
> > good argument against it..."you can make the plus operator multiply" is
> > not a good argument. I can make a "plus()" method that multiplies as
> > well...I can also do a lot of useful things with the ability to use
> > operators with my own types.
>
> Well, I know a good argument against it. So good in fact that it's the reason
> why every games programmer I know doesn't use operator overloading: It hides
> processing.
> > But it requires more thought about the wrong things...I don't see how it
> > can help.
>
> For us, these are not the wrong things, these are the things we want people
> to think about.
If you don't know anything about optimization. You optimize the big
things first, algorithms and specific bottlenecks. You do the smaller,
more work for the return items later, if necessary. By forcing more
focus on every little operation done, you make it more likely that some
larger problem will go unnoticed, and you make the programmer waste time
they could be spending doing actually useful optimizations.
> In most OO programming applications you want to free people to
> think at a higher level, we do not. In fact we seldom even use objects and
> inheritance, because we prefer to keep things at a lower level than that.
Frankly, I don't think you understand OO programming. Unless you use
virtual functions, inheritance has zero overhead. If you have virtual
functions, overhead is still miniscule. And abstracting things can be of
great help in creating a tight, efficient module that is still both easy
to use and understand. And I don't buy your argument about vector-matrix
multiplication...if you're doing high-performance code, you should
always be aware of the types you're working with.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <4038f726@news.povray.org>, Darren New <dne### [at] san rr com>
wrote:
> Warp wrote:
> > Int foo = container.size(); // <- gets a *reference*
> > foo -= 100; // Ooops! The container breaks badly!
>
> In this case, you'd make the -= operator return a new reference to be
> assigned to foo.
You make the initial = create a copy. The actual copy operation may be
done later, in the -= (copy on write), but from the point of view of the
user of the code, the -= operator should modify the value of the object
on the left hand side, not create a new one.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <4038f64d$1@news.povray.org>, Darren New <dne### [at] san rr com>
wrote:
> > wouldn't you (unless you want to make the language so that it does
> > not support virtual functions, which would limit its OO capabilities
> > by a whole lot).
>
> Well, then it wouldn't be OO at all, as you wouldn't have any dynamic
> dispatch.
Oh? Objective C doesn't have anything called virtual functions. It has
methods and messages instead. And they're not the same thing...the
messaging model is a bit more flexible than the member function call
model.
> > Someone will inevitably use it in the wrong way and his code can then
> > break with an updated version of the library.
>
> Interestingly enough, C# actually addresses this problem. Nice language,
> that.
Could you clarify this?
C# does sound like a good language from what I've heard, too bad it's
MS-only.
(Don't say Mono...it's incomplete, and will always be so...its existance
only gives people something to point at when claiming C# isn't MS-only.)
> That's actually what Eiffel does. You might want to look into it. It
> even goes a step farther, in that it allows you to restrict (for
> example) what values a child object is allowed to return from a member
> function it overrides.
So the superclass can define that a method returns a real value between
0 and 1, and subclass overrides must remain in that range? This is one
of Eiffel's design-by-contract features, right?
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> I've written a raytracer using vectors that use operator overloading. It
> was much easier to see what the code did than it is in POV, which uses
> macros for the vector operations.
Well yes, I'm not debating that. I'm saying for what you're doing it's better to
deal with things on a cleaner more mathematical basis, but for what I do at work
it's better to deal with things on a more technical implementation-based level.
> > > And this
> > > still isn't an argument against the existance of operator overoading.
> >
> > I never said it was!!!
>
> Yes you did...in a reply to one of my earlier messages:
No, I said it was an argument against the *use* of operator overloading, not
it's existence. I'm not saying it should never be used, I'm just explaining why
we don't use it.
> If you don't know anything about optimization. You optimize the big
> things first, algorithms and specific bottlenecks. You do the smaller,
> more work for the return items later, if necessary.
Which still is not a reason to hide what the code is actually doing.
Besides, a good optimiser does neither of those, you begin by profiling the
system extensively to ascertain what is slow. It doesn't matter how cumbersome
the big concepts are, or how badly implemented the low level things are, all
that matters is how long things take.
> By forcing more
> focus on every little operation done, you make it more likely that some
> larger problem will go unnoticed,
This is a valid point, but you must see that this is a balance. Depending on
your needs you choose how high/low level you want to be. If you only care about
the simplest processes you work in assembler, if you care most about the overall
structure you code in OO. We have gravitated to a point a little above the
functionality supported by C, and a little below true OO C++. This is the
balance that works for us, but I do not suggest it is applicable to all
situations.
> And abstracting things can be of
> great help in creating a tight, efficient module that is still both easy
> to use and understand.
High level code can be very good for dealing with high-level concepts. And
certainly as the games become more sophisticated people move naturally to higher
level concepts. But at this point in time the people I have worked with feel
that we're still dealing with concepts best expressed by C-style code with just
a few C++ features.
> And I don't buy your argument about vector-matrix
> multiplication...if you're doing high-performance code, you should
> always be aware of the types you're working with.
But how do I gain this awareness if it's not my code? Last project I was on had
20 programmers, and I was one of the main people assigned to optimise things. It
was more important to me to see how the code worked at a lower level than to see
nice clean algorithms.
However I know there are other games companies that go all out for OO code,
because they wish to code at a higher level. They do not produce such efficient
code as we do :)
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <4037f302@news.povray.org>, war### [at] tag povray org says...
> Patrick Elliott <sha### [at] hotmail com> wrote:
> > But it can happen.
>
> Of course it can happen. And it can also happen that a function
> named "multiply" calculates the square root. But that doesn't mean
> it's not avoidable. It just means the design of the program/library
> has a flaw.
>
But is it always a flaw?
For example, say you want to manipulate an image:
Fade(Object.DC)
function Fade(myDC AS DC ByRef)
Do you want Fade to have *only* the contents of the DC, which could be
40x40 or 80x20 or even 1600x1? No, you pass it a reference to the DC, so
you can manipulate the original contents.
You could also pass the DC to the function with it automatically making a
copy by using it like:
Object.Image = Fade(Object.DC)
function Fade(myDC AS DC ByVal)
But you are performing two copies here, instead of just manipulating the
actual data. This will take more time and added memory to accomplish. Why
exactly do you think the first version is bad design? It makes a whole
heck of a lot more sense that wasting extra processor cycles making
copies, instead of performing the effect on the original image. Yes, this
may not be the 'best' way in some case, but what if you do this:
set a = GetCompatibleDC(Object.DC)
Grayscale(a)
Fade(a)
FindEdges(a)
Object.DC = a
That eliminates 6 extra copy processes you have to make by passing the
contents of the DC, instead of a reference to the one copy your actually
needed. This is not *bad* library design.
--
void main () {
If Schrödingers_cat is alive
call functional_code()
else
call crash_windows();
}
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Tek" <tek### [at] evilsuperbrain com> wrote in message
news:40391d91$1@news.povray.org...
> "Warp" <war### [at] tag povray org> wrote in message
news:4038bb04@news.povray.org...
> > Tek <tek### [at] evilsuperbrain com> wrote:
> > > We like the clunkier syntax *because* it is harder to use and requires
more
> > > thought from the programmer. In our situation this is a good thing.
Thank you, Warp. This has been a puzzle for me for some time now: why do so
many programmers write such awful code? At first, I thought it was because
they didn't want other programmers to understand it because they could be
replaced. Then, I figured it was just because they were engineers with no
sense of cognitive psychology. Finally, I read your message, and now I
understand it: these engineers are doing the world a /favor/ by making code
hard to read because it makes other programmers think more. I get it now!
It's alturism.
Don't send me a resume.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <40392ffb@news.povray.org>, Darren New <dne### [at] san rr com>
wrote:
> Christopher James Huff wrote:
> > Oh? Objective C doesn't have anything called virtual functions.
>
> They're not called that, but that's the effect. Messages are dynamically
> dispatched to the appropriate method.
It's more than a different name for the same thing. Virtual functions
are just function calls that are looked up at run-time through a virtual
function table. Message lookup is based on a message selector that is
itself a piece of data the program can manipulate. You can forward
messages that you can't handle, for instance. You can even send them to
objects on other machines. The overhead is higher, but surprisingly low.
Virtual functions are just a specific implementation detail, not a core
requirement for object oriented languages.
> I've found it useful to learn a bunch of different languages, if only to
> understand useful paradigms, even if I never obtain a compiler for them.
I agree. If you don't keep learning new things, you'll end up being
unable to.
BTW, have you ever looked at Dylan?
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <4039335d$1@news.povray.org>,
"Dan P" <dan### [at] yahoo com> wrote:
> > > > We like the clunkier syntax *because* it is harder to use and requires
> more
> > > > thought from the programmer. In our situation this is a good thing.
>
> Thank you, Warp. This has been a puzzle for me for some time now: why do so
> many programmers write such awful code? At first, I thought it was because
> they didn't want other programmers to understand it because they could be
> replaced. Then, I figured it was just because they were engineers with no
> sense of cognitive psychology. Finally, I read your message, and now I
> understand it: these engineers are doing the world a /favor/ by making code
> hard to read because it makes other programmers think more. I get it now!
> It's alturism.
>
> Don't send me a resume.
Warp didn't write that. And even if he had, your attack would have been
completely unwarranted. Speaking as a member of the TAG, please stop
these personal attacks, insults, and other anti-social behavior. Now.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Dan P" <dan### [at] yahoo com> wrote in message
news:4039335d$1@news.povray.org...
> Thank you, Warp.
Uh, I said that, not him.
> This has been a puzzle for me for some time now: why do so
> many programmers write such awful code?
It seems impossible for me to make a statement without people taking it too far!
I'm *not* saying all abstraction is evil and should be avoided, but I'm also
*not* saying everything should be abstracted as much as possible. I'm talking
about finding a balance between the two, according to the needs of your task.
There is never any excuse for writing code that is needlessly difficult to read,
such as many unproffessional coders like to do in the flawed belief that it
makes them look clever.
However, there is good reason to sometimes write code that makes it harder to
see the overall structure if doing so provides you with some other useful
information. Obviously a balance must be found and that balance is different for
different applications, but in my work it is useful to avoid a lot of
abstraction.
--
Tek
www.evilsuperbrain.com
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <cjameshuff-CF95A3.17100922022004@news.povray.org> , Christopher
James Huff <cja### [at] earthlink net> wrote:
> I've written a raytracer using vectors that use operator overloading. It
> was much easier to see what the code did than it is in POV, which uses
> macros for the vector operations.
In the source code you have access to it doesn't!
Thorsten
____________________________________________________
Thorsten Froehlich, Duisburg, Germany
e-mail: tho### [at] trf de
Visit POV-Ray on the web: http://mac.povray.org
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Tek" <tek### [at] evilsuperbrain com> wrote in message
news:40393ba8$1@news.povray.org...
> "Dan P" <dan### [at] yahoo com> wrote in message
> news:4039335d$1@news.povray.org...
> > Thank you, Warp.
>
> Uh, I said that, not him.
>
> > This has been a puzzle for me for some time now: why do so
> > many programmers write such awful code?
>
> It seems impossible for me to make a statement without people taking it
too far!
Oh, I'm sorry; I didn't think that sounded like you, Tek :-)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <40392dba$1@news.povray.org>, "Tek" <tek### [at] evilsuperbrain com>
wrote:
> Well yes, I'm not debating that. I'm saying for what you're doing
> it's better to deal with things on a cleaner more mathematical basis,
> but for what I do at work it's better to deal with things on a more
> technical implementation-based level.
No...I don't give a damn about the mathematics. It's just cleaner
looking and easier to read with overloaded operators. Easier and faster
to write and debug, giving me much more time to spend on optimization or
extension of the program.
> > Yes you did...in a reply to one of my earlier messages:
> No, I said it was an argument against the *use* of operator overloading, not
> it's existence. I'm not saying it should never be used, I'm just explaining
> why we don't use it.
Then why did you even reply to my message?
> Which still is not a reason to hide what the code is actually doing.
The only information hidden is that which isn't of any use to the
situation anyway. You don't need to know exactly how vectors and
matrices are multiplied, it is enough to know that doing so is
time-consuming.
> Besides, a good optimiser does neither of those, you begin by
> profiling the system extensively to ascertain what is slow. It
> doesn't matter how cumbersome the big concepts are, or how badly
> implemented the low level things are, all that matters is how long
> things take.
I did mention "specific bottlenecks". How do you think those bottlenecks
would be found, if not by profiling the program?
> > And I don't buy your argument about vector-matrix
> > multiplication...if you're doing high-performance code, you should
> > always be aware of the types you're working with.
>
> But how do I gain this awareness if it's not my code?
You read the code.
> Last project I
> was on had 20 programmers, and I was one of the main people assigned
> to optimise things. It was more important to me to see how the code
> worked at a lower level than to see nice clean algorithms.
You regularly have separate programmers coding and optimizing? That does
not sound like a good idea...the person optimizing starts out knowing
nothing about the code.
And again, it's not about "nice clean algorithms", it's "nice clean
*code*" that lets you see what's being done!
> However I know there are other games companies that go all out for OO code,
> because they wish to code at a higher level. They do not produce such
> efficient code as we do :)
Then they're doing it wrong. And what company do you work for? I never
want to work there.
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Christopher James Huff" <cja### [at] earthlink net> wrote in message
news:cjameshuff-CD5ABF.18305722022004@news.povray.org...
> In article <4039335d$1@news.povray.org>,
> "Dan P" <dan### [at] yahoo com> wrote:
>
> > > > > We like the clunkier syntax *because* it is harder to use and
requires
> > more
> > > > > thought from the programmer. In our situation this is a good
thing.
> >
> > Thank you, Warp. This has been a puzzle for me for some time now: why do
so
> > many programmers write such awful code? At first, I thought it was
because
> > they didn't want other programmers to understand it because they could
be
> > replaced. Then, I figured it was just because they were engineers with
no
> > sense of cognitive psychology. Finally, I read your message, and now I
> > understand it: these engineers are doing the world a /favor/ by making
code
> > hard to read because it makes other programmers think more. I get it
now!
> > It's alturism.
> >
> > Don't send me a resume.
>
> Warp didn't write that. And even if he had, your attack would have been
> completely unwarranted. Speaking as a member of the TAG, please stop
> these personal attacks, insults, and other anti-social behavior. Now.
That wasn't an attack, that was sarcasm. I apologize, Warp; I didn't realize
that wasn't you that said that. Chris, if you want to single me out, okay,
but this group is anything but friendly and I'm just as happy to remove it
from my newsgroups list as you are to remove me from it. Because I feel
personally attacked every time I write a message on this board, particularly
when I post code of any sort. Messages like, "You should read an OO book"
are pretty damned insulting and pretty damned personal so I ask you,
politely, to remove the double-standard when wielding your "big stick".
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
In article <40393bc7$1@news.povray.org>,
"Thorsten Froehlich" <tho### [at] trf de> wrote:
> > I've written a raytracer using vectors that use operator overloading. It
> > was much easier to see what the code did than it is in POV, which uses
> > macros for the vector operations.
>
> In the source code you have access to it doesn't!
In the currently final version, the version that everyone has access to,
it does. ;-)
--
Christopher James Huff <cja### [at] earthlink net>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: <chr### [at] tag povray org>
http://tag.povray.org/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Dan P <dan### [at] yahoo com> wrote:
> Because I feel
> personally attacked every time I write a message on this board, particularly
> when I post code of any sort. Messages like, "You should read an OO book"
> are pretty damned insulting and pretty damned personal so I ask you,
> politely, to remove the double-standard when wielding your "big stick".
No, there's no conspiracy against you here.
I don't tend to remember people names for negative things, but tend to
easily forget them. If I have a flamewar with someone and then it stops,
after a week or two I have probably already totally forgotten the name
of my "adversary". In fact, I wasn't completely sure if it was you whose
C code I commented when I responded with the OO things (and I didn't make
much effort remembering, for that matter).
Although you might feel like it, this is not a place where regulars
select some newcomer at random and start attacking him as a team effort.
That would be completely silly.
If you are receiving tons of negative responses, then think about why
that may happen. It's certainly not a conspiracy against you personally.
--
#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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Warp" <war### [at] tag povray org> wrote in message
news:403946d7@news.povray.org...
> Dan P <dan### [at] yahoo com> wrote:
>
> Although you might feel like it, this is not a place where regulars
> select some newcomer at random and start attacking him as a team effort.
> That would be completely silly.
> If you are receiving tons of negative responses, then think about why
> that may happen. It's certainly not a conspiracy against you personally.
Actually, I think I am wired a little different. Here's an example: when you
said to someone, "If you don't know what operator+() does with the type you
are using, then you should seek another job, IMHO," I thought that was far
worse than anything I have ever said to anybody on here by at least a factor
of 10. I've never said you weren't qualified to do your job or even hinted
at it. In my response, I indirectly said that I wouldn't want you working
for /me/. But, I think you aren't using an active reference in your
sentence. What I mean by that is I read your message as, "You, poster, don't
know what the operator +() does and, therefore, you should seek another
job." What I think you must be saying, if it isn't insulting, is, "If some
person doesn't know whwat operator +() does with the type you are using,
then that person should seek another job." Even that could be taken the
wrong way, but it is not direct and, therefore, not an "attack".
I think we have different parsers and I'm going to have to adjust mine to
get along here. Plus, I felt way more negatively about what I thought you
were saying because I have to deal with that on a daily basis and it just
makes my job hard... I was emotional and /wrong/ for being so.
Can I get another chance at fixing my parser?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Thorsten Froehlich <tho### [at] trf de> wrote:
> > And in real languages, you don't even have to tell the compiler to do
> > that. ;-)
> You don't need to do in C++ either. "inline" is only a hint to the compiler
> just like the "register" keyword. Most modern compilers will inline
> whatever they see fit, and some will even completely ignore the "inline"
> keyword and find a better selection of functions to inline.
What I meant when I said that the operator function should be made
"inline" was that it should be implemented where it's declared (or
at least at the same visibility level).
If the function is declared in a header file but implemented in a
separate object file then the compiler naturally can't inline it.
--
plane{-x+y,-1pigment{bozo color_map{[0rgb x][1rgb x+y]}turbulence 1}}
sphere{0,2pigment{rgbt 1}interior{media{emission 1density{spherical
density_map{[0rgb 0][.5rgb<1,.5>][1rgb 1]}turbulence.9}}}scale
<1,1,3>hollow}text{ttf"timrom""Warp".1,0translate<-1,-.1,2>}// - Warp -
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Christopher James Huff <cja### [at] earthlink net> wrote:
> Argh...forget about virtual functions. They are an artifact of C++,
> which does everything statically by default. I specifically said no
> static binding. No virtual functions, because everything is dynamically
> bound.
What do you mean "no virtual functions"? If every function is dynamically
bound, then *every* member function is virtual.
At least you should be able to specify a default implementation for
a member function or live it as purely virtual.
If you leave all the member functions as purely virtual, then what
you have is an interface.
> > A class is abstract if it has pure virtual functions (that is,
> > the class does not implement the virtual function(s) and thus cannot
> > be instantiated because of this; it can only be used through
> > inheritance so that the derived class implements the virtual
> > function(s) in question).
> Again, I'm talking about single inheritance. Multiple inheritance is not
> necessary, and is needlessly complex.
Who is talking about multiple inheritance here? I'm not.
And multiple inheritance may be complex from the point of view of
the interpreter/compiler, not from the point of view of the user.
Why should that be a limit?
> Abstract classes are not as useful
> in single inheritance models, interfaces cover their functionality.
I don't understand what you are saying.
Why have *two* types of classes when you can have just one?
And why abstract classes are not useful in single inheritance model?
> Interfaces render multiple inheritance + multiple abstract root classes
> obsolete, not the other way around.
Interfaces are a poor way of making multiple inheritance. They have
all the logical problems of multiple inheritance and they force you
to make code repetition.
I have never understood what's so good about interfaces.
> > That's right. *You*. But that's ok only for as long as you don't
> > distribute that library of yours containing public member variables...
> > Someone will inevitably use it in the wrong way and his code can then
> > break with an updated version of the library.
> That's their fault
You can't design libraries with that principle.
--
#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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|
 |