Hacker News new | past | comments | ask | show | jobs | submit login

I am one of those people who accepted the lisp religion of "syntax is evil". I have a descent knowledge of python, and I've read a few ruby tutorials.

Neither python nor ruby are lisp. Python is not cool because of generators, list comprehensions, decorators or any other feature. Ruby is not cool because of blocks or monkey patching(im suspicions of anything called MONKEY patching). Ruby and python are cool because of really cool libraries and the way people use these languages, not because they have especially well designed syntax.

Instead of arguing about how cool your crappy syntax is, argue about which has the better libraries, which implementation is better, which is used for cooler projects. Non of these languages can top lisp when it comes to expressiveness and flexibility.




Syntax is human. Syntax is ergonomics. A programming language is the bridge between man and machine. Lisp, I would argue, is far more about the machine than the man and that is the simple reason why it's not more popular.

Python was cool before the libraries; that's why those libraries got written in the first place. Lisp has been around forever and is still lacking in libraries and other support.


I'm sorry having dabbled in Ruby and having actively coded in Python and Lisp (Scheme, Clojure) you and the OP are laying the FUD on thick. I would argue Lisp has been able to stay relevant for so long because it's syntax assumes nothing about what domain you might be modeling. On the other hand, so little syntax means less "landmarks" and lot of programmers are put off by that.

Syntax is human and syntax is ergonomics. That's why languages with good syntax are so popular and deservedly so.

At the same time I think the number one reason languages eventually die off is because of syntax. A particular syntax was designed for solving specific kinds of problems. Then people realize there are deeper or different problems that the syntax cannot adequately address. Since the language is not a Lisp it cannot be repaired.

I think Python and Ruby are cool and useful tools, but I don't think their design will last another 50 years as Lisp probably will.


"Lisp, I would argue, is far more about the machine than the man and that is the simple reason why it's not more popular."

Pleas do, i would love to hear your argument. I fail to see how lisp is less humane than python, when i find it to be exactly the opposite.

Edit: what i meant was that lisp is more about the human, not that python is more about the machine, i hope i don't get misunderstood.


As a non lisp programmer, it is hard for me to automatically see what is going on in a lisp program because of mismatched " ' " and a lot of parenthesis. I believe this is one of his points. When I was learning python, or ruby, for that matter ( I use both! ) I never felt like I had no idea what was going on in the code even before I learned the languages.


Should this really be so surprising, though? Lisp is based on a different model of computation than Python and Ruby. You can't follow non-trivial C code without understanding pointers, or Prolog without understanding unification.

Syntax aside, the semantics of Python are intended to be unsurprising to people with a conventional programming background. I don't have any practical experience with Ruby, but it looks like a mishmash of Smalltalk and Perl to me, and I can usually get the gist of code snippets. Likewise, I can kinda-sorta follow written Dutch (since I've studied German and speak English fluently), but I wouldn't expect to be able to just read Thai.


> I don't have any practical experience with Ruby, but it looks like a mishmash of Smalltalk and Perl to me

Those are, I think, probably the two most influential sources of inspiration for how the language is put together, in terms of the actual end result.


Oh, Lisp isn't so difficult once you get used to.

Interestingly I find myself equally baffled when I have to read code with side-effects. There's just so much implicit state (and state changes going on in the background), you have to keep in your head. Pure languages are so much easier to understand.


I should probably try to learn lisp. I primarily use emacs, so it would make a lot of sense. Some of the ruby/rails stuff out there for emacs really isn't very good.


Emacs lisp is handy for toying around with the editor, but it's a horrible Lisp. It does not even have lexical scoping. You are much better off in terms of entertainment (through learning interesting stuff) with e.g. PLT Scheme or perhaps Arc.

(My comment about pure languages above was meant to highlight the joys of Clean and Haskell. Curry may also be worth a look. And Prolog, if you dare.)


I'd say that learning Scheme is more likely to convey what's interesting about Lisp, and there is quite a bit of great programming literature associated with Scheme. I'm not sure if it's easier to learn CL after Scheme or vice versa, though.

I still haven't done anything with Prolog past using it for prototyping, but it has some really cool ideas, and I hope to have a good excuse to play with it more soon. (And it, too, has some great books.)


> You are much better off in terms of entertainment (through learning interesting stuff) with e.g. PLT Scheme or perhaps Arc.

. . . but if you want to actually use a LISP for practical programming, and you start out with any Scheme, you're going to have to follow that up by learning another (non-Scheme) LISP. You might as well just start out with Common Lisp and be done with it.

Judging by my experience, Scheme is not a language one should set out to learn so much as a language one should learn as a side-effect of going through a book like SICP or The Little Schemer. Trying to do anything "real" with Scheme is an exercise in frustration, especially if you want it to be portable across Scheme versions, since the biggest names in Scheme implementations appear to be entirely uninterested in library portability except where "portable" means "Well, we can use it, and don't care whether you can."

