[ ... ]
Of course they are, by special purpose I did not mean "single
application". FFT and DCT etc. was exactly what I was talking about.
Okay, so "special purpose" in your vocabulary translates to what most
people would call "extremely general purpose".
Bottom line: we're not talking about something extremely obscure that
virtually nobody ever has a reason to deal with, or anything like
that. We're talking about something that's reasonably representative
of what quite a few people really do on quite a regular basis.
[ ... ]
That this particular function is used in a wide array of gadgets
and programs, is really quite far besides the point.
It may be beside whatever point it was that you were trying to make,
but if so, it would seem to indicate that your "point" was really
pretty nearly pointLESS.
It seems to me that it is you who is conveniently forgetting that you
have been shown Lisp code that is shorter than your C++ code.
No, I have not. There was Lisp code shorter than the SPUC code -- _my_
C++ code is shorter still.
Of
course you think the C++ version "nicer", but don't pretend that's
anything but your subjective opinion.
The claim _seems_ to be that the Lisp code was better than the SPUC
code because it was shorter. If we take that as the measure, then my
C++ code is clearly better than the Lisp code that was posted.
I'm not convinced that's the case though -- both my code and the Lisp
code were shortened by introducing more indirection. While this often
increases convenience, it quite dependably slows execution speed. What
we have is a pretty clear tradeoff between size and speed. If you
don't need the speed, then the reduced size is an advantage, but
anybody making such a tradeoff should certainly realize that he hasn't
simply "improved" the code, but that he's changed the tradeoffs
involved.
In fact, I'd find it quite interesting to discuss your example from
another sub-thread.
Compare "h[n] = val/N;" to "(setf (aref h n) (/ val numtaps))".
Never mind that any person literate in both languages see these as
identical.
Close anyway.
The still leaves room for a fairly substantial and meaningful
difference though: that C++ is easily readable by quite a few people
who aren't familiar with C++ itself, but happen to be familiar with
Pascal, Fortran, BASIC, Java, or any number of other vaguely similar
languages.
By contrast, the Lisp is more or less unique to Common Lisp. Somebody
familiar with some older Lisp (e.g. ZetaLisp or MacLisp) or with
something like Scheme could probably take a pretty fair _guess_ at
what was going on, but that's about it -- setf has been implemented as
a macro in Scheme, but unless the Schemer in question happened to also
be familiar with Common Lisp as well, he really wouldn't know what was
going on.
This goes back to the (lack of) syntax in Lisp. Knowing one language
in the Algol/Fortran group tends to make quite a bit of almost any
other in the group fairly easy to understand. In Lisp, by contrast,
learning the syntax teaches you only syntax. That lets you identify
(to some extent) which things are going to be evaluated as
functions/special forms, but that's about it. Until you know exactly
what "setf" happens to mean, you can't divine anything about what this
might mean.
I do feel obliged to point out that Lisp's paucity of syntax doesn't
_have_ to spell the disasater embodied in CL. It's only a naming
convention, but at least when it's written at all well, Scheme is
clearly better in this respect -- setf would be named setf! (and let
is let!, etc.), predicates always end in "?", and so on, so the name
of a function can provide at least some information, whereas in CL you
have no more than a totally arbitrary association between a string and
some action.
I think my point above is illustrated even in these two
simple lines. Because, the Lisp syntax here (setf ..) scales very well
in terms of concepts and mechanisms. Once one learns to appreciate the
expressive power of Lisp's "places", of which "(aref h n)" is an
example here, it also becomes very natural to want to express array
elements as such places, and the idea that one should introduce
special syntax for this particular and mundane concept just to save
some characters of program text, or to emulate high-school maths,
becomes ridiculous.
Somehow I'm reminded of the old joke about the proud mother pointing
at her son in the parade and saying "Oh look, everybody's out of step
except my Johny."
"Once one learns to appreciate...it becomes natural" is a cheap
debating trick at best -- it basically translates to "Anybody who
disagrees with me on this point is stupid or ignorant." Unfortunately,
that's simply not a valid point.
The theoretical similarity of all Turing-complete languages has been
cited previously in this thread. There are real differences between
languages however: one is that a real language provides reasonably
syntax. Another is that a even though it is Turing complete, a real
language is defined to help solve problems in some specific category.
C++ provides a specialized syntax for array access for the simple
reason that this is often helpful in solving the problems for which it
is intended.
Lisp refuses to provide such special syntax. AFAICT, for the simple
reason that nobody has really ever pinned down what it's supposed to
be good at -- because its advocats persist in claiming that it's good
at everything. That result is a language that _could_ be good at
almost anything, but really _is_ good for almost nothing.
Lisp reminds me of one of my relatives: he's brilliant, athletic (or
used to be anyway), and good enough looking that even though he's now
past 60, he still attracts nearly every woman within miles. Deciding
what he was going to do when he grew up would have meant giving up
other things for which he really did have the potential. He refused to
do so, which has prevented him from concentrating on anything. The
result is that instead of missing out on some possibilities, he's
missed out on ALL of them.
The C++ syntax here, on the other hand, goes
nowhere. Points about syntax such as this is of course completely lost
on the casual reader of Lisp code, but they are valid and important,
nonetheless.
IOW, you like Lisp better, and dismiss all who disagree as lacking
your brilliant insights, etc., ad naseum.
Frankly, your lofty claims strike me as little more than hot air. Your
later guesses about C++ make it clear that you lack the knowledge
necessary to comment on it intelligently.
Let me point out that one needs to be a minimum of literate in any
language in order to be in a position where one can make any kind of
judgement on readability. That a language which you presumably rarely,
if ever, use extensively appears obscure to you, shouldn't surprise
you.
The code has an extra level of indirection. That has nothing to do
with my ability to read, and everything to do with how the code is
structured.
Your presumption that I rarely if ever make extensive use of the
language is simply incorrect -- in fact, if I chose to, I could put up
better arguments in its defense than you have so far (and Lisp I've
written is certainly better than the average of what's been posted so
far in this thread).
[ ... ]
Well, there's this concept called "exploratory programming" that I
really like and which is impossible with C++.
I believe any claim of the form "X is impossible in Y", where X is a
technique and Y is a major programming language, reflects ignorance or
dishonesty (or both) on the part of the person making the claim.
[ ... ]
It is you who is making unwarranted jumps here. I thought it obvious
from the context that "the bugs" refers to program errors resulting
from unexpected integer wrap-arounds. My point is simply that this is
something that does happen, even if 64-bit integers have been around
for a long time. And even 64-bit isn't immune to overflow.
I see -- so treating what you said as what you meant was an
"unwarranted jump". Okay, I guess from now on I'll know better than to
trust you.
In the end, we're left with one simple fact though: while people
certainly do write buggy code in C++ on a regular and ongoing basis,
integer overflows appear to account for no more than a miniscule
percentage of that.
I think you're tilting at a windmill here -- and AFAICT, the windmill
is imaginary.
[ ... ]
What you mean is that you have to start fighting the language: You'll
have two completely separate kinds of numbers, and you'll have to
concern yourself with which operators apply to which variables
etc.
Here we seem to nearly agree, but "It's like Lisp" is a lot more
succinct way of saying it.
And the compiler is left completely in the dark about what's
going on wrt. type inference etc., something I'd guess is true also
for C++.
Your guess indicates less about the subject than your ignorance of it.