My IDE can insert opening and closing braces and parens for me. The semi-colon is really a non-issue. One keystroke with marginal distance from where my fingers are
Uh, you do realize that a paren is a single keystroke too, right? =)
I feel like we have talked about Lambda functions before.
Yes, we did. But I didn't actually bring up lambdas this time either. You did.
Speaking of lambda functions, I don't think you provided the same links last time because I came away with the impression that C# lambda functions were basically just an alternate function definition syntax (now that I'm thinking about it, I believe it was someone else that was doing most of the 'talking' last time). In the stackoverflow examples an anonymous function was defined in the diff function. There was also an example of a delegate being defined and used inside of a function. Why does C# use two names for essentially the same thing? Delegates are functions, right?
I didn't see anyone returning functions (someone did mention that returning a Func<double,double>... I'm assuming that Func is the function meta-class in C#) or composing functions (eg write a function that given g(), f() and x returns the result [or function] g(f(x)) ) although I suspect both are possible, but slightly inelegant in C#. Perhaps we'll start a different thread doing this type of comparison sometime.
How about not having optional args with default values, args assigned keywords, or multiple length args?
Honestly, I don't come across a need for this most of the time. What do you mean by multiple length args? Like a varying number of them? List<T> will take care of that for you... you could even make a List<object> if you wanted to and then use typeof to get the type of data...
Sure, a list can hold the args. The problem with this is...
If I'm the API writer, I either have to create two functions... one using the list input and one without (or half-ass the API design and only write the list one).
If I'm the API user, I have to instantiate a list and populate it with the arg values in order to call the function (which is usually is time consuming in Java like languages*). I don't know about you, but ""I"" really prefer languages that WORK WITH ME, not AGAINST ME! =)
*Even Prolog has easier to use list facilities than Java & C++ (and I suspect C# as well).
Below is an example of optional/default argument values... You can achieve the same thing using method overloading, but I don't think it is nearly as elegant.
CL-USER> (defun foo (x &optional (y x))
(format t "x: ~a y: ~a~%" x y))
CL-USER> (foo 1 2)
x: 1 y: 2
CL-USER> (foo 1)
x: 1 y: 1
Why on earth would you return a function? Isn't the end result the value of the function? You can do that too, so long as the types match.
Well, your link had an excellent example... what if you're writing a Mathematica type application? You're going to need a function to return the 1st, 2nd, and nth derivatives of a function, right? You can't just return the value either. What if you're doing some really complicated distributed simulation. You might have one node responsible for creating (or preparing) 1000's of differential equations (or systems of equations) and using 20 other nodes to solve them.
Another example is something that DJ and I touched on earlier involves meta-programming. If I'm writing an API and can 'write' 10 functions by writing one function to create them, I think I'll go that route rather than writing all of them by hand. You can't do meta-programming if you're not able to return a function (or in 'static' OOP languages the method / class / interface / package equivalents).
The grip I have is the way you are required to put the parens around EVER statement. It gets hard to make sure you have the right number of parents in the right places. Ending each statement with a ; and putting it on its own line is much easier to debug (IMO).
A lot of people feel that way. The problem is that most people's only exposure to Lisp occurs in a AI class where the instructor 1) doesn't program in Lisp, and 2) doesn't have a good Lisp environment setup. Trust me, auto-paren matching has been around the Lisp community for a very long time. For an excellent exposure to the language, you should check out the SICP videos. I'll go out on a limb and say that by the fifth class, they're going to be doing things in Lisp (Scheme actually) that will have you stumped in C# (and keep in mind this was the very first CS class these students are taking).
Just out of curiosity, what is the largest LISP program you have had to maintain for a significant period of time? I just want to see if my experience can be comparable in terms of "size" (lines? Characters? I don't know how to make a "fair" comparison).
Even more importantly than the apples/oranges problem of lines vs characters when comparing two (very) languages is the type of programming that we do. Most of the Lisp code that I've written while working for a company, which is the smallest portion in total, involves hooks into emacs and small utilities to save me time doing things by hand (yes, me... C programmers do an absurd amount of stuff by hand bc they don't have a large lib available). The code that I've written for my academic career extremely algorithmic in nature, which translates to very small in size compared to business apps, but far more difficult to comprehend (You'll probably recall our previous "big dumb apps" conversation"). Things like performing word sense disambiguation and computational geometry among others. Also, quite a few of those apps utilize multiple languages/environments (eg the WSD code parsed a dataset file and spit out a matrix in matlab syntax, I then took the SVD of the matrix in matlab, and read that back into a lisp env for doing the WSD). My poker software is probably my largest lisp project (I would estimate it is in the 4K neighborhood and w/o macros I'm sure that would explode to well over 10K).
The other big difference is the way people write applications. I tend to write far denser code and far more ambitious software than nearly everyone that I've worked with at companies (on business type apps). They just don't have nearly the algorithm/ai/meta-programming background (I don't know how many times that I had to explain the halting problem can't be solved at Boeing... maybe 6? Or that 'parsing a word doc is not AI'... 4?). When I first started working at Boeing, I 'inherited' a rules-engine application that was approaching 40K SLOC with ~60 XML files and ~60 Word docs (the spec docs for the XML files). Compared to some of the other business apps that I've seen, the code was actually pretty normal (ie written by people that scrapped through an average CS program getting by on Cs and Bs). After my buddy Andrew (who is working on his phd @ UNC now) and I had finished rewriting the application, we were down to 3600 SLOC, 60 XML files and 0 word docs (we generated pdf spec files from the xml). To top it off, we actually provided quite a bit more functionality than the previous version as well (and it actually worked correctly). I repeated the feat a little later with a smaller application that was actually a mess (this guys was a D student... I hope). The original took over three minutes to create a 'database delivery' whereas my version did the same thing in under 6 seconds (w/o using threads, they decided six seconds was good enough and cut the project short).
Just out of curiosity, what are you actually trying to compare? Lisp certainly has 'programming in the large' facilities like packages and system definition functionality if that is what you're wondering.