Scheme itself is an excellent language, though. Too bad that, alone, is not enough.


What happened to the library situation in Common Lisp? Your comment looks like it improved since the last time I checked. That would be nice. (Though I fear Common Lisp is still too ugly for me to enjoy it. Perhaps some reader macro magic could rectify the situation. ;o)


I don't know if the library situation is good in Common Lisp. It's just enough worse in Scheme that it's kind of ridiculous to consider actually using it for other than academic purposes.


I tend to prefer languages which are expressive.

"Brevity is the soul of wit."

Therefore I like Python for imperative programming and its extensive libraries and far prefer Haskell to any LISP dialect for functional programming. Haskell is elegant in a way LISP wishes it could be.


I wholeheartedly agree that all languages should be judged on the quality of their libraries and implementation, as well as the success of the projects implemented on top of them. Ruby and Python have a pretty good track record there.

One of the themes of Gary's talk was that Ruby is more expressive/flexible than Python, and lisp was thrown into the discussion as sort of a "gold standard" of expressiveness/flexibility, without necessarily passing any judgment on overall merits of the three languages.

To the extent that Ruby strives for more flexibility, it is probably way more influenced by Perl than lisp.

As somebody who has used both Ruby and Python fairly extensively, I think Ruby is undeniably more expressive than Python at times, but also more arcane at others. Some of the differences probably come from irreconcilable tradeoffs, where you cannot have your cake and eat it too, but other tradeoffs are probably less necessary, which is why people continue to discuss it. In the case of Ruby, it's a pretty young language, so there are probably opportunities to make it more appealing to a Python mindset without losing its great flexibility, although I do not have specific proposals.

The conference Gary spoke at was a Python conference, so most people were more interested in ways that Python could learn from Ruby, without sacrificing Pythonicness. Gary seemed to reach the conclusion that the number one feature he envied in Ruby was blocks. Speaking for myself, I wish Python just had some kind of anonymous function syntax that was more rich than lambdas, even if it were not exactly semantically similar to Ruby blocks.


> I wish Python just had some kind of anonymous function syntax that was more rich than lambdas

A lot of people keep saying this, including the article author, and I'm having trouble understanding why. Lambdas are for "one-liners", functions are for more-liners.

Any time you want to write multiple lines in a lambda it's trivial to make it a named function.

    def listSomeTable(name):
        print name.center(40, "=")
        def getWeirdNumberPair(cap):
            while True:
                a = random.randint(1, cap)
                b = random.randint(1, cap)
                if (a==1) and (b==1):
                    continue
                return (a, b)
        for i in xrange(20):
            print getWeirdNumberPair(i)
        print "="*40
What do you want to use multiline-lambdas for that you can't do (equally simply and elegantly) with named functions?


First of all, your objection to anonymous functions with an example that names the function in two different places kind of takes us off topic from the discussion of "anonymous" functions, but I will still respond.

Second of all, multiline-lambdas are already possible in Python, but they are not anonymous functions.

Anonymous functions, as I said, allow for rich syntax; they do not affect the Turing completeness of the language. The context I am speaking of is "expressibility" in the sense of natural language, not whether or not something is expressible at all.

Ruby allows you to do stuff like this fairly naturally:

def process_event_until_timer_expires # check time, then call block only if # timer not expired end

process_events_until_timer_expires { |t, event| puts t fire_event_downstream(event) }

Having an anonymous function here allows you to read from outside in, which is more natural. From the outside, you know you are in some event loop, then you can look inside the block to see the details of how the event are handled. It's really that simple. Not earth-shattering different than Python, just subtly different and more expressive.

I've been using Python for a decade, and Ruby's still overly exotic to me, so I am sympathetic to people that defend the more Pythonic approach. But Ruby does allow for a different kind of expressiveness here.

Javascript also makes heavy use of anonymous functions, and if you use anonymous functions in other languages, you realize that they have value, even if they are occasionally abused and technically unnecessary.


The real problem with lambdas in Python isn't that they're restricted to one expression, but that Python's implementation of closures is clumsy (due to a scoping ambiguity). The argument about whether lambdas should be named or not is a canard. In languages that make heavy use of lexically scoped functions defined on the fly (Scheme, ML, etc.), they're often given local names. The problem is that Python's locally defined functions are less expressive. Apparently making heavy use of closures is not "pythonic".


You are correct. There is no reason not to just use an inline function that happens to have a name. I think the "lambdas can only be one line" is a newbie python mistake.


Personally, I dislike naming things that I won't use again. It feels like a waste. And then, since I have to name things, I have to come up with a _good_ name.

Just a matter of taste, mind you, but it's my reasoning for preferring anonymous functions.


They do make code more readable sometimes... but I think they are often used in Ruby as an alternative to @obj.method(:foo) -- in other words the Rubyist would use lambda{@obj.foo} and the pythonista would use obj.foo


