8 ms·
An Apology of Sorts: Functional Languages Are (Still) Overrated
- jballanc 14y agoI've recently been using Clojure more and more, including introducing it for a few nascent projects at work. I haven't been this excited about a new language since Ruby in 2005. Plenty has been written on its technical merits, but there is one aspect of Clojure that I don't think enough people pay attention to: the community! 4Clojure is just one example. The #clojure IRC channel is another. The Clojure community today feels like the Ruby community did back in 2005: hackers having fun and getting work done at the same time. You owe it to yourself to give it a chance...
- jonathansizz 14y ago4Clojure looks great .. what are some of the other stand-out community sites for learning and working with Clojure?
- ludicast 14y agoThis is awesome too, if a lot shorter: clojurekoans.herokuapp.com
- evilduck 14y agoI'm pretty much totally ignorant about Clojure in practice. One part I love about Ruby is being able to drop into an irb/pry session nearly instantly or run the Rails console and test out code and ideas interactively and being able to quickly restart the dev server if configs change. JRuby has always been appealing to me but it's kind of annoying to use for development due to the JVM startup time. I used to do Java development full time and had the same annoyance with needing the compilation/restart step to see changes. Does Clojure address this problem or are there workarounds (like Guard/Spork for testing in Rails)? Is there anything fundamentally different from JRuby that would alleviate the slow restarts, or am I simply thinking about the problem wrong?
- jballanc 14y agoThe Clojure community just recently put its full weight behind nREPL. You can run nREPL from Leiningen outside of a project directory, much like IRB. To be honest, I've never noticed the JVM startup time... But there is another way! Clojure inherits the concepts of SLIME/SWANK from the world of LISP. Essentially, since functions (not objects) are the top-level constructs in Clojure, you can redefine functions at any time while your program is running, and everything will "magically" start using the new definition. So, the typical way one develops in Clojure is to start a SWANK or nREPL server, then load their program files into this server. At that point, you can run any single function or if you're writing a web app, for example, you can run the function that starts the web server, hit a URL, edit a function, re-evaluate, reload the web site and immediately see the results. ClojureScript One is one example of how this can be taken advantage of. You can see a demo of it here: http://vimeo.com/35153207 http://vimeo.com/35153207
- habitue 14y ago"Essentially, since functions (not objects) are the top-level constructs in Clojure, you can redefine functions at any time while your program is running, and everything will "magically" start using the new definition. " This isn't exactly correct. It's not because clojure has first class functions that you get this behavior, but because clojure has late binding: http://en.wikipedia.org/wiki/Late_binding http://en.wikipedia.org/wiki/Late_binding
- jballanc 14y agoTrue, but Ruby also has late binding. Ruby also has open classes, so you could (in theory) do something very close to SLIME with Ruby. The problem is, Ruby also has singleton classes and singleton methods, so there's no guarantee that a change made in code and evaluated in the runtime will have the desired effect. Actually, Clojure has a similar problem with defonce, but in practice I've found that Clojure works much better with the SLIME development model than Ruby does.
- 14y ago
- Dn_Ab 14y agoI have two questions about Clojure. (1) How fast is it compared to Java and is the method for speed based on rules or tricks? (2) Compared to other lists how natural is metaprogramming? I've recently started playing with Scheme and the feeling I get is not quite just functional programming. It feels closer to Symbolic Programming, the same feeling I get with the languages in Maxima or Axiom. There is an intersection with functional programming but the feeling I get doesn't cluster as close with Haskell, Ocaml or F#. And even if the occasion should rarely occur where the full extent of this power is needed, just knowing that code and execution and data and algorithms are basically indistinguishable results in an incredible mindshift in style. I haven't seen anything comparable till I started to wrap my mind around genetics + DNA. So my question around all that rambling is, in clojure is the symbolic style on the counter, shelf or pantry?
- lkrubner 14y agoRegarding speed, you really need to read this essay that John Lawrence Aspden wrote, "Clojure Faster than Machine Code?" He walks through several experiments in which he figures out how to optimize Clojure for the JVM. Finally, he writes a macro that expands his code into code that adds type hints to all of the vars, and with the help of the type hints the JVM goes blazing fast. He concludes: " And so I wonder: This technique strikes me as very general, and very useful. All sorts of things can be represented as lookups in tables. This whole program took me one short day to write, and the whole time I was doing things that I've never done before, just going by intuition. Once you've got the hang of it, it's easy. I think that the program should be as fast as the equivalent java program would be, although I haven't got around to actually testing that, so I may have dropped the ball somewhere. In any case, it's probably possible to generate code like this that does run as fast as whatever the fastest Java implementation actually is. The JVM is widely thought to be around the same speed as native machine code or optimized C. I'm absolutely sure that I'm not able to write the equivalent program in Java, C, or assembler without code-generation. The code generation would be very very very much harder in Java, C or assembler. And so I wonder, is Clojure the fastest computer language in the world?" http://www.learningclojure.com/2010/09/clojure-faster-than-machine-code.html http://www.learningclojure.com/2010/09/clojure-faster-than-m...
- bunderbunder 14y agoThere is one language that stands way out at the forefront when it comes to working on enabling B grade programmers to write scalable, concurrent systems: C#. I think a big part of its success is that it avoids the hype machine. It isn't a disruptive language that changes the way we do things. It can't be, or management would be justifiably wary of it. Instead, it's a language that started out as a very close clone of Java, and since then its designers have been rapidly iterating to the point that it's now a (mostly, some would say) functional language that's solidly embedded in the enterprise space. It's somewhat disappointing that it's still missing algebraic data types and pattern matching. But considering I've got most of what I want without ever having had to pitch switching languages to an employer, I'm really not in a position to complain too much.
- debacle 14y agoWhile I don't disagree that C# is good, I don't see how you could say that Java is in any way behind. At least in concurrency, I would argue that it's somewhat ahead. Threading in Java was more intuitive to me than threading in C#.
- sk5t 14y agoBoth this and the parent post should be more specific, as pre-lambda, pre-TPL threading in C# was not too much different from standard Java threads. Long-standing language support for events and delegates put C# slightly ahead of Java at the start, but only in the last few years has C# left Java in the dust.
- bunderbunder 14y agoIt's been a while since I last spent much time with Java, but to my knowledge it's still missing: - User-defined value types - Lambdas - An equivalent to LINQ (and PLINQ) - Language-level support for asynchronous programming - True generics (Java's implementation is essentially syntactic sugar on good old-fashioned typecasting.) - Extension methods - Late binding
- debacle 14y ago
- debacle 14y agoFunctional languages historically suffer from weak libraries. Languages built on the JVM can side-skirt that issue quite a bit.
- joe_the_user 14y agoWell, What I would say about Functional Languages isn't that they're over-rated but they are mis-rated if they are described as means of replacing the abomination that is Object Oriented Programing (which I use every day). I would free acknowledge that functional programming constructs are powerful methods to concisely specify complex, well-behaved systems. I use arrays of function pointers and similar things when I want to create such a subsystem in a c++ program I'm working on (obviously not using full fp but it still give power-galore). The thing that FP isn't is means to tie two huge, horrible systems together (or accomplish similar tasks). And while fp might indeed be used to create a number of elegant systems, if fp is unable to beat back the forest of horrible, inelegant systems around us, it isn't going to replace OO and it isn't going to get wide adoption. Because OO may be awful but has the quality that if used judiciously, it can made ugly stuff somewhat less ugly.
- tmhedberg 14y agoI'm not sure what you mean by "FP isn't meant to tie two huge, horrible systems together". Is any language or programming paradigm really designed with that usage in mind? But assuming that that is in fact the case, I wonder whether it would still be the case if we lived in a bizarro world in which FP had dominated and OOP was seen in the mainstream as an impractical oddity. I suspect that, to the extent that functional languages do not make for good "glue code", that is primarily due to the impedance mismatch between FP and the largely object-oriented systems that need tying together, rather than because of some inherent limitation of functional programming itself. If those large systems were constructed in a functional style, would functional glue be more effective?
- tesseractive 14y agoOO code can work as reasonably effective good glue code for even older pre-OO procedural code, or even produce usable wrappers for big messy globs of assembly, should you have the misfortune to own that sort of mess. So I would say that your bizarro world would need to presuppose that functional code had dominated from the first instead of any imperative code, which may have been what you meant. However, my suspicion is that imperative code, at it's most basic, is the natural form for the first computer code to take, given development of simple, early processors. My intuition could be wrong on this point, of course. In general, though, if you have particular operations in an imperative program that are more useful to reason about using a functional methodology, it's easy to use OO code as glue code wrapped around it (in C#, F#, Scala, etc.). By contrast, adding bits of imperative code inside a functional program requires careful thought and planning to keep from breaking the rest of the program through unexpected side effects. So my suspicion is that OO is ultimately a better "glue paradigm" than FP. And why I suspect that ultimately, object-functional languages are likely to succeed more broadly in the real world than pure functional languages.
- pcote 14y agoThe merits of functional programming techniques are a lot more interesting than the languages that implement them, "pure" or not. Closures, first class functions, and list comprehensions are interesting topics of discussion. Java vs. Haskell not-so-much.
- ky3 14y agoJava vs. Haskell not-so-much. But it's mostly in such comparisons that "closures" and "first-class functions" are brought up. If you check out /r/haskell you'd be hard pressed to find those terms. I hardly ever think of closures qua closures; they are a language implementation detail that's at a level barely above assembly.
- dons 14y agoRemarkably content-free.
- SeanDav 14y agoI by no means want to start any kind of religious war but I feel that Scala has kind of eclipsed Clojure. I tend to notice more Scala skills required in real life projects than Clojure. This is just my opinion as someone that knows neither Scala nor Clojure and without any axe to grind in this debate.
- dagw 14y agoTo me it seems more that Scala and Clojure appeal to two slightly different groups. Scala is very appealing to people looking for a "better Java". A Java programmer can get up and running with Scala very quickly simply by treating as Java with some neat and powerful syntactic sugar, and then slowly segue into the more powerful features Scala offers as and when he needs them. Clojure on the other hand basically requires throwing out everything you know (assuming you're not coming from a LISP background) and starting from scratch. In exchange you end up with a very powerful and new way of approaching programming, one which is very appealing to many people and very effective for handling certain problems. So as such it makes sense that Scala is more visible. If I had a large Java shop and wanted to try using some functional programming in certain projects, then Scala would be a no brainer.
- stmartin 14y agoSo, if I program in a non-functional language, I must be a B-rated programmer? Wow... I thought I'd seen hubris :), but this tops everything.
- tikhonj 14y agoFunctional languages may be overrated, but not nearly as overrated as imperative languages (especially Python and Java). At the very least, avoiding Haskell is--unfortunately--quite easy; avoiding Java or Python in most places is nigh impossible. The past post he references can be summarized by its last sentence: "I seriously don't get it." It spends quite a bit of effort telling us very little about functional languages but quite a bit about the author. And, as usual, he mistakes difficultly for complexity--just because something is new and mind-bending does not mean it is complex; it could just be a little tricky to pick up. (This is where Rich Hickey's "Simple Made Easy" talk really shines.) And, of course, in the current post he misrepresents the main case for functional programming. Which is--quite critically--not concurrency or parallelism! These are, in fact, just nice benefits. The main point is using a higher level of abstraction, reducing coupling, simplifying code, writing less code to do more and making it easy to reason about and verify. If all you care about is concurrency, Haskell is probably not your best bet. But if you care about writing maintainable, reusable and more general code more quickly and without sacrificing too much performance, it is. I would--without thinking twice--use Haskell to write programs in a completely single-threaded world. Haskell may also be good at dealing with concurrent nonsense, but this is really just a symptom of a deeper cause: Haskell is good at dealing with complexity. If that doesn't convince you, Haskell also comes with a ton of shiny toys like QuickCheck and Parsec. It might not have the biggest collection of libraries, but it probably does have one of the most innovative.
- soup10 14y agoProgramming languages can strive to be either tools or toys. Programming languages that strive to be tools focus on high quality standard libraries, speed, good debugging facilities, being easy to learn, ability to handle large projects, and hardware support among other things. Toy languages strive to be innovative and explore new depths of computer science. Which is all well and good, but it's pretty annoying when people compare them with 'real' programming languages.
- Scriptor 14y agoThat's true, actual tools need all those criteria that you described. If you believe that functional languages don't meet those criteria, can you provide evidence for that? For example, from what I've gathered Clojure certainly has high quality libraries, an emphasis on speed when needed (performance is frequently superior to Python's), has debugging facilities, is easy to learn for someone with functional experience (just as Python or Java are relatively easy to learn for those with imperative experience) and can still be picked up with a little extra work otherwise, and has been used in production in large projects. I don't know about its hardware support so I won't comment on that.
- T_S_ 14y agoI have been using Haskell seriously for about two years now and humorously for a bit longer. For some reason I bought the old sales pitch some time ago. Now that I have a clue about the language I would like to rewrite the sales pitch for anyone considering a move. Here's what happens in the middle of a big Haskell project. 1) Take some existing code. 2) Refactor (Add a feature, change a record element, etc.) 3) Run ghc, then fix all the errors it reports. Repeat this step as needed. 4) Done. What would be different in python? For one, no compile errors means very little. How many test cases would you need? How would you find all the places the code must change? Lesson: A tough, smart compiler can be the programmer's best friend. Meta-lesson: There is little need to discuss laziness, purity or static typing to "sell" Haskell. They are enablers of ghc. What you need is a big, complicated code base and an urgent need to make changes to it. You won't have that until you get your feet wet. Is Haskell perfect? No, but I'll save that for an OP that is overhyping the language.
- zem 14y agoit always surprises me when erlang is lumped in with the other functional languages. i know it technically qualifies as one, but if i had to round up the "mainstream" fp languages, i'd put ocaml, haskell, scala and clojure in one group, and erlang off to one side by itself.
- ludicast 14y agoAgreed, Erlang is a total weirdo. As a language is "bad weird", but as a platform is "good weird". Projects like Elixir are way exciting for this reason.
- zem 14y agoapart from the string handling, i actually liked erlang as a language. mailboxes and destructuring pattern matching are a very pleasant way to organise code.
- nirvana 14y agoI look forward to the day when Hacker News moves beyond these "my language is better than yours" articles written by third rate programmers. In his first paragraph it makes it clear to me that he didn't understand the nature of any of the languages he originally discarded, and he discarded them because he didn't understand them in sort of a "its too hard or my brain, therefore they suck!" Which sets a really poor stage to then hear that Clojure is the second coming. I'm neutral on clojure- but in my experience, every time I learn a new language, for awhile it feels like the second coming, because if its a good language it has a reason for being, and in the scope of that reason for being, it really is the second coming. The problem-- and what makes this guy a third rate programer-- is the latching onto that language and it becoming your blub language. He decries FP as a fad and offers instead, a language specific fad. Seriously, dude? When you step up to the level where language is less important, and it constrains your thinking less, then you'll step up to the next level of programming ability.
- marawuti 14y agoThis has been a thoroughly fascinating read. The attitudes towards development are echos from the late '70s and the '80s. The wheel of incarnation is still turning guys & gals. Since the economics of systems have not changed much (70% of the cost of a system is in maintenance) I find it humorous that nobody has mentioned making code clear for the poor maintenance (enhancements, refactoring) schmuck. Everyone including the hoodwinked managers are focusing on the "window of opportunity" a.k.a lost opportunity cost of getting the project done - to market. This is as wrong headed now as it was in the '80s. Unless you are writing one-off systems that have a real world, crucial deadline - think new scud detection techniques during the 1st gulf war [done in Lisp BTW] - just focus on making systems that can first and foremost be comprehended quickly by someone else. You're working in a team. Right? All the rest of the hyper-fast development hoopla is self aggrandizing and for the most part a waste. I must admit though that the reminiscences of the days of "feeling like an artist" contained in this thread bring back heady memories. I hear the egos of me and my prior associates sprinkled throughout this thread. Bon chance.