"Maahes" <maa...@internode.on.net> writes: > > But of course, no Lisp programmer would write it this way. If you want a > > list, which contains all elements from n to 0, you can write it like this:
> > (defun make-down-list (n) > > (when (>= n 0) > > (cons n (make-down-list (1- n)))))
> I'll stress one last time - IMHO, the reason your not getting any converts > to Lisp from this thread is that those three lines look very complex to a C > program, simply because of the 5 brackets at the end of the last line. If I > wrote an IF statement with that many brackets, I have to be very careful > with it.. and I certainly wouldn't want to deal with that on every one of my > statements...
Your C++ example would look like magic to someone who wasn't conversant with the stl- if thats in fact what you're using. If it isn't, then I think your example is oversimplified.
I'm sure you're quite happy dealing with nested parens when writing arithemtic. Is there some reason why parens around code is different?
> I'll probably go off and learn some more lisp now, since all these posts > have made me think there might be a fabulous language there if you can get > past the excessive use of brackets...
C and C++ wouldn't be so bad if it weren't for all the semicolons.
> And its certainly a simple enough language to write your own compiler so > maybe I can play with that for a game. I doubt I'd have any luck convincing > anyone at work that our scripting language should be Lisp though... I don't > think most of our designers could handle all those brackets...
Can they handle the semicolons? If so, parentheses won't present any additional difficulty. But by all means, even if you don't use it at work, spend some time learning Lisp- it will certainly make you a better C/C++/Java programmer.
On Wed, 27 Oct 2004 14:33:01 +0000, Kenneth Tilton wrote: > 1. While working I can simply compile a changed (fixed or improved) > five-line function and re-run. Better, if this is an interactive > application which pauses for user input, I can do this during a pause, > then return to the application window and offer new input and see the > new code run. Or if I land in the debugger because of a bug in some > function, I can fix the function and then tell the debugger to > re-execute the stack frame which failed. Where the bug was actually in > some caller arbitrarily high up the call chain, I can tell the debugger > to restart /that/ frame.
This is not a language issue; this is a _tools_ issue. This is a question of whether or not your _debugger_ allows you to do this sort of thing; nothing in the C or C++ language specs prevents it.
> 2. Some bugs are not so obvious. The code looks fine, but they are > working on data which does not look right. My applications are modelled > in part with trees of long-lived instances. If I land in the debugger > while processing node X, I can have the debugger "return" the node to an > interactive command-line as a value I can then play with, say by passing > it to a custom bit of code which will traverse the tree looking for > anomalies. This can include developing new diagnostic code to traverse > the tree, all while my application is patiently waiting at the debug > prompt. I have many a time done this, found the problem, and not just > fixed a bug but refactored massively, including changing the class > hierarchy, and then discovered after hours of work that the debugger was > still waiting at the point where the application failed. And often it is > possible to simply say "try that again" and the application resumes > successfully.
Again, you're discussing _tool_ issues, not _language_ issues.
> 3. Hard bugs are hard bugs. We do not just find them, because all the > usual suspects had alibis. They seem impossible. I joke about having a > thousand monkeys typing, but in reality the many runs made sometimes > simply to make the bug reproducible are guided by decades of general > programming experience and complete knowledge of my design and it still > feels like monkeys typing. At unpleasant times like these, even a > twenty-second wait to recompile and link becomes an onerous burden to > anyone who has done development in an interactive environment.
And again...
>> there's plenty wondrous stuff written in C++ too.
> Hang on. Don't say "so what?". /You/ said you would not listen to anyone > who had not done a serious project. I did a serious project (several, > actually). Now you have to listen to me. :)
Sure, if you give us something that suggests there's a benefit to the language. So far, you haven't.
Why is Chevy better than Ford? Well, see, if I use Michelin radials, I get better road grip. Umm... so? That's a *tires* issue, has nothing whatsoever to do with why one car is better than the other. You keep giving us tires, while making claims about the cars.
On Mon, 25 Oct 2004 14:42:38 +0000, JKop wrote: > As for the issues raised being truly something you need to know about... do > you need to tell a child not to eat its own excrement? No. Why? It figures > that out for itself. If you're writing code and you have "new" all over the > place and you've no "delete"'s, then you'll figure out the aim of the whole > "Garbage Collection" ideal.
To hand-hold people who aren't bright enough to free memory they no longer need?
> This is not to say that Lisp, in the hands of an expert, is not an > incredibly powerful language which is fast and easy to program... But I > can't see it getting many converts from the land of C programmers...
I am one C (and Perl) programmer who switched to lisp; mainly because of lambdas/closures and macros. As someone who used to use pass around function pointers frequenty in order to customize the behavior of other functions, a Lisp closure is for me a huge huge win. And macros can save a huge amount of typing and code duplication; sure a function can often do the trick but there are cases when only a macro will do. The result of all this is extremely consise and clear code. Complaining about 'all those parentheses' is like saying XML would be great if it didn't have all those damn tags everywhere.
At least in my case I didn't come to Lisp until I was fed up with fighting with C to get it to do what I wanted it to. Early in my C career I hadn't had enough of these fights to realize yet why something like a closure or special var can be so useful. As far as macros, well I always had used C macros a lot; and of course a Lisp macro is an order of magnitude more powerful than a C macro.
Carl Muller wrote: > "Computer Whizz" <old486wh...@hotmail.com> wrote in message > <news:clq6pr$cmj$1@news6.svr.pol.co.uk>... >> I am also pointing out the fact that if Lisp is supposed to be good for >> the "newbie" then how come it looks WORSE off than every other >> programming language that I have "gazed" upon? >> It even looks worse than Assembler IMHO. Very confusing indeed. >> And I do try to be fair in my assessment, I do not want to attack Lisp's >> power etc in any way - just point out that the syntax isn't exactly >> "nice".
Christer Ericson <christer_eric...@NOTplayTHISstationBIT.sony.com> writes: > Read it again. The drawbacks with Lisp (GOAL) listed in the "what > went wrong" section have almost nothing to do with Lisp as a language, > but to do with the immaturity of their tools (often a problem with > proprietary tools), and the difficulty of finding employees who > grok Lisp.
That is, with the inability of management to advise lisp job in the right place or to offer decent wages.
As you said, what went wrong had nothing to do with lisp.
"Maahes" <maa...@internode.on.net> writes: > >> S = 1/2*a*sqr(t) + vi*t;
> >> I think all your brackets will put off most people wanting to experiment > >> with Lisp after using C/C++/Java/C#
> > and your object will never accelerate!
> Fine, if you want to be ANAL about it...
> S = 1.0/2.0*a*sqr(t) + vi*t;
> but your not adding anything to this thread...
And so goes a HUGE mistake that C and C++ programmers make all the time: using floating point arithmetic where it is not called for. Why do they do this? Because their language does not support rational arithmetic. And in classic "New Jersey"[1]-fashion, instead of solving the problem by doing the right thing, they just continue to repeat the same old mistake.
In any case, anyone who thinks that "S = 1/2*a*sqr(t) + vi*t;" is somehow "more normal" is speaking in a very subjective sense. If you want a notation that might be considered more "standard", how about ditching that ridiculous ASCII trash pretending to be math, and trying this:
> This is not a language issue; this is a _tools_ issue. This is a question > of whether or not your _debugger_ allows you to do this sort of thing; > nothing in the C or C++ language specs prevents it.
It's partly a language issue. Being dynamically typed makes certain kinds of alterations possible during runtime in Lisp that aren't possible in C++. Also, the concept of evaluating a general expression in a running C environment is pretty alien to the language; I doubt it would be at all easy to implement a C/C++ system which allowed this.
> Sure, if you give us something that suggests there's a benefit to the > language. So far, you haven't.
Have you been reading the thread? Anyway, here's my list. * Closures * Macros (ability to add your own control structures, etc.) * More sophisticated OO system (multiple dispatch, etc.) * Garbage collection. * More sophisticated exception handling system (allows restarts). * Better idioms for resource control (e.g. unwind-protect). * More paradigms suppported: Imperative, OO, functional, logic (if you use a library like Screamer).
And those are only (some of) the advantages of the language. The advantages of the tools shouldn't be dismissed either.
> On Wed, 27 Oct 2004 14:33:01 +0000, Kenneth Tilton wrote:
>> 1. While working I can simply compile a changed (fixed or improved) >> five-line function and re-run. Better, if this is an interactive >> application which pauses for user input, I can do this during a pause, >> then return to the application window and offer new input and see the >> new code run. Or if I land in the debugger because of a bug in some >> function, I can fix the function and then tell the debugger to >> re-execute the stack frame which failed. Where the bug was actually in >> some caller arbitrarily high up the call chain, I can tell the debugger >> to restart /that/ frame.
> This is not a language issue; this is a _tools_ issue. This is a question > of whether or not your _debugger_ allows you to do this sort of thing; > nothing in the C or C++ language specs prevents it.
>> 2. Some bugs are not so obvious. The code looks fine, but they are >> working on data which does not look right. My applications are modelled >> in part with trees of long-lived instances. If I land in the debugger >> while processing node X, I can have the debugger "return" the node to an >> interactive command-line as a value I can then play with, say by passing >> it to a custom bit of code which will traverse the tree looking for >> anomalies. This can include developing new diagnostic code to traverse >> the tree, all while my application is patiently waiting at the debug >> prompt. I have many a time done this, found the problem, and not just >> fixed a bug but refactored massively, including changing the class >> hierarchy, and then discovered after hours of work that the debugger was >> still waiting at the point where the application failed. And often it is >> possible to simply say "try that again" and the application resumes >> successfully.
> Again, you're discussing _tool_ issues, not _language_ issues.
>> 3. Hard bugs are hard bugs. We do not just find them, because all the >> usual suspects had alibis. They seem impossible. I joke about having a >> thousand monkeys typing, but in reality the many runs made sometimes >> simply to make the bug reproducible are guided by decades of general >> programming experience and complete knowledge of my design and it still >> feels like monkeys typing. At unpleasant times like these, even a >> twenty-second wait to recompile and link becomes an onerous burden to >> anyone who has done development in an interactive environment.
> And again...
>>> there's plenty wondrous stuff written in C++ too.
>> Hang on. Don't say "so what?". /You/ said you would not listen to anyone >> who had not done a serious project. I did a serious project (several, >> actually). Now you have to listen to me. :)
> Sure, if you give us something that suggests there's a benefit to the > language. So far, you haven't.
> Why is Chevy better than Ford? Well, see, if I use Michelin radials, I > get better road grip. Umm... so? That's a *tires* issue, has nothing > whatsoever to do with why one car is better than the other. You keep > giving us tires, while making claims about the cars.
Alex Drummond <a.drumm...@ucl.ac.uk> writes: >> No, it was the implementation of all those darned ()'s and spaces. >> I like the more natural way than that used in Lisp - that's all. >> It had nothing to do with Complex.
> Brackets: Lisp function calls have exactly the same number of brackets as C > function calls, the only difference is that the function name is inside the > brackets. You only have "extra" brackets in cases where C provides an infix > operator for a particular operation (e.g. addition). Unless you're doing > lots of arithmetic, Lisp syntax is just as natural as C syntax regarding > brackets.
One other thing that can be a bit confusing for folks who are coming from a C background is that you can't easily compose functions in C, so nested function calls look strange.
"Maahes" <maa...@internode.on.net> writes: > By bottom-up, I mean, your grouping all your lowest expression > together and then operating on them, and then operating on the > result of that.
>>If x is a function, then (f x y z) passes the function x to f. There's >>nothing wrong with this in Lisp, or in many other programming languages - >>it allows you to write things like map, the function that applies another >>function pointwise to every element in a list.
> Yes... While x has no parameters passed (or does it?). Does forgetting the > space (or common typo) mean that (f xy z) causes an error.
> "André Thieme" <address.good.until.2004.dec...@justmail.de> wrote in message news:clo166$1ij$2@ulric.tng.de... > >> Maahes schrieb: >> >> >>> Well, sounds like its probably very different to the lisp we used 15 years go. All we could seem to do is have lots of brackets with calls to functions embedded.. >>> >>> 2*(5+Speed)+Velocity >>> >>> looked something like: >>> >>> (+ (* 2 (5 Speed +)) Velocity) >>> >> >> One might easily think that Lispers accepted the brackets but still don't like them. In fact most Lispers even love them. The brackets (or any other mechanism that tells the compiler where an expression starts and ends) make many things easy. >> >> What if you want to compute something like that: >> a + b + c + d + e + f + g + h + i + j + k + l; >> >> (with usefull names) >> >> Here Lisp only needs one +: >> (+ a b c d e f g h i j k l) >> > > > Quite nice I suppose... Although I don't really mind adding those extra +'s.... Then again I can't really imagine just adding alot of variables together.
This was just an example regarding infix operators. The most common use for infix operators are functions which work on two arguments, like the addition. In CL the + has no special meaning like it has in C++, where it is an operator - in CL it is just a name. The could have called it also "add". Then it would look more common: add(100, 25); To make it shorter they called it +: +(100, 25);
Now remove the , and the ; and move the + inside the brackets and you have CL. That CL does not treat mathematical functions (which are usually written infix) different has the disadvantage that you need two brackets if you want to do it only one time, but on the other hand the advantage that it is a function which accepts any amount of arguments and saves some typing.
> > >> No need to look if there are other operators included. Anyway, if you need to do a lot of math then don't hesitate to use a math module, so you can write mathematical expressions like you are used to. >> >> That everything in Lisp uses the prefix notation can also make it very easy to learn. Some languages want a lot of syntax: >> ++c; c++; a+b; >> But most functions are using prefix anyway: >> f(x, y, z); or in Lisp >> (f x y z) > > > > That's horrible... What if 'x' was also a function name etc...
Image a C++ program where f and x are functions. What would happen if you do: f(x, y, z); Something "horrible". If you wanted to do f(x(), y, z); then it would be in Lisp: (f (x) y z)
> It just doesn't seem good to have the function name inside the ()'s to me.
This does not really mean much. In mathematics some people also write everything postfix: (x, y, z)f; [a "postfix C++"] (x y z f) [a "postfix Lisp"]
Use this five days and you don't see anything bad about it. In fact it is not the expression which is wrong.. it is the human brain which is so slow with adopting that. Your computer will accept any expression when you explain him how it is built. So in that way we can learn from our machines ;-)
>> and if you do in C f(x, y, g(z)); then you also need your brackets like the Lisp version; f(x y (g z)) > > > > Having the function name inside AND outside ()'s... I'll stick to the most common "always outside ()'s" thanks.
As others pointed it out: it was a typo from my side. The special thing about Lisp is, that if you know that (nearly always) the first thing in brackets is the name of a function and the rest are the arguments, then you nearly know all basics.
>> You don't need to remember stuff like "never put a semicolon after curly braces... as long they did not close a struct", etc... > > > > I don't remember that at all... I just put ','s in between the passed parameters. Just emphasises the difference between a space and a change of parameter. > > Say I wanted this in C++ > func(1, 2 + 3, a, "- b") > while in Lisp is seems it would be: > (func 1 (+ 2 3) a "- b") > but it's probably a tiny bit different.
Congrats to your first Lisp program! *g*
> What if I had forgotten the ()'s
What if you had forgotten them in C++? func(1, add 2, 3, a, "-b"); instead of func(1, add(2, 3), a, "-b");
If you are not using an infix operator in an expression then C++ always needs the same amout of brackets. And Common Lisps way to make +, -, *, etc NOT an operator but just normal functions is *good*. Why? Because you can just pass it as arguments to other functions! Imagine you have a function foo which accepts three arguments: one function and two arguments which will be passed to that function.
Something similar happens in quicksort() functions. You give them an array of objects (of a class) to sort and a function which does decide which object is "bigger" and which one is "smaller". But back to the "+" example: if you want to call foo with an addition function and two numbers in Lisp you could simply do that: (foo '+ 10 15)
But imagine to do this in C++: foo(+, 10, 15);
> inside and just had "func 1 + 2 3 a..." ,'s just "seperate" the parameters.
>>>>Not only that, + works when the numbers are complex as well:
>>>>(+ (complex 3 3) (complex 3 -3) 3) => 9
>>>>or even rational numbers
>>>>(+ 2/3 2/3 1/3) => 5/3
>>>Jesus! >>>*covers eyes* >>>It took me a couple of minutes to decipher that...
>>What was the difficult part? Did I confuse you with =>? => is not a >>part of Common Lisp, it's just a common way of showing the result of >>the function call.
>>>I really don't like that syntax at all!
>>It's the same /syntax/ as others have explained to you, e.g. (function >>arg1 arg2 ...). I just introduced a new function called /complex/ >>which will return a complex number given the real and imaginary part >>as argument.
>>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?
> Ha-ha... : ) > No, it was the implementation of all those darned ()'s and spaces. > I like the more natural way than that used in Lisp - that's all. > It had nothing to do with Complex.
You already showed in one example that you used the correct syntax. So if it was difficult for you this time that you probably did not look at it like you did before.
(+ 2/3 2/3 1/3) is in C++: 2./3. + 2./3. + 1./3. or also: (float)2/(float)3 + (float)2/(float)3 + (float)1/(float)3;
Now *that* is not so natural, is it? ;-)
In Lisp you not only have integers or floats, you also have rationals which are always accurate (but slower because they don't use the floating point unit) and even complex numbers. Complex numbers need some special way to write them down. This is similar to C where you need to say that 2 is a float by writing it either 2. or 2.0 or (float)2 or maybe float(2) C++ does not have complex numbers, Lisp does, and you write them down this way: #C(real i) for example #C(3 3) Of course + does work on complex numbers too. And you don't have to do explicit operator overloading and you are lucky, you don't need to write a class "Complex", *cheers*
> In article <ktilton-5B854B.10415227102...@nyctyp02-ge0.rdc-nyc.rr.com>, > ktil...@nyc.rr.com says... > > In article <MPG.1be987eae53acb2b989...@news.indigo.ie>, > > Gerry Quinn <ger...@DELETETHISindigo.ie> wrote:
> > > But > > > there's plenty wondrous stuff written in C++ too.
> > Hang on. Don't say "so what?". /You/ said you would not listen to anyone > > who had not done a serious project. I did a serious project (several, > > actually). Now you have to listen to me. :)
> I'm listening. But it'll take more than a few apparently successful > Lisp projects to convince me. Maybe I'm over-conservative, but even if > Lisp is all you say, the benefits of being an early adopter are dubious.
Agreed. Most IDEs are primitive compared to C/C++/Java IDEs. Libraries are scarcer, though that is beginning to improve a little.
The first Lisp IDE I used did not have an automatic project manager. But there are a couple of Lisp "make" tools, and my IDE was hackable (in Lisp), so I kinda just rolled my own project manager in a few hours. And now it is something I can tweak as I like, which is mad cool and also a traditional Lisp thing (building one's own little IDE).
And any time I want a library, I lose a few hours globally editing a C header file until it turns into a set of Lisp bindings to that library. Using a C++ library also means writing some C glue so Lisp can talk to it.
But those are finite tasks, and then I am back up to full speed using Lisp for months on end.
> Especially when Lisp has been touted the same way for about twenty > years. I've got lots of time to get on the bandwagon...
Yep. I found Lisp when looking for A Better Way than C to do version two of my commercial app. Something that would let me be vastly more productive, enough to make up for the occasional one-time effort. Believe me, Lisp roolz.
> On Wed, 27 Oct 2004 14:33:01 +0000, Kenneth Tilton wrote:
> > 1. While working I can simply compile a changed (fixed or improved) > > five-line function and re-run. Better, if this is an interactive > > application which pauses for user input, I can do this during a pause, > > then return to the application window and offer new input and see the > > new code run. Or if I land in the debugger because of a bug in some > > function, I can fix the function and then tell the debugger to > > re-execute the stack frame which failed. Where the bug was actually in > > some caller arbitrarily high up the call chain, I can tell the debugger > > to restart /that/ frame.
> This is not a language issue; this is a _tools_ issue. This is a question > of whether or not your _debugger_ allows you to do this sort of thing; > nothing in the C or C++ language specs prevents it.
> > 2. Some bugs are not so obvious. The code looks fine, but they are > > working on data which does not look right. My applications are modelled > > in part with trees of long-lived instances. If I land in the debugger > > while processing node X, I can have the debugger "return" the node to an > > interactive command-line as a value I can then play with, say by passing > > it to a custom bit of code which will traverse the tree looking for > > anomalies. This can include developing new diagnostic code to traverse > > the tree, all while my application is patiently waiting at the debug > > prompt. I have many a time done this, found the problem, and not just > > fixed a bug but refactored massively, including changing the class > > hierarchy, and then discovered after hours of work that the debugger was > > still waiting at the point where the application failed. And often it is > > possible to simply say "try that again" and the application resumes > > successfully.
> Again, you're discussing _tool_ issues, not _language_ issues.
> > 3. Hard bugs are hard bugs. We do not just find them, because all the > > usual suspects had alibis. They seem impossible. I joke about having a > > thousand monkeys typing, but in reality the many runs made sometimes > > simply to make the bug reproducible are guided by decades of general > > programming experience and complete knowledge of my design and it still > > feels like monkeys typing. At unpleasant times like these, even a > > twenty-second wait to recompile and link becomes an onerous burden to > > anyone who has done development in an interactive environment.
> And again...
> >> there's plenty wondrous stuff written in C++ too.
> > Hang on. Don't say "so what?". /You/ said you would not listen to anyone > > who had not done a serious project. I did a serious project (several, > > actually). Now you have to listen to me. :)
> Sure, if you give us something that suggests there's a benefit to the > language. So far, you haven't.
> Why is Chevy better than Ford? Well, see, if I use Michelin radials, I > get better road grip. Umm... so? That's a *tires* issue, has nothing > whatsoever to do with why one car is better than the other. You keep > giving us tires, while making claims about the cars.
I was responding to something someone wrote about not seeing the advantages of an interactive language. Come to think of it, I thought everyone liked interactive languages. Not sure why it needs explaining. The appeal gave birth to Python, and is giving birth to Groovy, which is Java's attempt at an interactive extension.
I have heard that some C/C++ tools make brave attempts at interactivity. If so, great. But I was just explaining to that one person why I liked an interactive language.
Ah, just thought of another one. Component Workshop. A now-deceased interactive C++.
As for language benefits: garbage collection, macros, special variables, untyped variables/typed data; the list datastructure; multimethods, editing-with-parentheses (shocked?); multiple-inheritance done right; the meta-object protocol; lexical scoping; closures; first-class functions; lack of syntax; native-compiled speed; reflection ala RTTI; the loop macro; &rest, keyword and optional arguments to functions; different kinds of method combinations; destructuring-bind (long story);...
Frank Buss <f...@frank-buss.de> writes: > But of course, no Lisp programmer would write it this way. If you want a > list, which contains all elements from n to 0, you can write it like this:
> (defun make-down-list (n) > (when (>= n 0) > (cons n (make-down-list (1- n)))))
> most Lisp implementations optimizes the tail-recursion to a jump, so > chances are good, that it is as fast as a normal loop.
But your make-down-list function is not tail recursive: it takes the result of the recursive call and gives it to CONS, instead of returning it directly. This makes it impossible to optimize the recursion to a jump.
André Thieme <address.good.until.2004.dec...@justmail.de> wrote: > C++ does not have complex numbers, Lisp does, and you write them down > this way: > #C(real i) > for example #C(3 3)
> I'm sure you're quite happy dealing with nested parens when writing > arithemtic. Is there some reason why parens around code is different?
absolultely NOT. Sometimes its unavoidable, especially complex IF statements, but its never a good thing when we have to do a line with lots of brackets, because its hard to read at a glance.
> Can they handle the semicolons? If so, parentheses won't present any > additional difficulty. But by all means, even if you don't use it at
I'll leave you to rethink that first statement coz I don't think it justifies an argument.
> work, spend some time learning Lisp- it will certainly make you a > better C/C++/Java programmer.
> Right, which is what I was indicating. It's no more a good idea to make > judgement calls about what's not appropriate for any (action) game based > on the limitations found on consoles any more than it is to judge > everything by PC standards.
I guarantee you if you program for a console, and port to PC, your PC version will run more efficiently... You won't be hitting as-fast-as-the-monitor-runs if your doing runtime garbage collection unless your game logic is so trivial that it doesn't tax the CPU anyway.. If your trying to push a 600mhz PC with complex gameplay, you won't be wasting cycles on that crap. If you have a 4ghz PC and don't care, why argue about performance anyway coz GC or Smart Pointers aren't going to tax your program if your using them intelligently.
<a.drumm...@ucl.ac.uk> wrote: >>>Have you ever seen a VB program segfault?
>> Plenty of times.
>I was wondering how long it would be before someone said that. Now, if >Visual Basic actually provides a direct means of attempting to access out >of bounds memory, you have a point, and I'd have to use some other high >level language as an example (I don't know for sure that it doesn't because >I don't know the language). If a VB program segfaulted via an external C >library (e.g. by passing incorrect arguments to some external function, >etc.) you're just being pedantic.
Its pretty near impossible in the latest incarnation (based on .NET) but earlier versions could easily be broken passing data to and from a COM control. Since COM integration was supposed to be one of VB's strengths, the relative ease of screwing it up was troublesome.
>> Definitions of "higher order" for functions vary but what C++ actually >> lacks natively is lexical closures - which can be emulated by function >> objects and nested classes.
>Not really. Function objects have to capture bindings manually, so the >emulation is rather clumsy. OK, you can use nested classes, but it's still >a PITA to define a class just to capture a few lexical bindings -- in Lisp >I can capture whichever bindings I like whenever I like, without any >hassle. The syntax for function objects is generally rather verbose. Using >higher order functions in C++ just isn't cheap enough to make it a widely >useful technique, especially when the types start getting complicated. If >you look at the kind of higher order functions which are trivial to write >in a strongly typed language like ML or Haskell, the type system of C++ is >just not up to the job regarding higher order functions. Of course, C++ is >not meant to be a functional language, and I'm not saying that it should >be. But some people like to pretend that it's trivial to simulate >functional programming features in C++, when it isn't.
I don't pretend it is trivial to emulate lexical closures in C++ and I completely agree that trying it is far from convenient. I'm not sure what constitutes "verbose" as regards function operators - you only define them once so it doesn't matter how ugly that is and calls look like any other function call.
Regarding higher order, I said definitions vary. It is certainly easy enough to pass functions as parameters and return them as results. The stumbling block to general effectiveness is the lack of easy closures.
>> This line of arguement is so ridiculous it almost doesn't merit >> response. I've coded professionally in C/C++ for almost 2 decades. >> I've written real time embedded software, network applications, an >> operating system and several compilers. I can count on my fingers the >> number of times I've been bitten by non trivial memory management >> problems. The same goes for most other experienced C/C++ programmers >> I've met - it just isn't an issue.
>That's funny, because I've only written small to medium sized programs in >C++, and I'm always getting bitten by nontrivial memory management issues >(e.g. you get nontrivial memory management issues if ever you want to have >complex expressions composed of objects without copying them, as you might >for example in a parser combinator library). There are plenty of very >experienced C++ programmers who say exactly the opposite of what you say >(many of them, of course, have subsequently moved to Lisp/Java/whatever). I >know I keep pointing to this, but if memory management is so trivial for >everyone, why would Boehm GC have been developed? See >http://www.hpl.hp.com/personal/Hans_Boehm/gc/issues.html, where he says for >example:
>"...commonly proposed estimates are that 30% or 40% of development time is >devoted to storage management for programs that manipulate complex linked >data structures. (See, for example, Rovner, ``On Adding Garbage Collection >and Runtime Types to a Strongly-Typed, Statically Checked, Concurrent >Language'', PARC CSL-84-7.)"
>Now I'm willing to bet that Hans Boehm has written a few big C++ programs in >his time.
I'm also willing to bet Boehm has written plenty of big programs. I also have written very big and complicated programs. I do question the statistic that 30% (or whatever) of development time is spent on memory management - I have never found that to be anywhere close to being true. I don't have rigorous numbers but a guesstimate based on my own experience would be closer to 5% for an experienced C++ coder.
It becomes automatic like breathing. Specifying how to cleanup is part of defining an object and complex data structures are modeled as objects. It is the second thing you do right after specifying how to construct the object. And notice I said "construct" rather than "initialize" ... those being separate concepts in C++.
It's largely a matter of coding dicipline and good design.
>> Decent C/C++ programmers who come to Lisp (or other GC'd languages) >> very quickly become spoiled by having Mom around to clean up after >> them. Because they now find themselves rarely thinking about memory >> management in contrast to the near constant awareness they had >> previously, the times they really had a problem stand out and tend to >> be exaggerated in their memories (though not intentionally I think).
>In other words, they realise what an enormous PITA memory management >actually is. You don't realise this until you do some serious programming >in a GC'd language. As you say, in C++ you have to maintain a "near >constant awareness".
Yes but as I said above, the "near constant awareness" is largely on auto pilot. You don't think about it as a problem because it's an integral part of your life.
>> OTOH, decent Lisp programmers who find themselves having to work in >> C/C++ have problems because they normally don't have to think about >> cleaning up after themselves and Mom isn't around to do it for them. >> So they tend to have problems whenever they confront C/C++ and thus >> have a distorted view of the reality of programming with it.
>Well, my view of programming in C++ is that it's rarely worth the effort. I >don't have any more problems with C++ than your average C++ programmer, I >don't think, I just /resent/ it more. Maybe this is what you meant.
That's exactly what I meant but I was coming at it from a different angle. Most complicated Lisp programs eventually end up in the FFI and I believe this is the source of most Lisp users' frustration with C/C++.
In my experience, people who learned lower level languages (C,C++,Pascal, etc.) first and then discovered the higher level languages have fewer problems changing gears than do people who learned the high level language first and learned the lower in order to work with the FFI.
>> I like Lisp (well actually I like Scheme better) far more than C++, >> but automatic memory management has little to do with my reasons. >> Learning to program involves learning effective resource management. >> I could easily argue that programmers who learn high level, GC'd >> languages first are done a disservice and are not as competent because >> they don't learn effective memory management.
>Yawn. If you learn C you don't learn effective processor register >management. If you suddenly find that you need to know about memory >management in detail, you can always buy a book on it, or indeed learn C, >if you think that would help. I'd also note that the ignorance goes the >other way.
Register management is not germane to this discussion - the subject of which is languages above the assembler level.
Memory is an important resource which must be managed even in Lisp. Witness the many newbies who get into trouble because they forgot to let go of bindings. Teaching using very high level languages results in important concepts being glossed over or ignored completely.
> Many C++ programmers have a poor knowledge of GC.
Many Lisp programmers do also. Out of sight means out of mind.
>> Programmer competency and experience are the real issues and they are >> independent of language.
>If they are the real issues, why are you making such a big deal out of Lisp >vs C++? Everyone knows that they're not the only issues. Anyone who's (say) >tried writing a text-munging program in C instead of Perl will know this. >Differences between languages are significant.
I don't give a rat about Lisp vs. C++ or whether you or anyone else here likes Lisp or C++. Somebody else started this "big deal" and others are still continuing it as I write this. I'm responding to what I considered to be an unfair characterization of one of the main topics of the discussion.
> But your make-down-list function is not tail recursive: it takes > the result of the recursive call and gives it to CONS, instead of > returning it directly. This makes it impossible to optimize the > recursion to a jump.
yes, you are right. Perhaps not so good as an example for tail-recursion:
(defun make-down-list (n &optional list) (let ((list (append list (list n)))) (if (> n 0) (make-down-list (1- n) list) list)))
But I'm sure it can be written simpler, even as a recursion.
"Maahes" <maa...@internode.on.net> writes: > > I'm sure you're quite happy dealing with nested parens when writing > > arithemtic. Is there some reason why parens around code is different?
> absolultely NOT. Sometimes its unavoidable, especially complex IF > statements, but its never a good thing when we have to do a line with lots > of brackets, because its hard to read at a glance.
You may rest assured that no-one who has become familiar with writing Lisp code has trouble with parentheses- which is what they are called- not brackets. Likewise, anyone who has become familiar with C doesn't have trouble with semicolons and curly braces.
> > Can they handle the semicolons? If so, parentheses won't present any > > additional difficulty. But by all means, even if you don't use it at
> I'll leave you to rethink that first statement coz I don't think it > justifies an argument.
I think it does. You see parentheses as problematic when it comes to understanding Lisp. I say semicolons are the same with C. Obviously you don't have trouble with semicolons, or braces for that matter- because you know C-like languages. My point is that semicolons, braces, parentheses are syntactical stuff that you learn quickly. I think the bigger problem you'll face is unlearning C, meaning, identifying and overcoming some of the unconscious design rules you've picked up about how software "should" be. Lisp takes a fundamentally different view in some respects- not as different as something like Prolog, but if you really want to start grokking Lisp, you'll end up having to relearn some things.
> > work, spend some time learning Lisp- it will certainly make you a > > better C/C++/Java programmer.
> entirely possible.
You'll look at programming differently afterwards.. good luck!