哪种编程语言支持语言级别的状态?

时间:2009-06-04 13:14:22

标签: programming-languages state-machine unrealscript

UnrealScript总是给我留下深刻的印象,它通过将函数和字段分组/重载到以下块来对状态(和潜在函数)进行内在支持:

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

这比在每个函数中使用大量switch-statements(它几乎是某种design by contract)要清晰得多。

还有其他更通用的编程语言本质上支持与此类似的状态声明(忽略可视化编程语言或Workflow Foundation等工具)吗?

编辑:

UnrealScript中的一些状态之美是你可以在子类中覆盖有状态函数,甚至可以定义新的命名状态。我认为这对于enum-switch(枚举不能扩展),委托或实现不同状态的共同类很麻烦,特别是在只支持单继承的C#或Java等语言中。

10 个答案:

答案 0 :(得分:3)

我所知道的,但支持通过元编程(例如Ruby)轻松编写特定领域语言的语言基本上可以假装。来自Rails的acts_as_state_machine插件:

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

(您还可以在event块中包含任意代码,而不仅仅是状态转换)

答案 1 :(得分:3)

任何面向对象的编程语言都可以让您轻松创建状态机。但你可能想看看QT,它是http://labs.trolltech.com/blogs/2009/01/30/qt-state-machine-framework/。我没试过。

我优先选择语言,使我能够创建各种支持结构的语言,为我提供适用于各种特殊情况的特殊功能。 QT中显示的C ++就是一个很好的例子。

答案 2 :(得分:2)

没有真正使用过UnrealScript,但你可以在任何支持一流函数/ lambda的语言中实现同样的目标吗?

答案 3 :(得分:2)

python中的boduch库可以声明状态......但这不是内在的

答案 4 :(得分:2)

我所知道的没有编程语言提供相同的功能,在UnrealScript中有“状态”。 UnrealScript中的状态与普通状态机不同。它们更像是可以放置在对象上的图层。拦截方法调用并可以访问对象内部状态的图层。

从UnrealEngine3开始,您还可以堆叠状态,因此具有多个活动层。 例如:

function bar()
{ 
    // print quux
}

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


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


    function bar()
    { 
        // print bar
    }
}

现在当你进入状态S2并调用foo()和bar()时,你会看到“bar bar” 当你进入状态S1(从开始状态或S2)并调用相同的方法时,你会看到“foo quux”。 但是,当您在S2中并在状态堆栈上按S1时,当您调用foo()bar()而不是“foo quux”时,您将看到“foo bar”。

无论如何,你回到最初的问题。获得与UnrealScript相同的状态功能的一种方法是采用AOP语言,该语言提供动态的方法来在运行时启用/禁用方面。

答案 5 :(得分:1)

我所知道的对状态和状态机具有内在支持的语言通常分为两类: Lexers 专家系统

Lexers 通常面向文本处理,但通常可以适应其他用途。词典的示例包括(f)lexAntlrQuex。我听说过使用lex进行机器人控制的人的故事。

专家系统旨在根据一组规则和您提供的情况做出决策(应该像专家一样)。实现自己的状态处理语言的专家系统的示例是makeClips。 make旨在帮助构建软件,因此如果您的世界视图可以基于文件日期,那么它最有效。剪辑更加灵活,但并不像make那样天生就能很好地了解外部操作系统。

答案 6 :(得分:1)

答案 7 :(得分:1)

Lua还支持有州的课程,前提是你愿意在Lua的桌子上编程。

或者,您使用我的库:MindState。我设计它是为了模仿UnrealScript的类系统,并尽可能地说明,从常规类继承到可堆叠状态。

答案 8 :(得分:1)

我一直想知道如何在C#中做到这一点,尤其是因为我使用UnrealEngine 3作为设计我自己的组件 - 对象模型的基础。 (顺便说一句,UDK是一种很好的原型功能。)除了使用像egarcia这样的外部方法(事实上,它可以通过LuaInterface在.NET中使用),我提出了两种可能性:

  1. 显式接口实现,每个状态都有一个接口。然后,您将对象转换为相应的接口(即“状态”)并调用该方法; CLR完成其余的工作。您甚至可以使用泛型方法包装此调用,并将接口(“state”)作为类型参数传递,但这可能是过度的。

  2. 创建一个由状态键入的字典,并将委托作为值。提供更大的灵活性,代价是看起来很糟糕。

  3. 就个人而言,我从编码的角度来看更喜欢方法1,因为我只关注强类型,但方法二更容易实现和更新。

    另外,如果你对egarcia的Lua方法感兴趣并且认为LuaInterface对你来说太慢了,我已经修改了LuaInterface以支持LuaJIT。它使用本机导入,但希望LuaJIT的性能将抵消调度调用。如果你想要消息来源,请给我留言。

答案 9 :(得分:1)

我天真的理解是'type state'为面向对象的语言提供了这种功能:

What is typestate?

可以用任何支持特征的语言轻松实现:

Mixins vs. Traits

我仍然在学习所有这些,所以我很乐意听到更有见识的答案。