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?

  • 2
    Should let in newCounter be let in*t* newCounter? – Josh Caswell Apr 4 '18 at 12:56
  • 1
    It is because the state happens to equal the last value. The state is usually a completely different type. – Florian F Apr 4 '18 at 13:11
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)
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.

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.