I was reading an article about functional programming where the writer states

(take 25 (squares-of (integers)))

Notice that it has no variables. Indeed, it has nothing more than three functions and one constant. Try writing the squares of integers in Java without using a variable. Oh, there’s probably a way to do it, but it certainly isn’t natural, and it wouldn’t read as nicely as my program above.

Is it possible to achieve this in Java? Supposing you are required to print the squares of first 15 integers, could you write a for or while loop without using variables?

Mod notice

This question is not a code golf contest. We are looking for answers that explain the concepts involved (ideally without repeating earlier answers), and not just for yet another piece of code.

  • 19
    Your functional example does use variables on the inside, but the language does all of it behind the scenes. You've effectively delegated the unpleasant parts to someone you believe has done it correctly. – Blrfl Feb 15 '13 at 13:47
  • 12
    @Blrfl: The "behind the scenes" argument kills all language-based debates, since every piece of code is ultimately translated to x86 machine code. x86 code is not object-oriented, not procedural, not functional, not anything, but these categories are valuable tags for programming languages. Look at the language, not the implementation. – thiton Feb 15 '13 at 14:52
  • 10
    @thiton Disagreed. What Blrfl is saying is that those functions probably use variables written in the same programming language. No need to go low-level here. The snippet is merely using library functions. You can easily write the same code in Java, see: squaresOf(integers()).take(25) (writing those functions is left as an exercise for the reader; the difficulty lies in the infinite set for integers(), but that's a problem for Java because of its eager evaluation, nothing to do with variables) – Andres F. Feb 15 '13 at 15:03
  • 6
    That quote is confusing and misleading, there's no magic there, just syntactic sugar. – yannis Feb 15 '13 at 15:04
  • 2
    @thiton I suggest you learn more about FP languages, but nevertheless, the code snippet doesn't support (or reject) the assertion that "variables" aren't needed (by which I assume you mean "mutable variables", because the other kind is common in FP). The snippet just shows library functions which could have been implemented in Java as well, barring lazy/eager problems which are offtopic here. – Andres F. Feb 15 '13 at 15:11

10 Answers 10


Is it possible to implement such an example in Java without using destructive updates? Yes. However, as @Thiton and the article itself mentioned, it will be ugly (depending on one's taste). One way is using recursion; here's a Haskell example that does something similar:

unfoldr      :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr f b  =
  case f b of
   Just (a,new_b) -> a : unfoldr f new_b
   Nothing        -> []  

Note 1) the lack of mutation, 2) the use of recursion, and 3) the lack of loops. The last point is very important -- functional languages don't need looping constructs built into the language, since recursion can be used for most (all?) cases where loops are used in Java. Here's a well-known series of papers showing how incredibly expressive function calls can be.

I found the article unsatisfying and would like to make a couple of additional points:

That article is a very poor and confusing explanation of functional programming and its benefits. I would strongly recommend other sources for learning about functional programming.

The most confusing part about the article is that it doesn't mention that there are two uses for assignment statements in Java (and most other mainstream languages):

  1. binding a value to a name: final int MAX_SIZE = 100;

  2. destructive update: int a = 3; a += 1; a++;

Functional programming eschews the second, but embraces the first (examples: let-expressions, function parameters, top-level defineitions). This is a very important point to grasp, because otherwise the article just seems silly and might leave you wondering, what are take, squares-of, and integers if not variables?

In addition, the example is meaningless. It doesn't show the implementations of take, squares-of, or integers. For all we know, they are implemented using mutable variables. As @Martin said, you can trivially write this example in Java.

