4

I've been reading Out of the Tar Pit by Ben Moseley and Peter Marks and in section 5.2.3 they discuss state in functional languages compared to procedural languages. The procedural example is as follows:

procedure int getNextCounter()
 // 'counter' is declared and initialized elsewhere in the code
 counter := counter + 1
 return counter

I can see there is internal state so this is fine. The functional example however is as follows:

function (int,int) getNextCounter(int oldCounter)
 let int result = oldCounter + 1
 let int newCounter = oldCounter + 1
 return (newCounter, result)

I can understand that you avoid internal state by passing in oldCounter, but why the two equal outputs?

Is this just to pass out the state and the result and both being equal is simply due to an overly simplistic example?

Isn't returning several values considered not that good of an idea?

Am I just not well versed enough in functional programming?

Robert Harvey
201k55 gold badges469 silver badges682 bronze badges
asked Apr 4, 2018 at 12:25
2
  • 2
    Should let in newCounter be let in*t* newCounter? Commented Apr 4, 2018 at 12:56
  • 1
    It is because the state happens to equal the last value. The state is usually a completely different type. Commented Apr 4, 2018 at 13:11

2 Answers 2

8

The code example provided by that author is meant to illustrate that, instead of maintaining a global counter variable outside of the function, you can simply pass a local copy of the counter from function invocation to function invocation as an extra parameter.

It further attempts to illustrate (perhaps poorly) that the result value of the function operates independently of the counter variable.

Of course, you don't really need all of those extra steps:

function int getNextCounter(int oldCounter)
 return oldCounter + 1

The let statements are probably there to illustrate the creation of a new counter object, rather than the modification of an existing one. In most programming languages this is simply redundant, as function arguments passed by value (typical of primitives like int) are already locally copied anyway.

So yes, the code example provided in the paper is a bit too simplistic to adequately capture all of the code features the author is trying to describe.

A better example would have more clearly illustrated the distinction between the result value and the counter object:

procedure int getNextCounterDoubled()
 // 'counter' is declared and initialized elsewhere in the code
 counter := counter + 1
 let int result = counter * 2
 return result
function (int, int) getNextCounterDoubled(int oldCounter)
 let int newCounter = oldCounter + 1
 let int result = newCounter * 2
 return (newCounter, result)
answered Apr 4, 2018 at 15:27
0

I would say your assertion about both being same due to simplistic example is true. The sequence of function is often different from it's internal state.

Another reason might be that there might be higher-order function, that accepts a "seed" value and function of same signature as functional getNextCounter and then it generates a sequence of second items in the tuple.

answered Apr 4, 2018 at 13:02

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.