Какие языки программирования поддерживают состояния на уровне языка? - PullRequest
4 голосов
/ 04 июня 2009

UnrealScript всегда меня несколько поражал своей внутренней поддержкой состояний (и скрытых функций) путем группировки / перегрузки функций и полей в блоки типа:

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

Что немного чище, чем использование множества операторов switch внутри каждой функции (это почти своего рода дизайн по контракту ).

Существуют ли другие языки программирования более общего назначения, которые по своей природе поддерживают объявления состояний, подобные этим (игнорируя языки визуального программирования или такие инструменты, как Workflow Foundation)?

Edit:

Часть красоты состояний в UnrealScript заключается в том, что вы можете переопределять функции с состоянием в подклассах и даже определять новые именованные состояния. Я думаю, что это сложно сделать с переключателями перечисления (где перечисления не могут быть расширены), делегатами или совместно используемыми классами, реализующими различные состояния, особенно в таких языках, как C # или Java, которые поддерживают только одиночное наследование.

Ответы [ 10 ]

3 голосов
/ 04 июня 2009

Любой объектно-ориентированный язык программирования позволяет легко создавать автоматы. Но, возможно, вы захотите взглянуть на QT, и он http://labs.trolltech.com/blogs/2009/01/30/qt-state-machine-framework/. Я еще не пробовал.

Я предпочитаю языки, которые позволяют мне создавать различные вспомогательные структуры по своему выбору, а не языки, которые предлагают мне специальные функциональные возможности для всех видов особых ситуаций. C ++, как показано в QT, является хорошим примером для этого.

3 голосов
/ 04 июня 2009

Мне ничего не известно, но язык, который поддерживает простое написание предметно-ориентированных языков посредством метапрограммирования (например, Ruby), может по существу претендовать на это. Из плагина acts_as_state_machine для 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

(вы также можете включить любой произвольный код в блоки event, а не только переходы состояний)

2 голосов
/ 05 июня 2009

Я не знаю ни одного языка программирования, обеспечивающего такую ​​же функциональность, как "состояния" в 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 () bar () вместо «foo quux».

В любом случае, вернитесь к первоначальному вопросу. Один из способов получить те же функциональные возможности состояния, которые предусмотрены в UnrealScript, - это использование языка AOP, который обеспечивает динамический способ включения / отключения аспектов во время выполнения.

2 голосов
/ 04 июня 2009

в python есть библиотека boduch , которая позволяет объявлять состояния ... но это не присуще

2 голосов
/ 04 июня 2009

В действительности не использовался UnrealScript, но вы наверняка могли бы добиться того же в любом языке, который поддерживает первоклассные функции / лямбда?

1 голос
/ 17 сентября 2011

Я наивно понимаю, что «состояние типа» предоставляет такую ​​функциональность для объектно-ориентированных языков:

Что такое типовое состояние?

и может быть легко реализовано на любом языке, который поддерживает черты:

Mixins vs. Traits

Тем не менее, я все еще изучаю все это, поэтому я хотел бы услышать более осведомленный ответ.

1 голос
/ 16 июля 2010

Мне было интересно, как это сделать и в C #, не в последнюю очередь потому, что я использую UnrealEngine 3 в качестве основы для разработки собственной модели компонент-объект. (Между прочим, UDK является отличным способом для создания прототипов функций.) Помимо использования внешнего подхода, подобного реализованному egarcia (который на самом деле может использоваться в .NET через LuaInterface), я предложил две возможности: *

  1. Явные реализации интерфейса с интерфейсом для каждого состояния. Затем вы приводите объект к соответствующему интерфейсу (т. Е. «Состояние») и вызываете метод; CLR делает все остальное. Вы могли бы даже обернуть этот вызов универсальным методом и передать интерфейс («состояние») в качестве параметра типа, но это может быть излишним.

  2. Создать словарь с указанием состояния с делегатами в качестве значений. Обеспечивает большую гибкость за счет того, что выглядишь как взломщик.

Лично я предпочитаю метод 1 с точки зрения кодирования, потому что я все о сильных типах, но метод два легче реализовать и обновить.

Кстати, если вам интересен подход Lua от egarcia и вы считаете, что LuaInterface слишком медленный для вас, я изменил LuaInterface для поддержки LuaJIT. Он использует собственный импорт, но, надеюсь, производительность LuaJIT компенсирует вызов отправки. Напишите мне, если вам нужен источник.

1 голос
/ 14 июля 2010

Lua также поддерживает классы с состоянием, при условии, что вы готовы программировать поверх таблиц Lua.

Или вы используете мою библиотеку: MindState . Я разработал его так, чтобы он имитировал систему классов UnrealScript и как можно больше состояний, от обычного наследования классов до стекируемых состояний.

1 голос
/ 29 марта 2010
1 голос
/ 05 июня 2009

Языки, которые я знаю с внутренней поддержкой машин состояний и состояний, обычно делятся на два класса: Lexers и Expert Systems .

Лексеры обычно ориентированы на обработку текста, но часто могут быть адаптированы для других целей. Примерами лексеров являются (f) lex , Antlr , Quex . Я слышал рассказы о людях, использующих lex для управления роботом.

Экспертные системы предназначены для принятия решений (предположительно в качестве эксперта) на основе набора правил и ситуации, с которой вы их представляете. Примерами экспертных систем, которые реализуют свои собственные языки обработки состояний, являются make и Clips . make предназначен для помощи в создании программного обеспечения, поэтому он работает лучше всего, если ваше представление о мире может основываться на датах файлов. Клипы гораздо более гибкие, но, по сути, не очень хорошо видят внешнюю ОС, как make.

...