Hi, i have several years of Java experience, but now my new job requires me to learn Lisp. I find it terribly frustrating at times, and need to rant to just let some steam off. But maybe other have some helpful tips for me to get into it easier. Note I do not want to advocate Java over lisp, it's just the only other language I know well enough to compare. So no need to get all defensive and point out how much better I will still be off when I prefer Lisp over Java, this is not a Lisp vs. Java post, I do not love Java nor do I care how much you hate it.
My situation is that I need to extend an existing system of lisp sources written by somebody else who is not around anymore, and who did not exactly intent his code to be extended, in terms of how he documented it.
I imagine from the Graham articles I read that Lisp is really more for the kind of jobs that one does for oneself, green-field development. I already understand that Lisp gives freedom of how to express things that is incredible compared to Java, and also plenty of ways to "hack" as Paul Graham puts it. Now unfortunately these do not seem as a great advantage to me having to understand and extend a system written by somebody else.
What I use is emacs with slime and allergro lisp. I already tweaked emacs to the expectations of lame eclipse users like me. But still I miss some IDE features Java IDEs offer me. Some things I do in Java to get an overview of a system new to me would be like generating UML diagrams showing all classes and dependencies, showing inheritence hierarchies and such. Slime CLOS Object inspection seems to generally be able to do roughly similar things, but I have not seen any function to get such a high- level overview. I am used to methods being neatly organized in classes, and classes in package, but in Lisp it seems functions and such are just like dropped in packages, in hundreds per package. What I'd do next in Java with an existing system is rename classes and methods if they seem badly named to me. But it seems in Lisp this works only by search and replace, which is hardly what I could do over hundreds of files. What I also miss is a function like "mark occurences", such that when the cursor is over a variable or function, all places in the code where it is used are highlighted, making it easier to track where which data goes. Next on my list of disappointments is exception handling. I am used for an exception to have mostly meaningful messages and above all show me exactly which line of the code caused the exception. Currently all I get is the function in which it happened, even worse if it happened within a macro, i do not even get that. And the Stack looks superflous, like (/ 1 0) gave me 20 stack frames, where I'd expect 2 at most in Java. These 20 cannot all be relevant to (/ 1 0), can they? Stepwise debugging also seems to be impossible with my setup with allegro list, and unfortunately I have no choice in that matter. Next on my list is declarations, I am used for methods in java to declare both the type returned as well as all checked exceptions. Now I see this is not convenient if you want to stay flexible about returning different types, but really most of the times I expect functions in lisp systems return just one time, don't they? Now to find out that type, it seems I have to go recursively through all branches of a function expanding all macros hoping I will not miss anything. Can't there be anything helping me there? I could try wrapping all function bodies in (the <type> ...) but that does not look so slick. And the same applies to function parameters, if their type can be inferred automatically, why can't the IDE infer their types for me? Another thing that annoys me greatly is that compiling in Emacs can yield different results, even if the sources did not change, based on the state of the REPL. When I look through the existing code, I find plenty of things pretty dirty, at first sight, making it hard for me to extend the code unless I am sure I understood it all perfectly. I of course greatly miss the power of Java code completion, which comes with the restrictions of the Java OO system. It makes it so easy to most classes you see for the first time, because the IDE would suggest all methods of instances, while in lisp I have to first learn all defined functions until I will have a chance to pick the one I wanted. I also seem to read very little about standards about documenting, unit-testing, logging. Like in the java world, there is javadoc, JUnit, Log4J, and one can be confident most open source projects will use those to a reasonable extend. Of course the system i have to deal with does not have any such standards, and it seems to me that such standards are not of great concern to lispers. I found things like Stefil, cldoc, log5, as alternatives, but they do not seem like standards. What would help me greatly in java to get the idea of the code is the visibility of methods. If a method is private to a class, I know I must be able to understand its usage just in this class, and changes that I could make could only change things in this class. For functions in lisp it seems there is no telling where they might be used, especially since they could be used from within macros or (eval ...) expressions, even for functions not exported from the package, as lisp does not enforce visibility rules. What I also like about Java is how many web resources there are for java, plenty of tutorials, but mainly also plenty of problems people ran into like me, and how they solved them. Today I googled for "rethrowing errors", you know, as in handling exceptions of some type, but not all of those. I found no usable result. The basic solution would be (error the-error) as I know by know, but even that seemed unpractical, as this does no more provide the stack of the original error. (handler-bind) seems to rethrow the original error with the original stack, but then it seems unable to prevent it from being rethrown. Now the whole point here is that google found no result, cltl2 was no big help, and this is just one of plenty of problems I expect to encounter in the future. Is rethrowing errors something exotic in lisp?
Now some of this is mere rant, but if you had similar experiences and found ways to reduce the frustratin, please share. And yeah, I read the joke about it being a good things Lisp being a bitch to some at first so that those give up and less bad lisp code gets written. haha, very funny. But don't give me "You'll get used to that."
I think I can imagine already why Lisp is a great choice for any one- man project, but it seems that it totally sucks for reverse engineering systems, because it allows so bloody much.
JavaLisper <nol...@mt2009.com> wrote: > Hi, > i have several years of Java experience, but now my new job requires > me to learn Lisp. > I find it terribly frustrating at times, and need to rant to just let > some steam off. But maybe other have some helpful tips for me to get > into it easier. > Note I do not want to advocate Java over lisp, it's just the only > other language I know well enough to compare. So no need to get all > defensive and point out how much better I will still be off when I > prefer Lisp over Java, this is not a Lisp vs. Java post, I do not love > Java nor do I care how much you hate it.
> My situation is that I need to extend an existing system of lisp > sources written by somebody else who is not around anymore, and who > did not exactly intent his code to be extended, in terms of how he > documented it.
> I imagine from the Graham articles I read that Lisp is really more for > the kind of jobs that one does for oneself, green-field development. I > already understand that Lisp gives freedom of how to express things > that is incredible compared to Java, and also plenty of ways to "hack" > as Paul Graham puts it. > Now unfortunately these do not seem as a great advantage to me having > to understand and extend a system written by somebody else.
Right, but there are also features in Lisp that will help small teams to write a bunch of libraries that are documented and can be used to create an application.
There was years ago a small book 'Lisp Style & Design' which explained how to structure an application and how to develop it. Unfortunately this book is hard to get and very expensive.
There is definitely some need for more tutorials on programming in Lisp (style & design), maintaining Lisp programs and using the IDEs (SLIME, LispWorks, Allegro CL, ...).
> What I use is emacs with slime and allergro lisp. I already tweaked > emacs to the expectations of lame eclipse users like me. But still I > miss some IDE features Java IDEs offer me.
Why not use the Allegro CL IDE? Anyway you might want to read the manual of Allegro CL (the development tool parts) and the manual about the Allegro CL IDE. The IDE is available for Windows and Linux.
> Some things I do in Java to get an overview of a system new to me > would be like generating UML diagrams showing all classes and > dependencies, showing inheritence hierarchies and such. > Slime CLOS Object inspection seems to generally be able to do roughly > similar things, but I have not seen any function to get such a high- > level overview. > I am used to methods being neatly organized in classes, and classes in > package, but in Lisp it seems functions and such are just like dropped > in packages, in hundreds per package.
There are tools to browse class hierarchies and generic functions.
> What I'd do next in Java with an existing system is rename classes and > methods if they seem badly named to me. But it seems in Lisp this > works only by search and replace, which is hardly what I could do over > hundreds of files.
There are cross reference tools.
> What I also miss is a function like "mark occurences", such that when > the cursor is over a variable or function, all places in the code > where it is used are highlighted, making it easier to track where > which data goes. > Next on my list of disappointments is exception handling. I am used > for an exception to have mostly meaningful messages and above all show > me exactly which line of the code caused the exception. Currently all > I get is the function in which it happened, even worse if it happened > within a macro, i do not even get that. And the Stack looks > superflous, like (/ 1 0) gave me 20 stack frames, where I'd expect 2 > at most in Java. These 20 cannot all be relevant to (/ 1 0), can > they?
You can use the stack frame to find the function source. Allegro CL records the source locations. You really should read the chapter on the Allegro CL debugger to see what features it offers.
> Stepwise debugging also seems to be impossible with my setup with > allegro list, and unfortunately I have no choice in that matter. > Next on my list is declarations, I am used for methods in java to > declare both the type returned as well as all checked exceptions. Now > I see this is not convenient if you want to stay flexible about > returning different types, but really most of the times I expect > functions in lisp systems return just one time, don't they?
> Now to find out that type, it seems I have to go recursively through > all branches of a function expanding all macros hoping I will not miss > anything. Can't there be anything helping me there? I could try > wrapping all function bodies in (the <type> ...) but that does not > look so slick. And the same applies to function parameters, if their > type can be inferred automatically, why can't the IDE infer their > types for me? > Another thing that annoys me greatly is that compiling in Emacs can > yield different results, even if the sources did not change, based on > the state of the REPL. > When I look through the existing code, I find plenty of things pretty > dirty, at first sight, making it hard for me to extend the code unless > I am sure I understood it all perfectly. > I of course greatly miss the power of Java code completion, which > comes with the restrictions of the Java OO system. It makes it so easy > to most classes you see for the first time, because the IDE would > suggest all methods of instances, while in lisp I have to first learn > all defined functions until I will have a chance to pick the one I > wanted.
> I also seem to read very little about standards about documenting, > unit-testing, logging. Like in the java world, there is javadoc, > JUnit, Log4J, and one can be confident most open source projects will > use those to a reasonable extend. Of course the system i have to deal > with does not have any such standards, and it seems to me that such > standards are not of great concern to lispers. I found things like > Stefil, cldoc, log5, as alternatives, but they do not seem like > standards. > What would help me greatly in java to get the idea of the code is the > visibility of methods. If a method is private to a class, I know I > must be able to understand its usage just in this class, and changes > that I could make could only change things in this class. For > functions in lisp it seems there is no telling where they might be > used, especially since they could be used from within macros or > (eval ...) expressions, even for functions not exported from the > package, as lisp does not enforce visibility rules.
For most uses, the Lisp IDE records the usage of functions and can be queried about it.
> What I also like about Java is how many web resources there are for > java, plenty of tutorials, but mainly also plenty of problems people > ran into like me, and how they solved them. Today I googled for > "rethrowing errors", you know, as in handling exceptions of some type, > but not all of those. I found no usable result. The basic solution > would be (error the-error) as I know by know, but even that seemed > unpractical, as this does no more provide the stack of the original > error. (handler-bind) seems to rethrow the original error with the > original stack, but then it seems unable to prevent it from being > rethrown. Now the whole point here is that google found no result, > cltl2 was no big help, and this is just one of plenty of problems I > expect to encounter in the future. Is rethrowing errors something > exotic in lisp?
> Now some of this is mere rant, but if you had similar experiences and > found ways to reduce the frustratin, please share. > And yeah, I read the joke about it being a good things Lisp being a > bitch to some at first so that those give up and less bad lisp code > gets written. haha, very funny. But don't give me "You'll get used to > that."
Lots of things are like you don't expect them. Some simply are not available (UML diagrams for Lisp code), some are different and some stuff is there that you might not know about. It might help to read the documentation of the Lisp you are using. Allegro CL has also its own Emacs interface (ELI) and its own IDE. Plus it might be useful to check if Franz offers training for their IDE. Allegro CL has quite a lot development features (metering, inspectors, debugger, cross reference, ...) that are really useful.
> I think I can imagine already why Lisp is a great choice for any one- > man project, but it seems that it totally sucks for reverse > engineering systems, because it allows so bloody much.
Common Lisp is also quite good for small teams. But there is no replacement for good software-engineering practice. Without them, one can create a mess that is much worse than in many other languages. A good IDE helps (check out the Allegro CL documentation, LispWorks is also a good alternative).
So, to sum it up, I understand your frustration:
* Lisp IDEs works different from Java IDEs * some tools are not there * some tools look different * some stuff is more complicated * lack of discipline leads to hard to maintain software
On Jan 28, 10:20 pm, JavaLisper <nol...@mt2009.com> wrote: Today I googled for
> "rethrowing errors", you know, as in handling exceptions of some type, > but not all of those. I found no usable result. The basic solution > would be (error the-error) as I know by know, but even that seemed > unpractical, as this does no more provide the stack of the original > error. (handler-bind) seems to rethrow the original error with the > original stack, but then it seems unable to prevent it from being > rethrown. Now the whole point here is that google found no result, > cltl2 was no big help, and this is just one of plenty of problems I > expect to encounter in the future. Is rethrowing errors something > exotic in lisp?
I removed the rest - I am sure that Lisp is hard to pick up from a Java background. Having (somewhat, I'm not really a programmer any more other than in the "run this script on 600 machines sense") moved the other way, you'll be glad to know that Java is pretty painful coming from a Lisp background as well: all that bondage and discipline :-)
In the specific thing you ask: yes you can do all this quite easily. However CL's condition system is somewhat different than Java's in the sense that you could build Java's from CL's (I am fairly sure) but you could *not* build CL's from Java's. The important thing to understand (and it takes a while to get your head around this) is that HANDLER- BIND deals with conditions *before the stack has unwound*. The more conventional HANDLER-CASE macro (which is somewhat similar to Java's try) is built from HANDLER-BIND (well, may be built from it in the sense that you could write your own version which was). That difference completely changes the way the condition system works, and (once you understand it) it's also a pointer to the way Lisp differs from languages like Java: you get these spectacularly powerful primitives from which, with macros, you can built more syntactically- convenient things (and of course, for CL, some of these syntactically- convenient things are already there, though you can build more).
In terms of development environments, CL doesn't really have anything as overwhelmingly helpful (or, perhaps, just overwhelming) as Eclipse. When I wrote a lot of CL I used the LispWorks environment, which I found very productive (it costs money other than for a slightly restricted version, which I realise is now seen as unacceptable by many: I've given up even trying to talk to those people as I find it is almost always just more useful to kill them straight away).
JavaLisper wrote: > Hi, > i have several years of Java experience, but now my new job requires > me to learn Lisp. > I find it terribly frustrating at times, and need to rant to just let > some steam off. But maybe other have some helpful tips for me to get > into it easier. > Note I do not want to advocate Java over lisp, it's just the only > other language I know well enough to compare. So no need to get all > defensive and point out how much better I will still be off when I > prefer Lisp over Java, this is not a Lisp vs. Java post, I do not love > Java nor do I care how much you hate it.
Actually, you better get used to it because this is your only consolation (the fact that you are lucky enough to be paid to use Lisp because it is so much more powerful (read "fun") than Java) because everything you whine about below is pretty accurate. Unless you can use Windows to program AllegroCL (or also some *nixes, I forget which, where they have ported their IDE) because they do have a nice IDE closer to (but still far from) what you are used to in Java.
But mostly you are right, you are doomed, Lisp development is not like Java development so you learn new tricks, such as using the MOP to explore OO models with custom scripts instead of an Object Browser tool.
> My situation is that I need to extend an existing system of lisp > sources written by somebody else who is not around anymore, and who > did not exactly intent his code to be extended, in terms of how he > documented it.
> I imagine from the Graham articles I read that Lisp is really more for > the kind of jobs that one does for oneself, green-field development. I > already understand that Lisp gives freedom of how to express things > that is incredible compared to Java, and also plenty of ways to "hack" > as Paul Graham puts it. > Now unfortunately these do not seem as a great advantage to me having > to understand and extend a system written by somebody else.
> What I use is emacs with slime and allergro lisp. I already tweaked > emacs to the expectations of lame eclipse users like me. But still I > miss some IDE features Java IDEs offer me. > Some things I do in Java to get an overview of a system new to me > would be like generating UML diagrams showing all classes and > dependencies, showing inheritence hierarchies and such. > Slime CLOS Object inspection seems to generally be able to do roughly > similar things, but I have not seen any function to get such a high- > level overview. > I am used to methods being neatly organized in classes, and classes in > package, but in Lisp it seems functions and such are just like dropped > in packages, in hundreds per package. > What I'd do next in Java with an existing system is rename classes and > methods if they seem badly named to me. But it seems in Lisp this > works only by search and replace, which is hardly what I could do over > hundreds of files. > What I also miss is a function like "mark occurences", such that when > the cursor is over a variable or function, all places in the code > where it is used are highlighted, making it easier to track where > which data goes. > Next on my list of disappointments is exception handling. I am used > for an exception to have mostly meaningful messages and above all show > me exactly which line of the code caused the exception. Currently all > I get is the function in which it happened, even worse if it happened > within a macro, i do not even get that. And the Stack looks > superflous, like (/ 1 0) gave me 20 stack frames, where I'd expect 2 > at most in Java. These 20 cannot all be relevant to (/ 1 0), can > they? > Stepwise debugging also seems to be impossible with my setup with > allegro list, and unfortunately I have no choice in that matter. > Next on my list is declarations, I am used for methods in java to > declare both the type returned as well as all checked exceptions. Now > I see this is not convenient if you want to stay flexible about > returning different types, but really most of the times I expect > functions in lisp systems return just one time, don't they? > Now to find out that type, it seems I have to go recursively through > all branches of a function expanding all macros hoping I will not miss > anything. Can't there be anything helping me there? I could try > wrapping all function bodies in (the <type> ...) but that does not > look so slick. And the same applies to function parameters, if their > type can be inferred automatically, why can't the IDE infer their > types for me? > Another thing that annoys me greatly is that compiling in Emacs can > yield different results, even if the sources did not change, based on > the state of the REPL. > When I look through the existing code, I find plenty of things pretty > dirty, at first sight, making it hard for me to extend the code unless > I am sure I understood it all perfectly. > I of course greatly miss the power of Java code completion, which > comes with the restrictions of the Java OO system. It makes it so easy > to most classes you see for the first time, because the IDE would > suggest all methods of instances, while in lisp I have to first learn > all defined functions until I will have a chance to pick the one I > wanted. > I also seem to read very little about standards about documenting, > unit-testing, logging. Like in the java world, there is javadoc, > JUnit, Log4J, and one can be confident most open source projects will > use those to a reasonable extend. Of course the system i have to deal > with does not have any such standards, and it seems to me that such > standards are not of great concern to lispers. I found things like > Stefil, cldoc, log5, as alternatives, but they do not seem like > standards. > What would help me greatly in java to get the idea of the code is the > visibility of methods. If a method is private to a class, I know I > must be able to understand its usage just in this class, and changes > that I could make could only change things in this class. For > functions in lisp it seems there is no telling where they might be > used, especially since they could be used from within macros or > (eval ...) expressions, even for functions not exported from the > package, as lisp does not enforce visibility rules. > What I also like about Java is how many web resources there are for > java, plenty of tutorials, but mainly also plenty of problems people > ran into like me, and how they solved them. Today I googled for > "rethrowing errors", you know, as in handling exceptions of some type, > but not all of those. I found no usable result. The basic solution > would be (error the-error) as I know by know, but even that seemed > unpractical, as this does no more provide the stack of the original > error. (handler-bind) seems to rethrow the original error with the > original stack, but then it seems unable to prevent it from being > rethrown. Now the whole point here is that google found no result, > cltl2 was no big help, and this is just one of plenty of problems I > expect to encounter in the future. Is rethrowing errors something > exotic in lisp?
> Now some of this is mere rant, but if you had similar experiences and > found ways to reduce the frustratin, please share. > And yeah, I read the joke about it being a good things Lisp being a > bitch to some at first so that those give up and less bad lisp code > gets written. haha, very funny. But don't give me "You'll get used to > that."
> I think I can imagine already why Lisp is a great choice for any one- > man project, but it seems that it totally sucks for reverse > engineering systems, because it allows so bloody much.
JavaLisper <nol...@mt2009.com> writes: > Hi, > i have several years of Java experience, but now my new job requires > me to learn Lisp. > I find it terribly frustrating at times, and need to rant to just let > some steam off. But maybe other have some helpful tips for me to get > into it easier.
I find that learning new programming language is like learning new human languages: to make it easy, you need to recover your baby mind.
Clear your mind, don't try to understand, plunge in it, and soon enough your powerfull 1e14 neurons will be able to make sense of it.
In the mean time, read about Lisp and read you Lisp program, independently of your java knowledge. (This is indeed the hard part, you have to detach yourself from known frames, temporarily).
> My situation is that I need to extend an existing system of lisp > sources written by somebody else who is not around anymore, and who > did not exactly intent his code to be extended, in terms of how he > documented it.
And clearly, he didn't have a Java mind when writting this lisp code (otherwise he could have written Java in Lisp and you would understand it easily).
> [...] > Next on my list of disappointments is exception handling. I am used > for an exception to have mostly meaningful messages and above all show > me exactly which line of the code caused the exception.
While with great efforts it would be, theorically, possible to give the (set of) line(s) where the condition originated, in lisp it is not very meaningful, because lisp sources are not text files, but s-expressions that are built in various ways, and from various origins. Of course, most of the time, these s-exps are built by the lisp reader from text files, but a lot of them are actually built by executing functions, either when reading the text files, or when compiling the program. These little s-exp building functions are what is called macros. Some macros themselves may be generated from macros, so identifing a source text file corresponding to some CONS cell in the source s-exp is really hard and meaningless.
If you remember that in Common Lisp, there are only 17 special operators, and about 70 macros (the rest being normal functions), you may realize that most of the source s-exps are not read from text files but generated dynamically by these macros.
> Currently all > I get is the function in which it happened, even worse if it happened > within a macro, i do not even get that. And the Stack looks > superflous, like (/ 1 0) gave me 20 stack frames, where I'd expect 2 > at most in Java. These 20 cannot all be relevant to (/ 1 0), can > they? > Stepwise debugging also seems to be impossible with my setup with > allegro lisp, and unfortunately I have no choice in that matter.
Have you tried (STEP (some-function 'some-argument)) ? Also, it may help if you compile your program having declared: (declare (optimize (space 0) (speed 0) (safety 3) (debug 3)))
> Next on my list is declarations, I am used for methods in java to > declare both the type returned as well as all checked exceptions. Now > I see this is not convenient if you want to stay flexible about > returning different types, but really most of the times I expect > functions in lisp systems return just one time, don't they? > Now to find out that type, it seems I have to go recursively through > all branches of a function expanding all macros hoping I will not miss > anything. Can't there be anything helping me there? I could try > wrapping all function bodies in (the <type> ...) but that does not > look so slick. And the same applies to function parameters, if their > type can be inferred automatically, why can't the IDE infer their > types for me?
Indeed. I agree that we lack sophisticated tools, doing global lisp program analysis, such as infering types, shaking trees, time-travelling debuggers (see google video "debugging in time"), etc. We need more lisp programmers to have the resources to develop these tools.
> Another thing that annoys me greatly is that compiling in Emacs can > yield different results, even if the sources did not change, based on > the state of the REPL.
You need to learn to use the REPL to good effect. It is not a command user interface for the compiler. It is a sandbox to explore new and old programs. With tools such as STEP, TRACE, INSPECT, etc, you can use the REPL to learn how the program works, from inside, trying out each functions, even internal functions, in addition to reading them.
> What would help me greatly in java to get the idea of the code is the > visibility of methods. If a method is private to a class, I know I > must be able to understand its usage just in this class, and changes > that I could make could only change things in this class. For > functions in lisp it seems there is no telling where they might be > used, especially since they could be used from within macros or > (eval ...) expressions, even for functions not exported from the > package, as lisp does not enforce visibility rules.
But exportation from a package _documents_ the visibility of a function! You thought there was no documentation, but the source is its own documentation. You just need to learn to read it.
> What I also like about Java is how many web resources there are for > java, plenty of tutorials, but mainly also plenty of problems people > ran into like me, and how they solved them. Today I googled for > "rethrowing errors", you know, as in handling exceptions of some type,
Using the right terminology might help. In lisp, errors are signaled, not thrown.
> but not all of those. I found no usable result. The basic solution > would be (error the-error) as I know by know, but even that seemed > unpractical, as this does no more provide the stack of the original > error. (handler-bind) seems to rethrow the original error with the > original stack, but then it seems unable to prevent it from being > rethrown. Now the whole point here is that google found no result, > cltl2 was no big help, and this is just one of plenty of problems I > expect to encounter in the future. Is rethrowing errors something > exotic in lisp?
Not at all. You noticed yourself that HANDLER-BIND does it. To handle the condition is to exit otherwise than by normal return. That is, you can THROW some object (CATCH it), you can RETURN-FROM some enclosing BLOCK, you can GO to some tag, you can SIGNAL another ERROR.
> Now some of this is mere rant, but if you had similar experiences and > found ways to reduce the frustratin, please share. > And yeah, I read the joke about it being a good things Lisp being a > bitch to some at first so that those give up and less bad lisp code > gets written. haha, very funny. But don't give me "You'll get used to > that."
Use groups.google.com to search this newsgroup. There are a lot of very good articles. But you will need to use the right terminology (read the CLHS glossary).
The first consequent program I wrote in Common Lisp was such a simplistic source analyzer for a C++ program, that would build a C++ methods call graph.
> My situation is that I need to extend an existing system of lisp > sources written by somebody else who is not around anymore, and who > did not exactly intent his code to be extended, in terms of how he > documented it.
OK. But if this is reasonable standard lisp code, then the original programmer should have chosen some nice, long, descriptive names for the functions, classes and methods. Oftentimes, the names themselves are chosen to be largely self-documenting.
On the other hand, it's possible to write bad, unmaintainable code in any language, so your mileage may vary.
> I imagine from the Graham articles I read that Lisp is really more for > the kind of jobs that one does for oneself, green-field development. I > already understand that Lisp gives freedom of how to express things > that is incredible compared to Java, and also plenty of ways to "hack" > as Paul Graham puts it. > Now unfortunately these do not seem as a great advantage to me having > to understand and extend a system written by somebody else.
Well, I and a lot of others would disagree. Many features of Common Lisp are more geared toward building large systems and not necessarily one-off programming jobs. Among these are the package system for managing namespaces and a lot of introspection code.
> What I use is emacs with slime and allergro lisp. I already tweaked > emacs to the expectations of lame eclipse users like me. But still I > miss some IDE features Java IDEs offer me.
OK. But make sure you make appropriate use of Meta-. (Meta-period) SLIME should also show you argument lists.
Finally, don't overlook some of the key features lisp has that is missing in Java, namely the ability to type code into the REPL and execute it interactively. Also, the TRACE macro for tracking function calls. And the INSPECT facility for examining data structures. And finally the natural serialization of much of the lisp data structures.
The REPL in particular allows you to experiment with some of the code to see what it does and how it behaves. It also allows you to make incremental changes in the code and try them out immediately, without the need to go through the laborious build cycle of Java.
There is also a nice interactive debugger, and the ability to redefine code while in a break loop and then continue on with the fixed code. The inspector is also available in the debugger break loop.
> Some things I do in Java to get an overview of a system new to me > would be like generating UML diagrams showing all classes and > dependencies, showing inheritence hierarchies and such. > Slime CLOS Object inspection seems to generally be able to do roughly > similar things, but I have not seen any function to get such a high- > level overview. > I am used to methods being neatly organized in classes, and classes in > package, but in Lisp it seems functions and such are just like dropped > in packages, in hundreds per package.
OK. There are two very important differences that you will need to get used to. First of all, I'll deal with packages and then with the VERY DIFFERENT object model in CLOS.
Packages in lisp manage name to symbol object mappings. That's it. They allow you to set up namespaces that are separate, so that different parts of a large system do not end up generating name conflicts. Packages only manage the namespace and the name to symbol mapping.
The CLOS object model is significantly different from the Java/C++ object model. Classes encapsulate DATA only. They support multiple inheritance nicely, and allow you to put storage (slots) into any of the inherited classes. Unlike Java interfaces, which do not allow code or fields.
Methods in CLOS do not belong to classes. This is important, so I'll repeat: Methods in CLOS do not belong to classes. Methods belong to generic functions. All of the methods that share a name are part of the same generic function. The choice of which method to invoke when a generic function is called is determined by dispatch on the type of all of the required arguments. This provides you with multiple dispatch.
So, what you will typically find in a well-organized lisp source file is a set of functions that are related to each other by what they do. The organization of files is around FUNCTION, not class. So typically a number of methods for the same generic function will often be in the same place. Along with related methods and functions.
> What I'd do next in Java with an existing system is rename classes and > methods if they seem badly named to me. But it seems in Lisp this > works only by search and replace, which is hardly what I could do over > hundreds of files. > What I also miss is a function like "mark occurences", such that when > the cursor is over a variable or function, all places in the code > where it is used are highlighted, making it easier to track where > which data goes.
Look at
> Next on my list of disappointments is exception handling. I am used > for an exception to have mostly meaningful messages and above all show > me exactly which line of the code caused the exception. Currently all > I get is the function in which it happened, even worse if it happened > within a macro, i do not even get that. And the Stack looks > superflous, like (/ 1 0) gave me 20 stack frames, where I'd expect 2 > at most in Java. These 20 cannot all be relevant to (/ 1 0), can > they?
Exceptions will generally show you which function generated it. That would be a particular stack frame. Some of this information is controlled by the degree of compiler optimization that has been done. In some cases a lot of stack frames are missing.
On the other hand, if you run interpreted code (such as what you will get in Allegro CL by typing at the REPL), you will end up with many more stack frames, since there is the information from the interpreter interspersed in the call stack. This can be a blessing or a curse. You will get more information with interpreted code, but sometimes too much. But you can control this by compiling or not, and also by setting additional options such as optimization and debug information levels.
> Stepwise debugging also seems to be impossible with my setup with > allegro list, and unfortunately I have no choice in that matter.
I generally never use a stepper when debugging lisp code. It is, however, easy to insert BREAK points in lisp. And then you can use the debugging tools to look over the state of the computation. You can also use the REPL to try out function calls, even in the middle of a debugger session.
It is a different mode of operation, but you will need to learn to use the appropriate debugging tools.
> Next on my list is declarations, I am used for methods in java to > declare both the type returned as well as all checked exceptions. Now > I see this is not convenient if you want to stay flexible about > returning different types, but really most of the times I expect > functions in lisp systems return just one time, don't they?
Usually. But what is returned should be specified by the function documentation or at the least the function's name. The type isn't really all that useful if you don't know what it means. After all, how helpful is it for you to see the following Java type signature:
public int f (int x, int y)
If I call it with f(2, 3) and it returns 8, is that the right answer?
> Now to find out that type, it seems I have to go recursively through > all branches of a function expanding all macros hoping I will not miss > anything. Can't there be anything helping me there?
TRACE calls to the function. That will show you the call and the return value. You should be able to determine the type from that.
> I could try > wrapping all function bodies in (the <type> ...) but that does not > look so slick.
DON'T DO THAT. Use a THE form is a promise to the compiler about the types produced. It is not something that is enforced or checked by the compiler. It is assumed that you would not lie to your compiler. If you are concerned about this you can look at CHECK-TYPE. But I would advise not going there initially.
If you really want to declare the types, you can do that. Look at the FTYPE declaration. But again, I don't think that would be necessary.
> And the same applies to function parameters, if their > type can be inferred automatically, why can't the IDE infer their > types for me?
The type isn't inferred automatically. All values in lisp have manifest type. That means that each value, including primitive literals carry their type information around with them. You can introspectively figure this out at any time. Just use TYPE-OF on the value. But generally, you don't need this level of detailed information about everything. So just concentrate on the parts that you need to understand.
You need to free your mind of this notion that types have to be specified for everything. Think instead of all parameters being typed Object, and able to handle anything.
> Another thing that annoys me greatly is that compiling in Emacs can > yield different results, even if the sources did not change, based on > the state of the REPL.
Huh?
This should only be the case if you modify some global state that the compiler depends on. And that should be rare, unless you are redefining things in the REPL.
If this is happening to you, then there is some other fundamental misunderstanding, but there aren't enough clues to diagnose it from afar right now.
> When I look through the existing code, I find plenty of things pretty > dirty, at first sight, making it hard for me to extend the code unless > I am sure I understood it all perfectly. > I of course greatly miss the power of Java code completion, which > comes with the restrictions of the Java OO system. It makes it so easy > to most classes you see for the first time, because the IDE would
You've basically rediscovered all of the reasons why good programmers no longer choose to use Lisp.
JavaLisper wrote: > My situation is that I need to extend an existing system of lisp > sources written by somebody else who is not around anymore, and who > did not exactly intent his code to be extended, in terms of how he > documented it.
Ah yes. I know this situation well. Lisp code is notoriously difficult to maintain. Hence, companies that buy Lisp code inevitably end up rewriting it. So rewrite your entire program in a modern language and document it.
> What I use is emacs with slime and allergro lisp. I already tweaked > emacs to the expectations of lame eclipse users like me. But still I > miss some IDE features Java IDEs offer me.
Lisp predates IDEs.
> Some things I do in Java to get an overview of a system new to me > would be like generating UML diagrams showing all classes and > dependencies, showing inheritence hierarchies and such.
Lisp predates UML.
> Next on my list of disappointments is exception handling. I am used > for an exception to have mostly meaningful messages and above all show > me exactly which line of the code caused the exception. Currently all > I get is the function in which it happened, even worse if it happened > within a macro, i do not even get that. And the Stack looks > superflous, like (/ 1 0) gave me 20 stack frames, where I'd expect 2 > at most in Java. These 20 cannot all be relevant to (/ 1 0), can > they?
That is probably just lack of decent development tools. However, I am surprised this is not better catered for because Lisp's lack of discipline forces its programmers to live in the debugger. Consequently, I would have expected it to be luxurious in there.
> Stepwise debugging also seems to be impossible with my setup with > allegro list, and unfortunately I have no choice in that matter. > Next on my list is declarations, I am used for methods in java to > declare both the type returned as well as all checked exceptions. Now > I see this is not convenient if you want to stay flexible about > returning different types, but really most of the times I expect > functions in lisp systems return just one time, don't they?
Of course, but Lisp predates modern type theory and is completely incapable of expressing such things in a usable way.The foundation is missing as well as the tools.
> Now to find out that type, it seems I have to go recursively through > all branches of a function expanding all macros hoping I will not miss > anything. Can't there be anything helping me there?
Learn to use the debugger and then use it to run through the program and watch how it works. However, unless the program does something inherently very complicated (unlikely if it can be written in Lisp) you are better off just rewriting the entire thing from scratch starting from the specification and forgetting the existing Lisp code.
> And the same applies to function parameters, if their > type can be inferred automatically, why can't the IDE infer their > types for me?
Lisp's basic design was ossified decades before decent type inference was invented. Lisp is nowhere near capable of expressing such things.
> Another thing that annoys me greatly is that compiling in Emacs can > yield different results, even if the sources did not change, based on > the state of the REPL.
That's due to undisciplined programming.
> When I look through the existing code, I find plenty of things pretty > dirty, at first sight, making it hard for me to extend the code unless > I am sure I understood it all perfectly.
Yes, of course.
> I of course greatly miss the power of Java code completion, which > comes with the restrictions of the Java OO system. It makes it so easy > to most classes you see for the first time, because the IDE would > suggest all methods of instances, while in lisp I have to first learn > all defined functions until I will have a chance to pick the one I > wanted.
Lisp was created a long time before such functionality was invented.
> What would help me greatly in java to get the idea of the code is the > visibility of methods. If a method is private to a class, I know I > must be able to understand its usage just in this class, and changes > that I could make could only change things in this class. For > functions in lisp it seems there is no telling where they might be > used, especially since they could be used from within macros or > (eval ...) expressions, even for functions not exported from the > package, as lisp does not enforce visibility rules.
Worse, Lisp allows any function to be replaced at run-time with anything else, even if there are trivial type errors. Hence the unmaintainable "rats nest" of code.
> What I also like about Java is how many web resources there are for > java, plenty of tutorials, but mainly also plenty of problems people > ran into like me, and how they solved them. Today I googled for > "rethrowing errors", you know, as in handling exceptions of some type, > but not all of those. I found no usable result. The basic solution > would be (error the-error) as I know by know, but even that seemed > unpractical, as this does no more provide the stack of the original > error. (handler-bind) seems to rethrow the original error with the > original stack, but then it seems unable to prevent it from being > rethrown. Now the whole point here is that google found no result, > cltl2 was no big help, and this is just one of plenty of problems I > expect to encounter in the future. Is rethrowing errors something > exotic in lisp?
No. Actually resumable exceptions are common in Lisp.
> Now some of this is mere rant, but if you had similar experiences and > found ways to reduce the frustratin, please share. > And yeah, I read the joke about it being a good things Lisp being a > bitch to some at first so that those give up and less bad lisp code > gets written. haha, very funny.
Funny but wrong. All the intelligent people left the Lisp community a long time ago.
> I think I can imagine already why Lisp is a great choice for any one- > man project, but it seems that it totally sucks for reverse > engineering systems, because it allows so bloody much.
Yes. The value of Lisp is that you can hack together something that looks good and sell it for a vast sum of money before the buyer realises the hidden cost of it having been written in Lisp. There have been several high profile occurrences of this (Lisp's "success" stories) and the codebase gets written almost all the time.
For example, Sony made the mistake of buying Lisp code with NaughtyDog only to have it completely rewritten:
On 2009-01-29, Jon Harrop <j...@ffconsultancy.com> wrote:
> JavaLisper wrote: >> My situation is that I need to extend an existing system of lisp >> sources written by somebody else who is not around anymore, and who >> did not exactly intent his code to be extended, in terms of how he >> documented it.
> Ah yes. I know this situation well. Lisp code is notoriously difficult to > maintain.
You've never given evidence that you have any experience or knowledge of Lisp. So basically, this is just made up.
> All the intelligent people left the Lisp community a long > time ago.
Note that one Jon Harrop is quite a fixture in the Lisp community, so that can't be right.
Maybe this is where you find dumb people with whom you can enjoy discussing on your own level?
Come on, just do a Lisp project; it's obviously what you want to do. :)
Sony bought Naughty Dog, because there are some awesome programmers, that would code in anything anyday just to get it working. Off course their development way had to be dumbed down, so other studios can use their technology.
On Jan 29, 2:34 am, Jon Harrop <j...@ffconsultancy.com> wrote: [elided]
JavaLisper: have a search back through the recent archives of CLL to decide whether you want to pay any attention to this person. The answer should be pretty clear, I think.
> You've basically rediscovered all of the reasons why good programmers no > longer choose to use Lisp.
> JavaLisper wrote: > > My situation is that I need to extend an existing system of lisp > > sources written by somebody else who is not around anymore, and who > > did not exactly intent his code to be extended, in terms of how he > > documented it.
> Ah yes. I know this situation well. Lisp code is notoriously difficult to > maintain. Hence, companies that buy Lisp code inevitably end up rewriting > it. So rewrite your entire program in a modern language and document it.
> > What I use is emacs with slime and allergro lisp. I already tweaked > > emacs to the expectations of lame eclipse users like me. But still I > > miss some IDE features Java IDEs offer me.
> Lisp predates IDEs.
> > Some things I do in Java to get an overview of a system new to me > > would be like generating UML diagrams showing all classes and > > dependencies, showing inheritence hierarchies and such.
> Lisp predates UML.
> > Next on my list of disappointments is exception handling. I am used > > for an exception to have mostly meaningful messages and above all show > > me exactly which line of the code caused the exception. Currently all > > I get is the function in which it happened, even worse if it happened > > within a macro, i do not even get that. And the Stack looks > > superflous, like (/ 1 0) gave me 20 stack frames, where I'd expect 2 > > at most in Java. These 20 cannot all be relevant to (/ 1 0), can > > they?
> That is probably just lack of decent development tools. However, I am > surprised this is not better catered for because Lisp's lack of discipline > forces its programmers to live in the debugger. Consequently, I would have > expected it to be luxurious in there.
> > Stepwise debugging also seems to be impossible with my setup with > > allegro list, and unfortunately I have no choice in that matter. > > Next on my list is declarations, I am used for methods in java to > > declare both the type returned as well as all checked exceptions. Now > > I see this is not convenient if you want to stay flexible about > > returning different types, but really most of the times I expect > > functions in lisp systems return just one time, don't they?
> Of course, but Lisp predates modern type theory and is completely incapable > of expressing such things in a usable way.The foundation is missing as well > as the tools.
> > Now to find out that type, it seems I have to go recursively through > > all branches of a function expanding all macros hoping I will not miss > > anything. Can't there be anything helping me there?
> Learn to use the debugger and then use it to run through the program and > watch how it works. However, unless the program does something inherently > very complicated (unlikely if it can be written in Lisp) you are better off > just rewriting the entire thing from scratch starting from the > specification and forgetting the existing Lisp code.
> > And the same applies to function parameters, if their > > type can be inferred automatically, why can't the IDE infer their > > types for me?
> Lisp's basic design was ossified decades before decent type inference was > invented. Lisp is nowhere near capable of expressing such things.
> > Another thing that annoys me greatly is that compiling in Emacs can > > yield different results, even if the sources did not change, based on > > the state of the REPL.
> That's due to undisciplined programming.
> > When I look through the existing code, I find plenty of things pretty > > dirty, at first sight, making it hard for me to extend the code unless > > I am sure I understood it all perfectly.
> Yes, of course.
> > I of course greatly miss the power of Java code completion, which > > comes with the restrictions of the Java OO system. It makes it so easy > > to most classes you see for the first time, because the IDE would > > suggest all methods of instances, while in lisp I have to first learn > > all defined functions until I will have a chance to pick the one I > > wanted.
> Lisp was created a long time before such functionality was invented.
> > What would help me greatly in java to get the idea of the code is the > > visibility of methods. If a method is private to a class, I know I > > must be able to understand its usage just in this class, and changes > > that I could make could only change things in this class. For > > functions in lisp it seems there is no telling where they might be > > used, especially since they could be used from within macros or > > (eval ...) expressions, even for functions not exported from the > > package, as lisp does not enforce visibility rules.
> Worse, Lisp allows any function to be replaced at run-time with anything > else, even if there are trivial type errors. Hence the unmaintainable "rats > nest" of code.
> > What I also like about Java is how many web resources there are for > > java, plenty of tutorials, but mainly also plenty of problems people > > ran into like me, and how they solved them. Today I googled for > > "rethrowing errors", you know, as in handling exceptions of some type, > > but not all of those. I found no usable result. The basic solution > > would be (error the-error) as I know by know, but even that seemed > > unpractical, as this does no more provide the stack of the original > > error. (handler-bind) seems to rethrow the original error with the > > original stack, but then it seems unable to prevent it from being > > rethrown. Now the whole point here is that google found no result, > > cltl2 was no big help, and this is just one of plenty of problems I > > expect to encounter in the future. Is rethrowing errors something > > exotic in lisp?
> No. Actually resumable exceptions are common in Lisp.
> > Now some of this is mere rant, but if you had similar experiences and > > found ways to reduce the frustratin, please share. > > And yeah, I read the joke about it being a good things Lisp being a > > bitch to some at first so that those give up and less bad lisp code > > gets written. haha, very funny.
> Funny but wrong. All the intelligent people left the Lisp community a long > time ago.
> > I think I can imagine already why Lisp is a great choice for any one- > > man project, but it seems that it totally sucks for reverse > > engineering systems, because it allows so bloody much.
> Yes. The value of Lisp is that you can hack together something that looks > good and sell it for a vast sum of money before the buyer realises the > hidden cost of it having been written in Lisp. There have been several high > profile occurrences of this (Lisp's "success" stories) and the codebase > gets written almost all the time.
> For example, Sony made the mistake of buying Lisp code with NaughtyDog only > to have it completely rewritten:
Lisp is a powerful tool. It takes a lot of intelligence to use it without hurting yourself and it takes a lot of intelligence to interpret the results since you need to understand the underlying reasoning. Blaming the tool for your own lack of intelligence is, well, not very intelligent.
Now, go be a good drone and write your daily thousand lines of "Modern" code and quit wasting our time.
Adde wrote: > Lisp is a powerful tool. It takes a lot of intelligence to use it > without hurting yourself and it takes a lot of intelligence to > interpret the results since you need to understand the underlying > reasoning. Blaming the tool for your own lack of intelligence is, > well, not very intelligent.
Has anyone ever been "intelligent" enough to build anything significant in Lisp without "hurting themselves"?
Regardless, that does not help someone who just inherited an unmaintainable rats nest of code from yet another unaccomplished Lisper.
Tim Bradshaw wrote: > On Jan 29, 2:34 am, Jon Harrop <j...@ffconsultancy.com> wrote: > [elided]
> JavaLisper: have a search back through the recent archives of CLL to > decide whether you want to pay any attention to this person. The > answer should be pretty clear, I think.
Careful, they may be the same person. If /Jon/ stops listening to himself he gets garbage collected. Have you seen the mulcher?
On Jan 28, 11:20 pm, JavaLisper <nol...@mt2009.com> wrote:
> Hi, > i have several years of Java experience, but now my new job requires > me to learn Lisp.
I believe that your story is fabricated. Any company smart enough to use lisp in the first place would act very dumb to hire programmer with zilch experience in lisp to be incharge for the system written in lisp. Than you say that you have Allegro, since it's a company that's certainly an enterprise edition. So why would someone coming from Eclipse would use or even less tweak with Emacs when nice Allegro IDE is in his hands? Or since your company have money for the best tools they could certainly spend little more for little training. Franz has a certification program. In whole your post you didn't mentioned any credential, like your name (are your parents calling you JavaLisper at home ?), the company that you are working for, or what the hell your system is suppose to do or even better who wrote such a crap? Lisp is a small town, you can't hide and that's exactly what you're trying to do. Why ? Because you're troll, and lispers and too nice persons to believe you. Put down your mask to see your face nol...@2009.com (mythrashmail account).
The others here use Emacs, and I am not sure whether Allegro IDE has actually more features, or whether the lack of the features I look for is due to the lisp language.
> You can use the stack frame to find the function source. > Allegro CL records the source locations.
Yes, I use that already. Still often I struggle to understand where in a function using macros the error happened. I'd love to see the error location in a some screen where the relevant function has been macroexpanded deep enough to show the location of the error exactly in expanded code.
> Learn about the IDE completion that is provided.
I already use completion, but I do not find it all that powerful. Similar for syntax highlighting, which I would have hope to be more semantic rather than mostly syntactical. Like in my IDE, the following code would be all the same font: ... (setf (aref output-array (get-x cell) (get-y cell)) (get-symbol car)) even though some of those are functions, others accessors, others variables.
> While with great efforts it would be, theorically, possible to give > the (set of) line(s) where the condition originated, in lisp it is > not very meaningful, because lisp sources are not text files, but > s-expressions that are built in various ways, and from various > origins.
As I replied to the previous poster, I'd often love to see the error location in the expanded code, where it would make most sense.
> Have you tried (STEP (some-function 'some-argument)) ?
No, I did not know that one. It helps a bit, though like the stack there is so much stuff going on around what I coded myself which I am not too interested about. I'd like a STEP which only shows steps "in my code" if that makes any sense.
Thanks, I will try. However I would have expected such functions and libraries to exist, and to be mature after I don't know, 50 years of Lisp, and that they would ship with lisp.
> Ah yes. I know this situation well. Lisp code is notoriously difficult to > maintain. Hence, companies that buy Lisp code inevitably end up rewriting > it. So rewrite your entire program in a modern language and document it. ... > For example, Sony made the mistake of buying Lisp code with NaughtyDog only > to have it completely rewritten:
Though the additional rant is not too helpful, thanks for those links. It helps me if some of the stories of the great success of LISP get demystified a bit.
> Hi, > i have several years of Java experience, but now my new job requires > me to learn Lisp. > I find it terribly frustrating at times, and need to rant to just let > some steam off. But maybe other have some helpful tips for me to get > into it easier. > Note I do not want to advocate Java over lisp, it's just the only > other language I know well enough to compare. So no need to get all > defensive and point out how much better I will still be off when I > prefer Lisp over Java, this is not a Lisp vs. Java post, I do not love > Java nor do I care how much you hate it.
> My situation is that I need to extend an existing system of lisp > sources written by somebody else who is not around anymore, and who > did not exactly intent his code to be extended, in terms of how he > documented it.
> I imagine from the Graham articles I read that Lisp is really more for > the kind of jobs that one does for oneself, green-field development. I > already understand that Lisp gives freedom of how to express things > that is incredible compared to Java, and also plenty of ways to "hack" > as Paul Graham puts it. > Now unfortunately these do not seem as a great advantage to me having > to understand and extend a system written by somebody else.
> What I use is emacs with slime and allergro lisp. I already tweaked > emacs to the expectations of lame eclipse users like me. But still I > miss some IDE features Java IDEs offer me. > Some things I do in Java to get an overview of a system new to me > would be like generating UML diagrams showing all classes and > dependencies, showing inheritence hierarchies and such. > Slime CLOS Object inspection seems to generally be able to do roughly > similar things, but I have not seen any function to get such a high- > level overview. > I am used to methods being neatly organized in classes, and classes in > package, but in Lisp it seems functions and such are just like dropped > in packages, in hundreds per package. > What I'd do next in Java with an existing system is rename classes and > methods if they seem badly named to me. But it seems in Lisp this > works only by search and replace, which is hardly what I could do over > hundreds of files. > What I also miss is a function like "mark occurences", such that when > the cursor is over a variable or function, all places in the code > where it is used are highlighted, making it easier to track where > which data goes. > Next on my list of disappointments is exception handling. I am used > for an exception to have mostly meaningful messages and above all show > me exactly which line of the code caused the exception. Currently all > I get is the function in which it happened, even worse if it happened > within a macro, i do not even get that. And the Stack looks > superflous, like (/ 1 0) gave me 20 stack frames, where I'd expect 2 > at most in Java. These 20 cannot all be relevant to (/ 1 0), can > they? > Stepwise debugging also seems to be impossible with my setup with > allegro list, and unfortunately I have no choice in that matter. > Next on my list is declarations, I am used for methods in java to > declare both the type returned as well as all checked exceptions. Now > I see this is not convenient if you want to stay flexible about > returning different types, but really most of the times I expect > functions in lisp systems return just one time, don't they? > Now to find out that type, it seems I have to go recursively through > all branches of a function expanding all macros hoping I will not miss > anything. Can't there be anything helping me there? I could try > wrapping all function bodies in (the <type> ...) but that does not > look so slick. And the same applies to function parameters, if their > type can be inferred automatically, why can't the IDE infer their > types for me? > Another thing that annoys me greatly is that compiling in Emacs can > yield different results, even if the sources did not change, based on > the state of the REPL. > When I look through the existing code, I find plenty of things pretty > dirty, at first sight, making it hard for me to extend the code unless > I am sure I understood it all perfectly. > I of course greatly miss the power of Java code completion, which > comes with the restrictions of the Java OO system. It makes it so easy > to most classes you see for the first time, because the IDE would > suggest all methods of instances, while in lisp I have to first learn > all defined functions until I will have a chance to pick the one I > wanted. > I also seem to read very little about standards about documenting, > unit-testing, logging. Like in the java world, there is javadoc, > JUnit, Log4J, and one can be confident most open source projects will > use those to a reasonable extend. Of course the system i have to deal > with does not have any such standards, and it seems to me that such > standards are not of great concern to lispers. I found things like > Stefil, cldoc, log5, as alternatives, but they do not seem like > standards. > What would help me greatly in java to get the idea of the code is the > visibility of methods. If a method is private to a class, I know I > must be able to understand its usage just in this class, and changes > that I could make could only change things in this class. For > functions in lisp it seems there is no telling where they might be > used, especially since they could be used from within macros or > (eval ...) expressions, even for functions not exported from the > package, as lisp does not enforce visibility rules. > What I also like about Java is how many web resources there are for > java, plenty of tutorials, but mainly also plenty of problems people > ran into like me, and how they solved them. Today I googled for > "rethrowing errors", you know, as in handling exceptions of some type, > but not all of those. I found no usable result. The basic solution > would be (error the-error) as I know by know, but even that seemed > unpractical, as this does no more provide the stack of the original > error. (handler-bind) seems to rethrow the original error with the > original stack, but then it seems unable to prevent it from being > rethrown. Now the whole point here is that google found no result, > cltl2 was no big help, and this is just one of plenty of problems I > expect to encounter in the future. Is rethrowing errors something > exotic in lisp?
> Now some of this is mere rant, but if you had similar experiences and > found ways to reduce the frustratin, please share. > And yeah, I read the joke about it being a good things Lisp being a > bitch to some at first so that those give up and less bad lisp code > gets written. haha, very funny. But don't give me "You'll get used to > that."
> I think I can imagine already why Lisp is a great choice for any one- > man project, but it seems that it totally sucks for reverse > engineering systems, because it allows so bloody much.
your rant & complaint is long and from a newbie context. I'll do a quick reply paragraph-by-paragraph style. But overall, i'd say 40% of your problem is unfamiliarity of developing with dynamic languages in larger scale software, 40% of being a lisp newbie, and 20% due to lisp is truely old lang lacking all modern goodies.
On Jan 28, 2:20 pm, JavaLisper <nol...@mt2009.com> wrote:
> My situation is that I need to extend an existing system of lisp > sources written by somebody else who is not around anymore, and who > did not exactly intent his code to be extended, in terms of how he > documented it.
just want to mention that in this situation, it's a pain to begin with, in any lang.
> I imagine from the Graham articles I read that Lisp is really more for > the kind of jobs that one does for oneself, green-field development. I > already understand that Lisp gives freedom of how to express things > that is incredible compared to Java, and also plenty of ways to "hack" > as Paul Graham puts it. > Now unfortunately these do not seem as a great advantage to me having > to understand and extend a system written by somebody else.
in general, lisp in real world is not that much malleable or extensible as lisp fanatics or books would picture it. It is flexibility is about in the same class of nynamic langs aka scripting langs, like perl, python, php, etc.
> What I use is emacs with slime and allergro lisp. I already tweaked > emacs to the expectations of lame eclipse users like me. But still I > miss some IDE features Java IDEs offer me.
Yes. Emacs is great for its power in text processing, however it doesn't have built-in semantic based processing features like Eclipse. There was some major effort, see: http://jdee.sourceforge.net/
however, it has been inactive for maybe 9 years.
it is comparatively trivial to add Eclipse-like features to emacs, because of the emacs lisp system there. Basically, you just need a coherent design. There are relatively very few elisp coders, and given that emacs's dev culture, it's not likely they will all work in one design. Instead, you have 100 persons each having some lisp code that does a bit this and that to satisfy their own need, adding them together is incoherent, usually incompatible or inconsistent UI.
since you are on the road to emacs, you might try:
> Some things I do in Java to get an overview of a system new to me > would be like generating UML diagrams showing all classes and > dependencies, showing inheritence hierarchies and such.
UML, supposedly “Universal” modeling “lang”, is basically exclusively used in OOP world only, in particular Java & C++. They are pretty much useless and become and redundant for functional langs. (this can be said for much of “Design Patterns” movement, and eXtreme Programing (XP was red HOT in early 2000, now it seems disappeared. LOL))
In fact, my opinion of it is that it is one of the worst sneak-oil in the computing world.
«... what society overwhelmingly asks for is snake oil. Of course, the snake oil has the most impressive names —otherwise you would be selling nothing— like “Structured Analysis and Design”, “Software Engineering”, “Maturity Models”, “Management Information Systems”, “Integrated Project Support Environments” “Object Orientation” and “Business Process Re-engineering” (the latter three being known as IPSE, OO and BPR, respectively).”» — Edsger W Dijkstra (1930-2002), in EWD 1175: The strengths of the academic enterprise.
> Slime CLOS Object inspection seems to generally be able to do roughly > similar things, but I have not seen any function to get such a high- > level overview.
I haven't tried Slime. Am not a Common Lisp coder. (am Mathematica and emacs lisp expert among others. (see my website for tutorial about 5 languages))
Try the other's advice about using the IDE of commercial lisp vendors.
> I am used to methods being neatly organized in classes, and classes in > package, but in Lisp it seems functions and such are just like dropped > in packages, in hundreds per package.
Yes, exactly. In functional programing world, you don't have everything as one giant inflexible tree with a million branches. Instead, you have packages/libraries, and each has functions. For a field X, you use library X, which provide functions for X. You don't have to get to know what is one particular library's tree. You just use the function you want on your data. In other words, in functional programing, you use functions on your data, as opposed to how functions/methods are coded/organanized in particular package you are using to see whether it is a suitable oop “object”.
> What I'd do next in Java with an existing system is rename classes and > methods if they seem badly named to me. But it seems in Lisp this > works only by search and replace, which is hardly what I could do over > hundreds of files.
don't know if this renaming is your personal quirk or need, but in general you don't rename existing code.
But if you need to (certainly i can imagine situations), yes, emacs and much of dynamic lang world does not have some systematic mechanical ways to rename. Search & replace dir-wide with eye-balling is pretty much what you do. (partly because non-static types it's harder)
> What I also miss is a function like "mark occurences", such that when > the cursor is over a variable or function, all places in the code > where it is used are highlighted, making it easier to track where > which data goes.
In emacs, you can type Alt+x highlight-phrase to highlight a phrase. There are also highlight-regexp, highlight-lines-matching-regexp. These works on the current buffer. To highlight a phrase of all files in a dir, you can Alt+x grep-find. (assuming you know basics of unix's “find” syntax.)
> Next on my list of disappointments is exception handling. I am used > for an exception to have mostly meaningful messages and above all show > me exactly which line of the code caused the exception. Currently all > I get is the function in which it happened, even worse if it happened > within a macro, i do not even get that. And the Stack looks > superflous, like (/ 1 0) gave me 20 stack frames, where I'd expect 2 > at most in Java. These 20 cannot all be relevant to (/ 1 0), can > they?
I HATE exceptions in Java, and in fact the whole concept of EXCEPTIONS in programing langs, i hate the very terminology of “EXCEPTIONS” (being inane, inaccurate, like a dishonest euphemism). My first exposure to the concept in in Java around 1999. I suppose it was first made popular in C++ ?
in particular, like Design Patterns, OOP, UML i hate, i think the concept of “exceptions” is also one of the things that primarily came out of the OOP world for OOP purposes. It is, in a sense, a complexity introduced by OOP paradigm, not applicable or much useful outside of OOP. See:
On Jan 29, 5:23 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com> wrote:
> On Jan 28, 11:20 pm, JavaLisper <nol...@mt2009.com> wrote:> Hi, > > i have several years of Java experience, but now my new job requires > > me to learn Lisp.
> I believe that your story is fabricated. Any company smart enough to > use lisp in the first place would act very dumb to hire programmer > with zilch experience in lisp to be incharge for the system written in > lisp. Than you say that you have Allegro, since it's a company that's > certainly an enterprise edition.
I see your point but I don't think your scepticism justifies your calling me a liar. I was hired into an academic position, not into a company, and I never claimed so, and a reason to hire me might have been lack of candidates with Lisp background willing to work for little money.
In article <f2553904-764c-4cb9-8e71-90a432bfe...@y23g2000pre.googlegroups.com>,
JavaLisper <nol...@mt2009.com> wrote: > > Why not use the Allegro CL IDE?
> The others here use Emacs, and I am not sure whether Allegro IDE has > actually more features, or whether the lack of the features I look for > is due to the lisp language.
So you did not read the manual?
> > You can use the stack frame to find the function source. > > Allegro CL records the source locations. > Yes, I use that already. Still often I struggle to understand where in > a function using macros the error happened. I'd love to see the error > location in a some screen where the relevant function has been > macroexpanded deep enough to show the location of the error exactly in > expanded code.
You can run code in interpreted mode and see the expanded code. A good stepper for example will step you through the code and the expansions. For debugging it sometimes helps to run the code in the interpreter.
> > Learn about the IDE completion that is provided.
> I already use completion, but I do not find it all that powerful. > Similar for syntax highlighting, which I would have hope to be more > semantic rather than mostly syntactical. > Like in my IDE, the following code would be all the same font: > ... (setf (aref output-array (get-x cell) (get-y cell)) (get-symbol > car)) > even though some of those are functions, others accessors, others > variables.
> > Some things I do in Java to get an overview of a system new to me > > would be like generating UML diagrams showing all classes and > > dependencies, showing inheritence hierarchies and such.
> UML, supposedly “Universal” modeling “lang”, is basically exclusively > used in OOP world only, in particular Java & C++. They are pretty much > useless and become and redundant for functional langs.
I do not love UML particularly, what I like to do is visualize components graphically instead of textually. Like just scribbling some boxes and arrows on paper, I don't do much more in UML most of the times. See, text is by its nature sequential, best for sequences, acceptable for trees, but very bad for graphs with cycles. To represent cycles in text, you need ids pointing to somewhere, and that means much more effort than just looking at an image.
Also UML like images help reduce the infromation to just the bits I am interested in sometimes. Like if I have 10 functions in 10 files, and I want to know how they call each other, I do not want to read them all, memorizing all calls from each to another, jumping between files. I do not believe this is either useless or redundant for functional programming neither.