Once again, I would recommend avoiding this article and others like it if you really want to learn about functional programming. It seems to be written more with the goal of shocking and offending rather than teaching concepts and fundamentals. Instead, why not check out one of my all-time favorite papers, by John Hughes. Hughes tries to tackle some of the same issues that the article covered (although Hughes doesn't talk about concurrency/parallelization); here's a teaser:

This paper is an attempt to demonstrate to the larger community of (nonfunctional) programmers the significance of functional programming, and also to help functional programmers exploit its advantages to the full by making it clear what those advantages are.


We shall argue in the remainder of this paper that functional languages provide two new, very important kinds of glue. We shall give some examples of programs that can be modularized in new ways and can thereby be simplified. This is the key to functional programming’s power — it allows improved modularization. It is also the goal for which functional programmers must strive — smaller and simpler and more general modules, glued together with the new glues we shall describe.

  • 10
    +1 for "I would recommend avoiding this article and others like it if you really want to learn about functional programming. It seems to be written more with the goal of shocking and offending rather than teaching concepts and fundamentals." – user40980 Feb 15 '13 at 15:20
  • 3
    Half the reason people don't do FP is because they don't hear/learn anything about it in uni, and the other half is because when they look into it they find articles which leave them both uninformed and thinking it's all for some fanciful playing about rather than being a thought-out reasoned approach with benefits. +1 for giving better sources of information – Jimmy Hoffa Feb 15 '13 at 16:08
  • 3
    Put your answer to the question at the absolute top if you would so it's more direct to the question and maybe this question will stay open then (with a direct question-focussed answer) – Jimmy Hoffa Feb 15 '13 at 16:24
  • 2
    Sorry to nitpick, but I don't understand why you chose this haskell code. I've read LYAH and your example is difficult for me to grok. I also don't see the relation to the original question. Why didn't you just use take 25 (map (^2) [1..]) as an example? – Daniel Kaplan Feb 15 '13 at 20:20
  • 2
    @tieTYT good question -- thanks for pointing this out. The reason I used that example is because it shows how to generate a list of numbers using recursion and avoiding mutable variables. My intent was for the OP to see that code and think about how to do something similar in Java. To address your code snippet, what is [1..]? That's a cool feature built in to Haskell, but does not illustrate the concepts behind generating such a list. I'm sure instances of the Enum class (which that syntax requires) are also helpful, but was too lazy to find them. Thus, unfoldr. :) – user39685 Feb 15 '13 at 20:31

You wouldn't. Variables are at the core of imperative programming, and if you try to program imperatively without using variables, you are just causing everyone a pain in the ass. In different programming paradigms, the styles are different, and different concepts form your basis. A variable in Java, when used well with a small scope, is no evil. Asking for a Java program without variables is like asking for a Haskell program without functions, so you don't ask for it, and you don't let yourself be fooled into viewing imperative programming as inferior because it uses variables.

So, the Java way would be:

for (int i = 1; i <= 25; ++i) {

and don't let yourself be fooled to write it in any more complex way due to a hatred of variables.

  • 5
    "Hatred of variables"? Ooookay... What have you read about Functional Programming? What languages have you tried? Which tutorials? – Andres F. Feb 15 '13 at 15:12
  • 8
    @AndresF.: More than two years of coursework in Haskell. I don't say FP is bad. However, there is a tendency in many FP-vs-IP discussions (such as the linked article) to condemn the use of re-assignable named entities (AKA variables), and to condemn without good reason or data. Unreasonable condemnation is hatred in my book. And hatred makes for really bad code. – thiton Feb 15 '13 at 15:39
  • 10
    "Hatred of variables" is causal oversimplification en.wikipedia.org/wiki/Fallacy_of_the_single_cause there are many benefits to stateless programming which could even be had in Java, though I agree with your answer that in Java the cost would be too high in complexity to the program and being non-idiomatic. I would still not go around hand-waving away the idea that stateless programming is good and stateful is bad as some emotional response rather than a reasoned, well thought out stance people have come to due to experience. – Jimmy Hoffa Feb 15 '13 at 15:53
  • 2
    Inline with what @JimmyHoffa says, I'll refer you to John Carmack on the topic of functional-style programming in imperative languages (C++ in his case) (altdevblogaday.com/2012/04/26/functional-programming-in-c). – Steven Evers Feb 15 '13 at 17:34
  • 5
    Unreasonable condemnation is not hatred, and avoiding mutable state is not unreasonable. – Michael Shaw Feb 15 '13 at 20:21

The simplest I can do with recursion is a function with one parameter. It's not very Java-esque, but it does work:

public class squares
    public static void main(String[] args)

    private static void squares(int x)
        if (x>0)
  • 3
    +1 for attempting to actually answer the question with a Java example. – KChaloux Feb 15 '13 at 19:12
  • I'd downvote this for code golf style presentation (see Mod notice) but can't force self to press down arrow because this code perfectly matches statements made in my favorite answer: "1) the lack of mutation, 2) the use of recursion, and 3) the lack of loops" – gnat Feb 15 '13 at 22:20
  • 3
    @gnat: This answer was posted before the Mod notice. I wasn't going for great style, I was going for simplicty, and satisfying the OP's original question; to illustrate that it is possible to do such things in Java. – FrustratedWithFormsDesigner Feb 15 '13 at 22:22
  • @FrustratedWithFormsDesigner sure; this wouldn't stop me from DVing (since you're supposed to be capable of editing to comply) - it's the strikingly perfect match that did the magic. Well done, really well done, fairly educative - thank you – gnat Feb 15 '13 at 22:26

In your functional example we don't see how the squares-of and take functions are implemented. I'm not a Java expert, but I'm pretty sure we could write those functions to enable a statement like this...


which is not so very different.

  • 6
    Nitpick: squares-of is not a valid name in Java (squares_of is though). But otherwise, good point which shows that the article's example is poor. – user39685 Feb 15 '13 at 16:37
  • I suspect that the article's integer lazily generates integers, and the take function picks 25 of the squared-of numbers from integer. In short, you should have a integer function to lazily produce integers to infinity. – OnesimusUnbound Feb 18 '13 at 6:30
  • It is a bit insanity to call something like (integer) a function - a function is still something that maps an argument to a value. It turns out that (integer) is not a function, but merely a value. One could even go so far to say that integer is a variable that is bound to an infinite strem of numbers. – Ingo Feb 22 '13 at 0:06

In Java you could do this (esp. the infinite list part) with iterators. In the following code sample, the number supplied to the Take constructor can be arbitrarily high.

class Example {
    public static void main(String[] a) {
        Numbers test = new Take(25, new SquaresOf(new Integers()));
        while (test.hasNext())

Or with chainable factory methods:

class Example {
    public static void main(String[] a) {
        Numbers test = Numbers.integers().squares().take(23);
        while (test.hasNext())

Where SquaresOf, Take and Integers extend Numbers

abstract class Numbers implements Iterator<Integer> {
    public static Numbers integers() {
        return new Integers();

    public Numbers squares() {
        return new SquaresOf(this);

    public Numbers take(int c) {
        return new Take(c, this);
    public void remove() {}
  • 1
    This shows the superiority of OO paradigm over functional one; with proper OO design you can mimic functional paradigm but you cannot mimic OO paradigm in a functional style. – m3th0dman Feb 18 '13 at 22:48
  • 3
    @m3th0dman: With proper OO design you can possibly half-assedly mimic FP, just like any language that has strings, lists, and/or dictionaries could half-assedly mimic OO. The Turing equivalence of general-purpose languages means that given enough effort, any language can simulate the features of any other. – cHao Feb 19 '13 at 1:04
  • Note that Java-style iterators like in while (test.hasNext()) System.out.println(test.next()) would be a no-no in FP; iterators are inherently mutable. – cHao Feb 19 '13 at 1:07
  • 1
    @cHao I hardly believe that true encapsulation or polymorphism can be mimicked; also Java (in this example) cannot truly mimic a functional language because of the strict eager evaluation. I also believe that iterators can be written in a recursive manner. – m3th0dman Feb 19 '13 at 7:59
  • @m3th0dman: Polymorphism wouldn't be hard at all to mimic; even C and assembly language can do it. Just make the method a field in the object or a class descriptor / vtable. And encapsulation in the data hiding sense is not strictly needed; half the languages out there don't provide it, when your object is immutable, it doesn't matter as much whether people can see its guts anyway. all that is needed is data wrapping, which the aforementioned method-fields could easily provide. – cHao Feb 19 '13 at 13:13

Short version:

In order to make single-assignment style work reliably in Java, you'd need (1) some kind of immutable-friendly infrastructure, and (2) compiler- or runtime-level support for tail-call elimination.

We can write much of the infrastructure, and we can arrange things to try to avoid filling the stack. But as long as each call takes a stack frame, there will be a limit on how much recursion you can do. Keep your iterables small and/or lazy, and you shouldn't have major issues. At least most of the problems you'll run into don't require returning a million results at once. :)

Also note, since the program has to actually effect visible changes in order to be worth running, you can't make everything immutable. You can, however, keep the vast majority of your own stuff immutable, using a tiny subset of essential mutables (streams, for example) only at certain key points where the alternatives would be too onerous.

Long version:

Simply put, A Java program can not totally avoid variables if it wants to do anything worth doing. You can contain them, and thus restrict mutability to a huge degree, but the very design of the language and API -- along with the need to eventually change the underlying system -- make total immutability infeasible.

Java was designed from the start as an imperative, object-oriented language.

  • Imperative languages nearly always depend on mutable variables of some kind. They tend to favor iteration over recursion, for example, and nearly all iterative constructs -- even while (true) and for (;;)! -- are utterly dependent on a variable somewhere changing from iteration to iteration.
  • Object-oriented languages pretty much envision every program as a graph of objects sending messages to each other, and in nearly all cases, responding to those messages by mutating something.

The end result of those design decisions is that without mutable variables, Java has no way to change the state of anything -- even something as simple as printing "Hello world!" to the screen involves an output stream, which involves sticking bytes in a mutable buffer.

So, for all practical purposes, we're limited to banishing the variables from our own code. OK, we can kinda do that. Almost. Basically what we'd need is to replace almost all iteration with recursion, and all mutations with recursive calls returning the changed value. like so...

class Ints {
     final int value;
     final Ints tail;

     public Ints(int value, Ints rest) {
         this.value = value;
         this.tail = rest;
     public Ints next() { return this.tail; }
     public int value() { return this.value; }

public Ints take(int count, Ints input) {
    if (count == 0 || input == null) return null;
    return new Ints(input.value(), take(count - 1, input.next()));

public Ints squares_of(Ints input) {
    if (input == null) return null;
    int i = input.value();
    return new Ints(i * i, squares_of(input.next()));

Basically, we build a linked list, where each node is a list in itself. Each list has a "head" (the current value) and a "tail" (the remaining sublist). Most functional languages do something akin to this, because it's very amenable to efficient immutability. A "next" operation just returns the tail, which is typically passed to the next level in a stack of recursive calls.

Now, this is an extremely oversimplified version of this stuff. But it's good enough to demonstrate a serious problem with this approach in Java. Consider this code:

public function doStuff() {
    final Ints integers = ...somehow assemble list of 20 million ints...;
    final Ints result = take(25, squares_of(integers));

Although we only need 25 ints for the result, squares_of doesn't know that. It is going to return the square of every number in integers. Recursion 20 million levels deep causes pretty big problems in Java.

See, the functional languages you'd typically do wackiness like this in, have a feature called "tail call elimination". What that means is, when the compiler sees code's last act being to call itself (and return the result if the function's non-void), it uses the current call's stack frame instead of setting up a new one and does a "jump" instead of a "call" (so the stack space used remains constant). In short, it goes about 90% of the way toward turning tail-recursion into iteration. It could deal with those billion ints without overflowing the stack. (It'd still eventually run out of memory, but assembling a list of a billion ints is going to mess you up memorywise anyway on a 32-bit system.)

Java doesn't do that, in most cases. (It depends on the compiler and runtime, but Oracle's implementation doesn't do it.) Each call to a recursive function eats up a stack frame's worth of memory. Use up too much, and you get a stack overflow. Overflowing the stack all but guarantees the death of the program. So we have to make sure not to do that.

One semi-workaround...lazy evaluation. We still have the stack limitations, but they can be tied to factors we have more control over. We don't have to calculate a million ints just to return 25. :)

So let's build us some lazy-evaluation infrastructure. (This code was tested a while back, but i've modified it quite a bit since then; read the idea, not the syntax errors. :))

// Represents something that can give us instances of OutType.
// We can basically treat this class like a list.
interface Source<OutType> {
     public Source<OutType> next();
     public OutType value();

// Represents an operation that turns an InType into an OutType.
// Note, these can be the same type.  We're just flexible like that.
interface Transform<InType, OutType> {
    public OutType appliedTo(InType input);

// Represents an action (as opposed to a function) that can run on
// every element of a sequence.
abstract class Action<InType> {
    abstract void doWith(final InType input);
    public void doWithEach(final Source<InType> input) {
        if (input == null) return;

// A list of Integers.
class Ints implements Source<Integer> {
     final Integer value;
     final Ints tail;
     public Ints(Integer value, Ints rest) {
         this.value = value;
         this.tail = rest;
     public Ints(Source<Integer> input) {
         this.value = input.value();
         this.tail = new Ints(input.next());
     public Source<Integer> next() { return this.tail; }
     public Integer value() { return this.value; }
     public static Ints fromArray(Integer[] input) {
         return fromArray(input, 0, input.length);
     public static Ints fromArray(Integer[] input, int start, int end) {
         if (end == start || input == null) return null;
         return new Ints(input[start], fromArray(input, start + 1, end));

// An example of the spiff we get by splitting the "iterator" interface
// off.  These ints are effectively generated on the fly, as opposed to
// us having to build a huge list.  This saves huge amounts of memory
// and CPU time, for the rather common case where the whole sequence
// isn't needed.
class Range implements Source<Integer> {
    final int start, end;
    public Range(int start, int end) {
        this.start = start;
        this.end = end;
    public Integer value() { return start; }
    public Source<Integer> next() {
        if (start >= end) return null;
        return new Range(start + 1, end);

// This takes each InType of a sequence and turns it into an OutType.
// This *takes* a Transform, rather than just *implementing* Transform,
// because the transforms applied are likely to be specified inline.
// If we just let people override `value()`, we wouldn't easily know what type
// to return, and returning our own type would lose the transform method.
static class Mapper<InType, OutType> implements Source<OutType> {
    private final Source<InType> input;
    private final Transform<InType, OutType> transform;

    public Mapper(Transform<InType, OutType> transform, Source<InType> input) {
        this.transform = transform;
        this.input = input;

    public Source<OutType> next() {
         return new Mapper<InType, OutType>(transform, input.next());
    public OutType value() {
         return transform.appliedTo(input.value());

// ...

public <T> Source<T> take(int count, Source<T> input) {
    if (count <= 0 || input == null) return null;
    return new Source<T>() {
        public T value() { return input.value(); }
        public Source<T> next() { return take(count - 1, input.next()); }

(Keep in mind that if this were actually viable in Java, code at least somewhat like the above would already be part of the API.)

Now, with an infrastructure in place, it's rather trivial to write code that doesn't need mutable variables and is at least stable for smaller amounts of input.

public Source<Integer> squares_of(Source<Integer> input) {
     final Transform<Integer, Integer> square = new Transform<Integer, Integer>() {
         public Integer appliedTo(final Integer i) { return i * i; }
     return new Mapper<>(square, input);

public void example() {
    final Source<Integer> integers = new Range(0, 1000000000);

    // and, as for the author's "bet you can't do this"...
    final Source<Integer> squares = take(25, squares_of(integers));

    // Just to make sure we got it right :P
    final Action<Integer> printAction = new Action<Integer>() {
        public void doWith(Integer input) { System.out.println(input); }

This mostly works, but it's still somewhat prone to stack overflows. Try takeing 2 billion ints and doing some action on them. :P It will eventually throw an exception, at least until 64+ GB of RAM becomes standard. Problem is, the amount of a program's memory that's reserved for its stack is not that big. It's typically between 1 and 8 MiB. (You can ask for bigger, but it doesn't matter all that much how much you ask for -- you call take(1000000000, someInfiniteSequence), you will get an exception.) Fortunately, with lazy evaluation, the weak spot is in an area we can better control. We just have to be careful about how much we take().

It'll still have lots of problems scaling up, because our stack usage increases linearly. Each call handles one element and passes the rest off to another call. Now that i think about it, though, there is one trick we can pull which might gain us quite a bit more headroom: turn the chain of calls into a tree of calls. Consider something more like this:

public <T> void doSomethingWith(T input) { /* magic happens here */ }
public <T> Source<T> workWith(Source<T> input, int count) {
    if (count < 0 || input == null) return null;
    if (count == 0) return input;
    if (count == 1) {
        return input.next();
    return (workWith(workWith(input, count/2), count - count/2);

workWith basically breaks up the work into two halves, and assigns each half to another call to itself. Since each call reduces the size of the working list by half rather than by one, this should scale logarithmically rather than linearly.

Problem is, this function wants an input -- and with a linked list, getting the length requires traversing the whole list. That's easily solved, though; simply don't care how many entries there are. :) The above code would work with something like Integer.MAX_VALUE as the count, since a null stops the processing anyway. The count is mostly there so we have a solid base case. If you anticipate having more than Integer.MAX_VALUE entries in a list, then you can check workWith's return value -- it should be null at the end. Otherwise, recurse.

Keep in mind, this touches as many elements as you tell it to. It's not lazy; it does its thing immediately. You only want to do it for actions -- that is, thingies whose sole purpose is to apply itself to every element in a list. As i'm thinking it over right now, it seems to me that sequences would be a lot less complicated if kept linear; shouldn't be a problem, since sequences don't call themselves anyway -- they just create objects that call them again.


I've previously tried to create an interpreter for a lisp-like language in Java, ( a few years ago and all the code was lost as it was in CVS at sourceforge ), and the Java util iterators are a bit verbose for functional programming on lists.

Here's something based on a sequence interface, which just has the two operations you need to get the current value and get the sequence starting at the next element. These are named head and tail after the functions in scheme.

It's important to use something like the Seq or Iterator interfaces as it means the list is created lazily. The Iterator interface can't be an immutable object, so is less suited to functional programming - if you can't tell if the value you pass into a function has been changed by it, you lose one of the key advantages of functional programming.

Obviously integers should be a list of all the integers, so I started at zero and alternately returned positive and negative ones.

There's two version of squares - one creating a custom sequence, the other using map which takes a 'function' - Java 7 doesn't have lambdas so I used an interface - and applies it to each element in the sequence in turn.

The point of the square ( int x ) function is only to remove the need to call head() twice - normally I would have done this by putting the value into a final variable, but adding this function means there are no variables in the program, only function parameters.

The verbosity of Java for this sort of programming led me to write the second version of my interpreter in C99 instead.

public class Squares {
    interface Seq<T> {
        T head();
        Seq<T> tail();

    public static void main (String...args) {
        print ( take (25, integers ) );
        print ( take (25, squaresOf ( integers ) ) );
        print ( take (25, squaresOfUsingMap ( integers ) ) );

    static Seq<Integer> CreateIntSeq ( final int n) {
        return new Seq<Integer> () {
            public Integer head () {
                return n;
            public Seq<Integer> tail () {
                return n > 0 ? CreateIntSeq ( -n ) : CreateIntSeq ( 1 - n );

    public static final Seq<Integer> integers = CreateIntSeq(0);

    public static Seq<Integer> squaresOf ( final Seq<Integer> source ) {
        return new Seq<Integer> () {
            public Integer head () {
                return square ( source.head() );
            public Seq<Integer> tail () {
                return squaresOf ( source.tail() );

    // mapping a function over a list rather than implementing squaring of each element
    interface Fun<T> {
        T apply ( T value );

    public static Seq<Integer> squaresOfUsingMap ( final Seq<Integer> source ) {
        return map ( new Fun<Integer> () {
            public Integer apply ( final Integer value ) {
                return square ( value );
        }, source );

    public static <T> Seq<T> map ( final Fun<T> fun, final Seq<T> source ) {
        return new Seq<T> () {
            public T head () {
                return fun.apply ( source.head() );
            public Seq<T> tail () {
                return map ( fun, source.tail() );

    public static Seq<Integer> take ( final int count,  final Seq<Integer> source ) {
        return new Seq<Integer> () {
            public Integer head () {
                return source.head();
            public Seq<Integer> tail () {
                return count > 0 ? take ( count - 1, source.tail() ) : nil;

    public static int square ( final int x ) {
        return x * x;

    public static final Seq<Integer> nil = new Seq<Integer> () {
        public Integer head () {
            throw new RuntimeException();
        public Seq<Integer> tail () {
            return this;

    public static <T> void print ( final Seq<T> seq ) {
        printPartSeq ( "[", seq.head(), seq.tail() );

    private static <T> void printPartSeq ( final String prefix, final T value, final Seq<T> seq ) {
        if ( seq == nil) {
        } else {
            printPartSeq ( ",", seq.head(), seq.tail() );

How to write useful Java programs without using mutable variables.

You can in theory implement just about anything in Java using just recursion and no mutable variables.

In practice:

  • The Java language is not designed for this. Many constructs are designed for mutation, and are hard to use without it. (For instance, you can't initialize a variable length Java array without mutation.)

  • Ditto for the libraries. And if you limit yourself to library classes that don't use mutation under the cover, it is even harder. (You can't even use String ... take a look at how hashcode is implemented.)

  • Mainstream Java implementations don't support tail-call optimization. That means that recursive versions of algorithms tend to be stack space "hungry". And since Java thread stacks don't grow, you need to preallocate big stacks ... or risk StackOverflowError.

Combine these three things, and Java is not really a viable option for writing useful (i.e. non-trivial) programs without mutable variables.

(But hey, that's OK. There are other programming languages available for the JVM, some of which do support functional programming.)


As we're looking for an example of the concepts, I'd say let's set aside Java and look for a different yet familiar setting in which to find a familiar version of the concepts. UNIX pipes are rather similar to chaining lazy functions.

cat /dev/zero | tr '\0' '\n' | cat -n | awk '{ print $0 * $0 }' | head 25

In Linux this means, give me bytes each of which is composed of false rather than true bits, until I lose my appetite; change each of those bytes to a newline character; number each line thus created; and produce the square of that number. Furthermore I have appetite for 25 lines and no more.

I claim that a programmer wouldn't be ill advised to write a Linux pipeline in that manner. It's relatively normal Linux shell scripting.

I claim that a programmer would be ill advised to attempt writing the same thing similarly in Java. The reason is software maintenance as a major factor in the lifetime cost of software projects. We don't want to befuddle the next programmer by presenting what is ostensibly a Java program but actually is written in effect in a custom one-off language by elaborately duplicating functionality that already exists in the Java platform.

On the other hand, I claim that the next programmer could be more accepting if some of our "Java" packages are actually Java Virtual Machine packages written in one of the functional or object/functional languages such as Clojure and Scala. These are designed to be coded by chaining functions together and to be called from Java in the normal manner of Java method calls.

Then again, it can still be a good idea for a Java programmer to take inspiration from functional programming, in places.

Recently my favorite technique [was] to use an immutable, uninitialized return variable and a single exit so that, as some functional language compilers do, Java checks that no matter what happens in the body of the function, I always provide one and only one return value. Example:

int f(final int n) {
    final int result; // not initialized here!
    if (n < 0) {
        result = -n;
    } else if (n < 1) {
        result = 0;
    } else {
        result = n - 1;
    // If I would leave off the "else" clause,
    // Java would fail to compile complaining that
    // "result" is possibly uninitialized.
    return result;

  • I'm about 70% certain Java already does the return value check anyway. You should get an error about a "missing return statement" if control can fall off the end of a non-void function. – cHao Feb 20 '13 at 1:39
  • My point: If you code it as int result = -n; if (n < 1) { result = 0 } return result; it compiles just fine and the compiler has no idea whether or not you intended to make it equivalent to the function in my example. Maybe that example is too simple to make the technique look helpful, but in a function with lots of branches I feel it's nice to make clear that the result is assigned exactly once regardless what path is followed. – minopret Feb 20 '13 at 2:43
  • If you say if (n < 1) return 0; else return -n;, though, you end up with no problem...and it's simpler besides. :) Seems to me that in that case, the "one return" rule actually helps cause the issue of not knowing when your return value was set; otherwise, you could just return it and Java would be more able to determine when other paths might not return a value, cause you're no longer divorcing the calculation of the value from the actual returning of it. – cHao Feb 20 '13 at 3:56
  • Or, for your answer's example, if (n < 0) return -n; else if (n == 0) return 0; else return n - 1;. – cHao Feb 20 '13 at 4:04
  • I just decided I don't want to spend any more moments of my life defending the OnlyOneReturn rule in Java. Out it goes. When and if I think of a Java coding practice that I feel like defending that's influenced by functional programming practices, I'll put in a replacement for that example. Until then, no example. – minopret Feb 20 '13 at 4:04

The easiest way to find that out would be feed the following to the Frege compiler, and look at the generated java code:

module Main where

result = take 25 (map sqr [1..]) where sqr x = x*x
  • After a few days I found my thoughts returning to this answer. After all part of my suggestion was to implement the functional programming parts in Scala. If we consider applying Scala in those spots where we really had Haskell in mind (and I think I'm not the only one blog.zlemma.com/2013/02/20/…), shouldn't we at least consider Frege? – minopret Feb 21 '13 at 15:08
  • @minopret This is indeed the niche Frege is trageting - people that have come to know and love Haskell and yet need the JVM. I am confident one day Frege will be mature enough to get a serious consideration at least. – Ingo Feb 21 '13 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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