C++ sucks for games

G

Gerry Quinn

rmagere@*the-mail-that- said:
I am sorry I don't understand but if the complain is about the fact that
"generated code" is bad (though I am not sure this is what you are saying)
and that "self-modifying code" is not a important definition distinction
from "generated code" (again I am not sure whether you meant this, this
premises is only what I understood from your messages but I might be wrong),
then aren't all programming languages above machine level bad? I mean as far
as I understood it when you write a C,C++ or Lisp program what used to
happen is that it got translated into assembler code (or machine code) i.e.
assembler code got "generated" by the compiler.

There is a key difference here. The compiler is a well-tested program
that grinds all source into object code. Compilers are hard to write,
especially optimising ones, but when they are done, they are done. They
can be compared to libraries that see massive re-use. They are expected
to work just about perfectly and not have bugs.

A 'compiler' that exists to compile just one program is a different
kettle of fish. It does something complicated, perhaps more complicated
than writing the original in assembly! But it is not so well tested, it
will inevitably have obscure bugs. In short, it's too clever to be good
programming practice. (Of course there are exceptions to everything.)

Also, the standard compiler is not self-modifying, because the output of
the compiled programs is not it's real output - the compiled programs
are. That is much not the case in a compiler that compiles a single
program, because it only exists to create the output of that program.

So there is a general association between self-modifying code and
'badness'.
I don't see the difference between C code that generates C code and compiler
that translates C code to machine code (or whatever). However I feel that
there is a conceptual difference between code that modifies itself rather
than just creating new code. But as I said I am not sure I understood fully
this branch of the thread.

The conceptual difference, as I see it, is 'who owns the output'. Is it
a different program that is fed to the compiling program, just one of
many - or is it essentially part of the same program, as in the case of
a compiler built for a specific task? Is the system modifying itself,
or something else?

Maybe that's an over-subtle way of defining self-modifying code, but it
seems to get to the nub of the issue, and hints about why it tends to be
a bad idea.

- Gerry Quinn
 
G

Gerry Quinn

newsmailcomp5 said:
Did you read the wikipedia article? You seem to make you your own
definition of established terms.

That differs from 'wikipedia', how?

But anyway, the article starts with "In computer science, self-modifying
code is code that modifies itself on purpose." You just have to get
away from a pedantic definition of what is code. If it helps, think
about "self-modifying programs", or "self-modifying systems of
programs". That is what the issue is really about.

- Gerry Quinn
 
K

Kenneth Tilton

Gerry Quinn said:
I honestly don't care how Lisp-ers like program.

Correct me if I'm wrong, but above you cared enough to form "a distinct
impression of [Lisp-ers] preferring generic programming." :)

If you follow c.l.l., at least, you will find lots of threads about the
best way to use CLOS (including generic functions) for any given task.

My wild guess is that because CLOS is so much better than any other OO
model, we will see a Second Coming for OO as Lisp continues to move back
into the mainstream. ie, OO may have failed at the Grail thing only
because the implementations suck so badly.

Case in point: at least one cll reg is also a Java dude who does not
like to use inheritance in OO design. This in a language which is all OO
all the time. My, my. Java really must have blown it, I suppose by not
handling multiple inheritance, and by making the syntax so unwieldy.

otoh, my refactoring is as often about reshuffling a class hierarchy as
it is about dicing and slicing functions. And this is painless in CL
because I do not then have to run around changing type declarations all
over my code -- there are none.

kenny
 
M

Maahes

A very quick survey of a bit of my own code suggests that
I write slightly fewer comments in Lisp code than in C or C++.
Generally, the things I do in Lisp are harder than the things
I do in C or C++, which you'd expect to imply more commenting.
So I have some weak evidence that Lisp code doesn't need
such heavy commenting as C++ code does.
I think all you have is weak evidence that you need to comment your Lisp
more...
 
K

Kenneth Tilton

A very quick survey of a bit of my own code suggests that
I write slightly fewer comments in Lisp code than in C or C++.
Generally, the things I do in Lisp are harder than the things
I do in C or C++, which you'd expect to imply more commenting.
So I have some weak evidence that Lisp code doesn't need
such heavy commenting as C++ code does.
I think all you have is weak evidence that you need to comment your Lisp
more...[/QUOTE]

