Live data from Hacker News

The Roots of Lisp (2001)

paulgraham.com

11–20 of 92 posts

Re: The Roots of Lisp (2001)

#11

IMO Lisp is just overrated, it lacks visual clues, reads right to left with horrible nesting etc.. Sure it has some good concepts. But fanboys on internet make it seem like some God tier thing.

"Some good concepts"?

It was the first language to add "if/else" constructs, GC, closures, first class functions, reference semantics, and recursion.

It took between 5 to 40 years before these became available in mainstream languages (conditionals like if/else were adopted early, GC not so much, closures took even more). Add to that macros and the flexibility of runtime evaluation / code creation, which most mainstream languages still lack.

And of course, Lisp's rules remain (and will always be) the most succinct way to define a full blown programming language with meta-programming facilities to boot -- as opposed to a mere Turing machine like thing or assembler.

>IMO Lisp is just overrated, it lacks visual clues, reads right to left with horrible nesting etc..

This doesn't make any sense...

The nesting is the same as in almost any language.

"reads right to left" - huh?

You know that Lisp code can be indented right?

Re: The Roots of Lisp (2001)

#12
post #11

IMO Lisp is just overrated, it lacks visual clues, reads right to left with horrible nesting etc.. Sure it has some good concepts. But fanboys on internet make it seem like some God tier thing.

"Some good concepts"? It was the first language to add "if/else" constructs, GC, closures, first class functions, reference semantics, and recursion. It took between 5 to 40 years before these became available in mainstream languages (conditionals like if/else were adopted early, GC not so much, closures took even more). Add to that macros and the flexibility of runtime evaluation / code creation, which most mainstre…

I think they are referring to the nested nature of lisp function calls.

    (second-fn (first-fn val))
I think that is really just personal preference/what you were taught as opposed to good or bad language design. But it really doesn't matter as one of the big benefits of lisp is it's ability to be metaprogrammed. That same example could be rewritten in clojure as

    (-> val first-fn second-fn)
thanks to macros and doesn't suffer from the right->left reading.

Re: The Roots of Lisp (2001)

#13

It amazes me how @pg managed to conquer the business side of startups and started YC given his very technical background! To me it is not very common for (very) technical people to be good at both tech and business!

I'm electronics and embedded software developer, but I took a pause from that and founded a small web business startup with few guys two years before PG founded Viaweb. The product was very similar to PG 's Viaweb. Viaweb was more general and consumer market oriented. We had narrow focus with b2b trough our connections.

It's hard to describe how easy it was to make money in the late 90's with even little technical skill and tiniest amount of business understanding. We were making money hand over fist knowing next to nothing.

PG sold his company for $50 million, we sold ours for $5 million after we took the mountain of cash out of it (another $5 million). After reading how PG did it, I think his genius was paying $16,000 a month for a PR firm. He understood the value of PR, we didn't. http://www.paulgraham.com/submarine.html

His essays, HackerNews and Y combinator are expression of this understanding. He has created expanding self-reinforcing network of affordable PR and connections for startups. That's the real scarcity in the startup scene. Being accepted into a batch is valuable. Instead of hiring PR firm, PR firm accepts you and stamps you with the Y Combinator brand.

Re: The Roots of Lisp (2001)

#14
post #11

Earlier quoted context omitted.

"Some good concepts"? It was the first language to add "if/else" constructs, GC, closures, first class functions, reference semantics, and recursion. It took between 5 to 40 years before these became available in mainstream languages (conditionals like if/else were adopted early, GC not so much, closures took even more). Add to that macros and the flexibility of runtime evaluation / code creation, which most mainstre…

I think they are referring to the nested nature of lisp function calls. (second-fn (first-fn val)) I think that is really just personal preference/what you were taught as opposed to good or bad language design. But it really doesn't matter as one of the big benefits of lisp is it's ability to be metaprogrammed. That same example could be rewritten in clojure as (-> val first-fn second-fn) thanks to macros and doesn't…

> I think they are referring to the nested nature of lisp function calls. (second-fn (first-fn val))

How's this different than:

  secondFn(firstFn(val))
 
other than the placement of parenthesis, the two cases read exactly the same, left to right.

Re: The Roots of Lisp (2001)

#15
McCarthy wasn’t just interested in making Lisp for AI, he was thinking about the possible applications AI, with Lisp as a platform to get to more advanced states of understanding. An example of this is in his paper “Computer Control of a Machine for Exploring Mars." Stanford Artificial Intelligence Project, Memo N. 14, June 15, 1964, Author: McCarthy, John, 1927-2011; Stanford University Library collections.

