Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The real disadvantage of pure functional programming is that it is notoriously difficult to use and thus only very few programs outside specialized domains are written in them.

For example I would guess that in a typical enterprise (say, a manufacturing company), 0.0001% of the software is written in a pure functional language.

Things OO languages 'force' us seem to be relatively easy to use: sending a message to a certain object, thinking in categories (elephants, houses, chairs, moveable objects, ...), state (position, speed, size, shape),... Thus it is not surprising that the overwhelming majority of software written in the last 10 years has been written in OO languages.



I work in a group of teams that is mostly new college grads and nobody has trouble writing pure FP business logic in Scala. We don't go as far as doing pure FP for all effects though (although we are starting to do that more as well)

If we can do it, so can everyone else ;)


To what extent does the proving of theorems about your code play in your development process? I ask because that was singled out as one of the main reasons for using functional languages by Eutectic in the comment that started this sub-thread.


I'm going to answer this question in the larger scope of "how does pure FP help us be confident that we are pushing correct code to production?"

"Prove it" is our first line of defense. By always writing total functions, we can be confident that our services and jobs don't fail in uncontrolled ways. "Proving of theorems" is what you end up doing as you write total functions. NonEmptyList, ADTs, Options, Coproducts, These, singleton types, sized collections. All these things can provide powerful proof that is used to write total functions. The proof that various types provide makes it easier to write total functions as we can use Scala's powerful type system to greatly restrict which programs we even have to think about. And (thinking in reverse), forcing yourself to write pure, total programs ends up forcing you to prove various things about your program in order to achieve those properties.

So all in all, we perform the "proving of theorems" all the time. It just doesn't look or feel like it. But a large portion of CR discussion is about the types used in a program, which is in effect a discussion about which theorems we think we should prove before we push the code to production.


In my experience, business logic is often relatively easy to express in pure FP. Where things start to get trickier is the boilerplate and boundaries, e.g. I'm writing a Rails app at the moment where the business logic is in pure functions, but the boundaries with other systems like ActiveRecord and external webservices tends to end up being more object-oriented.

For example, the ruby library I use to connect to webservices is very OO, and requires you to derive from its base class to build each webservice client.

This is of course very natural in Ruby, but I do see lots of OO in Scala libraries too (e.g. Spray).


> In my experience, business logic is often relatively easy to express in pure FP.

Agreed. This makes it a pretty easy sell to get everyone to commit to using immutability and purity and all those nice things in the business logic layer.

> Where things start to get trickier is the boilerplate and boundaries, e.g. I'm writing a Rails app at the moment where the business logic is in pure functions, but the boundaries with other systems like ActiveRecord and external webservices tends to end up being more object-oriented.

We're in the same boat, except in an in-house Java-based service framework. The "shell" of the program reads from the DB/makes service calls to gather input, passes this input to the pure business logic layer, and then based on the output throws exceptions, writes to the DB, makes other service calls, etc. This conscious division between effects and logic alone makes programs better.

In areas where we need concurrency or have more complicated effects we wish to unit test, we have started to use scalaz.concurrent.Task and scalaz.Free.


They come Berkeley and MIT, colleges that are renowned for teaching functional languages in their intro to programming courses, don't they.


Nope we mostly come from either state schools of our original residence or small liberal arts schools. I know of two hires from those schools, and I am the one who taught them pure typed FP.

I'm the only one who came in knowing pure FP at all and I didn't learn it via classes.


That's a bit biased. Berkeley and MIT students are pretty pragmatic, and are not typically FP enthusiasts (as in, many aren't even if some are on their own accord). Many European universities have more of an affinity to FP, comparatively speaking.


Err, not exactly, Berkeley and Mit use python now and have been for a while.


I can't speak for MIT but Berkeley has essentially translated SICP material to Python and then you have to write a Scheme interpreter.

Students there have more FP experience than most.


I went to a state College (Mizzou) and everybody I knew that was in a CS degree took a Haskell course.


The majority of software written ever has been written in the world's most popular functional programming language: Excel.


Yes but the majority of excel sheets consist of calculations. The source code of many OO programs will also consist of pure functions if that program is focused on calculation. So calculations are easy to express as pure functions, everybody knows that.

On the other hand, if you want to make an interactive application in excel you use VBA which exposes a large and rich set of objects.


Yes, VBA is a break away from the nice purely functional world of spreadsheets.