> Lambdas are for "one-liners", functions are for more-liners.

The problem, though, is that this is entirely a Python conceit. It is in no way, shape, or form any kind of programming truism. In fact, taking a more principles-oriented approach, a named function is really just a special case of a lambda. I think this may be one of those things that using a LISP (such as Scheme or Common Lisp) helps people realize.

This:

    (define (foo n)
      ( . . . ))
. . . is just syntax sugar for this:

    (define foo
      (lambda (n)
        ( . . . )))
The fact that the syntax sugar is all many languages expose to the programmer doesn't change that fact, and the one-line restriction on "lambdas" in Python seems quite arbitrary.


Giving people concise syntax for passing anonymous functions allows one to implement a lot of control-flow operations, and combinators from functional programming, as libraries, rather than language constructs.

In python, although they could technically be done as libraries, from a syntactic point of view, having to declare named functions and pass them explicitly as arguments rather defeats the elegance of the approach.

So instead we have special features and syntax added to the language, like with statements and list comprehensions, which are limited special cases of what can be expressed more generally with a nice syntax for passing closures as arguments.

Not that it necessarily matters, there's always a pythonic way to do the equivalent thing. Although a lot of the time it's more imperative, and my taste is for functional programming idioms where possible.


Yes, Python's functions are meant to be named.


Python generators (the ones you can get with "yield") are not just syntax. They can be viewed as a distant relative of continuations or lazy evaluation.

Lisp (or lets say Scheme, because Common Lisp is ugly and imperative) does have some nice points. I rather like the syntax. But e.g. strict evaluation by default and lots of side-effects hamper the expressiveness and flexibility of the language.


You do Haskell don't you? :-)


Yes, and Clean.

I just like to counter those smug Lispians. Lisp has nice syntax, but the underlying semantics is nothing to write home about any longer. Add tail call optimization to Python (and perhaps continuations) and you have something similar to Scheme modulo syntax.


How a python vs ruby thread turned in to Haskell vs Lisp argument i will never know. The essence of Haskell is that its a lazy statically typed functional language, the essence of lisp is that it treats code as data. There is NOTHING stopping someone from making a Haskell with lisp syntax, and calling that lisp, in fact i think there is such a thing. Code as data is such a powerful idea, it is independent of the underlying paradigm of the language, you can have an algol with lisp syntax and it would be lisp, you can have smalltalk with lisp syntax and it would be lisp. Code is data is the only lisp feature you can't take away from lisp, because if you add it to your language, you don't have a new language, you have a new lisp.

Thats why lispers are smug sometimes, they know that their language will change dramatically in the future to adapt to the new environment, its the source of lisps immortality, it is destined to be reinvented.


Oh, I did not want to create a `versus' argument. Please pardon me, if I did.


>Neither python nor ruby are lisp.

You may or may not agree, but you'll probably be interested in Why Ruby is an acceptable Lisp: http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-a...

Covered on HN previously here:

http://news.ycombinator.com/item?id=416589


Yes, i have read that article. Here is my humble opinion: Having 80% of the expressibility, even if you don't need the other 20% that often, does not make you lisp. Which is why the title is not "Why ruby is lisp", but uses the word "acceptable". Its just semantics, and i don't want to argue about what makes something lisp, it wasn't even my main point.


I think "Why Ruby is Good Enough" makes for a better title, I'd agree. I don't think Ruby is Lisp either, I just felt that it went along with your point, that's all.


Does this boil down to a case of Worse is Better?


That is a good question, and worthy of an upvote. My first inclination is to say it is not, because if Ruby really were the "worse" to Lisp's "better" in some measurable, objective sense, then presumably Matz would have created something like Clojure rather than Ruby.


And not being Lisp is one of the big reasons for the success of both Python and Ruby. :-)

FLAMEBAIT -> FLAMEBAIT


I fail to see how that is flame bait. It's actually a quite insightful statement that is worth repeating: Python, Ruby and all other languages exist for a reason. The reason is that other languages, including Lisp, are not considered to be equally useful for the tasks for which a specific language is being used. Python is not only not Lisp: it's not Java, not Haskell, not Erlang, not ...

Whether it is a good reason, and whether these considerations are sensible, is a separate discussion. Whichever way you put it: they exist and should be acknowledged.


I agree. Lisp just plain looks weird because of all the parentheses and the prefix notation. I also can't help get the feeling that even with macros available to me, coding directly in the form of parse trees just might not be optimal. Also, it makes my head hurt sometimes.

As I sit here writing this, it strikes me that someone who's using these kinds of things to avoid learning Lisp is a lot like the Python newbie who's discovered the language and wanders on to comp.lang.python complaining about the syntactically significant indentation. As with most matters, I'm inclined to believe that Lisp's problem here is primarily a people problem rather than a technical problem.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: