473,439 Members | 1,920 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,439 software developers and data experts.

C++ sucks for games

Hey

Recently, I researched using C++ for game programming and here is what
I found:

C++ game developers spend a lot of their time debugging corrupted
memory. Few, if any, compilers offer completely safe modes.

Unsurprisingly, there is a very high failure rate among projects using
C++ for modern game development.

You can not even change function definitions while the program is
running and see the effects live (the ultimate debugging tool).

Alternatively, you can't execute a small portion of the program
without compiling and linking the whole thing, then bringing your game
into a specific state where your portion of the code is being executed.

The static type system locks you into a certain design, and you can't
*test* new ideas, when they come to you, without redesigning your
whole class hierarchy.

C++ is so inflexible, even those who do use it for games, have to
write their game logic in some other language (usually very slow,
inexpressive and still garbage collected). They also have to interface
the two languages.

C++ lacks higher-order functions. Function objects emulate them
poorly, are slow and a pain to use. Additionally, C++ type system does
not work well with function objects.

C++ programs can not "think" of new code at run-time, and plug that
new code into themselves in compiled form. Not easily, anyway.

C++ coding feels very repetitive, for example, when writing class
accessors, you often have to write const and non-const methods with
completely identical function bodies. Just look at STL.

When programming in C++ you feel like a blind person trying to draw
something. You don't _see_ the data structures that your procedures
will operate on. Lisp programming is much more visual.

Constructors and smart pointers make it hard to tell cheap operations
from expensive ones.

C++ lacks automatic memory management and so it encourages copying
objects around to make manual memory management manageable.
Reference-counting schemes are usually slower than modern garbage
collectors and also less general.

Most important, C++ syntax is irregular, and you often find yourself
typing repetitive patterns again and again - a task easily automated
in languages with simpler syntax. There are even books on C++
patterns, and some C++ experts take pride in being able to execute
those patterns with computer-like precision - something a computer
should be doing to begin with.

C++ programs are slow: even though the compilers are good at
micro-optimizing the code, programmers waste their time writing
repetitive patterns in C++ and debugging memory corruption instead of
looking for better algorithms that are far more important for speed
than silly micro-optimizations.

It's hard to find good programmers for C++ projects, because most of
the good programmers graduated to languages like Lisp or avoided C++
altogether. C++ attracts unimaginative fellows with herd mentality.
For creative projects, you want to avoid them like a plague.

It is my opinion that all of the above makes C++ a very bad choice for
commercial game development.
Jul 22 '05
761 27935
Kenny Tilton wrote:
Gareth McCaughan wrote:

....
Yes, they did. And at the "(1 ..." in the Lisp code.
I'm sorry if you think taking a couple of seconds to
spot a typo at 1.30am local time is proof of incompetence.


Naw, I was just being a d*ckhead. That is what /I/ do at 1:30am when I
get back from the pub.


Fair enough. :-)

--
Gareth McCaughan
..sig under construc
Jul 22 '05 #401
In article <cm**********@services.kq.no>, sv*******@aas.no says...
Gerry Quinn wrote:
In article <cf**************************@posting.google.com >,
ka*@ashi.footprints.net says...
The C++ style of protection is completely at odds with the very design
of the object system, because there is no notion of class scope. The
body of a method in Lisp is not in some special scope in which the
symbols denoting the variables of a class are magically bound to those
slots. The ordinary scoping rule applies.


You've lost me, I'm afraid...

C++ method call: foo.munge(bar);
Equivalent Lisp call: (munge foo bar)

The C++ function specializes on the first argument, that is to say "foo".
The language doesn't support multi-methods, so if you want to specialize on
bar as well, you'll have to do it by hande.


In other words, the statement "The body of a method in Lisp is not in
some special scope in which the symbols denoting the variables of a
class are magically bound to those slots." is garbage because it implies
the existence of a language feature in C++ that doesn't exist. [And
isn't needed.]

- Gerry Quinn
Jul 22 '05 #402
In article <QUrid.355735$3l3.229855@attbi_s03>, se***********@lavos.net
says...
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:
That's because whatever 'class' functions you bolt on to Lisp, the
language is not object-oriented and never will be, except maybe at
package level. Deal with it.


It sounds like you're claiming that encapsulation is a integral part of
"object orientation". This comes up a lot in discussions of CLOS.


That's part of it. But my main point is that "object orientation" means
more than "allowing objects". You have to be oriented towards classes.
If you are oriented towards functions, or macros, you are not object-
oriented.

- Gerry Quinn
Jul 22 '05 #403
In article <m3************@jcooper02.sagepub.com>, jo***@mail.com
says...
Gerry Quinn <ge****@DELETETHISindigo.ie> writes:
Now I have eliminated a source of typos and made the code much more
readable. Note that a function will not work for this because I am
establishing lexical bindings for "...some code..."


Sure, that's a reason why you might want to use this. And I think, if
you are making the point that this should not be called 'self-modifying
code' in the proper sense, you do have a point - you are manipulating
strings in a way that might be handled elsewise in another language. If
you look at the above, it's really data you are manipulating, not code.


No, I am not manipulating strings or data, I am manipulating code.
Although C macros work on strings, Lisp macros do not, despite the
fact that the Lisp source code does reside in a file. This is because
the Lisp reader parses the expressions for me and hands my macro a
data structure. This particular example is rather simple, but there
are plenty of other uses of macros in which a code 'tree' is
traversed, examined and transformed. This is far more powerful than
simple string substitution as C has.


There is no firm dividing line between data and code. Data is
structured code. Code is executable data. Your first example looks
more like data to me, your second looks more like self-modifying code.
But in any case, this kind of stuff can be dealt with in any high-level
language.
However, there are those who feel that defining new syntax is too
powerful a feature for a language, they should stay clear of this sort
of thing.


And their are those who are more interested in 'clever' programming than
in producing useful software - they will doubtless love it.

- Gerry Quinn

Jul 22 '05 #404
In article <m3************@scimul.dolphinics.no>, newsmailcomp5
@gustad.com says...
Gerry Quinn <ge****@DELETETHISindigo.ie> writes:
In article <cm**********@uns-a.ucl.ac.uk>, a.********@ucl.ac.uk says...
> I would say "self-modifying code" includes any program in which code is
> generated and executed as part of the expected output of the program.
> It's no longer running itself as originally written.

Well, you can do that in Lisp, but it's not usually encouraged. Usually you
generate the code at compile time (using macros) and thus there is no
self-modifying code by your definition.

You're also using a somewhat odd definition of "self-modifying". This is
generally taken to mean code which actually changes existing code at
runtime, rather than just adding more code.


I disagree - it is in fact rare for code to be changed per se. What
would be the point in writing code whose only purpose is to be written
over? Whether original code is erased or not is completely irrelevant
to the issue of whether code is self-modifying. The *program* is still
self-modifying.


