Подтвердить что ты не робот

Что такое scala экспериментальный сопоставление виртуальных шаблонов?

Я видел довольно несколько недавно упоминал о новой виртуализированной " шаблон для scala. Я пропустил записку, объяснив, что это на самом деле...

4b9b3361

Ответ 1

"виртуализированный" шаблон - это переписывание существующего соединителя. Мотивация для этого заключалась в поддержке виртуализации сопоставления шаблонов для полиморфных встроенных DSL, не относящихся к 2.10.

Как говорит Юлиан в комментариях ниже: он очень похож на то, как компилируются компиляции: вместо прямого генерации кода они переводятся на foreach, map, filter и т.д. Последовательность шаблонов может быть переведенные на ряд вызовов методов, которые DSL могут перезаписывать. Реализация по умолчанию будет учитывать текущую семантику, и задача состоит в том, чтобы сделать ее такой же эффективной, как и текущую. Похоже, Адриаан очень близок к этой цели. "Виртуализированная" реализация проще и исправляет несколько ошибок в текущей реализации.

"Полиморфные встроенные DSL" - это идея, что можно писать программы в scala, которые не должны запускаться на JVM. То есть scalac будет выводить вывод, который описывает, что делает программа. Затем это может быть повторно скомпилировано против конкретной архитектуры. Такие вещи обсуждались на ScalaDays 2011.

Эта запись в конечном итоге станет стандартным шаблоном шаблонов scala. Старый шаблонный шаблон был (как я понимаю) недостижимым.

Ответ 2

К сожалению, (единственный) существующий ответ низок на сочных битах, а ссылки на комментарий нарушены. Поэтому позвольте мне попытаться добавить немного сока здесь, потому что, если нет другой причины, моя собственная ссылка, когда я на самом деле решаю что-то сделать с ней в будущем, видя, что этот ответ находится на вершине каждого поиска google, который я делаю.

Виртуализированный паттерн шаблонов, как уже упоминалось, является переписыванием того, как компилятор Scala обрабатывает сопоставление шаблонов. Он служил многим целям, а часть "виртуализации" означала, что он является частью виртуализированного усилия Scala. Это усилие немного противоположно макросам: оно принимает вещи, которые "запускаются" во время компиляции, а затем перемещаются, чтобы запустить время.

Например, учитывая наличие правильного определения в области видимости, выполните следующие действия:

if (false) 1 else 2

вместо того, чтобы скомпилироваться в байт-коды ветвей и литералов или даже оптимизирован для литерала "2", фактически скомпилируется как следующий оператор:

__ifThenElse(false, 1, 2)

Дополнительную информацию см. в scala виртуализированной вики и некоторые примеры того, что это может быть полезно для.

Я сказал, однако, что переписывание шаблонов шаблонов служило многим целям. Еще одна важная цель заключалась в том, чтобы превратить код спагетти, который был старым шаблоном, полным или специальным и угловым случаями и ошибками, во что-то, с чем можно было бы рассуждать, расширять и улучшать более легко. В этом переписании исправлено так много проблем, что люди просто просмотрели список проблем, в которых используется пример кода для вопросов, связанных с шаблоном, и отмечая, что проблемы "фиксированы", когда они работали. У этого есть новые ошибки, но в гораздо меньшем масштабе.

Теперь очень мало информации о том, как работает новый шаблонный макет, но в основном он переводится в несколько вызовов метода, которые "реализованы" в компиляторе с монадой Option. Затем он переходит в фазу оптимизации, которая создает оптимальный байт-код.

Можно ввести свой собственный матчи, хотя он заблокирован за флагом -Xexperimental. Попробуйте выполнить следующий код, скопированный из набора Scala test, с и без этого флага:

trait Intf {
 type Rep[+T]
 type M[+T] = Rep[Maybe[T]]

 val __match: Matcher
 abstract class Matcher {
   // runs the matcher on the given input
   def runOrElse[T, U](in: Rep[T])(matcher: Rep[T] => M[U]): Rep[U]

   def zero: M[Nothing]
   def one[T](x: Rep[T]): M[T]
   def guard[T](cond: Rep[Boolean], then: => Rep[T]): M[T]
   def isSuccess[T, U](x: Rep[T])(f: Rep[T] => M[U]): Rep[Boolean] // used for isDefinedAt
 }

 abstract class Maybe[+A] {
   def flatMap[B](f: Rep[A] => M[B]): M[B]
   def orElse[B >: A](alternative: => M[B]): M[B]
 }

 implicit def proxyMaybe[A](m: M[A]): Maybe[A]
 implicit def repInt(x: Int): Rep[Int]
 implicit def repBoolean(x: Boolean): Rep[Boolean]
 implicit def repString(x: String): Rep[String]

 def test = 7 match { case 5 => "foo" case _ => "bar" }
}

trait Impl extends Intf {
 type Rep[+T] = String

 object __match extends Matcher {
   def runOrElse[T, U](in: Rep[T])(matcher: Rep[T] => M[U]): Rep[U] = ("runOrElse("+ in +", ?" + matcher("?") + ")")
   def zero: M[Nothing]                                             = "zero"
   def one[T](x: Rep[T]): M[T]                                      = "one("+x.toString+")"
   def guard[T](cond: Rep[Boolean], then: => Rep[T]): M[T]          = "guard("+cond+","+then+")"
   def isSuccess[T, U](x: Rep[T])(f: Rep[T] => M[U]): Rep[Boolean]  = ("isSuccess("+x+", ?" + f("?") + ")")
 }

 implicit def proxyMaybe[A](m: M[A]): Maybe[A] = new Maybe[A] {
   def flatMap[B](f: Rep[A] => M[B]): M[B]                          = m + ".flatMap(? =>"+ f("?") +")"
   def orElse[B >: A](alternative: => M[B]): M[B]                   = m + ".orElse("+ alternative +")"
 }

 def repInt(x: Int): Rep[Int] = x.toString
 def repBoolean(x: Boolean): Rep[Boolean] = x.toString
 def repString(x: String): Rep[String] = x
}

object Test extends Impl with Intf with App {
  println(test)
}

Результат без флага - это то, что вы ожидаете:

scala> Test.main(null)
bar

С -Xexperimental, однако, компиляция альтернативного соответствия "engine":

scala> Test.main(null)
runOrElse(7, ?guard(false,?).flatMap(? =>one(foo)).orElse(one(bar)))

См. также дополнительную информацию о скалядах для PatternMatching и MatchMonadInterface.

Отказ от ответственности: выше было извлечение и выполнялось из версии Scala на главной ветке после 2.10.0, поэтому могут быть различия. Я, к сожалению, испытываю недостаток в чистой среде 2.10.0 или 2.10.1, чтобы проверить ее.