Now here is some meat for a grand flamewar!

Comments are /strong/ evidence that the code needs to be better. Unless
of course they are simply taking up space to make their author feel
grand as he describes what the code plainly does. More likely, however,
they describe what the code did three refactorings ago.

When starting work on legacy code, first, we delete all the comments.
Then as we figure out what the code does, we correct all the variable
and function names. See Confucius on this one. The rest is easy.

Well, enough BS, Frank G has persuaded Cello the Dancing Bear to balance
atop OS X and I have a screaming GPU to bench.

:)

kenny
 
M

Maahes

Class method call:
What is this? are you saying that the class rabbit has a static member
function that takes a rabbit and a 3? I'm not sure why you would want such
a thing..

Who are you replying to?

You've deleted the important part of my email in your response???
In C++, the syntax is:

Rabbit::jump(3)... you do not pass in "rabbit" to this class function.

in C that is:

rabbit_jump(3)... different parameters since we aren't dealing with
an actual object now.


C is consistent across all uses as far as syntax goes, though there is no
data involved in the class method, though there is a data object involved in
all other references, so obviously the syntax must change to reflect this.
 
M

Maahes

Method call:
C doesn't have classes and methods AFAIK. The Lisp call above is
really to a method of the rabbit class, but it looks exactly the same
as an ordinary function call.
class's and methods are just a structural concept. C has structs and if you
wanted to implement a class with methods, its just as easy to do it in C.
Of course, virtuals and hierachy get messier, though still possible.

== C++ ==

class Rabbit
{
Vector pos;

public:
Jump(int distance);
};


== C ==

struct Rabbit
{
Vector pos;
};
Rabbit_Jump(int distance);



I assumed that even if the design decision was made to make jump a
class method, one would like to know which rabbit object the caller
wanted to have jump. Hence it is passed as an argument.
Sorry, I assumed you had made a mistake, since it makes no sense to pass in
a "rabbit" object to a static method of a rabbit class. Static methods have
a different syntax coz they don't require any object data. If you choose to
pass in a rabbit to try and make the code interface look inconsistent, I
guess you can do that.
Lisp and C? Well, in C's case that's because there is really one one
kind of call, so it's not all that surprising that the syntax for that
kind of call is consistent.

How many kinds of calls does Lisp have?
 
M

Maahes

So I have some weak evidence that Lisp code doesn't need
Now here is some meat for a grand flamewar!

Comments are /strong/ evidence that the code needs to be better. Unless
of course they are simply taking up space to make their author feel
grand as he describes what the code plainly does. More likely, however,
they describe what the code did three refactorings ago.

When starting work on legacy code, first, we delete all the comments.
Then as we figure out what the code does, we correct all the variable
and function names. See Confucius on this one. The rest is easy.

:)

That's a bit left field, but there is some truth there.
Though if your code is at that stage, I suggest starting clean. :)

The original thread was inferring that have less comments was because the
code was so easy to read, which is a totally subjective statement. We have
reams of C++ code with NO comments at all, but I don't think this is
/strong/ evidence that C++ does need as heavy commenting as Lisp code.
 
C

chris

Greg said:
There are no "member functions" in Lisp, all functions exist outside
the definition of classes. That will sound strange to people only
familiar with the C++ style of OO, but it works very nicely once you
get used to it.

In that case, you could simply write C++ and not use member functions.
Arguing that C++'s member functions don't look like normal function
calls and in lisp they do sounds stupid if in fact lisp doesn't have
member functions.

Chris
 
M

Maahes

What is it that you use access specifiers for?
Okay, so access specifiers are for protection.



Okay, so access specifiers are *not* for protection.

What are access specifiers for again?

See first statement. I don't know where he gets the "ease of use" from.
If it was for "ease of use", we wouldn't use them coz they are a pain when
your debugging coz its harder to hack into the variables from other classes.
 
M

Maahes

Team programming in Lisp is eminently doable. I worked on four sizeable
team projects using Lisp for development:

1. GATE was a three-person, two year project that developed a
knowledge-based, network-aware automated testing system that was used to
find hundreds of pre-release bugs in Mac System 7. It was written in
Common Lisp.

