13 ms·
Why Lisp is a Big Hack and Haskell is Doomed to Succeed (2011)
- bbradley406 13y agoThe author raises valid points about Haskell, but I disagree with his statement about a static-typed lisp. Typed Racket is useful and enjoyable to program with, and includes a handy optimization coach.
- lukeqsee 13y agoI cannot speak for Lisp, but I am in the throes of writing a compiler from scratch in Haskell (while concurrently learning Haskell). I feel/felt very much as this article described—constrained. And then I learned ETA-reduces. Then I learned monads. And then I learned … The list just keeps going. As I slowly learned the language the proper way, I am now able to do anything I did in a imperative/OOP/whatever language, but now I have that foundation of type safety. Like many will say, if it compiles, it most likely just works. Coupling this with automatic checking via GHC-mod and I am just as performant (in terms of writing code) and encounter half as many bugs as any other language I've ever used. Haskell isn't a panacea, but it's a very good language.
- axman6 13y ago> if it compiles, it most likely just works I believe the more you learn, the more this becomes true as well. To begin with, you'll write a lot of code that has potential bugs (like missing cases when pattern matching, using types that you really shouldn't, using error when something like Maybe or Either would be more flexible etc.). eventually you realise how to write code that can avoid a lot of these problems.
- jes5199 13y agoFor a language that prioritizes "safety" above all things, there is an awful lot of flying blind and dangerously in Haskell. It's so, so easy to write Haskell code that's safe until you change something distant in the system, which changes when things get lazily-evaluated, and now you have a very serious resource leak. And because of the IO restrictions, you aren't likely to put logging in your code - and if you do, the logs will themselves change the lazy evaluation behavior of your code. I've seen Haskell programs that stop crashing when you pass in --debug ! If the Haskell environment was more like a virtual machine - like in Java - where you could connect into a side-channel and see what types of data were persisting in memory as the program ran - you'd at least have a chance of debugging this sort of thing. But instead it compiles to machine binaries. There doesn't seem to be any interest in the Haskell community in making tools to deal with this sort of thing - they say "you should learn not to make resource-leaking code". Which is the same thing the Lisp hackers say - "just learn not to make type errors".
- lukeqsee 13y agoI concur when it comes to lazy-evaluation. I once lost 10% of my grade in a project because I removed a debugging print statement, which in turn made a data-structure lazily evaluated, which in turn meant that a significant portion of my type-checking was never evaluated.
- dietrichepp 13y agoWhat? This means that you must have been using exceptions to communicate type-checking information. That's just a terrible way to write Haskell. Exceptions only have nice semantics when they're e.g. thrown in the IO monad. -- No, no, no, no! checkValid :: Int -> () checkValid x = if x >= 5 then error "Invalid number!" else () -- This works fine. checkValid :: Int -> Either String () checkValid x = if x >= 5 then fail "Invalid number!" else return () This may sound a bit harsh, but I think you deserved to lose that 10% if you had such a fundamental misunderstanding of "lazy evaluation".
- cliftonk 13y agoTelling a kid in college (I was a sophomore when I was writing Haskell) that he deserves to lose 10% over something like that is crazy. The obvious to us, many years into programming professionally, is not always obvious to newer folks.
- tensor 13y agoThe ideal purpose of grades is teaching. It's a way of informing you of the parts of the curriculum that you do not yet fully understand. This sounds like an entirely appropriate situation to lose grade points on. Unfortunately, grades now also serve as some poor measure of intelligence or competency in many people's minds.
- ubercow13 13y agoA grade is also how they decide if you get your undergraduate degree. It would be a strange shame if that decision had nothing to do with your intelligence or competency as you imply.
- avmich 13y agoAn interesting, to me, capacity of Lisp is to be represented uniformly - so called homoiconicity. For example, having a Lisp program, you can relatively easily add - statically - a debug statement after each statement, and then use that resulting program instead. That would be harder to do in Haskell - because the Haskell syntax is much richer. Another doubt to "eating all languages lunches" comes from having multiple different paradigms in programming languages. I can imagine Haskell eating, say, Prolog's lunch - for example, Norvig has shown how Prolog could be implemented as embedded in Lisp. But I suspect it's going to be harder to repeat in Haskell the strong points of Forth (stack computations), Tcl (strings as universal media?) or J (composability of primitives), even though some approximations could be made. It's fishy idea to search for a singular "perfect" language - unless that's something like English, with all its imperfections built-in.
- judk 13y agoCoincidentally, I just saw a reddit comment where someone showed a way to statically add a debug statement to every function definition. The trick is to use a "pattern guard" to evaluate the trace, and then compare the result to "undefined" (never matches), so that the program continues on to look for a pattern that matches.
- axman6 13y agodo you mean the: foo x | trace (show x) False = undefined | otherwise = ... x ... ? That's not comparing anything to undefined, now is it a pattern guard, it's executing the trace function which then returns False leading to the next guard being evaluated and the actual computation being performed. The undefined is just there because it always type checks, and will never execute.
- iopq 13y agoThe singular "perfect" language would have to have pluggable syntax - so that anyone can have their perfect syntax as long as it generates the same parse tree. At the same time, its type system will be pluggable too, so that people can keep improving the type system (dependent types, dynamic types, etc.) without changing the language. Oh yeah, and of course its code generation/execution model will be pluggable as well. Do you want to interpret it? Sure! Do you want to compile it so it performs better on your target computers? No problem! Compile it to JavaScript? Why not? In that way everyone can be programming in the same language that's flexible enough for everyone's use, but at the same time can contain DSLs. Pluggable syntax/custom type checking means you can embed SQL code and make sure it's valid before running it. It also means SQL could be a custom SQLStatement data type with its own semantics. In short, only a language that allows every type of programming can be the "one true language"
- X4 13y agohaskell evangelism? I mean I like haskell, but this theory or prophecy is based on no facts.
- ksikka 13y agoYour logic and reasoning seems to be all correct except for one thing... "Better languages" don't necessary succeed. I mean, just look at PHP and Javascript... Would you say that they were doomed to succeed because of their language features? There's more to "language success" than the technical characteristics of the language.
- skybrian 13y agoYes, PHP and JavaScript show that deployment is everything. A language that works well with your target platform is better than one that doesn't. (With PHP, it was apparently a bit subtle; ISP's can host it easily and it works well with live updates via ftp, and that beat out language features.) Objective C is a third example: It's popular because iPhone.
- systems 13y agoi would argue that clojure is very successful i think (probably more like a statment of obvious) language success depends equally on the libraries available for it clojure have a lot of libraries, and leiningen and echo the "worse is better" slogan i think that languages that offer a little more feature above the current mainstream languages, will success more than languages that offer a lot more most programmers are doers, they prefer to spend more time doing rather than learning languages that are too smart ... are less likely to succeed not until the day ... they become only a little bit better than the mainstream we move slowly from c to c++ to java to ruby ... the next big language is one that is only a little bit better than ruby ... not a lot better i think clojure fit the bill
- deadghost 13y agoIf clojure is only a little bit better than ruby, is there a language you think is a lot better?
- systems 13y agowell, i guess ... having a second thought about it, clojure is very different from ruby, being a lisp i am sure most of the ideas in clojure wont be alien to most rubyist ... but still its a fairly large departure from ruby a language that is only one or few steps above ruby, will have to use closer syntax ... be more or less focused on OO rather than functional programming
- m0nastic 13y agoIt seems weird to think that there exists any language currently which will wind up being the one-true-language. As an industry (and a research area) there still doesn't seem to be any real consensus around "what's best"; just a bunch of differing opinions and trade-offs. I don't think any amount of evidence (were it even to exist) would convince someone not amenable to strongly-enforced static types to see their value. The entire practice of software development seems oriented around feelings and past experience. I can appreciate that their are groups of people doing research to try and bring rigor and quantified data to the process, but if at the end of the day, a developer can spend a weekend putting together a node.js web app and have that take off and prove successful, you've pretty much lost any opportunity to convince them that they should stop using their tools and switch to some different tools. I don't actually think there's anything wrong with that either; good for them for being suspicious. I decided to investigate Haskell about 8 months ago when I had an opportunity to write a big system for my job. It fit well within my constraints and requirements, and the little I knew of it at the time seemed like it would be a good language to spend time getting to know. I liked that everything in the language seemed like it got there through reasoned debate and experimentation, and that it seemed like a language-feature sandbox that more mainstream languages were eventually pulling from (Perl advocates say the same thing about Perl, mainly that it already has all the features that other languages are now trying to figure out how to implement). I liked that they don't seem to punt on the hard problems (which over time become more and more of the problems left for languages to address), even if that means that doing complicated things in Haskell is complicated. I don't know how I'd feel about Haskell suddenly becoming super popular though. Even aside from the "God I hate that this band I've been into for a while is now suddenly popular" trendiness, I don't think the community would be able to handle sanely what an influx of massive amounts of new users would do to things. It's hard enough getting all the category theorists and abstract algebra professors to deal with the fact that Cabal takes lower and upper bounds on dependencies. If I could spend the entirety of my career using Haskell for everything, maybe that would be great. I haven't gotten good enough yet to have strong opinions about its failings, so I'm still very much in the honeymoon period. But that seems like a silly thing to shoot for, even if I feel the same way about Haskell in 10 years that I do now. And it seems silly to expect that everyone else would feel the same way.
- 13y ago
- pron 13y agoUsing the type system to create less buggy code beyond what's done in mainstream statically typed languages (that are not types-all-the-way-down) is an interesting, but still very-much -open research question. The type system, beside being expressive, would need to be easy to understand and debug and require significantly less effort to wield than debugging less-typed code. On a related note, I'm watching with interest how the new Java 8's pluggable type systems[1][2] would play out (I understand the project is expected to have a big released April 1st). Those are pluggable intersection types, that can be inferred and injected to legacy code that was written without them. [1] http://docs.oracle.com/javase/tutorial/java/annotations/type_annotations.html http://docs.oracle.com/javase/tutorial/java/annotations/type... [2] http://types.cs.washington.edu/checker-framework/ http://types.cs.washington.edu/checker-framework/
- enupten 13y agoThe impression I have from reading the comments, seems to indicated that many believe Common Lisp not to have types ! With CLOS (and :before methods!), and optional type declarations, and the awesome implementations which do type inferencing, you tend to catch far more bugs compared to say, something like Python. Yes, dear brethren, Common Lisp code (with SBCL) will not compile if the ftype conflicts with the inferred types of the arguments. Edit: Besides, the author, does not seem to have the same opinion about Lisp vs Haskell today.
- Grue3 13y agoIt really is amazing how many errors SBCL catches during compilation. At first it was annoying me coming from a more lax CLISP, but then I found that it was always my mistake that resulted in them.
- orthecreedence 13y agoSo Haskell will eventually be able to do everything lisp does, but it's impossible for lisp to do everything Haskell does. I smell bullshit. Both languages have their place. Sometimes functional and type-safe isn't the best way to go about something. Sometimes it is. Sometimes it depends on the programmer. There is no One Right Way or One True Language.
- 6cxs2hd6 13y agoAlso, it's a weird comparison because Haskell is one, crisply-defined thing -- but what does he mean by "Lisp"? Common Lisp? Scheme? Racket? Clojure? Does Dylan count? The only Lisp he mentions specifically is Emacs' Elisp -- which would be a straw man to pick for a comparison. Things like Typed Racket (and its port to Clojure.Typed) show that you can have a lisp with static typing, as well as the traditional strengths of a lisp. You can also have a lisp like Dylan or Pyret that doesn't even use s-expressions, but is most definitely a lisp.
- tehabe 13y agoHow is something which needs a >700 MB runtime doomed to succeed. I think even Java is smaller than that. Not sure though.
- Agathos 13y agohttp://stackoverflow.com/questions/4858585/why-is-ghc-so-large-big/4867236#4867236 http://stackoverflow.com/questions/4858585/why-is-ghc-so-lar...
- thirsteh 13y ago700 MB runtime implies every compiled binary is 700+ MB, which is obviously untrue. You probably mean the compiler and standard libraries.
- deleted 13y ago[deleted]
- iopq 13y ago700MB? Considering my SSD is 400GB, why would I care?
- Ygg2 13y agoBecause some devices don't have 400GB of SSD?
- mrottenkolber 13y agoLisp can do that stuff. Point two depends on the implentation but point one is standardized.
- ruttiger 13y agoWhy controversial blog post titles get clicked and why...
- edem 13y agoI fail to see the concrete examples you came up with to back your claims up. Or...were there none?
- kristianp 13y agoOriginal hn discussion: https://news.ycombinator.com/item?id=2062436 https://news.ycombinator.com/item?id=2062436
- ggchappell 13y agoCan someone explain why anyone would think that dynamic typing is "clearly-on-the-horizon" for Haskell? (Not saying it isn't; just wondering.) Also, FTA: > Haskell is clearly moving towards dependent typing, which in theory, allows the expression of arbitrary invariants that are maintained statically, without having to run the program. Well, "arbitrary" within limits. Dynamic type checking is still strictly more powerful than static type checking -- in the sense of what Boolean statements it can test about particular values -- no matter how you slice it. (No, I'm not arguing for dynamic type checking.)