Live data from Hacker News

On Lisp

paulgraham.com

101–107 of 107 posts

Re: On Lisp

#101
post #93
post #25

Earlier quoted context omitted.

That's basically the consensus among professional academics on the matter. Also among well respected programmers in senior roles like Joshua Bloch and John Carmack.

The problem is static typing is applicable to only a subset of any particular programming task (in other words, even a Haskell or ML program that compiles is not necessarily guaranteed to be correct, insofar as it still may not produce the output desired by the programmer.) Because of this, it introduces incidental complexity into a program, because it subdivides the programming task into a part that can be addressed…

Sorry for the long rant ahead.

This is anecdotal, but I find that in general a static, strongly typed language actually helps me when I am writing the program. One quarter of the time, I find that the code I just wrote doesn't make sense and end up having a conversation with the compiler and REPL until it works.

One important place where I find types help me is error handling. I typically prefer to have Maybe/Option, Either, or similar types for normal errors, and to have exceptions reserved for when the program enters an unrecoverable state and needs to crash.

There are also cases where a dynamically typed language will error during runtime, and where a statically typed language would have instead errored during compile time. It is possible to encode invariants into types, for example to force all red-black trees to be balanced.

I haven't found a case yet where such an error wasn't due to flawed reasoning on my part, and depending on the language implementation it is possible to optionally defer type errors to runtime. The language I tend to use the most also has an escape hatch to allow dynamic types if you want them (implemented as a library).

Regarding incidental complexity, in a Hilney-Milner language, most code can be written without any type annotations whatsoever, although in my language of choice (Haskell), it is standard practice to include type annotations anyway to help readability.

Encoding invariants into the code does increase the complexity, and you'll see most library writers strike a balance between complexity and correctness. If you go for an even stronger type system than Haskell's (such as Coq's, Agda's or Idris's) then it is possible to encode all invariants using the types, although type inference doesn't work as well anymore.

Static, strong typing is there to help the programmer, and typing a dynamically-typed language is probably easier. Haskell's type system helps automatic unit testing libraries such as quickcheck and hunit work better. Computer hardware doesn't care about types, but rather where the bits and bytes are and what points to them. Static typing is there purely for the programmer's benefit, rather than the computer's.

I can't say that writing software in a language that has a weak type system is anywhere as enjoyable, and I find myself having to debug my code.

Re: On Lisp

#102
post #60
post #38

Earlier quoted context omitted.

> Both Clojure and Common Lisp have type systems that can do most things ml and haskell can do. I don't know about that, Haskell has quite a few very non-trivial extensions in it's type system that I have yet to see replicated outside of research languages. ( Rank-N Types, GADTs, Kind polymorphism, etc).

See things, like this http://en.wikipedia.org/wiki/Qi_%28programming_language%29 or https://github.com/clojure/core.typed

Both of those projects implement fairly simple type systems, they both even look simpler than even ML. Having at least outer rank-1 quantification is what I consider a "modern" typing system.

Re: On Lisp

#103

Earlier quoted context omitted.

Yep, that's what the link in my original post was hoping to demonstrate. I find rolling up a few lets one after the other more natural in some other situations.

Although I'm second-guessing my let example now. Lets are great for assigning names to your building blocks, but I don't really like using them to obscure my processing flow as above. Perhaps this would be a better compromise: (defn example [n] (let [square #(* % %) halve #(/ % 2.0) add3 #(+ % 3)] (-> n square halve add3 str))) > (example 1) "3.5"

If the function name or docstring is descriptive enough, I'd just go for

    (defn square-halve-add3-to-string [n] 
      (-> n 
        (#(* % %)) 
        (/ 2.0) 
        (+ 3) 
        str))

Re: On Lisp

#104
post #64

Earlier quoted context omitted.

Common Lisp is ugly (e.g. see https://en.wikipedia.org/wiki/Lisp-1_vs._Lisp-2 ) and not particularly functional. There are a few reasons you might want to learn it nonetheless, but they don't apply to someone new to Lisp. (In case you ask: Common Lisp is a useful target, if you want to port programs from even older Lisps, like emacs' elisp.)

Oh I see by Ugly you mean practical. Lisp is about Metaprogramming not referential transparency. On the otherhand once you start diving in the source code of Clojure you quickly find yourself looking at javaclasses ime. On the other hand CL has CLOS, an object system which puts others to shame. And reader macros to define your own syntax. See cl-annot to see the decorator syntax from python being ported to CL or how…

You can have CLOS in Racket, too. And Macros.

What's practical about a Lisp-2?

Re: On Lisp

#105
post #60

Earlier quoted context omitted.

See things, like this http://en.wikipedia.org/wiki/Qi_%28programming_language%29 or https://github.com/clojure/core.typed

Both of those projects implement fairly simple type systems, they both even look simpler than even ML. Having at least outer rank-1 quantification is what I consider a "modern" typing system.

Im not a expoert. But I think at least Qi is as advanced as haskell or ml. The clojure one is relativly new and not jet full featured.

Re: On Lisp

#106
post #46

Earlier quoted context omitted.

What do you mean by indentation problem? In practice, everyone just uses emacs to indent, no problem.

Oh, I was just thinking that it would be nice to visualize lisp in a more two-dimensional way, something like this: http://bl.ocks.org/mbostock/4063582 I'm not really a lisp coder at all (a bit of clojure experience), but the relentless self-similarity of lisp languages is both a strength and a weakness, IMHO. But it's regular syntax would make it a good candidate for a treemap. Just sayin'.

Most clear clojure code doesn't look parenthetical at all really. Usually my code ends up looking like a few let declarations and then a single line of execution - and I'm only a beginner!

4clojure.com is a good resource to see how experienced clojure programmers can turn what would 50 lines of imperative code into a handful of keywords. The self-similarity is a non-issue. Saying it is a negative is like saying Mozart used "too many notes" in his music.

Re: On Lisp

#107
post #89
post #54

Did someone try (and possibly succeed) converting it to epub, by chance?

http://www.mbishop.name/post/4113599512/on-lisp-by-paul-grah...

thanks! although the diagrams don't seem to work for me, unfortunately
Post reply on HN