Мне нужно создать DSL для непрограммистов (клиентов нашей компании), который должен обеспечивать некоторые языковые функции более высокого уровня (циклы, условные выражения, переменные ... - так что это не просто «простой» DSL).
Работать с DSL должно быть легко; люди должны иметь возможность экспериментировать с этим и изучать это, играя. Мы хотим добиться чего-то похожего на макросы в Microsoft Excel - многие пользователи Excel могут создавать простые формулы, суммы или вычисления и никогда не работали с «настоящим» (универсальным) языком программирования.
Очевидно, что не каждый пользователь Excel понимает более сложные встроенные методы (например, When ()), но они могут использовать простые методы, такие как SUM () или AVG (). Я хочу добиться аналогичного эффекта с DSL - пользователи должны иметь возможность интуитивно работать с ним и определять простые правила или выполнять простые вычисления. В то же время DSL должен предлагать функции более высокого уровня для более технически подкованных - например, циклы, операторы if, возможно, методы или лямбда-выражения.
И это подводит меня к моему (-ым) вопросу (-ам): Какие языковые конструкции интуитивно понятны, просты в изучении и понимании?
В текущей экспериментальной версии DSL мы опробовали метод цепочки методов, например: list.where(item -> item.value > 5).select(item -> item.name + " " + item.value)
). Думайте о where
и select
как о конструкциях foreach
, где item
- это переменная, представляющая текущий элемент в цикле.
Причина, по которой мы сначала попробовали этот подход, заключается в том, что было бы легко поддерживать завершение кода - всякий раз, когда пользователь вводит точку (.
), показывать список возможных методов. Однако я не уверен, что эта концепция соответствует моим критериям интуитивности и простоты понимания и чтения.
Легче / читабельнее для пользователей, если нет фигурных скобок? (как в LINQ: from item in list where item.value > 5 select item.name + " " + item.value
). Однако в этом случае нет «границ» - в предыдущем примере пользователь знает, что оператор заканчивается последней закрывающей фигурной скобкой - в этом случае, если он наберет больше кода после select
части оператора, он не сделает этого. знать, принадлежит ли он оператору или нет (кроме того факта, что синтаксический анализатор тоже не знал бы, и должно было быть какое-то закрытие).
Я надеюсь, что с этими двумя примерами мой вопрос станет немного яснее - я ищу рекомендации по дизайну, передовой опыт, реальный опыт, возможно, исследовательские материалы, из которых язык конструирует благоприятны для других - или некоторая оценка плюсов и минусов определенных языковых конструкций.
Я не ищу информации о том, как создать DSL, какие генераторы парсеров я мог бы использовать и т. д., а также я не могу использовать существующий язык общего назначения (Ruby, Python, ... ) вместо этого из-за способа использования DSL. (DSL при синтаксическом анализе работает напрямую с нашей объектной моделью - я не буду здесь вдаваться в подробности, поскольку этот вопрос и так уже достаточно длинный).
Изменить: Возможно, мне следует указать, что под "языковыми конструкциями" я подразумеваю синтаксис, способ написания чего-либо, а не то, какую функциональность должен предлагать язык - у нас уже есть список возможностей DSL. должен предоставить. Вопрос в том, как лучше всего выразить эти функции, чтобы можно было создавать (и поддерживать) простые и сложные формулы.