As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
It seems to me from my experimenting with Haskell, Erlang and Scheme that functional programming languages are a fantastic way to answer scientific questions. For example, taking a small set of data and performing some extensive analysis on it to return a significant answer. It's great for working through some tough Project Euler questions or trying out the Google Code Jam in an original way.
At the same time it seems that by their very nature, they are more suited to finding analytical solutions than actually performing practical tasks. I noticed this most strongly in Haskell, where everything is evaluated lazily and your whole program boils down to one giant analytical solution for some given data that you either hard-code into the program or tack on messily through Haskell's limited IO capabilities.
Basically, the tasks I would call 'practical' such as
Aceept a request, find and process requested data,
and return it formatted as needed
seem to translate much more directly into procedural languages. The most luck I have had finding a functional language that works like this is Factor, which I would liken to a reverse-polish-notation version of Python.
So I am just curious whether I have missed something in these languages or I am just way off the ball in how I ask this question. Does anyone have examples of functional languages that are great at performing practical tasks or practical tasks that are best performed by functional languages?
Regarding languages, I think F# is an example of a languages that's primarily 'functional' but also 'practical'. Scala and Clojure are probably others in this category.
(Going one level deeper, I think the 'formula for success' here is a language that leans strongly towards 'functional', but has access to vast practical libraries (e.g. .Net/JVM/some C FFI) and has good tooling (e.g. IDE support).)
I at least somewhat agree with the implicit premise of the question, namely that there is a tension between 'succinct/beautiful analytical power' and 'pragmatics'.
Does anyone have examples of functional languages that are great at performing practical tasks or practical tasks that are best performed by functional languages?
Our business runs on F# code, for everything from on-line credit card transactions to web analytics. These LOB apps are composed of tiny F# scripts that do everything required quickly and simply using .NET's seamless interop and automation of applications like Outlook and Excel.
Our business makes most of its money selling software written in F# that solves practical problems to customers from many sectors from embedded software for medical equipment to maritime internet service providers.
IMO, Scheme is too minimalistic to be practical- it is used in several courses for teaching (see Structure and Interpretation of Computer Programs). However, modern Lisp languages like Common Lisp, and especially Clojure are gaining importance. Erlang is used by several large industries for high concurrency applications, and I personally haven't seen it being used by end-user programmers. Haskell on the other hand is quite a real-world language, and has been used to write a lot of wonderful software including:
XMonad is an X Window System window manager written purely in Haskell.
Leksah, an IDE for Haskell is written in Haskell itself.
Pugs, one of the leading implementations of Perl 6 is written in Haskell.
Lastly, the Glasgow Haskell Compiler is written in Haskell.
Funny, you and I have very different notions of "practical tasks". You say it's:
Aceept a request, find and process
requested data, and return it
formatted as needed
This is pretty much what a functional language is made for: functions that take data and return new data without preserving any state in-between calls (ie no side effects). This is what you have here and it's also called piping.
Now this isn't what I'd call a practical task. In modern programs you have to deal with GUI's, multithreaded functions and network I/O. All these have state that is required to hold data in-between function calls. Data isn't piped into a function and the result piped out, the functions affect the "global" state too.
And it's this definition of "practical task" where functional programs start to fail. Writing a GUI in a functional program is pretty much impossible if you don't use their imperative extensions for example.
So in conclusion, the answer you're asking for is a heart-felt yes, functional programs are up to the task. The answer you're really looking for however, is that it's a bit more complicated than that.
Have you ever used LINQ?
If so, congratulations. You have used a functional language in a practical context. This is what functional development is about.
And yes, F# is VERY useful.
Erlang is well known for its robustness and features for writing highly-concurrent servers.
It also has a DBMS out-of-box.
Functional Programming in the Real World
Basically, the tasks I would call
'practical' such as
Aceept a request, find and process
requested data, and return it
formatted as needed
You experimented with Erlang and couldn't find a practical task for it under this description of practical?
Accept a request.
You mean like receive. Or just being called straight up as a function.
Find and process requested data.
I'm not entirely sure what you mean here, but for finding data there's file I/O, networking I/O, (distributed) inter-process communication, etc. etc. etc. For finding subsets of that data there's regular expressions, pattern matching, etc.
For processing there's a whole bunch of stuff for strings, lists, mathematics, sets, graphs, etc. Is this not enough for processing? What else are you looking for?
Return it formatted as needed.
I can return the resulting data as atoms, lists, binary blobs, formatted strings, numbers, etc. What was missing from Erlang in this regard? I'm really honestly confused here.
I'm not sure about 'Practical Tasks' definition and what it refers to.
but in other words I think you are talking about solving problems by algorithms that need to be represented by a programming language. if so then the functional language is very useful and practical.Specially when you have limits in time to find the solution and implement it.
for me I still use non-functional languages when participating in solving complex algorithmic contests like Google CodeJam .
I'm planning to learn a functional language that will be better for me for these kind of tasks or problems.
Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
as an engineering student with a strong mathemathical background, i dealing some problems like this at university:
(numerical) Simulations
AI Problems
Robotics
Control Systems
and some more
as you can see some are just numerical ones, others have to process some kinds of symbols.
currently i'm working with java, but i'm not very pleased with it (can't say exactly why, probably a personal taste) and now i'm searching for a programming language, in which i can easily prototype new algorithms, like for example in python, and don't care about low level stuff, but has the ability to speed things up if neccessary, e.g. with concurrent/parallel programming, etc. (writing it in python and rewrite it in C/C++ isn't really a option i prefer...)
to sum it up:
easy to prototype, but
the ability to speed algorithms up
syntax without boilerplate stuff like in java
syntax which is easy to read (i know this could be achived with the most, but some language encourage you more...)
i've looked around at sites, like http://rosettacode.org/ and picked 2 or 3 favorites: Go, Lisp (and maybe Haskell) but other recommandations are welcome
Common Lisp using SBCL is pretty fast if you take the time to make it fast.
Why does this fit what you want?
symbolic computations
good number handling
compiles to native on demand by default.
I would use python together with cython: http://www.cython.org for speeding up your code. For symbolic computations you have http://code.google.com/p/sympy/
Try Clojure; it fulfills most of your requirements.
Uses Java libraries, compiles to Java bytecode, and has plugins for Java IDEs, so some of your existing knowledge about Java and its ecosystem will come in handy.
Very concise, readable, and ease of prototyping is extremely high.
Great support for different concurrency strategies.
Performance is getting better fast; typical stuff is within a speed factor of 2 of Java, and slow things can typically be made fast with minimally confounding changes (e.g. a few type hints here and there to use Java primitives.)
An alternative to Common Lisp would be a implementation of scheme. My favorite so far is Racket.
http://racket-lang.org/
When I first got into Lisp I started with scheme and ended up being able to learn it within a matter of days. Also Lisp-wise Racket is a pretty complete language and has a decent IDE in DrRacket.
How about F#?
F# is a remarkable language for prototyping for the following reasons:
F# has an interactive mode allowing you to evaluate blocks of code directly, without compiling your entire project.
Type inference helps keep code small, and makes refactoring your type hierarchy relatively painless. This may not be so important in production code, but I found that to be very valuable during prototyping.
F# integration with .NET makes it easy to prototype extensions of your existing products. In the all-too-common case when a prototype becomes a product (due to time constraints), it's also easy to integrate your F# code within your .NET product.
If prototyping makes up a significant part of your overall development process, then F# can really help you speed up your coding.
I don't think F# will produce code that is significantly faster than other .NET languages. The functional style of programming, in particular purity (no side-effects), can be applied to other programming languages, meaning it is just as easy to write concurrent programs in other languages as well. It does however "feel more natural" to do so in F#.
F# has the Option type, which can be used in place of null values. Code reliability with respect to null-pointer exceptions can be guaranteed at compile time, which is a huge benefit.
Finally, be advised that F# is still in development, and suffers issues, some of which may disappear over time, but not all. See for instance what devhawk and Oliver Sturm have to say about it (in particular about linear scoping and interdependent classes, other issues like overloading, better Visual Studio integration have already been addressed).
this is stated in article: https://stackoverflow.com/questions/328329/why-should-i-use-f
by JOH
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Software Engineering as it is taught today is entirely focused on object-oriented programming and the 'natural' object-oriented view of the world. There is a detailed methodology that describes how to transform a domain model into a class model with several steps and a lot of (UML) artifacts like use-case-diagrams or class-diagrams. Many programmers have internalized this approach and have a good idea about how to design an object-oriented application from scratch.
The new hype is functional programming, which is taught in many books and tutorials. But what about functional software engineering?
While reading about Lisp and Clojure, I came about two interesting statements:
Functional programs are often developed bottom up instead of top down ('On Lisp', Paul Graham)
Functional Programmers use Maps where OO-Programmers use objects/classes ('Clojure for Java Programmers', talk by Rich Hickley).
So what is the methodology for a systematic (model-based ?) design of a functional application, i.e. in Lisp or Clojure? What are the common steps, what artifacts do I use, how do I map them from the problem space to the solution space?
Thank God that the software-engineering people have not yet discovered functional programming. Here are some parallels:
Many OO "design patterns" are captured as higher-order functions. For example, the Visitor pattern is known in the functional world as a "fold" (or if you are a pointy-headed theorist, a "catamorphism"). In functional languages, data types are mostly trees or tuples, and every tree type has a natural catamorphism associated with it.
These higher-order functions often come with certain laws of programming, aka "free theorems".
Functional programmers use diagrams much less heavily than OO programmers. Much of what is expressed in OO diagrams is instead expressed in types, or in "signatures", which you should think of as "module types". Haskell also has "type classes", which is a bit like an interface type.
Those functional programmers who use types generally think that "once you get the types right; the code practically writes itself."
Not all functional languages use explicit types, but the How To Design Programs book, an excellent book for learning Scheme/Lisp/Clojure, relies heavily on "data descriptions", which are closely related to types.
So what is the methodology for a systematic (model-based ?) design of a functional application, i.e. in Lisp or Clojure?
Any design method based on data abstraction works well. I happen to think that this is easier when the language has explicit types, but it works even without. A good book about design methods for abstract data types, which is easily adapted to functional programming, is Abstraction and Specification in Program Development by Barbara Liskov and John Guttag, the first edition. Liskov won the Turing award in part for that work.
Another design methodology that is unique to Lisp is to decide what language extensions would be useful in the problem domain in which you are working, and then use hygienic macros to add these constructs to your language. A good place to read about this kind of design is Matthew Flatt's article Creating Languages in Racket. The article may be behind a paywall. You can also find more general material on this kind of design by searching for the term "domain-specific embedded language"; for particular advice and examples beyond what Matthew Flatt covers, I would probably start with Graham's On Lisp or perhaps ANSI Common Lisp.
What are the common steps, what artifacts do I use?
Common steps:
Identify the data in your program and the operations on it, and define an abstract data type representing this data.
Identify common actions or patterns of computation, and express them as higher-order functions or macros. Expect to take this step as part of refactoring.
If you're using a typed functional language, use the type checker early and often. If you're using Lisp or Clojure, the best practice is to write function contracts first including unit tests—it's test-driven development to the max. And you will want to use whatever version of QuickCheck has been ported to your platform, which in your case looks like it's called ClojureCheck. It's an extremely powerful library for constructing random tests of code that uses higher-order functions.
For Clojure, I recommend going back to good old relational modeling. Out of the Tarpit is an inspirational read.
Personally I find that all the usual good practices from OO development apply in functional programming as well - just with a few minor tweaks to take account of the functional worldview. From a methodology perspective, you don't really need to do anything fundamentally different.
My experience comes from having moved from Java to Clojure in recent years.
Some examples:
Understand your business domain / data model - equally important whether you are going to design an object model or create a functional data structure with nested maps. In some ways, FP can be easier because it encourages you to think about data model separately from functions / processes but you still have to do both.
Service orientation in design - actually works very well from a FP perspective, since a typical service is really just a function with some side effects. I think that the "bottom up" view of software development sometimes espoused in the Lisp world is actually just good service-oriented API design principles in another guise.
Test Driven Development - works well in FP languages, in fact sometimes even better because pure functions lend themselves extremely well to writing clear, repeatable tests without any need for setting up a stateful environment. You might also want to build separate tests to check data integrity (e.g. does this map have all the keys in it that I expect, to balance the fact that in an OO language the class definition would enforce this for you at compile time).
Prototying / iteration - works just as well with FP. You might even be able to prototype live with users if you get very extremely good at building tools / DSL and using them at the REPL.
OO programming tightly couples data with behavior. Functional programming separates the two. So you don't have class diagrams, but you do have data structures, and you particularly have algebraic data types. Those types can be written to very tightly match your domain, including eliminating impossible values by construction.
So there aren't books and books on it, but there is a well established approach to, as the saying goes, make impossible values unrepresentable.
In so doing, you can make a range of choices about representing certain types of data as functions instead, and conversely, representing certain functions as a union of data types instead so that you can get, e.g., serialization, tighter specification, optimization, etc.
Then, given that, you write functions over your adts such that you establish some sort of algebra -- i.e. there are fixed laws which hold for these functions. Some are maybe idempotent -- the same after multiple applications. Some are associative. Some are transitive, etc.
Now you have a domain over which you have functions which compose according to well behaved laws. A simple embedded DSL!
Oh, and given properties, you can of course write automated randomized tests of them (ala QuickCheck).. and that's just the beginning.
Object Oriented design isn't the same thing as software engineering. Software engineering has to do with the entire process of how we go from requirements to a working system, on time and with a low defect rate. Functional programming may be different from OO, but it does not do away with requirements, high level and detailed designs, verification and testing, software metrics, estimation, and all that other "software engineering stuff".
Furthermore, functional programs do exhibit modularity and other structure. Your detailed designs have to be expressed in terms of the concepts in that structure.
One approach is to create an internal DSL within the functional programming language of choice. The "model" then is a set of business rules expressed in the DSL.
See my answer to another post:
How does Clojure aproach Separation of Concerns?
I agree more needs to be written on the subject on how to structure large applications that use an FP approach (Plus more needs to be done to document FP-driven UIs)
While this might be considered naive and simplistic, I think "design recipes" (a systematic approach to problem solving applied to programming as advocated by Felleisen et al. in their book HtDP) would be close to what you seem to be looking for.
Here, a few links:
http://www.northeastern.edu/magazine/0301/programming.html
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.86.8371
I've recently found this book:
Functional and Reactive Domain Modeling
I think is perfectly in line with your question.
From the book description:
Functional and Reactive Domain Modeling teaches you how to think of the domain model in terms of pure functions and how to compose them to build larger abstractions. You will start with the basics of functional programming and gradually progress to the advanced concepts and patterns that you need to know to implement complex domain models. The book demonstrates how advanced FP patterns like algebraic data types, typeclass based design, and isolation of side-effects can make your model compose for readability and verifiability.
There is the "program calculation" / "design by calculation" style associated with Prof. Richard Bird and the Algebra of Programming group at Oxford University (UK), I don't think its too far-fetched to consider this a methodology.
Personally while I like the work produced by the AoP group, I don't have the discipline to practice design in this way myself. However that's my shortcoming, and not one of program calculation.
I've found Behavior Driven Development to be a natural fit for rapidly developing code in both Clojure and SBCL. The real upside of leveraging BDD with a functional language is that I tend to write much finer grain unit tests than I usually do when using procedural languages because I do a much better job of decomposing the problem into smaller chunks of functionality.
Honestly if you want design recipes for functional programs, take a look at the standard function libraries such as Haskell's Prelude. In FP, patterns are usually captured by higher order procedures (functions that operate on functions) themselves. So if a pattern is seen, often a higher order function is simply created to capture that pattern.
A good example is fmap. This function takes a function as an argument and applies it to all the "elements" of the second argument. Since it is part of the Functor type class, any instance of a Functor (such as a list, graph, etc...) may be passed as a second argument to this function. It captures the general behavior of applying a function to every element of its second argument.
Well,
Generally many Functional Programming Languages are used at universities for a long time for "small toy problems".
They are getting more popular now since OOP has difficulties with "paralel programming" because of "state".And sometime functional style is better for problem at hand like Google MapReduce.
I am sure that, when functioanl guys hit the wall [ try to implement systems bigger than 1.000.000 lines of code], some of them will come with new software-engineering methodologies with buzz words :-). They should answer the old question: How to divide system into pieces so that we can "bite" each pieces one at a time? [ work iterative, inceremental en evolutionary way] using Functional Style.
It is sure that Functional Style will effect our Object Oriented
Style.We "still" many concepts from Functional Systems and adapted to
our OOP languages.
But will functional programs will be used for such a big systems?Will they become main stream? That is the question.
And Nobody can come with realistic methodology without implementing such a big systems, making his-her hands dirty.
First you should make your hands dirty then suggest solution. Solutions-Suggestions without "real pains and dirt" will be "fantasy".
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I've caught the bug to learn functional programming for real. So my
next self-study project is to work through the Structure and
Interpretation of Computer Programs. Unfortunately, I've never
learned Lisp, as I was not a CS major in college.
While SICP does not emphasize the tools for programming, doing the
exercises entails picking a Lisp-like language to use. It seems like
some implementation of Scheme would be the path of least
resistance. On the other hand, I hear of others who have used Common
Lisp and Clojure. It seems to me that Common Lisp or Clojure would be
more likely to be used in production code, and therefore slightly
better for my resume. BTW, I fully get the argument that learning a
language is worthwhile for its own sake, but learning a language that
helps my resume is still a benefit. I'm a capitalist and an academic
about my learning.
If you had to self-study SICP, which language would you pick and why?
Ideally, I would like to use a language that can run on the JVM.
I can certainly work with a language where REPL works with bash
and emacs.
ADDITION: have any of you tried reading SICP without using Scheme? If so, what was your experience like?
Use Scheme. It is one of the simplest and easiest languages in existence, and you will spend very little time learning enough of it to understand SICP. Once you understand SICP, you will see how the concepts apply in any language.
Use DrScheme. As others have said, Scheme is a simple language, and DrScheme is a great environment to use it in which has a lot of support and mediocre-to-good documentation.
Not a direct answer but I expect this information to be useful for anyone working through SICP. Be sure to have a look at the videos here:
http://swiss.csail.mit.edu/classes/6.001/abelson-sussman-lectures/
There are 20 episodes of an hour each. They were presented by Abelson and Sussman in 1986 for Hewlett Packard employees. I put them on my iPod and watched them while commuting. Fascinating.
Also, the full text of the book is available online at http://mitpress.mit.edu/sicp/
As someone who hires people, I'll tell you that having Scheme on a resume is a good thing. Having Scheme, SML, Ocaml or Haskell on your resume suggests you are a very well rounded programmer, and quite a thinker.
That said, if you are trying for functional programming, why not Haskell instead? Scheme is multiparadigm, it can be OO, Funcitonal, Streams based, or anything else under the sun. This makes it awesome to try out new programming styles and paradigms, but if your goal is strictly functional, it can be a problem. (You will end up writing non functional code and not realizing it.)
I agree that you should just use Scheme. However, if you really have the itch to use Common Lisp or Clojure, I'd pick the latter. Scheme and Clojure are both Lisp-1s, so the code in the book will be more congruent between the two (except for tail calls, but if you understand how to compensate you'll be fine). Common Lisp is a Lisp-2 and will probably obscure the beauty of what SICP is trying to teach you.
The code in the book is Scheme so you'll have to read it anyways - you might as well write it. You might even like it!
To get real value out of the book you'll have to use Scheme. Which implementation of scheme depends on your current environment:
Windows - Dr Scheme (PLT Scheme) - http://download.plt-scheme.org/
Linux - If this is a remote account - you may consider MZScheme (PLTScheme) (http://download.plt-scheme.org/) otherwise you'll want to use Dr Scheme if this is a local instance of Linux.
I think Clojure fits what you want to do just perfectly. It's much more functional than Scheme because the data structures are immutable and it can be very useful as it runs on the JVM. But, be aware that you'll end up learning Scheme anyway to be able to understand the code in the book.
I've caught the bug to learn functional programming for real.
From what I've heard, SICP is about a lot more than just functional programming.
Caveat: I have not read the whole book
Since the examples rely on closures and continuations, you would be better served by using a language with both of those features, otherwise you would need to implement them yourself.
For example, writing a metacircular evaluator in Scheme leverages the fact that Scheme provides closures and continuations.
I used lua when I had a look at sicp
works out pretty well
Use anything but scheme.
While using something else then scheme, you will be encouraged to think more, and avoid temptation to just retype the examples. It is a good thing.
Of course, it has to be similar enough, in lisp-1 sense, so clojure and arc are good to go.
I have used scheme for my self-study. The best way to learn from SICP is to do all the exercises relegiously.
I have used Gnu guile for scheme.
While you could use something other than Scheme, you'd be needlessly adding extra work and possibly cutting yourself off from fully understanding what the book is about. SICP was an introductory programming book. It is a stepping stone to deeper topics in computer science. Getting bogged down in 'translating' from Scheme to CL or Clojure would probably obscure the finer points. That would be a shame, because SICP is truly a gateway to understanding what programming is really about.
Learning Scheme is really straight forward (especially compared to both CL and Clojure) and, in fact, the introductory course as well as the book, assumes the student doesn't know it already. CL and Clojure carry considerable baggage relative to the task at hand.
I hear of others who have used Common Lisp and Clojure.
You should use whatever language most motivates you, but 99% of folks working through SICP are going to use Scheme.
I worked through (most) of it earlier this year, and used Common Lisp, simply because I didn't have Scheme available (don't ask).
As has already been noted, Scheme is a Lisp-1 language whereas Common Lisp is a Lisp-2. There are enough differences between the languages to mean that you have think carefully about translating the code in the book, so it forced me to really get to grips with the material.
but learning a language that helps my resume is still a benefit.
You should try using VB6 or COBOL, then, as there is a lot of billing work out there for it.
I think Scheme would be the natural choice (since it is the "native" language of SICP)
However, since the true value of SICP comes from the concepts rather than the mechanics of the particular language, I think it would be a valuable learning exercise to attempt it in any Lisp-like language. I've personally tried some of the exercises in Clojure and they all translate pretty well.
For those interested there is an ongoing project to create a Clojure translation of SICP.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What do you think the benefits of functional programming are? And how do they apply to programmers today?
What are the greatest differences between functional programming and OOP?
The style of functional programming is to describe what you want, rather than how to get it. ie: instead of creating a for-loop with an iterator variable and marching through an array doing something to each cell, you'd say the equivalent of "this label refers to a version of this array where this function has been done on all the elements."
Functional programming moves more basic programming ideas into the compiler, ideas such as list comprehensions and caching.
The biggest benefit of Functional programming is brevity, because code can be more concise. A functional program doesn't create an iterator variable to be the center of a loop, so this and other kinds of overhead are eliminated from your code.
The other major benefit is concurrency, which is easier to do with functional programming because the compiler is taking care of most of the operations which used to require manually setting up state variables (like the iterator in a loop).
Some performance benefits can be seen in the context of a single-processor as well, depending on the way the program is written, because most functional languages and extensions support lazy evaluation. In Haskell you can say "this label represents an array containing all the even numbers". Such an array is infinitely large, but you can ask for the 100,000th element of that array at any moment without having to know--at array initialization time--just what the largest value is you're going to need. The value will be calculated only when you need it, and no further.
The biggest benefit is that it's not what you're used to. Pick a language like Scheme and learn to solve problems with it, and you'll become a better programmer in languages you already know. It's like learning a second human language. You assume that others are basically a variation on your own because you have nothing to compare it with. Exposure to others, particular ones that aren't related to what you already know, is instructive.
Why Functional Programming Matters
http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf
Abstract
As software becomes more and more complex, it is more and
more important to structure it well. Well-structured software is easy
to write and to debug, and provides a collection of modules that can
be reused to reduce future programming costs.
In this paper we show
that two features of functional languages in particular, higher-order
functions and lazy evaluation, can contribute significantly to
modularity. As examples, we manipulate lists and trees, program
several numerical algorithms, and implement the alpha-beta heuristic
(an algorithm from Artificial Intelligence used in game-playing
programs). We conclude that since modularity is the key to successful
programming, functional programming offers important advantages for
software development.
A good starting point therefore would be to try to understand some things that are not possible in imperative languages but possible in functional languages.
If you're talking about computability, there is of course nothing that is possible in functional but not imperative programming (or vice versa).
The point of different programming paradigms isn't to make things possible that weren't possible before, it's to make things easy that were hard before.
Functional programming aims to let you more easily write programs that are concise, bug-free and parallelizable.
I think the most practical example of the need for functional programming is concurrency - functional programs are naturally thread safe and given the rise of multi core hardware this is of uttermost importance.
Functional programming also increases the modularity - you can often see methods/functions in imperative that are far too long - you'll almost never see a function more than a couple of lines long. And since everything is decoupled - re-usability is much improved and unit testing is very very easy.
It doesn't have to be one or the other: using a language like C#3.0 allows you to mix the best elements of each. OO can be used for the large scale structure at class level and above, Functional style for the small scale structure at method level.
Using the Functional style allows code to be written that declares its intent clearly, without being mixed up with control flow statements, etc. Because of the principles like side-effect free programming, it is much easier to reason about code, and check its correctness.
Once the program grows, the number of commands in our vocabulary becomes too high, making it very difficult to use. This is where object-oriented programming makes our life easier, because it allows us to organize our commands in a better way.
We can associate all commands that involve customer with some customer entity (a class), which makes the description a lot clearer. However, the program is still a sequence of commands specifying how it should proceed.
Functional programming provides a completely different way of extending the vocabulary. Not limited to adding new primitive commands; we can also add new control structures–primitives that specify how we can put commands together to create a program. In imperative languages, we were able to compose commands in a sequence or using a limited number of built in constructs such as loops, but if you look at typical programs, you'll still see many recurring structures; common ways of combining commands
Do not think of functional programming in terms of a "need". Instead, think of it as another programming technique that will open up your mind just as OOP, templates, assembly language, etc may have completely changed your way of thinking when (if) you learned them. Ultimately, learning functional programming will make you a better programmer.
If you don't already know functional programming then learning it gives you more ways to solve problems.
FP is a simple generalization that promotes functions to first class values whereas OOP is for large-scale structuring of code. There is some overlap, however, where OOP design patterns can be represented directly and much more succinctly using first-class functions.
Many languages provide both FP and OOP, including OCaml, C# 3.0 and F#.
Cheers,
Jon Harrop.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I really feel that I should learn Lisp and there are plenty of good resources out there to help me do it.
I'm not put off by the complicated syntax, but where in "traditional commercial programming" would I find places it would make sense to use it instead of a procedural language.
Is there a commercial killer-app out there that's been written in Lisp ?
Lisp is a large and complex language with a large and complex runtime to support it. For that reason, Lisp is best suited to large and complicated problems.
Now, a complex problem isn't the same as a complicated one. A complex problem is one with a lot of small details, but which isn't hard. Writing an airline booking system is a complex business, but with enough money and programmers it isn't hard. Get the difference?
A complicated problem is one which is convoluted, one where traditional divide and conquer doesn't work. Controlling a robot, or working with data that isn't tabular (languages, for example), or highly dynamic situations.
Lisp is really well suited to problems where the solution must be expandable; the classic example is the emacs text editor. It is fully programmable, and thus a programming environment in it's own right.
In his famous book PAIP, Norvig says that Lisp is ideal for exploratory programming. That is, programming a solution to a problem that isn't fully understood (as opposed to an on-line booking system). In other words: Complicated problems.
Furthermore, learning Lisp will remind you of something fundamental that has been forgotten: The difference between Von Neumann and Turing. As we know, Turing's model of computation is an interesting theoretical model, but useless as a model for designing computers. Von Neumann, on the other hand, designed a model of how computers and computation were to execute: The Von Neumann model.
Central to the Von Neumann model is that you have but one memory, and store both your code and your data there. Notice carefully that a Java program (or C#, or whatever you like) is a manifestation of the Turing model. You set your program in concrete, once and for all. Then you hope you can deal with all data that gets thrown on it.
Lisp maintains the Von Neuman model; there is no sharp, pre-determined border between code and data. Programming in Lisp opens your mind to the power of the Von Neumann model. Programming in Lisp makes you see old concepts in a new light.
Finally, being interactive, you'll learn to interact with your programs as you develop them (as opposed to compile and run). This also change the way you program, and the way you view programming.
With this intro I can finally offer a reply to your question: Will you find places where it outshines "traditional" languages?
If you are an advanced programmer, you need advanced tools. And there is no tool more advanced than Lisp.
Or, in other words: The answer is yes if your problems are hard. No otherwise.
One of the main uses for Lisp is in Artificial Intelligence. A friend of mine at college took a graduate AI course and for his main project he wrote a "Lights Out" solver in Lisp. Multiple versions of his program utilized slightly different AI routines and testing on 40 or so computers yielded some pretty neat results (I wish it was online somewhere for me to link to, but I don't think it is).
Two semesters ago I used Scheme (a language based on Lisp) to write an interactive program that simulated Abbott and Costello's "Who's on First" routine. Input from the user was matched against some pretty complicated data structures (resembling maps in other languages, but much more flexible) to choose what an appropriate response would be. I also wrote a routine to solve a 3x3 slide puzzle (an algorithm which could easily be extended to larger slide puzzles).
In summary, learning Lisp (or Scheme) may not yield many practical applications beyond AI but it is an extremely valuable learning experience, as many others have stated. Programming in a functional language like Lisp will also help you think recursively (if you've had trouble with recursion in other languages, this could be a great help).
In response to #lassevk:
complicated syntax??
The syntax for lisp is incredibly simple.
Killer app written in lisp: emacs. Lisp will allow you to extend emacs at will to do almost anything you can think of that an editor might do.
But, you should only learn lisp if you want to, and you may never get to use at work ever, but it is still awesome.
Also, I want to add: even if you find places where lisp will make sense, you will probably not convince anyone else that it should be used over java, c++, c#, python, ruby, etc.
I can't answer from first-hand experience but you should read what Paul Graham wrote on Lisp. As for the "killer-app" part, read Beating the averages.
I programmed in Lisp professionally for about a year, and it is definitely worth learning. You will have unparalleled opportunity to remove redundancy from your code, by being able to replace all boilerplate code with functions where possible, and macros where not. You will also be able to access unparalleled flexibility at runtime, translating freely between code and data. Thus, situations where user actions can trigger the need to build complex structures dynamically is where Lisp truly shines. Popular airline flight schedulers are written in Lisp, and there is also a lot of CAD/CAM in Lisp.
Lisp is very useful for creating little DSLs. I've got a copy of Lisp in a Box running at work and I've written little DSLs to interrogate SQL server databases and generate data layers etc in C#. All my boiler plate code is now written in lisp macros that output to C#. I generate HTML, XML, all sorts of things with it. While I wish I could use Lisp for everyday coding, Lisp can bring practical benefits.
If you like programming you should learn Lisp for the pure joy of it. XKCD perfectly expresses the intellectual enlightenment that ensues. Learning Lisp is for the programmer what meditation is for the Buddhist monk (and I meant this without any blasphemous connotation).
Any language looks a lot harder when one doesn't use the common indentation conventions of a language. When one follows them of Lisp, one sees how it expresses a syntax-tree structure quite readily (note, this isn't quite right because the preview lies a little; the r's should align with the fns in the recursive quicksort argument):
(defun quicksort (lis)
(if (null lis)
nil
(let* ((x (car lis))
(r (cdr lis))
(fn (lambda (a)
(< a x))))
(append (quicksort (remove-if-not fn
r))
(list x)
(quicksort (remove-if fn
r))))))
I found that learning a new language, always influences your programming style in languages you already know. For me it always made me think in different ways to solve a problem in my primary language, which is Java. I think in general, it just widens your horizon in term of programming.
I took a "lisp class" in college back in the eighties. Despite grokking all the concepts presented in the class, I was left without any appreciation for what makes lisp great. I'm afraid that a lot of people look at lisp as just another programming language, which is what that course in college did for me so many years ago. If you see someone complaining about lisp syntax (or lack thereof), there's a good chance that they're one of those people who has failed to grasp lisp's greatness. I was one of those people for a very long time.
It wasn't until two decades later, when I rekindled my interest in lisp, that I began to "get" what makes lisp interesting--for me anyway. If you manage to learn lisp without having your mind blown by closures and lisp macros, you've probably missed the point.
Learning LISP/Scheme may not give you any increased application space, but it will help you get a better sense of functional programming, its rules, and its exceptions.
It's worth the time investment just to learn the difference in the beauty of six nested pure functions, and the nightmare of six nested functions with side effects.
From http://www.gigamonkeys.com/book/introduction-why-lisp.html
One of the most commonly repeated
myths about Lisp is that it's "dead."
While it's true that Common Lisp isn't
as widely used as, say, Visual Basic
or Java, it seems strange to describe
a language that continues to be used
for new development and that continues
to attract new users as "dead." Some
recent Lisp success stories include
Paul Graham's Viaweb, which became
Yahoo Store when Yahoo bought his
company; ITA Software's airfare
pricing and shopping system, QPX, used
by the online ticket seller Orbitz and
others; Naughty Dog's game for the
PlayStation 2, Jak and Daxter, which
is largely written in a
domain-specific Lisp dialect Naughty
Dog invented called GOAL, whose
compiler is itself written in Common
Lisp; and the Roomba, the autonomous
robotic vacuum cleaner, whose software
is written in L, a downwardly
compatible subset of Common Lisp.
Perhaps even more telling is the
growth of the Common-Lisp.net Web
site, which hosts open-source Common
Lisp projects, and the number of local
Lisp user groups that have sprung up
in the past couple of years.
If you have to ask yourself if you should learn lisp, you probably don't need to.
Learning lisp will put Javascript in a completely different light! Lisp really forces you to grasp both recursion and the whole "functions as first class objects"-paradigm. See Crockfords excellent article on Scheme vs Javascript. Javascript is perhaps the most important language around today, so understanding it better is immensely useful!
"Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot."
--Eric S. Raymond, "How to Become a Hacker"
http://www.paulgraham.com/avg.html
I agree that Lisp is one of those languages that you may never use in a commercial setting. But even if you don't get to, learning it will definitely expand your understanding of programming as a whole. For example, I learned Prolog in college and while I never used it after, I gave me a greater understanding of many programming concepts and (at times) a greater appreciation for the languages I do use.
But if you are going to learn it...by all means, read On Lisp
Complicated syntax? The beauty of lisp is that it has a ridiculously simple syntax. It's just a list, where each element of the list can be either another list or an elementary data type.
It's worth learning because of the way it enhances your coding ability to think about and use functions as just another data type. This will improve upon the way you code in an imperative and/or object-oriented language because it will allow you to be more mentally flexible with how your code is structured.
Gimp's Script-Fu is lipsish. That's a photoshop-killer app.
Okay, I might be weird but I really don't like Paul Graham's essays that much & on Lisp is a really rough going book if you don't have some grasp of Common Lisp already. Instead, I'd say go for Siebel's Practical Common Lisp. As for "killer-apps", Common Lisp seems to find its place in niche shops, like ITA, so while there isn't an app synonymous with CL the way Rails is for Ruby there are places in industry that use it if you do a little digging.
To add to the other answers:
Because the SICP course (the videos are available here) is awesome: teaches you Lisp and a lot more!
Killer app? Franz Inc. has a long list of success stories, but this list only includes users of AllegroCL... There are probably others. My favourite is the story about Naughty Dog, since I was a big fan of the Crash Bandicoot games.
For learning Common Lisp, I'd recommend Practical Common Lisp. It has a hands-on approach that at least for me made it easier than other books I've looked at.
You could use Clojure today to write tests and scripts on top of the Java VM. While there are other Lisp languages implemented on the JVM, I think Clojure does the best job of integrating with Java.
There are times when the Java language itself gets in the way of writing tests for Java code (including "traditional commercial programming"). (I don't mean that as an indictment of Java -- other languages suffer from the same problem -- but it's a fact. Since the topic, not Java, I won't elaborate. Please feel free to start a new topic if someone wants to discuss it.) Clojure eliminates many of those hindrances.
Lisp can be used anywhere you use traditional programming. It's not that different, it's just more powerful. Writing a web app? you can do it on Lisp, writing a desktop application? you can do it on Lisp, whatever, you can probably do it on Lisp, or Python, or any other generic programming (there are a few languages that are suited for only one task).
The biggest obstacle will probably be acceptance of your boss, your peers or your customers. That's something you will have to work with them. Choosing a pragmatic solution like Clojure that can leverage the current install base of Java infrastructure, from the JVM to the libraries, might help you. Also, if you have a Java program, you may do a plug-in architecture and write Clojure plug-ins for it and end up writing half your code in Clojure.
Not a reason but (trivial) AutoCAD has LISP & DCL runtime support. It is a convenient way to write complex macros (including ActiveX automation) if you don't want to use VBA or their C++ or .NET SDKs, or if a DIESEL expression doesn't cut it.
A lot of AutoCAD's functions are actually LISP routines.
This is a topic i myself have pondered for a while but I have not really come to a decision, as usual time is the main problem... ;)
And since I can´t find these links sofar in this post i add them for public interest:
Success and Failure story:
Lisping at JPL
Really impressive success story:
Lisp in use at the Orbitz corporation
Comparison and analysis of whether to use Lisp instead of Java:
Lisp as an Alternative to Java
Syntax is irrelevant, readability is not!
Not saying this is a killer app but it looks like it could be cool
http://code.google.com/p/plop/
Killer app? The flight search engine by ITA Software is one.
As for "why", it will most probably make you a better developer and is extremnely unlikely to make you a worse one. It may, however, make you prefer lisp dialects to other languages.