How to do functional programming

606 views
Skip to first unread message

Pattern-chaser

unread,
Oct 8, 2015, 9:08:54 AM10/8/15
to Clojure
I started in software with structured design. In the 80s/90s, I discovered OO, and was surprised to find that the main thing I gained was a different way of looking at things. This informed my designs from then on, even when I returned from C++ to C (I'm a firmware designer by specialisation). Now I want to find out about functional programming, in the hope that another new perspective will inform and improve my design and programming skills. The question I'm posing here is simple: how do you do functional programming?

For an OO design, you put together a number of co-operating but autonomous class instances, and let them get on with it. Functional programming doesn't seem to involve classes or any of the OO concepts I'm used to. So how you do you design a program in a functional way?

TIA for your advice, opinions and thoughts. :)

Jason Stewart

unread,
Oct 8, 2015, 9:21:13 AM10/8/15
to clo...@googlegroups.com
The way I like to think about FP vs OO is that OO usually couples state with identity and the code that operates on both, while FP defines a clear boundary between data, state, and the functions that operate on the data. 

Designing a FP program often involves looking at the data first, then thinking about what transformations that the data needs in order to become what you want it to be. I like to think of functions as instructions about how to transform that data.

This is overly simplistic, and I would definitely recommend some background reading/watching of videos.

A good starting point would be to watch these:

And read the book Functional Programming for the Object Oriented Programmer by Brian Marick if you've been writing OO code for a long time.

Cheers,
Jason


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raoul Duke

unread,
Oct 8, 2015, 3:35:34 PM10/8/15
to clo...@googlegroups.com

Raoul Duke

unread,
Oct 8, 2015, 3:36:38 PM10/8/15
to clo...@googlegroups.com
> The way I like to think about FP vs OO is that OO usually couples state with
> identity and the code that operates on both, while FP defines a clear
> boundary between data, state, and the functions that operate on the data.

https://en.wikipedia.org/wiki/Expression_problem

> Designing a FP program often involves looking at the data first, then
> thinking about what transformations that the data needs in order to become
> what you want it to be. I like to think of functions as instructions about
> how to transform that data.

http://lists.racket-lang.org/users/archive/2010-April/038935.html

Mimmo Cosenza

unread,
Oct 8, 2015, 3:42:34 PM10/8/15
to clo...@googlegroups.com
https://tbaldridge.pivotshare.com/media/oop-lesson-1/28290

I do not remember if the other tutorials (2,3 and 4) on OOP are free as well…

mimmo

Raoul Duke

unread,
Oct 8, 2015, 3:45:44 PM10/8/15
to clo...@googlegroups.com
> https://tbaldridge.pivotshare.com/media/oop-lesson-1/28290
> I do not remember if the other tutorials (2,3 and 4) on OOP are free as
> well…


i did this one a while back as a refresher on my university stuff :-)
https://www.coursera.org/course/progfun

Raoul Duke

unread,
Oct 8, 2015, 3:46:36 PM10/8/15
to clo...@googlegroups.com
heck if you pay me U$D120 an hour, you can send me your code (as long
as it isn't more than a single page at 10 pt font, with regular
formatting ;-) and i'll tell ya how to do it more FPish!!!!!!!!!!!!
(kidding.)

Sean Corfield

unread,
Oct 8, 2015, 4:00:40 PM10/8/15
to clo...@googlegroups.com
On 10/8/15, 12:45 PM, "Raoul Duke" <clo...@googlegroups.com on behalf of rao...@gmail.com> wrote:


>i did this one a while back as a refresher on my university stuff :-)
>https://www.coursera.org/course/progfun

I’ll second this as a great recommendation. I first took the course several years ago and I’ve taken it twice since as a Community TA — that’s how much I like that course! :)

It is switching from scheduled to on-demand so it won’t be available for a while yet, but then folks will be able to take it whenever they want, at their own speed.

Sean


Colin Yates

unread,
Oct 8, 2015, 4:32:29 PM10/8/15
to clo...@googlegroups.com
This is a great course. I still get a bit green with envy when I recall the workbook capabilities in Eclipse. Another recommendation for Brian Marick’s OO to FP book.

Sean Corfield

unread,
Oct 8, 2015, 8:19:52 PM10/8/15
to clo...@googlegroups.com
On 10/8/15, 1:32 PM, "Colin Yates" <clo...@googlegroups.com on behalf of colin...@gmail.com> wrote:


>This is a great course. I still get a bit green with envy when I recall the workbook capabilities in Eclipse. Another recommendation for Brian Marick’s OO to FP book.

Ah, just realized this is Odersky’s course which is not what I was thinking of! I really did NOT enjoy the progfun course. I found the exercises boring and I found Scala itself fussy and annoying (and I _hate_ Eclipse!). And this is from someone who did Scala in production for about 18 months before switching to Clojure in 2011!

The course I was thinking of, which I praised so highly was actually this one:

https://www.coursera.org/course/proglang

Programming Languages, University of Washington, Professor Dan Grossman.

That’s the one I enjoyed so much I took it three times!

It starts out with Standard ML to teach you about statically typed FP, then it moves on to Racket to teach you about dynamically typed FP, then it wraps up with Ruby to look at how dynamically typed OOP contrasts with the two FP approaches.

Sean

Raoul Duke

unread,
Oct 8, 2015, 8:24:14 PM10/8/15
to clo...@googlegroups.com
> https://www.coursera.org/course/proglang

cool. thanks for the pointer, i will have to find the time.

Baishampayan Ghose

unread,
Oct 9, 2015, 1:47:43 AM10/9/15
to Clojure Group
Haha, Sean... you got me stumped there for a second. I completely
agree with your assessment though. Dan Grossman's course on
"Programming Languages" is an absolute blockbuster. Highly
recommended! ~BG
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Baishampayan Ghose
b.ghose at gmail.com

Colin Yates

unread,
Oct 9, 2015, 5:14:33 AM10/9/15
to clo...@googlegroups.com
he he.

Coming from many years of ‘Java Enterprise Applications’ (e.g. Spring, Hibernate and if you were feeling adventurous maybe free marker instead of JSP - ooooh.) this was a wonderful breath of fresh air for me. https://www.coursera.org/course/proglang looks great as well.

Mark Nutter

unread,
Oct 9, 2015, 6:41:16 AM10/9/15
to clo...@googlegroups.com
Neal Ford has a good talk on "Functional Thinking" https://www.youtube.com/watch?v=7aYS9PcAITQ

Sean Corfield

unread,
Oct 9, 2015, 12:34:11 PM10/9/15
to clo...@googlegroups.com
On 10/9/15, 2:13 AM, "Colin Yates" <clo...@googlegroups.com on behalf of colin...@gmail.com> wrote:


>Coming from many years of ‘Java Enterprise Applications’ (e.g. Spring, Hibernate and if you were feeling adventurous maybe free marker instead of JSP - ooooh.) this was a wonderful breath of fresh air for me.

Thank you for starting my Friday off with a good chuckle, Colin!

Yes, your background will hugely influence how you feel about various languages. My arc at that brought me to Scala in 2009 was such that it was a breath of fresh air at the time — and I was still an Eclipse user back then — although I’d also used a number of dynamically typed scripting languages and advanced code editors (rather than IDEs) so I knew there was a world of lightweight freedom out there :)

If I hadn’t switched to Clojure in 2011, I’d probably still enjoy doing Scala…

Sean


Pattern-chaser

unread,
Oct 11, 2015, 2:54:45 PM10/11/15
to Clojure


On Thursday, 8 October 2015 14:21:13 UTC+1, Jason Stewart wrote:
Designing a FP program often involves looking at the data first, then thinking about what transformations that the data needs in order to become what you want it to be. I like to think of functions as instructions about how to transform that data.

This is overly simplistic, and I would definitely recommend some background reading/watching of videos.

