LINUX.ORG.RU

Scala и Java-stack technology

 , , ,


0

1

Всем привет.

Есть ли годные приспособы, интегрирующие код на Scala в такие применения Java как JSP/JSF и иже с ними? Нашел пару более-менее годных статей на английском на этот счет, но хочется большего - да, вот такой я сибарит в программировании :) Писать Scala-код в стиле Java по моему мнению, не канает.

//Разыскал информацию о Swing в Scala.

★★★★★

Последнее исправление: LongLiveUbuntu (всего исправлений: 1)
Ответ на: комментарий от vertexua

Но лучше попробовать делать не через свойство бина, а как вызов метода. Типо не ${user.name} а ${user.name()}, если память не изменяет - работает

vertexua ★★★★★
()

Разыскал информацию о Swing в Scala.

Если кто-то напишет библиотеку без документации то она немедленно должна проследовать в /dev/null. Лучший паттерн для свинга - написать implicit conversions для функций в listeners и пользоваться просто Java Swing, который дотошно документирован.

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

Лучший паттерн для свинга - написать implicit conversions для функций в listeners и пользоваться просто Java Swing

И получить утечку памяти, потому что такой listener не удалить.

dave ★★★★★
()

может взять какой-нибудь Scalate?

shty ★★★★★
()
Ответ на: комментарий от vertexua

Я имею в виду следующее.

Допустим, у нас есть функция f, которая может быть неявно преобразована в слушатель. Методы addXListener и removeXListener добавляют и удаляют слушателя соответственно. Проблема в том, что легко ошибиться, передав f как аргумент методу removeXListener.

Ниже создается иллюзия, что все правильно, а на самом деле имеем утечку памяти, поскольку невозможно восстановить тот слушатель, к которому первоначально был преобразован f при вызове addXListener:

x.addXListener(f)
...
x.removeXListener(f)   // утечка памяти

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

dave ★★★★★
()

там все суть костыли, лучше взять тот же нативный play.

Rastafarra ★★★★
()

Фу, маргинал.

anonymous
()
Ответ на: комментарий от dave

x.removeXListener(f)

Обычно такое не делают, в этом вся суть. Но сам объект имеет ссылку, потому когда он будет удален, например при dispose, то и слушатели тоже будут удалены.

Но если есть явная необходимость манипулировать слушателями, то можно написать объект ячейку, которая с помощью apply получает лямбду, возвращает слушатель и сохраняет слушатель. В конце концов напишите анонимный слушатель, который запросто замкнет контекст.

Естественно с имплиситами гибкость не супер, но зато кратко. И это вы еще не упоминали слушатели с многими методами.

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

Мне больше нравится подход, примененный в F#. Это - Event и Observable. Развитие идеи делегатов из .NET в функциональном ключе. Там получается так.

Если нужны слушатели, то можно ими оперировать явно, подписывая их и отписывая в случае необходимости как в обычном C#. Но для функций существует два кратких метода: Add и Subscribe. Последний подписывает функцию, не слушателя, и возвращает объект IDisposable, который если освободить, освобождает подписку функции, т.е. нет утечки. Метод Add похож на Subscribe, но ничего не возвращает. Его вызывают как раз тогда, как тот самый removeXListener не нужен.

Подход замечателен еще тем, что можно определить функции Map, Filter и тому подобное над самими событиями - там завязано на IDisposable. Плюс еще интегрируется с асинхронными вычислениями async. В итоге подводит нас к так называемому «реактивному функциональному программированию».

В общем, мне так понравился подход F#, что я его использую в Scala и Common Lisp. Никаких громоздких listeners в духе Java.

dave ★★★★★
()
Ответ на: комментарий от dave

Да, вполне можно так. Я такое как раз предложил, но конечно без такой удобной композиции. Здесь все упирается в то, что Java addListener ничего не возращают. Вообще поэкспериментирую на досуге

vertexua ★★★★★
()
Ответ на: комментарий от korvin_
trait ShapeNode extends RectangleNode {

  private var _shape: Shape = defaultShape

  protected def defaultShape: Shape = ShapeNode.initialShape

  def shape: Shape = _shape
  def shape_=(v: Shape) {

    if (_shape != v) {

      triggerShapeChanging()

      val v0 = _shape
      _shape = v

      logShapeChanged(v0, v)

      triggerShapeChanged()
      triggerEntryChanged()

      reallocate()
    }
  }

  def shapeChanging = eventSources.publish(ShapeNode.shapeChangingEvent)
  def shapeChanged = eventSources.publish(ShapeNode.shapeChangedEvent)

  protected def triggerShapeChanging() {
    eventSources.trigger(ShapeNode.shapeChangingEvent, this, ())
  }

  protected def triggerShapeChanged() {
    eventSources.trigger(ShapeNode.shapeChangedEvent, this, ())
  }

  ...
}

object ShapeNode {

  val initialShape: Shape = RectangleShape

  val shapeChangingEvent = new Object
  val shapeChangedEvent = new Object

  ...
}
dave ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.