0

I have a stream parsing method in C# that reads portions of a protocol frame from the STOMP protocol; the specification isn't the important part for the question though. What is important is that I have written the code in an imperative style, since that is what I know.

Can anyone give some examples of processing in a functional manner? (Psuedo-code, or any language will constitute an acceptable answer)

/// <summary>
/// Reads a STOMP command string asynchronyously.
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns>CommandString if read; otherwise null</returns>
public async Task<string> ReadStompCommand(CancellationToken cancellationToken)
{
    string commandString = null;

    //Create a new buffer, maximum possible allowed bytes in the line is 13
    var commandBuffer = new byte[13]; 

    //EOL is the line ending as defined in the spec of STOMP 1.2
    //EOL can either be CRLF or LF alone
    var eolIndex = -1;
    var bytesRead = 0;

    //while we haven't maxed out our buffer and we haven't found an EOL sequence
    while (bytesRead < commandBuffer.Length && eolIndex == -1)
    {
        //move forward in the buffer
        var offset = bytesRead;

        //Reading 1 byte at a time for now, may change in a future implementation
        const int length = 1;
        var bytesFound = 0;

        bytesFound += await Stream.ReadAsync(commandBuffer, offset, length, cancellationToken);

        //check for EOL in the bytes we read. (1 iteration since length is const of 1)
        for (var i = offset; i < offset + bytesFound; i++)
        {
            if (commandBuffer[i] == 0x0a)
                eolIndex = i;
        }

        bytesRead += bytesFound;
    }

    //if we have a potentially meaningful line (STOMPs shortest command is 3 characters)
    if (eolIndex > 2)
    {
        //If last byte before LF was CR, move the EOL start index back one
        if (commandBuffer[eolIndex - 1] == 0x0d)
        {
            eolIndex--;
        }

        //Convert bytes to string in UTF-8 from beginning to start of EOL
        commandString = Encoding.UTF8.GetString(commandBuffer, 0, eolIndex);
    }

    return commandString;
}
2
  • 2
    This kind of request is off-topic; there's no correct answer and as far as I know C# doesn't have functional data structures out of the box. But I'll give you some hints: 1) replace loops with recursion or higher-order functions like Select or Aggregate which return a value, 2) any time you would mutate something, return a modified copy of it instead. – Doval Jun 28 '16 at 19:18
  • Thanks Doval, not sure how I could frame this to make it more on topic. The root of the question is how do you deal with a mutable buffer in a functional space. Creating new arrays every time or reading a single byte at a time are both performance no-nos. – Ovan Crone Jun 28 '16 at 20:00
2

I have a stream parsing method in C# that reads portions of a protocol frame from the STOMP protocol... Can anyone give some examples of processing in a functional manner?

You're thinking about this at the wrong level.

The interesting question is not "how would I implement this low-level byte-buffer code in a functional style?" The private implementation details of the method are just that -- private implementation details. There is no benefit to the user of the method of your writing the method's implementation in a functional style.

The interesting question is: how can I make the method as a whole more amenable to users of the method who wish to program in a functional style?

Because your method here is really not functional. It takes no arguments (of any interest; plainly the value of the cancellation token does not influence the output), and it returns a deferred string that will potentially be different every time it is fetched. Or, more accurately, it returns a deferred string that will get passed to a callback when it is available.

What then is the more functional way to structure this code? We wish to think of the entire sequence of strings that will be pushed into callbacks going into the future as a single object. Just the same way that we think of an on-demand sequence of elements -- IEnumerable<T> -- as being a single object that can provide arbitrarily many objects in the future.

In short, the more functional way to structure this code is by creating an object that is an observable collection of strings. The thing you want to research here is functional reactive programming.

That should be enough to get you started down this particular rabbit hole.

Bonus: once you have a basic understanding of FRP, try wrapping your head around the IO monad in Haskell if you really want to see how to structure these sorts of operations in a purely functional style.

1
  • Thanks @Eric I really appreciate the insight and guidance! I'd mark both answers as Accepted if I could! – Ovan Crone Jun 30 '16 at 4:51
2

For your specific piece of code, it's very low level, reading bytes from an input and writing them to an output. In C#, this code is not going to be functional.

But you can add a wrapper so that you can pass a fake "state of the world" to your non-functional methods and make them return the "altered" state of the world along with your result.

The signature is:

class World {}
class WorldAndResult<T> {
    World world;
    T t; // this is your normal result
    WorldAndResult(World w, T theT) { world = w; t = theT; }
}

public WorldAndResult<Int> mutator(World w, otherArgs...) {
    int ret = wrappedMutator(otherArgs...);
    return new WorldAndResult(w, ret);
}

Now you can chain these calls together and pretend they are functional and that they mutate the "World". It's a dummy object that stands in for whatever side effects your method has.

final WorldAndResult<Integer> war = mutator(new World(), 37);
final WorldAndResult<Integer> war2 = mutator(war.world, 54);

Computer hardware is imperative. It mutates in place. It has side effects: hardware interrupts, writing to disk, changing the display buffer, reading and writing from the network card...

Every functional language, every functional tool-kit, wraps all the imperative stuff in a minimum-side-effect wrapper that prevents non-essential mutating in place. When necessary for performance reasons, it does mutate in place, but it hides that mutation from the programmer.

Functional programming is efficient in the large, even if it can be inefficient for some details. Simplifying your code frees your brain up to make more efficient design choices that you would when you concentrate on bit twiddling and looping. So I always start functional. It is very rare that I have to take a second pass to speed something up. Unless, of course, I'm writing infrastructure to use in functional programming. :-)

3
  • I'm pretty sure this doesn't answer the question, which was about writing a given piece of code using functional approaches, rather than barely using the piece of code as-is in a functional language. – Arseni Mourzenko Jun 28 '16 at 21:46
  • 1
    @MainMa to do things efficiently for something like this, using the piece of code functionally seems like the ideal answer. For practical purposes, who cares what's on the inside if it behaves functionally on the outside? If you want some kind of academic purity, then there may not be an efficient solution. – GlenPeterson Jun 28 '16 at 22:33
  • 2
    I think this answer is very useful in that it shows a way to go forward from the commanding world to the functional world. The number one method for dealing with mutable data is to hide the mutability. – BobDalgleish Jun 28 '16 at 22:33

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.