The UNIX Programming Environment (the classic text) states that the UNIX approach to programming is to build small, well-defined tools that can be combined to solve more complex problems. In learning C and the Bash shell, I've found this to be a powerful concept that can be used to deal with a wide range of programming problems.

Just using a Linux platform, the concept is pretty clear and used all the time. Any expression formed on the command line that redirects I/O, linking system tools like ls, grep, more, and so on shows how powerful this concept is.

The thing that confuses me is that many of these programs are written in C, using an imperative/procedural programming style, yet the way they are used and joined together on the command line seems much more like functional programming to me, where each program is an isolated function that doesn't depend on the state of any other program it might be joined to.

Is this accurate, understanding the UNIX programming philosophy is basically functional programming using tools that may have been built using an imperative programming style?

  • 6
    I don't think it is important whether that analogy is accurate or not. The question is, is it a useful analogy to you? Does thinking of it in those terms help you write programs and get work done?
    – stinkymatt
    Mar 22, 2011 at 13:46
  • Small well-defined tools can be run in a row in an imperative style, like in a bash script.
    – qwr
    Aug 21, 2023 at 21:21

5 Answers 5


I think you've got a point there, but cp, rm, cd and a lot of others change state, so they aren't really functions. The UNIX philosophy is more about doing only one thing but doing it well; often doing it well means allowing functional usage, but not always.


The answer is in the "Monadic i/o and UNIX shell programming" by Oleg Kiselyov.

This is an essay inspired by Philip Wadler's paper "How to Declare an Imperative" [Wadler97]. We will show uncanny similarities between monadic i/o in Haskell, and UNIX filter compositions based on pipes and redirections. UNIX pipes (treated semantically as writing to temporary files) are quite similar to monads. Furthermore, at the level of UNIX programming, all i/o can be regarded monadic...

  • iirc before powershell was called powershell it was called monad
    – jk.
    Aug 10, 2020 at 22:02

Well, I guess you can sort of look at it that way if you ignore the whole side effects issue. Unix commands frequently do NOT act functional in regards to always returning the same data set with the same inputs. However, as you mentioned, the piping aspect is similar to how functional programming can be done.

  • 1
    Have you really got an airplane?? ;) (sorry for offtopic comment)
    – BlackBear
    Mar 22, 2011 at 13:48
  • @BlackBear Not my own personal one. I'm in a club where about 50 of us collectively own 4 airplanes. It's a little more affordable that way. :-) Mar 22, 2011 at 13:53
  • @Brian Knoblauch: I'd like to have an airplane in the future.. money permitting :P
    – BlackBear
    Mar 22, 2011 at 13:57
  • 6
    Functional programming does not imply "no side-effects". The concept where the same function always produces the same result is called "idempotence" and is not a necessary condition for a program to be functional. This is also known as "pure functional".
    – Travis Webb
    Mar 22, 2011 at 18:30

To an extent you can say that. But that isn't necessarily true. I think you should read that more as 'ability to achieve more' with a simplistic design approach. And in order to be simple you will have to divide the task into easily understandable and easy to assemble parts. The UNIX philosophy to be frank with you,can be explain with the following example.

All programming is some sort of data manipulation! And in some cases programming is also program manipulation itself(Meta programming). Now the way UNIX philosophy works is, Imagine processing text. What is text? Text is some sort of data after all. When assemble into organized definition Text also becomes XML's and JSON's. Text can also be a list of numbers, Text can also be csv's, tsv's and what not! In other Text or string can represent a real huge area of programming data, just because its context can twisted and turned into what we want!

All programming requires data organization of some sort. Organizing requires searching...

a. There you go with just have 'grep', 'fgrep' and its family to do that.

Once you search you need to do some sorting..

b. Now we have 'sort' command to do that.

You've just sorted two files, now you wish to compare them.

c. Now we have 'diff', 'cmp' et al to do that.

You've just found there is no difference between the files. You need more of organized data now.

d. You have 'cat', pipes and redirection operators to write to a file.

You need more specific parsing..

e. You have head, tail, more, less, cut et al to do that...

All of this sew together using the '|' to generate real powerful stuff some time without writing any code at all. For more searching and sewing you have..

f. awk, shell and sed.

awk, shell and sed give you more control over text than what cut, diff et al can give you. Have you ever wondered that command1 | command2 | command3 ... series is a sort of workflow mechanism. When combined with If's this becomes more powerful.

Now comes more fun.

Have you ever heard of a utility called 'Perl', this thing is so powerful you can virtually do any task at hand with as little work imaginable. Sewed together with a utility like DBM you can do even small time persistence demands for your application. Remember we haven't even stepped out of the text world but yet managed to cover most aspects of a programming environment.

So I think UNIX is more than a operating system. It's a collection of tools and environment designed to solve the problems in the most simple way. A simple way doesn't necessarily imply simplicity of implementation of the solution. But simplicity itself doesn't take you much far.

I read this some where on reddit.

"If your only design goal is simplicity, you will get as many users as Plan9"

  • Perl is an excellent example of a fast and nifty bikeshed tool. Unfortunately applications can only grow to a certain size before they collapse under their own weight. Aug 11, 2020 at 12:41

The way they are joined together on the command-line and interact with one another is very functional. However, I'd say that this has more to do with the design of the shell, and less to do with whether those underlying programs are written imperatively or functionally. Most good functional languages support imperative/procedural concepts, even though their overall design lends itself to functional programming. Yes many of the UNIX shell features employ functional concepts but, again, this is more due to the design of the shell than the particular implementation of the underlying programs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.