You are describing a program-generating program as self-modifying.


Not unless the output of the generated program is an expected part of
output of the original program.
Using your discription every compiler which can execute its generated
code would be self-modifying (like a Common Lisp compiler). I think
Not if there is a division between the outputs, as there is in this
example. A compiler is not self-modifying code. It modifies the code
of a distinctly different program.
many people (including myself) will disagree with you, e.g. see:
http://en.wikipedia.org/wiki/Self_modifying_code I have only heard the term self-modifying in the context where the
program will modify the some of its following instructions. The
purpose is to implement adaptive algorithms and to save program
memory. Self modifying code has been known to cause problems with the
CPU instruction cache. However, self-modifying programs are not so
common since memory is cheap and almost all CPU's have instruction
caches where one would like to keep a high hit-ration as possible.


Surely the insistence that there must be some original code to be
written over is purely arbitrary and irrelevant? When code generated by
the program is executed, it is completely irrelevant whether it was
written in a portion of memory that contained some original source.

// Program A:

PUT_CODE_HERE:
NOP
NOP
NOP
NOP
GenerateCodeAt( PUT_CODE_HERE );
ExecuteCodeAt( PUT_CODE_HERE );

// Program B:

void* putCodeHere = (void*)( new opSizeItem[ 4 ] );
GenerateCodeAt( putCodeHere );
ExecuteCodeAt( putCodeHere );

They are both self-modifying, aren't they?
- Gerry Quinn

Jul 22 '05 #405
In article <87************@nyct.net>, rj***@nyct.net says...
Gerry Quinn <ge****@DELETETHISindigo.ie> writes:
You just don't get it, do you? Object-orientation is about program
architecture as well as language features. It's not about mixing and
matching a multiplicity of 'paradigms'.


Oh really? So you shouldn't use imperative code in an OO application?
Interesting.


You should write it in its place, and not elsewhere.
OO as 'language feature' is cargo-cult OO.


Yes, we're not true cultists, sorry. We don't follow the One True Way of
typopace (type/scope/namespace) object orientation in every line of our
code. We'd rather write each section of code in a way that allows that
code to make as much sense and be as maintainable as possible. We're
horrible people.


You can be oriented to objects, or oriented to something other than
objects. Your choice. What you can't do is say "here's the OO language
feature, we're not going to use it much but just because it's there our
programs must be object-oriented."

- Gerry Quinn

Jul 22 '05 #406
Gerry Quinn <ge****@DELETETHISindigo.ie> writes:
In article <QUrid.355735$3l3.229855@attbi_s03>, se***********@lavos.net
says...
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:
That's because whatever 'class' functions you bolt on to Lisp, the
language is not object-oriented and never will be, except maybe at
package level. Deal with it.
It sounds like you're claiming that encapsulation is a integral part of
"object orientation". This comes up a lot in discussions of CLOS.


That's part of it. But my main point is that "object orientation" means
more than "allowing objects". You have to be oriented towards classes.


If you are oriented towards functions, or macros, you are not object-
oriented.


This statement is confusing to me- C++ is plenty oriented towards all
those things. As is every other language that claims to be
"object-oriented"- leaving aside a precise definition of that for a
moment. Lisp's model of datatypes and code makes everything a
first-class object, which seems to me to make it more thoroughly
oriented towards objects than something like C++.

Gregm
Jul 22 '05 #407
Gerry Quinn wrote:
But my main point is that "object orientation" means
more than "allowing objects". You have to be oriented towards classes.
If you are oriented towards functions, or macros, you are not object-
oriented.


If you are oriented towards classes, you are class-oriented, not
object-oriented. (I am only half-joking.)

In Common Lisp, functions, macros, classes etc., are also objects. Go
figure. ;)
Pascal

--
Pascal Costanza University of Bonn
mailto:co******@web.de Institute of Computer Science III
http://www.pascalcostanza.de Römerstr. 164, D-53117 Bonn (Germany)
Jul 22 '05 #408
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:
And their are those who are more interested in 'clever' programming than
in producing useful software - they will doubtless love it.


You cannot dismiss a powerful feature of a programming language by
disparaging the motivations of those who use the feature. The feature is
powerful, and that is that.

As for those who use the feature, it is always about producing software.
Great athletes do not make fancy moves to show off*, they do it to fake
the fullback out of his jockstrap on their way to the goal.

If you check that Lisp newbie survey, you will find a whole category for
folks who, before they discovered Lisp, had crudely re-invented some
unusual capability of Lisp, precisely because they were reaching for the
expressive power it promised.

Does every programmer feel held back by Java/C++/whatever? No. We once
discovered a consultant had cut and pasted fifteen lines of Vax Basic
twenty times; changing each time the three variables to make the code
work in the new context, rather than create a function with three
parameters.

But any good programmer is certainly held back by lesser languages. I
found Lisp because, well, there is another category in the survey, for
those who went on an active search for a better way before they even
knew there was a better way, simply because they sensed that they were
being held back by their languages.

kenny
Jul 22 '05 #409
On Fri, 5 Nov 2004, Gerry Quinn wrote:
That's part of it. But my main point is that "object orientation" means
more than "allowing objects". You have to be oriented towards classes.


There are a number of classless OO languages whose creators would beg to
differ.

--
fl****@flippac.org
Jul 22 '05 #410
On Fri, 5 Nov 2004, Gerry Quinn wrote:
You can be oriented to objects, or oriented to something other than
objects. Your choice. What you can't do is say "here's the OO language
feature, we're not going to use it much but just because it's there our
programs must be object-oriented."


Nobody's said that. They've said the /language/ is OO. C++ doesn't have
much of a better claim beyond the fact the type system needed explicit
extension to add OO to it.

--
fl****@flippac.org
Jul 22 '05 #411
Gerry Quinn <ge****@DELETETHISindigo.ie> writes:
SNIP ... (in which Gerry corrects my incomplete recollection of C++
access specifier semantics, including reminding me of the
long-forgotten 'friend' specifier, and the the default specifier is
private)

Thanks again for the information.
My habit is to start a class definition with:

class MyClass
{
public:
// member data
protected:
// member data
public:
// member functions
protected:
// member functions
};

(only without the comments). Ideally the first category should be
empty, and typically the fourth is biggest. Often I move stuff around
during development.
Very interesting. Thanks for sharing this information.

In CLOS, as others have already pointed out, you'd make the
distinction as follows (code below the body of the text):

1. define a package
2. within the package scope, define the class

*this is basic definition stuff*

3. export from the package those things that you want to have
visible from the outside.

*this adds public status* - for use by folks outside of the
package - but is only a _suggestion_ at this point