2. The unnamed first version of the Newton operating system was a
60-person, four year project written mostly in Ralph, a Lisp dialect that
later evolved into the Dylan language. (The Dylan compiler and IDE were
written in Common Lisp.)

3. Bauhaus was the second Lisp-based version of the Newton operating
system, also written in Ralph (a third version, written in C++ and
NewtonScript, and chosen for non-technical reasons, was the one shipped).
It was a five-person, two-year project.

4. SK8 was a 10-person, five-year project to develop a general-purpose
multimedia authoring system. It was used to build perhaps a dozen projects
at Apple, some of which were later productized and some of which were
given away to educational projects. SK8 itself was eventually released as
freeware. Sk8 was written in Common Lisp.

None of them were games (though SK8 was used to build several games and
several applications that incorporated interactive video elements).

Cool. I think this thread is being fuelled heavily by the cross posting.
Since it is also in comp.games, you'll get a lot of posts from people like
me that are not satisfied unless we here from someone who has shipped a 10
month project with 7+ programmers on a console title in Lisp.

Also, it doesn't help the case when you here that the version of Bauhaus
that shipped was a C++ version... why would you even consider writing a C++
version when you've already got 2 versions written in Lisp, which is
supposed to be a far better language...
 
M

Maahes

For protecting your implementation from the other programmers.
Don't you document your code?
yep, sure do. And I hated private & public and was forced to use them
because people are inherently lazy and will hack your class before asking
for an interface to do what they want unless you stop them.
 
G

Gareth McCaughan

Maahes said:
I think all you have is weak evidence that you need to comment your Lisp
more...

Depends which of the following two hypotheses you think more
likely.

(A) I over- or under- comment to about the same degree
whatever language I'm using.

(B) All languages require about the same level of commenting,
measured in comments per line of code. (At least for
code written by me).

I find (A) much more plausible than (B).
 
G

Gareth McCaughan

[Greg Menke:]
There are no "member functions" in Lisp, all functions exist outside
the definition of classes. That will sound strange to people only
familiar with the C++ style of OO, but it works very nicely once you
get used to it.
[Chris:]
In that case, you could simply write C++ and not use member
functions. Arguing that C++'s member functions don't look like normal
function calls and in lisp they do sounds stupid if in fact lisp
doesn't have member functions.

I think you may have misunderstood Greg. Although it's true
that Lisp doesn't have "member functions", it isn't true that
Lisp is like C++-without-member-functions. If you abandon
member functions in C++, then inheritance becomes impossible.
Lisp's "generic functions" *do* support inheritance.
 
?

=?iso-8859-1?q?Bj=F6rn_Lindberg?=

No problem. I *was* being sloppy in my terminology: even if I
personally think 'class method' is a better term than 'static member
function', using a non-standard term will cause confusion.


One could also argue the other case: 1) maybe different things
*should* be expressed differently. More to learn, but each case is
distinctive. 2) If someone really dislikes the variable syntaxa
(sp?), they could just use overloaded functions for type dispatch.

Not really, because then they would lose all
polymorphism. Ie. overloaded functions can be used to achieve type
dispatch, but the dispatch will not be polymorphic. Polymorphism is
after all what OO is about.


Björn
 
R

rmagere

Gerry Quinn said:
The conceptual difference, as I see it, is 'who owns the output'. Is it
a different program that is fed to the compiling program, just one of
many - or is it essentially part of the same program, as in the case of
a compiler built for a specific task? Is the system modifying itself,
or something else?

Ok I think I understand your point of view i.e. it's my "system" (composed
of many functions) changes any part of itself than it's self-modifying as
opposed to is a function actually changing re-writing itself.
Maybe that's an over-subtle way of defining self-modifying code, but it
seems to get to the nub of the issue, and hints about why it tends to be
a bad idea.