Simon Peyton Jones once did some work on giving Excel more programmatic power without having to go to VBA.

http://research.microsoft.com/en-us/um/people/simonpj/Papers...


The paper deals with more examples of calculations: convert fahrenheit to celcius, calculate volume. It does not cover interactive applications. I hope you are not redefining the problem to fit the solution which can be a weakness of pure mathematicians and functional programmers (and negative though it is I have to add: Its a waste of everybody's time. It would be much better if people were direct about what their solution addresses instead of leaving it vaguely defined in the hope that people will think it is of practical use for more than it actually is)


Yes, Excel is limited. Yet, people manage to solve lots of business relevant problems within its constraints.

Excel is very interactive: you can change input and immediately get a different output. (I think you were trying to talk about a different restriction. Excel is very limited in the kinds of inputs and outputs you can make, and even more so in the kind of side-effects you can cause.)


>On the other hand, if you want to make an interactive application in excel you use VBA which exposes a large and rich set of objects.

Please don't encourage this. Because honestly debugging VBA written by consultants has definitely shortened by lifespan by a couple years


99.99% of what people do with Excel does not qualify as "software", unless you classify "A1+C3" as "software", in which case calling it "functional" becomes meaningless.


In that sense Excel is comparable to Bash.


Oh God, if you saw the Excel workbook my previous boss created as the back end for the financial calculations used in all our applications you'd scream in horror. Like just about every contingency in the process was done within the excel workbook and not just as a wrapper around some simplified formulas.


I would argue this is inertia and a hype train that never slowed down -- up until the last 2 or so years that is.

I do agree with you that thinking in FP takes a bit more experience however.


Actually, from what I've seen, pure FP forces people with less experience into design and structures of their code that they'd only do in imperative settings with considerably more experience.

Eg when I asks students to do some simple exercise like "write a function that finds the shortest path through a given graph", in impure languages their solutions tend to return a path if they find one, but just give up with eg a message printed to screen when there's no path.

In pure and types languages, I see more people reaching for a Maybe or Either return type to express that the function as asked for might not succeed.


Funny choice of exmple, the algorithms I am aware of for finding shortest paths require mutable vertices that store the scores and pointers (edges) for the best part found so far.

No doubt there ways to do it in a pure functional language -- but that requires a bit of thought. Compared to that difficulty, this business of return values seems trivial.

Worse, a language that forces people to Do The Right thing, might be acceptable for experienced programmers who want to work within that limitation. But when given to student, it just encourages closed minded rule-following.


> Worse, a language that forces people to Do The Right thing, might be acceptable for experienced programmers who want to work within that limitation. But when given to student, it just encourages closed minded rule-following.

Citation needed. I find the safety net of that kind of language empowering: I can concentrate on thinking about the actual problem, and be confident that the language won't let me shoot myself in the foot.


>Worse, a language that forces people to Do The Right thing ... just encourages closed minded rule-following.

I think experience shows that freedom to do the wrong thing frequently leads to the wrong thing happening. There are many case studies to be found in security and concurrency.


> [...] the algorithms I am aware of for finding shortest paths require mutable vertices that store the scores and pointers (edges) for the best part found so far.

No problem. Traditional loops with mutable variables translate straight-forward to tail recursive calls, if you want to write your algorithm like that.

Though actually my argument was less about not mutating your functions internal variables---but about interacting with the world outside your function via a well defined interface. (In this case, via arguments and returned values.)

The most 'mainstream' language that encourages such a strong adherence to declared interfaces is Haskell. But the imperative D can do something similar:

"In a slightly less precise way, this means that pure functions always have the same effect and/or return the same result for a given set of arguments. As a consequence, a pure function for example cannot call other impure functions, or perform any kind of I/O (in the classical sense)."

http://klickverbot.at/blog/2012/05/purity-in-d/


I'm sure you're right. Apologies for me misleading. It appears I'm twisted by years of OOP during the start of my career.


Haha. No worries. Mine is also just an observation I made with the few people I'm mentoring and teaching.

Also, they seem to grasp recursion much better via Haskell than in Python or Java. I believe that's mostly because Haskell makes structural recursion real easy (ie recursion along the structure of your data type, eg like along a tree)---and once they are comfortable with the basic idea from that, other patterns of recursion are easier to understand.

Algebraic datatypes and pattern matching on them are a great benefit for that structural recursion.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: