Что именно улучшилось в Scala благодаря сопоставлению с образцом в версии 2.10?

Мне показалось интересным, что эта головоломка, а именно этот код:

val (i, j): (Int, Int) = ("3", "4")

Сбой во время выполнения в Scala 2.9.1, но сбой во время компиляции с 2.10 M3 (и это здорово). Я пытаюсь отслеживать, что будет в новых версиях Scala, но не могу соединить все точки здесь. Какое улучшение привело к такому более точному поведению?


person Adam Rabung    schedule 17.05.2012    source источник
comment
Я понятия не имею, почему это может привести к сбою во время выполнения, а не во время компиляции в любой версии Scala.   -  person Dan Burton    schedule 17.05.2012
comment
Я предполагаю, что это просто где-то проскочило через тест. На самом деле это довольно забавно: вчера я разговаривал с приверженцем Python о том, насколько великолепен Scala, но сегодня обнаружил, что Scala терпит неудачу, когда ему предлагают задание, которое по своей природе является почти классическим Python.   -  person pmcs    schedule 17.05.2012
comment
val (i:Int, j:Int) = ("3","4") не работает во время компиляции в 2.9.1   -  person Rogach    schedule 17.05.2012
comment
@pmcs — Scala прекрасен! Но нет ничего идеального ;)   -  person Rogach    schedule 17.05.2012
comment
@Dan - присваивание в scala выполняется следующим образом: val p = x, где p - любой шаблон. Шаблон x: (Int, Int) — это проверка типа во время выполнения, но помните, что во время выполнения из-за удаления типа тип (Int, Int) на самом деле просто Tuple2. Вот почему он компилируется, но падает с исключением приведения класса во время выполнения.   -  person oxbow_lakes    schedule 17.05.2012
comment
@pmcs Ближайший эквивалент Scala для python: val (i,j) = ("3","4"). Это просто работает. И, как и в python, вам нужно будет преобразовать строки в целые числа, если вам нужна арифметика.   -  person paradigmatic    schedule 17.05.2012
comment
@pmcs Вы понимаете, что весь смысл примера в том, что он должен потерпеть неудачу, верно? Если Python примет его, то он работает хуже, чем Scala 2.9.1 (сбой во время выполнения) и Scala 2.10 (сбой во время компиляции). Но я предполагаю, что в Python это также не удастся, как только вы попытаетесь использовать i или j в качестве чисел.   -  person Daniel C. Sobral    schedule 17.05.2012
comment
@oxbow_lakes Почему этот шаблон является проверкой во время выполнения, в отличие от ML, OCaml, F#, Haskell и т. д.? Например, let (a, b) : int * int = "3", "4" выдает ошибку типа в OCaml или F#.   -  person J D    schedule 18.05.2012
comment
@JonHarrop: интересный момент; Я предполагаю, что это следствие разрешения произвольного сопоставления с образцом. Например, val Foo((a, b): (Int, Int)) = (3, 4) может быть допустимым, например, если Foo.unapply имеет тип Any => Option[Any]. В этом случае проверка типа должна выполняться во время выполнения. Я не думаю, что вы можете выразить это без подтипа, и ни один из языков, которые вы упомянули, не имеет определяемых пользователем экстракторов AFAIK. Тем не менее, в некоторых случаях проверка типов может быть доказана раньше, так что в настоящее время Scala так же хороша в этом примере.   -  person Blaisorblade    schedule 27.07.2012


Ответы (2)


Дело в том, что новый сопоставитель шаблонов гораздо проще улучшать и поддерживать, потому что это не бесполезный кусок кода. В следующем примере кода также должно быть такое же изменение:

("3", "4") match { case (i, j): (Int, Int) => /* whatever */ }

Происходит то, что Scala во время компиляции понимает, что шаблон никогда не может быть сопоставлен.

person Daniel C. Sobral    schedule 17.05.2012

В scala 2.10 средство сопоставления с образцом было полностью переписано и теперь является виртуализированным средством сопоставления с образцом. Подробнее об этом!

person oxbow_lakes    schedule 17.05.2012
comment
Ну, виртуальная часть просто внутренняя, если вы не передадите флаг, iirc. Фактический вывод не является виртуальным (т. е. не реализуется как обращение к монаде). - person Daniel C. Sobral; 17.05.2012
comment
Ну да. Но главное в том, что он представляет собой полную переработку (что объясняет, почему его поведение могло измениться). - person oxbow_lakes; 17.05.2012
comment
Почему сопоставление с образцом должно иметь значение для этого примера? Я ожидаю, что компилятор отклонит код во время проверки типов, прежде чем он попадет в сопоставитель шаблонов... - person J D; 18.05.2012