[racket] Why functional?

From: George Rudolph (george.rudolph at citadel.edu)
Date: Thu May 23 07:40:57 EDT 2013


Lawrence Bottorff <borgauf at ...> writes:

> 
> I posted the following question at stackoverflow and got 3 pluses and a 
star (favorite question) -- although only one response. I'd really like to 
clear these issues up in my mind. Here goes:
> ----
> 
> 
> I've read some of the discussions here, as well as followed links to other 
explanations, but I'm still not able to understand the mathematical 
connection between "changing state" and "not changing state" as it pertains 
to our functional programming versus non-FP debate. I understand the basic 
argument goes back to the pure math definition of a function, whereby a 
function maps a domain member to only one range member. This is subsequently 
compared to when a computer code function is given certain input, it will 
always produce the same output, i.e., not vary from use to use, i.e.i.e., 
the function's state, bzw. its domain to range mapping behavior, will not 
change.

------------------------------
Lawrence,
Take a different perspective entirely.  Forget the mathematical and 
theoretical
stuff for the moment.  Think about sources for bugs in imperative, 
procedural or OO programming,
when left up to a programmer to manage:
1.	pointers
2.	memory management
3.	assigning and reassigning values to variables/memory locations
4.	breaking an interface (whether it’s OO or not)
Let’s just stop at those 4. People might mention others…

Also think about some other things that we do repeatedly in coding solutions 
to many problems:
5.	iterate over a list or collection to do something to each element of 
that collection
6.	interrupt computation at time t, restart from the same point at time 
t+x.
7.	use “potentially infinite” and possibly recursive data set

Pure functional languages do not allow (re)assignment. You can assign a 
variable/identifier once,
then it is immutable.  If you need a new value, it is a different identifier 
(different memory location 
under the covers).  It removes a number of shared-memory bugs caused by 
updating a location
incorrectly, whether your application is single-threaded or multi-threaded 
or distributed.

Similarly a programmer can create new things, like lists, but is not 
*required* to explicitly manage when
a list gets destroyed/deallocated.  Typically, the system will do it.

Functional languages allow a clean way of passing functions (and closures) 
as parameters and
returning functions as values from another function.  This enables higher-
order functions such as map, filter, 
fold and list comprehensions to work in predictable, sane ways.  Again so 
the programmer doesn’t have to explicitly manage, or even think about, 
operating on a collection as explicit iteration.  Functions with closures 
allow you to cleanly stop execution of a function, “memorize it” (to use 
some jargon) and restart it later, with the expectation that it will 
generate the same result as though it had simply run from beginning to end.

And then there is lazy versus strict evaluation. When dealing with 
potentially infinite data, the programmer’s
code does not have to change versus dealing with a collection that only has 
10 items.  Typically the programmer includes
a lazy version of the same code, or change a library import, or something 
like that—which is much less likely 
to introduce bugs in code than having to change a lot of function/method 
names. Lazy versus strict evaluation
of code/data is a behavioral, semantic issue, usually not a syntactic one.

George



Posted on the users mailing list.