Thanks, Jason. This is the sort of hint I was hoping for. :) [Aside: I'm the sort of Luddite that doesn't like to watch videos on a computer; that's what TVs are for. Yes, I know. Be kind. We all have our failings. ;)] I shall be seeking out the Brian Marick book ASAP. If anyone has any more such high (abstract) level comments like this, I'd love to read them...?

So, am I right, at this highly-simplified level, that a functional program will tend to look (to an OO programmer) like a simple series of function calls or maybe a Unix shell script? Of course the 'functions' (or shell script calls) are native/library functions of the FP language, but is that roughly right?

Piyush Katariya

unread,
Aug 7, 2016, 3:10:50 PM8/7/16
to Clojure

www.slideshare.net/piyushkatariya/thinking-functionally

Gary Johnson

unread,
Aug 8, 2016, 11:42:04 AM8/8/16
to Clojure
A shell script written in a procedural style (e.g. with Bash or equivalent shell language) will frequently start out by declaring some global variables, then perform some conditional checks (if then else), throw in a few loops (for, while), and ultimately end up with some new values in those initially declared variables that you use as your program's output. If you are feeling particularly intrepid, you might factor out some repetitive operations into separate subroutines defined higher up in the file and then call them as necessary in those aforementioned conditional blocks and loops.

The mental model behind this type of programming is the Universal Turing Machine. Your variables are some internal state that the program instructions are reading and writing, reading and writing, writing and reading until you get to the last instruction that returns some subset of the final variable values. The driving principle is that computation is accomplished by the free mutation of state.

A program written in a functional style (e.g. with any Lisp, one of the MLs, Haskell, Clean, etc) begins with a chunk of data, which may either be hard-coded, input from the outside world, or generated internally with a function like "range" or "rand". This piece of data may or may not be stored in one or more global variables. However (and this is HUGE however), these are not generally mutated over the life of the program. That is to say, they are constants. More often than not, you won't even store the initial data in a global variable but will just feed it into a function that processes it and spits out some new data, which is then fed to another function that performs some other processing operation and again spits out some new data. Ultimately, the data that you produce is passed through an arbitrarily long pipeline of functions until the final result is produced and returned by the program. In practice, these function calls are rarely linear and are much more likely to form a branching call tree. But ultimately, the relevant branches of this tree will be traversed and executed in a depth first manner (unless lazy evaluation inserts its magic to reorder some of that computation behind the scenes) and you still get to a final output returned by the last function fall evaluated.

The mental model behind this type of programming is Lambda Calculus. There is no mutable state anywhere in a pure functional program, and instead the intermediate results are passed through the call stack from function to function. In practice, because stack sizes are limited, most values passed between functions will be boxed references pointing to memory locations on the heap. However, as far as the functional programmer is concerned, there is no heap and there is no mutable state. Immutable values simply flow seamlessly from one function to the next until the program has finished. The driving principle is that computation is accomplished by transforming data through mapping a set of immutable inputs to an immutable output. Think f(x,y) = z.

In order to accomplish this stateless pipeline of data transformations, functions much possess a property called "referential transparency". This means that a function must be able to calculate its outputs deterministically using only its inputs AND without modifying any of its inputs in the process. This property is preserved even when global variables are referenced within the body of a function as long as the values associated with those global variables are constants throughout the lifetime of the program.

In practice, very few languages (outside of Haskell) actually try to be completely pure and allow no mutation of state whatsoever. Clojure opts to make all data immutable by default, but provides some special language features (refs, atoms, agents, volatiles) that you can use if you really do want to write an algorithm that involves some mutable state. Unless there is a performance bottleneck (as in numerical computing) or no other sensible way to model the domain (as in some web applications), making use of these features for mutable state is generally frowned upon. When they are really necessary and valuable, however, Clojure's language tools for accomplishing mutation are wonderful because they carefully protect it against concurrency clashes in multi-threated environments.

To approach writing a functional program, first think about how to model the computation as a series of data transformations. Then build your program from the bottom up (prototyping and testing it in the REPL) by writing small, referentially transparent functions that describe the lower level operations that you will need. Then build higher level functions on top of those that build up your abstractions in a layer cake style until you reach your entry point function that either takes input data from the outside world or generates it internally and then starts the execution of the function call tree.

This is, of course, my attempt at summarizing the mindset that I frequently use when trying to write a new functional program, and I welcome additions or corrections from other folks in this thread to further flesh it out. Best of luck in your functional programming adventures and with Clojure in particular. The FP way of thinking can be a bit tricky to wrap your mind around when coming from a traditional OOP background, but once you grok it, there is a great feeling of freedom and simplicity that emerges from what I suspect many of my fellow Clojurians would agree is a far more elegant and powerful programming paradigm.

John Newman

unread,
Aug 8, 2016, 12:54:15 PM8/8/16
to Clojure
So I've been hammocking it up recently on this subject. Just to add more philosophical perspective - you could look at the universe in two different ways: from the _inside_, where a thing subjectively experiences the flow of time, as the world mutates around it; and from the _outside_, where objectively no time exists, and the history of the universe is a static network of immutable states, like a unidirectional graph. Animals understand things from the _inside_ perspective, teleologically, where things seem dynamic, contextual, and place oriented in time and space. Physics and philosophy give us the second, ontological understanding. Some might say the inside perspective is more intuitive while the outside perspective is more correct or precise.

FP has an ideally unidirectional flow of causality, whereas OOP has loops, where state flows backwards in the causal chain. A class instance is like a state machine (to my mind) and that machine moves through time, updating it's properties. (Banging on things in place)

FP allows you to more easily create an objective universe, where you control all states from the outside and have absolute control over those states. This also, however, requires more explicit definition of what you want to occur, because the context of your transformation is not implicit in the data itself.

OOP allows you to more easily forget about the complexities of the global, outside context and operate under the illusion that context is built into the instance - that the same "thing" is moving across the causal graph, through time. Unfortunately, as our programs become more complex this illusion breaks down and our efforts to hide the complexities of the outside context in looping state machines makes us in fact ignorant of too much. No, the class is not a duck. No, the method does not actually quack. It's convenient to pretend like it does, in the small, but the inside, subjective metaphor becomes a burden in the large.

So while FP sometimes requires more explicit definition of the desired transformations from one state to the next, you'll end up with a lot more hair on your head when working with large systems, if Rich and Stu's heads are any indication :)

John


--
Reply all
Reply to author
Forward
0 new messages