I am not sure that it actually hints at why it is a bad idea - it does
explain why you think of self-modifying code that other people think is not.
Regarding the "badness" of it well I think there are a number of situations
in real world (not computer games, or at least this is not as important in
computer games) where a significant source of problems (especially when
trying to interpret visual scenes) comes from the inability to precisely
predict the nature of the enviroment in which the programs (in this dealing
with image understanding) are expected to operate. Furthermore even if you
could know all the different states that the enviroment could be in, you
wouldn't know a priori what the state of the enviroment would be in any
particular time. Consequently one (maybe not the only one) way to achieve
robust performace is a program that is capable to determine the state of the
enviroment at runtime and adapt to the enviroment that is found.
"Self-adaptive software" (I think the name was originally introduced in 1998
by a DARPA research project) is a model-based approach to building robust
systems. What happens is that in the real world the lack of adaptiveness is
bad as usually it means only that your program will work brilliantly in the
demo case but not in the actually challenging problems.

However this is a bit off the "sucks for games" alley so I'll leave it at
that. (But overall I agree the average programmer doing the average job
probably doesn't need self-adaptiveness and possibly if introduced it could
worsen the results)
 
S

Svein Ove Aas

Maahes said:
How many kinds of calls does Lisp have?

Hmm...

Standard function calls, of course.
Generic function calls, for OO.

I'd say that's... two.
Macros/specials don't count, because although they usually look *similar* to
ordinary function calls, they have different evaluation order, at least. If
they didn't, they wouldn't need a macro.

Of course, it's possible to define generic functions in terms of ordinary
functions, so in effect you could say there's just one call, and you can
also add different kinds of calls such as Prolog evaluation or foreign
calls. I'd say the answer is "N".
 
P

Peter Lewerin

Maahes said:
In C++, the syntax is:

Rabbit::jump(3)... you do not pass in "rabbit" to this class function.

Is there any language rule that explicity says that?

My point was to show three different ways to call jump with two
parameters; rabbit and 3. Can you give any reason to exclude the
rabbit object in this particular case? What entity will do the
jumping in your scenario?

In any case, a call to a static member function will use the syntax
namespace::name, which is inconsistent with syntax for other calls.
Whether this is good or bad is another issue.
C is consistent across all uses as far as syntax goes, though there is no
data involved in the class method,

Again, why is there no data involved in a static member function call?
 
P

Peter Lewerin

Maahes said:
class's and methods are just a structural concept.

I disagree, but that's probably another discussion (and we might
possibly agree if it is pursued).
C has structs and if you
wanted to implement a class with methods, its just as easy to do it in C.

Yes, but that doesn't create new types of function calls.
If you choose to pass in a rabbit to try and make the code interface
look inconsistent, I guess you can do that.

I passed in a rabbit to make the examples as similar as possible.
It's not the parameters that makes the syntax inconsistent:

foo( ... )
bar.foo( ... )
Bar::foo( ... )

are still inconsistent.
How many kinds of calls does Lisp have?

In this area of comparison, two: 'Ordinary' function call and method
call, basically.
 
C

chris

Gareth said:
[Greg Menke:]
There are no "member functions" in Lisp, all functions exist outside
the definition of classes. That will sound strange to people only
familiar with the C++ style of OO, but it works very nicely once you
get used to it.

[Chris:]

In that case, you could simply write C++ and not use member
functions. Arguing that C++'s member functions don't look like normal
function calls and in lisp they do sounds stupid if in fact lisp
doesn't have member functions.


I think you may have misunderstood Greg. Although it's true
that Lisp doesn't have "member functions", it isn't true that
Lisp is like C++-without-member-functions. If you abandon
member functions in C++, then inheritance becomes impossible.
Lisp's "generic functions" *do* support inheritance.

Ah, sorry. I know a (little) lisp, so I should have realised the point.

I find these lisp vs. C++ discussions fun, but also wonder if they have
any purpose. My opinion on the subject (in case anyone cares) is that I
enjoy programming in lisp more than C++, but one problem with lisp is
that it's incrediable flexability is it's greatest weakness. When
working on a number of large projects, the quite fixed structure imposed
by say Java or C++ can make life much easier in terms of debugging and
long term support, which in my opinion are actually much more important
than writing the original code (I'm sure 90% of the time I'm looking at
code it is code either I or someone else wrote more than 6 months ago).
C++ would be nicer if the type system didn't have holes you can drive a
bus through.

Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,667
Latest member
DaniloB294

Latest Threads

Top