Есть несколько вопросов (вернее опросов) про dsl д...
# russian
s
Есть несколько вопросов (вернее опросов) про dsl для ui (react, anko, tornadofx и т.д.). Задаю их т.к. прямо сейчас нужно начинать большой проект с кучей ui кода, и при использовании подхода dsl в указанных выше либах есть сложности. Есть штука с альтернативным подходом, но хочется понять насколько он лучше (и есть ли аналогичные проблемы у дргуих). 1. Всех ли устраивает добавление элементов в родительский компонент через неявный вызов функций-билдеров? вариант 1:
Copy code
verticalLayout {
        view {
как мне кажется было бы удобнее если бы эти методы назывались addVerticalLayout, или что то вроде: вариант 2:
Copy code
+VerticalLayout {
        +View {
В варинате 2, имхо, проще читать код, т.к. функции билдеров визуально сложно отличить от простых функций с лямбдой (forEach, map и да и if в конце концов). В простом коде это не заментно, но когда начинается смесь из билдеров и функций лямбд, очень лего запутаться. Кроме того добавление текста в kotlinx.html уже выглядит также как тут
+"text"
2️⃣ 2
1️⃣ 6
b
Насколько понимаю, для варианта 1 можно просто сделать extenstion функции готовых компонентов. А для unaryPlus надо делать отдельный класс, куда этот оператор помещать, и этот класс в общем ничем другим кроме сборки заниматься не будет.
В TornadoFX unaryPlus для компонентов не используется совсем, там только если plusAssign
s
Если у компонента есть список children, то унарный оператор + может добавлять в него. Его также можно объявить как экстеншн функцию
b
А в Swing и то и другое часто бесполезно, потому что как правило к вызову add() надо добавлять вторым аргументом constraints для компонента
s
Если компоненты иммутабельные, то можно передавать прямо лямбду. Или билдер списка, да
Насколько понимаю, для варианта 1 можно просто сделать extenstion функции готовых компонентов.
это да, но это придется делать для всех компонетов, в том числе для проектных. Я вот начал так писать, и очень быстро надоело объявлять и класс компонента и функцию которая добавляет его в родительский компонента
А для реакта - вобще жесть имхо
Copy code
class HomeView : ReactDOMComponent<HomeView.Props, HomeView.State>() {
    companion object : ReactComponentSpec<HomeView, Props, State>
b
По этому кусочку кода ничего не понятно
Я, правда, react не знаю
s
Для реакта JB сделали обертку в которой компоненты объаявляются вот таким вот образом
это нужно написать для каждого нового компонента
companion object, по сути, выполняет роль функции которая добавляет компонент в родительский компонент
т.е. можно где то написать
Copy code
div {
  HomeView {
   // ...
  }
}
b
В Swing/JavaFX можно определять plusAssign только для верхнего компонента в иерархии виджетов
s
тут по сути про это и речь, я как раз за
+
. Но люди голосуют за функции билдеры
b
Мне бы не понравилось создавать класс который занимается только билдерством, а потом тут же выбрасывается
s
если компонент не иммутабелен (есть mutable children), то билдер не нужен
а если иммутабелен - то без него в любом случае никак...
operator fun Component.unaryPlus() { this.children += this@unaryPlus }
b
В react иммутабельны?
s
да. список передается в React.createElement, последними параметрами
ну вернее не совсем так. сами компоненты mutable
а props компонентов - immutable
props (параметры компонента), вместе со списком дочерних элементов передаются в React.createElement, реакт копирует их и сохраняет. Далее вызывается рендер, и если элементы отличаются от того что сейчас в дереве, рендер идет внутрь переданных элементов, и т.д.
b
Мне кажется, универсальный DSL для "вообще любого" фреймворка не получится
Где-то удобнее одно, где-то другое
Если ориентируетесь на React, то затачиваете на него
s
Да, про универсальность вопрос отдельный, нужно было разделить вопросы. Конкретно про реакт, с подходом JB жить сложновато, поэтому и родился вот этот альтернативный подход, про который собственно и опрос.
b
И потом задачи могут быть разные - написать DSL на уже готовый набор компонентов или же начать с нуля