views:

282

answers:

9

UnrealScript has always impressed me, somewhat, with it its intrinsic support for states (and latent functions) by grouping/overloading functions and fields into blocks like:

state() SomeState
{
    ...
    function void Foo()
    {
        GotoState('SomeOtherState');
    }
    ...
}

Which is quite a bit cleaner than using loads of switch-statements inside every function (it's almost some sort of design by contract).

Are there any other more general-purpose programming languages that intrinsically support state declarations similar to this (ignoring visual programming languages or tools like Workflow Foundation)?

Edit:

Some of the beauty of states in UnrealScript is that you can override stateful functions in subclasses, and even define new, named states. I think this is troublesome to do with enum-switches (where enums cannot be extended), delegates, or co-classes implementing different states, especially in languages like C# or Java that only support single-inheritance.

+1  A: 

Not really used UnrealScript, but you could surely achieve the same thing in any language that supports first-class functions / lambda?

Aiden Bell
+2  A: 

None that I know of, but language that support easy writing of domain-specific languages through metaprogramming (e.g., Ruby), can essentially pretend to. From the acts_as_state_machine plugin for Rails:

class Nonprofit < ActiveRecord::Base
  acts_as_state_machine :initial => :created, :column => 'status'

  # These are all of the states for the existing system.
  state :submitted
  state :processing
  state :nonprofit_reviewing
  state :accepted

  event :accept do
    transitions :from => :processing,          :to => :accepted
    transitions :from => :nonprofit_reviewing, :to => :accepted
  end

  event :receive do
    transitions :from => :submitted, :to => :processing
  end

  # either a CTP  or nonprofit user edits the entry, requiring a review
  event :send_for_review do
    transitions :from => :processing,          :to => :nonprofit_reviewing
    transitions :from => :nonprofit_reviewing, :to => :processing
    transitions :from => :accepted,            :to => :nonprofit_reviewing
  end
end

(you can also include any arbitrary code in the event blocks, not just state transitions)

Stephen Touset
+1  A: 

there's the boduch library in python which enables to declare states...but this is not intrinsic

LB
The boduch library looks quite cool.
Aiden Bell
i haven't used it yet but it seems quite promising but in its early stages
LB
+2  A: 

Any object oriented programming language enables you to create state-machines easily. But you might want to take a look at QT and it's http://labs.trolltech.com/blogs/2009/01/30/qt-state-machine-framework/. I haven't tried it though.

I prefere languages that enable me to create a variety of supporting structures of my choice to languages that offer me special functionality for all different kinds of special situations. C++ as shown in QT is a good example for that.

Tobias Langner
+1  A: 

There is no programming language that I know about that provides the same functionality has "states" in UnrealScript. States in UnrealScript are not like ordinary state machines. They are more like layers you can place on top of objects. Layers that intercept method calls and have access to the internal state of the object.

Starting from UnrealEngine3 you can also stack states, thus have more than one active layer. For example:

function bar()
{ 
    // print quux
}

state S1
{
    function foo()
    { 
        // print foo
    }
}


state S2
{
    function foo()
    { 
        // print bar
    }


    function bar()
    { 
        // print bar
    }
}

Now when you go to state S2 and call foo() and bar() you will see "bar bar" When you go to state S1 (from either the start state or S2) and call the same methods you will see "foo quux". However, when you are in S2 and push S1 on the state stack, you will see "foo bar" when you call foo() bar() instead of "foo quux".

Anyway, yo go back to the original question. One way to get the same state functionality as provided in UnrealScript is by adopting an AOP language that provides dynamic a way to enable/disable aspects at runtime.

elmuerte
A: 

The languages I know of with intrinsic support for state and state machines generally fall into two classes: Lexers and Expert Systems.

Lexers are generally oriented towards text processing, but can often be adapted to other uses. Examples of Lexers are (f)lex, Antlr, Quex. I've heard tales of people using lex for robot control.

Expert Systems are designed to make decisions (supposedly like an expert) based of a set of rules and the situation you present them with. Examples of expert systems that implement their own state-processing languages are make and Clips. make is designed to help build software, so it works best if your view of the world can be based off of file dates. Clips is a lot more flexible, but doesn't innately have a very good view of the external OS like make does.

T.E.D.
A: 

The Pawn language does: http://en.wikipedia.org/wiki/Pawn_%28programming_language%29

Drealmer
A: 

Lua also supports classes with state, providing that you are willing to program on top of Lua's tables.

Or, you use my library: MindState. I've designed it so it mimics UnrealScript's class system and states as much as I could, from regular classes inheritance to stackable states.

egarcia
A: 

I've been wondering how to do this in C# as well, not least because I'm using UnrealEngine 3 as a basis for designing my own component-object model. (Incidentally, UDK is a great way to prototype features.) Aside from using an external approach like egarcia has implemented (which can, in fact, be used in .NET via LuaInterface), I've come up with two possibilities:

  1. Explicit interface implementations, with an interface for each state. You then cast the object to the corresponding interface (i.e., "state") and call the method; CLR does the rest. You could even wrap this call with a generic method and pass the interface ("state") as the type parameter, but this may be overkill.

  2. Create a dictionary keyed by state with delegates as the values. Offers greater flexibility at the cost of looking kind of hack-ish.

Personally, I prefer method 1 from a coding standpoint because I'm all about strong types, but method two is easier to implement and update.

On a side note, if you're interested in egarcia's Lua approach and think LuaInterface is too slow for you, I've modified LuaInterface to support LuaJIT. It uses native imports, but hopefully the performance of LuaJIT will offset the dispatch call. Drop me a line if you'd like the source.

Tom