Thursday, November 18, 2010

Language Ideas Part 2

State. It's not something that is particularly liked in functional programming languages as it can lead to bugs. But what are the real issues with state? To me, the real issue is state across different scopes, such as global variables. So, I did some thinking and I felt that having no mutable variables at all was too restrictive. The question was, what is the right amount of mutability?

The D Programming Language has the concept of pure functions where they cannot access anything outside of the scope of the function. However, you can modify variables inside of the function, such as a loop counter. This is a concept that I liked a lot as it allows for mutable state, but in such a way that's much safer than normal. So, I tried to incorporate something like this in SPL.

This brings us to the concept of factories in SPL. Factories are similar to classes in that they contain methods that can be executed. However, they are vastly different. First, there are two types: pure and stateful. A pure factory will always return the same result for the exact same input as there is no state stored within the factory. Essentially, it's a class with only methods and no member variables. A stateful, on the other hand, does not have that guarantee. However, the state associated with the factory is contained solely in the factory, thus preventing direct outside modification. Think of it as a class where all member variables are private.

Why is state allowed here? Simply put, there are many different algorithms that are made much simpler if state is allowed. For example, if I have a factory that implements a queue, instead of passing the entire queue from function call to function call, I can keep it within the factory and modify as needed. The key is that the mutable data is only accessible to functions within the factory and from nowhere else. This prevents any accidental modification of the data as you would have to explicitly call a method within the factory to modify the data.

This brings up the next key differences between factories and classes: message passing. The design of the language was to allow a simple interface for communicating with a factory that not only isolated the design of the factory from the code, but also could allow for performance optimizations through threading. To hit on the latter point quickly, it was envisioned that an implementation of SPL could implicitly have factories be different threads, much like Erlang processes. This can allow for asynchronous messages to be executed by the factory without the main program stopping. Think of a good logger.

Why does this make communication simpler? The main reason is loose coupling between the code sending the message and the code executing the message. My vision was that each factory would have a dispatcher that would examine a message and call the correct method. The beauty of this is that if I decide to replace one method with another, the calling code does not have to change. I can create the new method, perhaps put a new entry in the dispatcher for testing, and when it's ready, simply change the entry in the dispatcher to point to the new method. Granted, not every case is safe from changes to the caller, however the more we can make it simpler to update a factory safely, the better.

Another reason for message passing is the concept of fail-fast error handling. Erlang is designed like this and I wanted to have that concept in this as well as it's a simple and proven method to make reliable software. In short, if there is a failure in a factory, stop execution of the factory, generate error information, and send that back to the caller. The caller is then responsible for what to do if an error occurs.

In the end, I felt that this was a very reasonable language construct. It allowed for good encapsulation without being overly complex. Aspects of the system can be redesigned with minimal impact on the code using it.


Labels: ,


Post a Comment

Links to this post:

Create a Link

<< Home