4. if you want to completely remove access to a symbol, unintern it
after the methods that use it are defined (obviously, it can't be
:exported either)

*this adds protected status wrt methods defined while the symbol
was interned* - in other words, they will be able to access it,
but no one else will

*this adds private status wrt methods defined after the symbol
has been uninterned* - all methods after the (unintern ...), as
well as those external to the package will not be able to use it
I can't think of how to trivially support the friend semantics.
One minor dilemma I often encounter is whether to use accessor
functions to get at protected data. Ideally, I suspect, a class
should have its own internal accessors, but that is too much
typing, so it remains conceptual! I do sometimes implement it in a
small way, i.e. with a public const accessor, and a protected
non-const accessor/mutator.


In CLOS, you can get at slots by using (slot-value obj 'slot-name)
Since this returns a *place*, you can (setf ..) it for a mutator.
If you want, you can specify the name of an :accessor (or a :reader
/ :writer) function that CLOS will create to hide the (slot-value
..) bit.

(defpackage "my-package"
(:use "COMMON-LISP")
(:export my-package::person))

(in-package "my-package")

(defclass person ()
((name :accessor person-name :initarg :person-name :initform "Bonzo")
(age :writer person-age :initarg :person-age :initform 15)
(height :reader person-height :initarg :person-height :initform 70)))

(defclass person2 (person)
((weight :initarg :person-weight :initform 180)))

(defmethod weigh-em ((the-victim person2))
(slot-value the-victim 'weight))

(let ((bonzo (make-instance 'person2)))
(format t "~A is ~A pounds.~%"
(person-name bonzo)
(weigh-em bonzo)))

(unintern 'weight)

(let ((bob (make-instance 'person2 :person-name "Bob" :person-weight 150)))
(format t "~A is ~A pounds.~%"
(person-name bob)
(weigh-em bob))
(format t "~A is ~A pounds.~%"
(person-name bob)
(slot-value bob 'weight)))

-------------------------------------------------------------
Upon loading, this yields:

CL-USER 1 > (load "~/Desktop/person.lisp")
; Loading text file /Users/ipmonger/Desktop/person.lisp
Bonzo is 180 pounds.
Bob is 150 pounds.

Error: The slot WEIGHT is missing from #<PERSON2 100B635B> (of class #<STANDARD-CLASS PERSON2 100AFD83>), when reading the value.
1 (continue) Try loading ~/Desktop/person.lisp again.
2 Give up loading ~/Desktop/person.lisp.
3 Try loading another file instead of ~/Desktop/person.lisp.
4 (abort) Return to level 0.
5 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed, or :? for other options

my-package 3 : 1 > :c 5
-------------------------------------------------------------

At the REPL you'd do (assuming it's already loaded):

CL-USER 4 > (use-package "my-package")
T

CL-USER 5 > (make-instance 'person)
#<PERSON 100D1AE3>

CL-USER 6 > (make-instance 'person2)

Error: PERSON2 is not the name of a class
1 (continue) Try finding the class PERSON2 again
2 (abort) Return to level 0.
3 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed, or :? for other options

CL-USER 7 : 1 > :c 3
Jul 22 '05 #412
In article <b7**************************@posting.google.com >,
pe***********@swipnet.se says...
chris <ca*@cs.york.ac.uk> wrote
>Class method call:
> C++: Rabbit::jump(rabbit, 3)
> Lisp: (jump rabbit 3)

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..


Most likely you wouldn't, but if you wanted it, that's how it would
look like. Maybe I should have just written f(a, b) / a.f(b) /
T::f(a, b), but I kind of wanted to go with the "rabbit jump" thing.


My diagnosis is that you don't actually know C++. Your function
"Rabbit::jump(rabbit, 3)" makes no sense whatsoever. If the rabbit is
being told to jump, it doesn't need to be told it's a rabbit. And if it
is jumping over another rabbit, the other rabbit should be passed as a
reference, not a copy.

- Gerry Quinn

Jul 22 '05 #413
In article <cm**********@services.kq.no>, sv*******@aas.no says...
Gerry Quinn wrote:

One minor dilemma I often encounter is whether to use accessor functions
to get at protected data. Ideally, I suspect, a class should have its
own internal accessors, but that is too much typing, so it remains
conceptual! I do sometimes implement it in a small way, i.e. with a
public const accessor, and a protected non-const accessor/mutator.

There's an advantage of Lisp right there, then. It's very, very easy to
define accessor methods (or separate reader and writer methods, if that
fits better), and if you later change the contents of the slot (or remove
it), you can just remove the accessor declaration and define your own to
fit the new slot.

It's what I suspect you wanted to do, and the compiler is smart enough that
accessor calls don't neccessarily involve function calls, especially if you
use type declarations.


No, it's pretty easy in C++ too, just a bit of a chore. I doubt there
is any real difference.

- Gerry Quinn

Jul 22 '05 #414
In article <kt***************************@nyctyp02-ge0.rdc-nyc.rr.com>,
kt*****@nyc.rr.com says...

But any good programmer is certainly held back by lesser languages. I
found Lisp because, well, there is another category in the survey, for
those who went on an active search for a better way before they even
knew there was a better way, simply because they sensed that they were
being held back by their languages.


And if Lisp programmers were demonstrably more productive and effective,
I'd take such claims seriously. As, more importantly, would those who
tend to hire programmers.

[Likewise for 'agile' programmers, or 'test-driven' programmers, or
'generic' programmers, or any other of the many varieties of silver
bullet programmers.]

- Gerry Quinn
Jul 22 '05 #415
In article <Pine.WNT.4.53.0411051737030.372@SLINKY>, fl****@flippac.org
says...
On Fri, 5 Nov 2004, Gerry Quinn wrote:
You can be oriented to objects, or oriented to something other than
objects. Your choice. What you can't do is say "here's the OO language
feature, we're not going to use it much but just because it's there our
programs must be object-oriented."

Nobody's said that. They've said the /language/ is OO. C++ doesn't have
much of a better claim beyond the fact the type system needed explicit
extension to add OO to it.


The other thing is that people actually DO program C++ in an OO fashion.
Not always, but often enough. Correct me if I'm wrong, but Lisp-ers
give a distinct impression of preferring generic programming.

- Gerry Quinn
Jul 22 '05 #416
On Sat, 6 Nov 2004, Gerry Quinn wrote:
The other thing is that people actually DO program C++ in an OO fashion.
Not always, but often enough. Correct me if I'm wrong, but Lisp-ers
give a distinct impression of preferring generic programming.


IM(limited)E, lispers code however they feel is best for the task.
Personally (as a non-lisper but with a related mindset) I often end up
with designs that look like OO designs in the large, I just don't find
traditional OO tools to be a useful means of doing programming in the
small (including the higher-level bits of code). Actually, I'll go a step
further - I don't find traditional OO tools to be a useful means of
analysing much (of my) programming in the small. I find they tend to offer
extensibility in all the wrong places, for example.

One thing I /do/ make a lot of use of is (sub)systems communicating in a
specified language. In fact, a current project has a setup that looks
suspiciously like threads-as-objects for pretty much that reason. Many of
my preferred constructs end up looking pretty close to the duals of OO
constructs, for that matter. Which makes a lot of sense if the traditional
OO constructs seem to be getting everything backwards.

--
fl****@flippac.org
Jul 22 '05 #417
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:
And if Lisp programmers were demonstrably more productive and effective,
I'd take such claims seriously.


There's at least one data point:

http://www.flownet.com/gat/papers/lisp-java.pdf

rg
Jul 22 '05 #418
In article <Pine.WNT.4.53.0411061254390.372@SLINKY>, fl****@flippac.org
says...
On Sat, 6 Nov 2004, Gerry Quinn wrote:
The other thing is that people actually DO program C++ in an OO fashion.
Not always, but often enough. Correct me if I'm wrong, but Lisp-ers
give a distinct impression of preferring generic programming.
IM(limited)E, lispers code however they feel is best for the task.
Personally (as a non-lisper but with a related mindset) I often end up
with designs that look like OO designs in the large, I just don't find
traditional OO tools to be a useful means of doing programming in the
small (including the higher-level bits of code). Actually, I'll go a step
further - I don't find traditional OO tools to be a useful means of
analysing much (of my) programming in the small. I find they tend to offer
extensibility in all the wrong places, for example.

One thing I /do/ make a lot of use of is (sub)systems communicating in a
specified language. In fact, a current project has a setup that looks
suspiciously like threads-as-objects for pretty much that reason. Many of
my preferred constructs end up looking pretty close to the duals of OO
constructs, for that matter. Which makes a lot of sense if the traditional
OO constructs seem to be getting everything backwards.


'Dual' is a word that has occurred to me in this context. Certainly we
can imagine (broadly) a scheme in which generic functions act as a dual
for classes in OO programming.

But the Lisp-ers on this thread seem to be heading for the notion of
making everything first-class. Which can only be its own dual.

Of course I have sub-systems that communicate too, but they are objects.
Possibly the languages they use tend to be less sophisticated, but they
serve my purposes well enough.

- Gerry Quinn



Jul 22 '05 #419
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:
In article <kt***************************@nyctyp02-ge0.rdc-nyc.rr.com>,
kt*****@nyc.rr.com says...

But any good programmer is certainly held back by lesser languages. I
found Lisp because, well, there is another category in the survey, for
those who went on an active search for a better way before they even
knew there was a better way, simply because they sensed that they were
being held back by their languages.


And if Lisp programmers were demonstrably more productive and effective,
I'd take such claims seriously.


Claims? What claims? Those are good programmers who answered my survey
by saying they went looking for a better way and found it. Do you think
that survey is a mass conspiracy to promote Lisp? If so, why have C++
guru's joined the conspiracy?:

http://www.mindview.net/WebLog/log-0025

Titled: "Thinking About Computing -- Bruce Eckel's Web Log"

Highlight film: "In recent years my primary interest has become
programmer productivity. Programmer cycles are expensive, CPU cycles are
cheap, and I believe that we should no longer pay for the latter with
the former.

How can we get maximal leverage on the problems we try to solve?
Whenever a new tool (especially a programming language) appears, that
tool provides some kind of abstraction that may or may not hide needless
detail from the programmer. I have come, however, to always be on watch
for a Faustian bargain, especially one that tries to convince me to
ignore all the hoops I must jump through in order to achieve this
abstraction. Perl is an excellent example of this...

"....This began with a 2-month love affair with Perl, which gave me
productivity through rapid turnaround. (The affair was terminated
because of Perl's reprehensible treatment of references and classes...

" After I had worked with Python (free at www.Python.org) for awhile a
language which can build large, complex systems I began noticing that
despite an apparent carelessness about type checking, Python programs
seemed to work quite well without much effort, and without the kinds of
problems you would expect from a language that doesn't have the strong,
static type checking that we've all come to "know" is the only correct
way of solving the programming problem.

" This became a puzzle to me: if strong static type checking is so
important, why are people able to build big, complex Python programs
(with much shorter time and effort than the strong static counterparts)
without the disaster that I was so sure would ensue?

" This shook my unquestioning acceptance of strong type checking
(acquired when moving from C to C++, where the improvement was
dramatic)...

" But deciding that [Java's] checked exceptions seem like more trouble
than they're worth (the checking, not the exception. I believe that a
single, consistent error reporting mechanism is essential) did not
answer the question "why does Python work so well, when conventional
wisdom says it should produce massive failures?"

The recurring theme here is much greater productivity (even in Perl)
when one can shed the syntactic strait jackets and find some other way
to get to program correctness. And that is what I am talking about when
I say some folks found Lisp because they knew there had to be a better
way, that they were being held back.

Gerry, the simple fact is that you would be much more productive in Lisp
than you are in C++. Python, too, but that is still pretty slow and a
bit of a hack as languages go. Here is another C++ guru:

http://www.artima.com/weblogs/viewpost.jsp?thread=4639

I will let Eckels summarize what you will find there (watch for the
phrase "could be much more productive"):

"Robert Martin is one of the long-time inhabitants of the C++ community.
He's written books and articles, consulted, taught, etc. A pretty
hard-core, strong- static type checking guy. Or so I would have thought,
until I read this weblog entry. Robert came to more or less the same
conclusion I have, but he did so by becoming "test infected" first, then
realizing that the compiler was just one (incomplete) form of testing,
then understanding that a weakly-typed language could be much more
productive but create programs that are just as robust as those written
in strongly-typed languages, by providing adequate testing."

As for how crazy this all sounds:

" Of course, Martin also recieved [sic] the usual "how can you possibly
think this?" comments. Which is the very question that lead [sic] me to
begin struggling with the strong/weak typing concepts in the first
place. And certainly both of us began as strong static type checking
advocates. It's interesting that it takes an earth-shaking experience
like becoming test-infected or learning a different kind of language to
cause a re-evaluation of beliefs."

kenny
Jul 22 '05 #420
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:
In article <kt***************************@nyctyp02-ge0.rdc-nyc.rr.com>,
kt*****@nyc.rr.com says...

But any good programmer is certainly held back by lesser languages. I
found Lisp because, well, there is another category in the survey, for
those who went on an active search for a better way before they even
knew there was a better way, simply because they sensed that they were
being held back by their languages.


And if Lisp programmers were demonstrably more productive and effective,
I'd take such claims seriously. As, more importantly, would those who
tend to hire programmers.

[Likewise for 'agile' programmers, or 'test-driven' programmers, or
'generic' programmers, or any other of the many varieties of silver
bullet programmers.]


Speaking of silver bullets (defined as an order of magnitude improvement
by Brooks), I first experimented with a Lisp (in the form of Logo)
because I once saw Lisp described as a 4GL, where 4GL was defined simply
as an order of magnitude better than 3GL. This was shocking to me,
because I knew just enough Lisp to know that it was nothing like most
4GLs with their automatic database and screen building.

After three days of Logo, I understood. :)

kenny
Jul 22 '05 #421
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:
In article <Pine.WNT.4.53.0411051737030.372@SLINKY>, fl****@flippac.org
says...
On Fri, 5 Nov 2004, Gerry Quinn wrote:
You can be oriented to objects, or oriented to something other than
objects. Your choice. What you can't do is say "here's the OO language
feature, we're not going to use it much but just because it's there our
programs must be object-oriented."

Nobody's said that. They've said the /language/ is OO. C++ doesn't have
much of a better claim beyond the fact the type system needed explicit
extension to add OO to it.


The other thing is that people actually DO program C++ in an OO fashion.
Not always, but often enough. Correct me if I'm wrong, but Lisp-ers
give a distinct impression of preferring generic programming.


You mean generic functions? Anyway, I would say you have gotten the
wrong impression, possibly because gurus Richard Gabriel and Paul Graham
loathe and despise OO. You may also be seeing what seems to me a general
failure of OO to win the hearts and souls of programmers. Even when they
use it, they do not use it much.

kt
Jul 22 '05 #422
Kenneth Tilton <kt*****@nyc.rr.com> wrote in message news:<kt***************************@nyctyp02-ge0.rdc-nyc.rr.com>...
But any good programmer is certainly held back by lesser languages. I
found Lisp because, well, there is another category in the survey, for
those who went on an active search for a better way before they even
knew there was a better way, simply because they sensed that they were
being held back by their languages.


"Certainly" ?

I'd rather say for a good programmer there's no such thing as a
"lesser language". You either get the job done or you don't.
Everything else are sorry excuses.

~velco
Jul 22 '05 #423
ve***@fadata.bg (Momchil Velikov) writes:
I'd rather say for a good programmer there's no such thing as a
"lesser language". You either get the job done or you don't.
Everything else are sorry excuses.


Yes, thanks to Greenspun's Tenth Law.
--
__Pascal Bourguignon__
Jul 22 '05 #424
In article <87**************************@posting.google.com >,
ve***@fadata.bg (Momchil Velikov) wrote:
Kenneth Tilton <kt*****@nyc.rr.com> wrote in message
news:<kt***************************@nyctyp02-ge0.rdc-nyc.rr.com>...
But any good programmer is certainly held back by lesser languages. I
found Lisp because, well, there is another category in the survey, for
those who went on an active search for a better way before they even
knew there was a better way, simply because they sensed that they were
being held back by their languages.
"Certainly" ?

I'd rather say for a good programmer there's no such thing as a
"lesser language".


Well, let's not get into word-quibbles. 6502 assembler is a fine
language, but the subject here is getting real projects done. Folks
worked out a while ago that an HLL would let programmers think at a
higher level of abstraction without mug cost; a good compiler might even
outdo some handcoded assembly language. So 6502 is sweet, but as far as
productivity goes it simply does not measure up.

As Eckel said, the key is programmer productivity, and an order of
magnitude improvement in that is worth a few cycles one might save by
coding in assembler (tho I guess he was contrasting Python with C++,
which is quite a bit more than a few cycles.).
You either get the job done or you don't.
Well, I keep pointing out that Lisp programmers tend also to kick ass in
more popular languages. They do get the job done. And they find Lisp
precisely because they are the best programmers and have ideas their
current languages cannot handle.

The guy who cuts and pastes code because they are not sure of the syntax
of a function in Vax Basic is most certainly not noticing metapatterns
in code which could be handled by procedural macros.
Everything else are sorry excuses.


Same answer. Who needs an excuse when they are the best in the shop and
deliver C++ or Java or Cobol faster than anyone else in the shop?

kenny
Jul 22 '05 #425
Kenneth Tilton <kt*****@nyc.rr.com> writes:
Well, let's not get into word-quibbles. 6502 assembler is a fine
language, but the subject here is getting real projects done. Folks
worked out a while ago that an HLL would let programmers think at a
higher level of abstraction without mug cost; a good compiler might even
outdo some handcoded assembly language. So 6502 is sweet, but as far as
productivity goes it simply does not measure up.
Yes, it does. Just implement a lisp on 6502 and you're done.

As Eckel said, the key is programmer productivity, and an order of
magnitude improvement in that is worth a few cycles one might save by
coding in assembler (tho I guess he was contrasting Python with C++,
which is quite a bit more than a few cycles.).


Of course, the difference is made by a programmer who would try to do
all his application in 6502 and the one who will implement the lisp on
6502 and do the application in lisp.
--
__Pascal Bourguignon__
Jul 22 '05 #426
Gerry Quinn wrote:

[about "self-modifying code", under which heading Gerry apparently
includes code generated by Lisp macros. (And C++ templates? And the
C preprocessor?)]
Surely the insistence that there must be some original code to be
written over is purely arbitrary and irrelevant? When code generated by
the program is executed, it is completely irrelevant whether it was
written in a portion of memory that contained some original source.

// Program A:

PUT_CODE_HERE:
NOP
NOP
NOP
NOP
GenerateCodeAt( PUT_CODE_HERE );
ExecuteCodeAt( PUT_CODE_HERE );

// Program B:

void* putCodeHere = (void*)( new opSizeItem[ 4 ] );
GenerateCodeAt( putCodeHere );
ExecuteCodeAt( putCodeHere );

They are both self-modifying, aren't they?


No, neither of them is self-modifying. There is no code
being modified in either case. There is code being
*generated*.

You are welcome to think that this is just as bad as
(what I'd call) self-modifying code. It seems fairly
clear to me that it isn't, but I don't know what your
reasons are for disapproving of self-modifying code;
maybe those reasons all apply equally to code generation.

--
Gareth McCaughan
..sig under construc
Jul 22 '05 #427
Pascal Bourguignon <sp**@mouse-potato.com> writes:
Of course, the difference is made by a programmer who would try
to do all his application in 6502 and the one who will
implement the lisp on 6502 and do the application in lisp.


It must have been around 1981 when I wrote my first LISP
functions into a computer (I might have written LISP functions
before - but only on paper). I still remember, writing a
"flaten" function for Lists. This was done using a 6502-Lisp,
called "HGL-Lisp".

It ran on my Pet 2001, i.e., on a 6502. I had bought HGL-Lisp
personally from its developer, Hans-Georg L.[1], who lived in
Berlin. I believe, there were few items sold and nowadays this
Usenet posting might be the only record (available via Usenet
or Web) of the existence of this Lisp implementation called
"HGL-Lisp".

[1] I know his full name, but I do not know, whether he wants
it to be published on the Usenet. I also have lost track of
him for a long time.

Jul 22 '05 #428
Gerry Quinn <ge****@DELETETHISindigo.ie> writes:
In article <b7**************************@posting.google.com >,
pe***********@swipnet.se says...
chris <ca*@cs.york.ac.uk> wrote
>>Class method call:
>> C++: Rabbit::jump(rabbit, 3)
>> Lisp: (jump rabbit 3)
>
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..


Most likely you wouldn't, but if you wanted it, that's how it would
look like. Maybe I should have just written f(a, b) / a.f(b) /
T::f(a, b), but I kind of wanted to go with the "rabbit jump" thing.


My diagnosis is that you don't actually know C++. Your function
"Rabbit::jump(rabbit, 3)" makes no sense whatsoever. If the rabbit is
being told to jump, it doesn't need to be told it's a rabbit. And if it
is jumping over another rabbit, the other rabbit should be passed as a
reference, not a copy.


Eh?

1 There is only one rabbit there.
2 You have no way of knowing that it's being passed as a copy
rather than by reference; if the first argument to Rabbit::jump
was declared, say, as "const Rabbit &" then the call would
look just the same.

Of course jumping rabbits as such are of no relevance here;
here's a legitimate circumstance in which you could get a
function call of the kind you're saying is proof that Peter
doesn't know C++.

- Your program has a logging subsystem, based around
a class called Log whose instances are suitable
recipients for logging information.

- The Log class also has some static member functions;
for instance, there's one called "stringify" that
accepts an object reference and returns a string
that describes the object. This is in the Log class
because its behaviour is affected by a number of
parameters that are used elsewhere in the logging
subsystem.

- When a Log object is created and ready to start
logging, the first thing it does is to record some
information about itself for debugging purposes.

- This is done using the "stringify" function.

- So in Log::Log, or perhaps Log::begin or something
of the kind, you have some code that looks like this:

string s = Log::stringify(*this, some, other, parameters);
write_line(... some stuff involving s ...);

This isn't the exact same form as Peter's example, but
I think it's clearly just as "bad". The first argument
(passed by reference) is statically known to be of type Log,
after all.

Note: I don't claim that the above is great design,
and if I were actually designing a logging subsystem
I wouldn't expect it to look quite like that. But
it's certainly not crazy enough to warrant saying
that anyone who'd do it "doesn't actually know C++".

--
Gareth McCaughan
..sig under construc
Jul 22 '05 #429
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote
My diagnosis is that you don't actually know C++.
ROFL, again. Half a year ago I was randomly chatting with some
colleagues in university. The complexity of C++ came up, and I said,
half-jokingly: "I think only a half-dozen people in the world actually
know C++ really good". The other guy said: "Well, you know Henrik
[one of our 'visiting lecturers'] is really good at C++". To which I
had the perfect once-in-a-lifetime reply: "Of course! After all, *I*
taught him!"

Bottom line, I've used C++ professionally for quite a few years as a
programmer, and I've taught it for some years more. I know it well
enough.

You really shouldn't attempt to make up for your lack of solid
arguments by questioning other people's knowledge. Prove that
*you're* correct, instead of just shouting that *I'm* wrong.
Your function "Rabbit::jump(rabbit, 3)" makes no sense whatsoever.
Well, it *can* make sense, but that's not the point. You made the
point that C++ has a consistent syntax, and I demonstrated that it
does not, or at least not as consistent as Lisp's.
If the rabbit is being told to jump, it doesn't need to be told it's a
rabbit.
Presumably implemented as rabbit.jump(3), another example.
And if it is jumping over another rabbit, the other rabbit should be
passed as a reference, not a copy.


Firstly, how can you tell it's a copy and not a reference?

Secondly, it's still the case that if for some arcane reason it's
really imperative to call jump as a class method, there's no good way
of supplying the object that we wish to have jump except by passing it
as an argument. You may still say it's stupid and I might agree, but
it's valid C++.
Jul 22 '05 #430
In article <kt***************************@nyctyp01-ge0.rdc-nyc.rr.com>,
kt*****@nyc.rr.com says...
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:

And if Lisp programmers were demonstrably more productive and effective,
I'd take such claims seriously.
Claims? What claims? Those are good programmers who answered my survey
by saying they went looking for a better way and found it.


[Followed by some claims by two guys. Guys who may be eminent in the
computing field but whose primary work seems to be writing and
consulting. Guys who therefore have a vested interest in language churn
and silver bullets.]

What exactly did they *build* with their various flavour-of-the-month
languages?
Gerry, the simple fact is that you would be much more productive in Lisp
than you are in C++. Python, too, but that is still pretty slow and a
bit of a hack as languages go.


Why is that a fact? Can you point me to the Windows games and
screensavers written in these languages?

- Gerry Quinn

Jul 22 '05 #431
In article <87************@g.mccaughan.ntlworld.com>,
ga**************@pobox.com says...
Gerry Quinn wrote:

[about "self-modifying code", under which heading Gerry apparently
includes code generated by Lisp macros. (And C++ templates? And the
C preprocessor?)]


It might or might not. What I'm pointing out, after all, is that the
details of how the modified code is generated doesn't count.
Surely the insistence that there must be some original code to be
written over is purely arbitrary and irrelevant? When code generated by
the program is executed, it is completely irrelevant whether it was
written in a portion of memory that contained some original source.

// Program A:

PUT_CODE_HERE:
NOP
NOP
NOP
NOP
GenerateCodeAt( PUT_CODE_HERE );
ExecuteCodeAt( PUT_CODE_HERE );


No, neither of them is self-modifying. There is no code
being modified in either case. There is code being
*generated*.


NOP; NOP; NOP; NOP is code that is modified. Or if you object to this I
could change it to something that does something more interesting, or
would if it were not erased and replaced by alternative code.

The fact is it makes no difference. It is all about the level of the
generated code.

- Gerry Quinn
Jul 22 '05 #432

"Gerry Quinn" <ge****@DELETETHISindigo.ie> wrote in message
news:MP************************@news.indigo.ie...
In article <87************@g.mccaughan.ntlworld.com>,
ga**************@pobox.com says...
Gerry Quinn wrote:

It might or might not. What I'm pointing out, after all, is that the
details of how the modified code is generated doesn't count.
NOP; NOP; NOP; NOP is code that is modified. Or if you object to this I
could change it to something that does something more interesting, or
would if it were not erased and replaced by alternative code.

The fact is it makes no difference. It is all about the level of the
generated code.

- Gerry Quinn

Hi,
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.
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.
Jul 22 '05 #433
In article <b7**************************@posting.google.com >,
pe***********@swipnet.se says...
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote
Your function "Rabbit::jump(rabbit, 3)" makes no sense whatsoever.


Well, it *can* make sense, but that's not the point. You made the
point that C++ has a consistent syntax, and I demonstrated that it
does not, or at least not as consistent as Lisp's.

Secondly, it's still the case that if for some arcane reason it's
really imperative to call jump as a class method, there's no good way
of supplying the object that we wish to have jump except by passing it
as an argument. You may still say it's stupid and I might agree, but
it's valid C++.


Fair enough, and I apologise for doubting your knowledge of C++. I
think in part I was misled by your use of the term 'class method' for
what in a purely C++ context would usually be called a 'static method'.
Mainly though, it's probably just that the rabbit example is
exceptionally unsuited to an example of such a method! Sometimes
knowing a language can cause one to be blind to abnormal uses of it...

Of course C++ has a wide variety of usable function syntax, arguably too
wide. Though this is at a tangent to the original point of discussion
anyway.

- Gerry Quinn

Jul 22 '05 #434
"Gerry Quinn" <ge****@DELETETHISindigo.ie> wrote in message
news:MP************************@news.indigo.ie...
Claims? What claims? Those are good programmers who answered my survey
by saying they went looking for a better way and found it.


[Followed by some claims by two guys. Guys who may be eminent in the
computing field but whose primary work seems to be writing and
consulting. Guys who therefore have a vested interest in language churn
and silver bullets.]

What exactly did they *build* with their various flavour-of-the-month
languages?


Anybody else's irony meter pinging its glass casing? Lisp, with roots 40+
years old and a decade old ANSI standard being referred to as "flavour of
the month"!

--
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
Jul 22 '05 #435
Gerry Quinn wrote:

[I said:]
[about "self-modifying code", under which heading Gerry apparently
includes code generated by Lisp macros. (And C++ templates? And the
C preprocessor?)]
[Gerry:]
It might or might not. What I'm pointing out, after all, is that the
details of how the modified code is generated doesn't count.


I don't think it's at all obvious that the details don't
matter. One of the reasons for avoiding self-modifying code
is that programs that use self-modifying code are hard to
understand. The way in which the code is generated can
make a difference to how hard the program is to understand.
Surely the insistence that there must be some original code to be
written over is purely arbitrary and irrelevant? When code generated by
the program is executed, it is completely irrelevant whether it was
written in a portion of memory that contained some original source.

// Program A:

PUT_CODE_HERE:
NOP
NOP
NOP
NOP
GenerateCodeAt( PUT_CODE_HERE );
ExecuteCodeAt( PUT_CODE_HERE );


No, neither of them is self-modifying. There is no code
being modified in either case. There is code being
*generated*.


NOP; NOP; NOP; NOP is code that is modified. Or if you object to this I
could change it to something that does something more interesting, or
would if it were not erased and replaced by alternative code.

The fact is it makes no difference. It is all about the level of the
generated code.


I don't understand that last statement. What do you mean by it?

As I hinted in the grandparent of this article, it would
be helpful if you'd explain exactly what you consider to
be the reasons for disapproving of self-modifying (or, more
generally, generated) code. There are several possible
such reasons, and some of them but not others apply (at
least in some measure) to all code generation. Also,
some of them are (at least in some measure) bogus reasons. :-)

I'd say that there are several different questions that
need to be answered about an instance of code generation
before you can tell whether it's a Bad Thing or not. For
instance, and this is far from an exhaustive list,
- Does it happen at compile time or run time or what?
- Does the code responsible for generating it make
the function of the generated code clear? Preferably,
just as clear as the function of the normally-compiled
code in the program?
- Is any other code being replaced by the generated code?
- What determines whether or not the code gets generated,
and *what* code gets generated?
- Does the same code get modified several times during
the execution of the program?
- Is it necessary to understand exactly what's going on
with the code generation, in order to understand the
program?
- What safeguards are in place to ensure that the
code generation doesn't stomp on code that isn't
meant to be modified?

So, for instance, if you're writing code that looks like
this then it's pretty majorly bad. (My apologies to anyone
reading this in, e.g., comp.lang.lisp who may be offended
by the choice of C syntax...)

int do_something(int x) {
/* blah blah blah */
}

void hack_it(int a, int b, int c, const char * s) {
char * p = &do_something;
char t;
/* write preamble: */
*p++ = 0x90;
*p++ = 0xf3;
/* write main code */
while ((t=*s++) != 0) {
switch (t) {
case 'a':
*p++ = 0x83;
*p++ = 0x1f;
*p++ = a & 0xff;
break;
/* ... other equally hideous cases .. */
}
}
/* write postamble */
*p++ = 0xaa;
*p++ = 0xdc;
do_something(b);
flush_icache(&do_something, 0x100+(char*)&do_something);
}

Spotting all the things that suck about the crawling horror above
is left as an exercise for the reader. There are rather a lot.
But there are plenty of other things that can reasonably be called
code generation, and they don't all share all those problems.

Now, you've been describing Lisp macros as "self-modifying code".
I don't know how much you know about Lisp macros, but they are
certainly an *entirely* different kettle of fish from the nasty
C code above. Different enough that I can't imagine why anyone
would call them "self-modifying code".

--
Gareth McCaughan
..sig under construc
Jul 22 '05 #436
Gareth McCaughan <ga**************@pobox.com> writes:
So, for instance, if you're writing code that looks like
this then it's pretty majorly bad. (My apologies to anyone
reading this in, e.g., comp.lang.lisp who may be offended
by the choice of C syntax...)
Yes, you could have done it in lisp:

(defun do-something ())

(defun hack-it (args exprs)
(let ((ignored (gensym)))
(eval `(defun do-something ,(append args (list '&rest ignored))
(declare (ignore ,ignored)
(prin1 "entered do-something")
(unwind-protect (progn ,@exprs)
(prin1 "exiting do-something")))))))
To be used for example with:

(run-in-parallel-threads
(loop (apply (function do-something) '(1 2 3 4 5)) (sleep 1))
(loop for args in '((a) (x y) (z) ())
for expr in '(((print a)) ((print (+ x y)))
((setf z (z + (sin z))) (print z))
((print "Who I am?")))
do (hack-it args expr) (sleep (random 3))))

Spotting all the things that suck about the crawling horror above
is left as an exercise for the reader. There are rather a lot.
But there are plenty of other things that can reasonably be called
code generation, and they don't all share all those problems.
Well, here (and in your C source) it's rather controlled. For example,
I believe above hack-it function to be perfectly Common-Lisp
conformant.
Another case which could be frowned about would be if hack-it had
modified itself, or like this:

(defun hack-it (next-result)
(let ((result '(nil)))
(PROG1 (first result)
(SETF (first result) next-result)))

(list (HACK-IT 1) (HACK-IT 2) (HACK-IT 3)) ==> (NIL 1 2) ; on clisp
(list (HACK-IT 1) (HACK-IT 2) (HACK-IT 3)) ==> (NIL NIL NIL) ; on sbcl

But what about:

(DEFUN hack-it (payload)
(LABELS
((FIND-CAR (TOKEN TREE)
(COND
((ATOM TREE) NIL)
((EQ TOKEN (CAR TREE)) TREE)
(T (OR (FIND-CAR TOKEN (CAR TREE))
(FIND-CAR TOKEN (CDR TREE)))))))
(prog1 :result
(LET* ((SOURCE '(DEFUN hack-it (payload)
(LABELS
((FIND-CAR (TOKEN TREE)
(COND
((ATOM TREE) NIL)
((EQ TOKEN (CAR TREE)) TREE)
(T (OR (FIND-CAR TOKEN (CAR TREE))
(FIND-CAR TOKEN (CDR TREE)))))))
(prog1 :result
(LET* ((SOURCE ':QUINE)
(QUINE (COPY-TREE SOURCE)))
(SETF (CAR (FIND-CAR :QUINE QUINE)) SOURCE)
(SETF (CAR (FIND-CAR :result QUINE)) payload)
(eval QUINE))))))
(QUINE (COPY-TREE SOURCE)))
(SETF (CAR (FIND-CAR :QUINE QUINE)) SOURCE)
(SETF (CAR (FIND-CAR :result QUINE)) payload)
(eval QUINE)))))

(list (HACK-IT 1) (HACK-IT 2) (HACK-IT 3) (HACK-IT 4))
==> (:RESULT 1 2 3) ; on any Common-Lisp I believe.

Now, you've been describing Lisp macros as "self-modifying code".
I don't know how much you know about Lisp macros, but they are
certainly an *entirely* different kettle of fish from the nasty
C code above. Different enough that I can't imagine why anyone
would call them "self-modifying code".


--
__Pascal Bourguignon__
Jul 22 '05 #437
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote
Fair enough, and I apologise for doubting your knowledge of C++.
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.
Of course C++ has a wide variety of usable function syntax, arguably too
wide.


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.
Jul 22 '05 #438
Gerry Quinn <ge****@DELETETHISindigo.ie> writes:
Surely the insistence that there must be some original code to be
written over is purely arbitrary and irrelevant?


Did you read the wikipedia article? You seem to make you your own
definition of established terms. Same thing with object oriented
programming languages somewhere else in this thread.

Petter
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #439
In article <kt***************************@nyctyp01-ge0.rdc-nyc.rr.com>,
kt*****@nyc.rr.com says...
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:
The other thing is that people actually DO program C++ in an OO fashion.
Not always, but often enough. Correct me if I'm wrong, but Lisp-ers
give a distinct impression of preferring generic programming.


You mean generic functions? Anyway, I would say you have gotten the
wrong impression, possibly because gurus Richard Gabriel and Paul Graham
loathe and despise OO. You may also be seeing what seems to me a general
failure of OO to win the hearts and souls of programmers. Even when they
use it, they do not use it much.


I honestly don't care how Lisp-ers like program. And gurus appeal
mainly to those who want magic new 'paradigms' and associated jargon
that makes them feel clever.

- Gerry Quinn
Jul 22 '05 #440
In article <cm**********@news.ox.ac.uk>, rmagere@*the-mail-that-
burns*.com says...

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


Jul 22 '05 #441
In article <m3************@scimul.dolphinics.no>, newsmailcomp5
@gustad.com says...
Gerry Quinn <ge****@DELETETHISindigo.ie> writes:
Surely the insistence that there must be some original code to be
written over is purely arbitrary and irrelevant?


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
Jul 22 '05 #442
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:
In article <kt***************************@nyctyp01-ge0.rdc-nyc.rr.com>,
kt*****@nyc.rr.com says...
In article <MP************************@news.indigo.ie>,
Gerry Quinn <ge****@DELETETHISindigo.ie> wrote:
The other thing is that people actually DO program C++ in an OO fashion.
Not always, but often enough. Correct me if I'm wrong, but Lisp-ers
give a distinct impression of preferring generic programming.


You mean generic functions? Anyway, I would say you have gotten the
wrong impression, possibly because gurus Richard Gabriel and Paul Graham
loathe and despise OO. You may also be seeing what seems to me a general
failure of OO to win the hearts and souls of programmers. Even when they
use it, they do not use it much.


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
Jul 22 '05 #443
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...
Jul 22 '05 #444
In article <41********@duster.adelaide.on.net>,
"Maahes" <ma****@internode.on.net> wrote:
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...


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
Jul 22 '05 #445
>>>Class method call:
C++: Rabbit::jump(rabbit, 3)
Lisp: (jump rabbit 3)

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.



Jul 22 '05 #446
>> > Method call:
> C++: rabbit.jump(3)
> Lisp: (jump rabbit 3)


C: rabbit_jump(rabbit, 3)


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);

> Class method call:
> C++: Rabbit::jump(rabbit, 3)
> Lisp: (jump rabbit 3)


C++: Rabbit::jump(3)
C: rabbit_jump(3)

I don't know lisp, but it doesn't look right. A class call would have no
concept of a rabbit object as there is no data related to the class call.
So
what does the "rabbit" do in your line.


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.
> Well, *one* language has syntax that remains consistent throughout.

*two* languages.


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?


Jul 22 '05 #447
>> > 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...


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.

Jul 22 '05 #448
Greg Menke wrote:
chris <ca*@cs.york.ac.uk> writes:

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
Jul 22 '05 #449
>> > What is it that you use access specifiers for?

For protecting your implementation from the other programmers.
If you don't protect your variables and strictly define your interfaces,
and
limit their power, you'll find the other programmers will completely
misusing your code. Then when you go to rewrite it to provide new
features,
you'll find you can't because all the variables you want to trash are
being
used in critical parts of multiple projects.


Okay, so access specifiers are for protection.

In article <up*******************@news.indigo.ie>,
JKop <NU**@NULL.NULL> wrote:
Putting stuff in the "private" or "protected" section is purely for ease
of
use - it's *not* intended to "protect" the internals of the class.


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.


Jul 22 '05 #450

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

39
by: Peter Lewerin | last post by:
peter.lewerin@swipnet.se (Peter Lewerin) wrote > There is a paradigm > difference between CLOS and non-OOP Lisp code, but the language is the > same, and it's quite possible to mix the two. ...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.