Вопрос спорный. Как мне кажется, основной выигрыш ...
# russian
s
Вопрос спорный. Как мне кажется, основной выигрыш DSL в том что сразу получаем мощную поддержку IDE, с кучей рефакторингов и прочим
2
i
Меня немного напрягает обилие плюсов и необходимость их не забывать. В cycle.js https://cycle.js.org/ сделали топорнее и проще, но тем не менее как мне кажется не сильно уступает таким DSL
Copy code
div([
      label('Name:'),
      input('.field', {attrs: {type: 'text'}}),
      hr(),
      h1('Hello ' + name),
    ])
s
в этом случае невозможно будет использовать код для построения дочерних элементов (например вместо for или if придется использовать функциональный подход: map, filter и т.д.).
такой же подход например у Flutter
в котлине это могло бы выглядеть вот так:
Copy code
Section(
      key = "s1",
      title = "About",
      children = listOf(
        Text("About contents")
      )
    )
Меня немного напрягает обилие плюсов и необходимость их не забывать.
тут согласен, но есть тиекты на аннотации для ide, который заставят ее ругаться если компонент не используется (в том числе нет +)
и про обилие плюсиков тоже, выглядит довольно чужеродно. но, с другой стороны, помогает отличать от других вызовов функций с лямбдами. ну и позволяет занчительно упростить объявление компонентов (они тут же становятся доступными в dsl)...
i
Создавать странные DSL, чтобы потом поддерживать их в IDE - странно
Можно сделать что-то вроде array literal через get оператор.
s
ну, эта аннотация полезна не только для этого dsl, а, например и для Deffered из корутин
i
Copy code
h[
  h1,
  *func(param),
   div
]
s
интересная идея
а как тогда добавить например if внутрь?
нужно делать лямбду?
i
Да, похоже на JSX
s
проблема в том, что в jsx происходит своеобразное переключение режимов: в обычном js мы просто что то взываем, а в тэгах jsx, каждое упоминание тэга добавляет его в родительский элемент (впрочем как и с dsl который в anko, javafx и тд)
i
т.е. происходит именно то, что достигается через оператор unaryPlus
s
да
i
Т.е. абстрактно можно вот так дерево строить:
Copy code
fun div(children: List<Renderable> = listOf()) = Div(children)

object h {
    operator fun <K> get(vararg items: K): List<K> = arrayListOf(*items)
}

val dom = h[
    div(h[
        div()
    ])
]
s
можно было бы наверное даже так: div(class = "123") [ div() ]
но вопрос про if и for внутри [ ] остается открытым
тут либо мы находимся в режиме вставки, либо в режиме кода. в случае с [] - режим вставки, если делать {} - то режим кода
i
не нужно писать внутри - выносить в отдельные функции
тогда прям форсится хороший стиль кода
s
мне кажется это будет выглядеть слишком громоздко, попробую придумать пример
вот три варианта:
Copy code
fun usersList(users: List<User>) = div [
        users.map { 
            div [
                it.name
            ] 
        }
    ]

fun usersList(users: List<User>) {
    div {
        users.forEach {
            div {
                it.name
            }
        }
    }  
} 

fun usersList(users: List<User>) {
    +Div {
        users.forEach {
            +Div {
                it.name
            }
        }
    }  
}
вы имели ввиду первый?
i
можно на ты 🙂
s
ок). или имелось ввиду users.map вынести в функцию?
i
Экспереминтирую