https://stacks.stanford.edu/file/druid:qh147kq8662/SC1041_SA...

Re: The Roots of Lisp (2001)

#16
post #14

Earlier quoted context omitted.

I think they are referring to the nested nature of lisp function calls. (second-fn (first-fn val)) I think that is really just personal preference/what you were taught as opposed to good or bad language design. But it really doesn't matter as one of the big benefits of lisp is it's ability to be metaprogrammed. That same example could be rewritten in clojure as (-> val first-fn second-fn) thanks to macros and doesn't…

> I think they are referring to the nested nature of lisp function calls. (second-fn (first-fn val)) How's this different than: secondFn(firstFn(val)) other than the placement of parenthesis, the two cases read exactly the same, left to right.

I've seen a lot of breaking that out into the following in imperative languages.

    var intermediaryVal = firstFn(val);
    var result = secondFn(intermediaryVal);

Re: The Roots of Lisp (2001)

#17
post #3

Recently had a conversation on how functional programming and declarative programming were somewhat linked, and how i observed that languages that started to go down the functional road slowly tried to add more and more capabilities for DSLs, and then slowly moved toward becoming a lisp. But that was just my feeling. is this theorized somewhere ? Or am i just dreaming ?

Anecdotal experience:

(dynamic) functional programming enables very 'easy' succinct abstractions through combing out concretions and composing functions out of a general tool-set. Think code-reuse in the small.

With some discipline you naturally end up with a very data-oriented codebase, where the specificity of your application/library ends up in your data-structures.

Now these data-structures are really just plain data, without specific behavior attached to them, so they embody the (maybe almost) declarative part of your program/system. The next step would be to polish them to make them more human readable.

An additional feature of Lisps is their homoiconicity and macros. These come into play when plain data-structures are not the right fit anymore. Typically you want to handle some user/client defined behavior. You can now transform the syntax of the language itself to clean up your API to reduce boilerplate and increase readability.

In a sense you have now programmed your own DSL.

Re: The Roots of Lisp (2001)

#18
post #14

Earlier quoted context omitted.

> I think they are referring to the nested nature of lisp function calls. (second-fn (first-fn val)) How's this different than: secondFn(firstFn(val)) other than the placement of parenthesis, the two cases read exactly the same, left to right.

I've seen a lot of breaking that out into the following in imperative languages. var intermediaryVal = firstFn(val); var result = secondFn(intermediaryVal);

  (let [intermediary-val (first-fn val)
        result (second-fn intermediary-val)])
Or as one of the parents said

  (-> val first-fn second-fn)

Re: The Roots of Lisp (2001)

#19
post #11

IMO Lisp is just overrated, it lacks visual clues, reads right to left with horrible nesting etc.. Sure it has some good concepts. But fanboys on internet make it seem like some God tier thing.

"Some good concepts"? It was the first language to add "if/else" constructs, GC, closures, first class functions, reference semantics, and recursion. It took between 5 to 40 years before these became available in mainstream languages (conditionals like if/else were adopted early, GC not so much, closures took even more). Add to that macros and the flexibility of runtime evaluation / code creation, which most mainstre…

One small detail - though COND and IF/ELSE are very closely related, they aren't quite the same thing. Early Smalltalk also started out with COND (a right arrow which made code look like modern switch/case) and later evolved to #ifTrue:ifFalse: which is still postfix, so feels backwards compared to other languages. Lisp and Scheme got more conventional if/else eventually.

Re: The Roots of Lisp (2001)

#20
post #11

IMO Lisp is just overrated, it lacks visual clues, reads right to left with horrible nesting etc.. Sure it has some good concepts. But fanboys on internet make it seem like some God tier thing.

"Some good concepts"? It was the first language to add "if/else" constructs, GC, closures, first class functions, reference semantics, and recursion. It took between 5 to 40 years before these became available in mainstream languages (conditionals like if/else were adopted early, GC not so much, closures took even more). Add to that macros and the flexibility of runtime evaluation / code creation, which most mainstre…

Nesting can be sorted via macros, e.g. closures threading macros

    (defn unique [str]
       (->> (str/split str #"\s+")
            (map #(Integer/parseInt %))
            (partition-by even?)
            (take-while #(not= (count %) 1))
            (first)
            (count)
            (inc)))

  (unique "2 4 6 8 7 10 12")
   => 5
Post reply on HN