SlideShare a Scribd company logo
1 of 19
Download to read offline
Scala magic

Александр Подхалюзин

    19 мая 2012 г.




                       1 / 19
Syntactic sugar
For
comprehensions
By-name
parameters
Non local return
Local functions
Lazy values
Generated
ByteCode
Binary
                   Syntactic sugar
compatibility

Questions?




                                     2 / 19
For comprehensions

Syntactic sugar
For
                   В Scala for является синтаксическим сахаром, тем не
comprehensions
By-name
                   менее правила преобразования довольно сложны
parameters
Non local return        Один генератор с ’yield’ тоже, что вызов метода ’map’
Local functions
Lazy values             Один генератор без ’yield’ тоже, что ’foreach’
Generated               Несколько генераторов транслируются во ’flatMap’
ByteCode
Binary
compatibility

Questions?          f o r ( i <− 1 t o    5)       (1 to 5) . map { i = i    > i }
                        yield i       i            (1 to 5) . f o r e a c h {
                    f o r ( i <− 1 t o
                        println ( i )
                                          5)       }
                                                     i = println ( i )
                                                        >

                    f o r { i <− 1 t o    5        (1 to 5) . f l a t M a p {
                            j <− 1 t o    5}         i = (1 to 5) . map { j = i + j }
                                                        >                       >
                        yield i + j                }


                   Подробнее можно почитать в спецификации.



                                                                                        3 / 19
By-name parameters

Syntactic sugar
For
                   Возможность в вызов метода передавать выражения
comprehensions
By-name
                   лениво это другой пример того, где неявно могут быть
parameters
Non local return
                   зашиты closures. Следующие два примера идентичны:
Local functions
Lazy values
                    d e f foo ( x : => Int ) {   d e f foo ( x : ( ) => Int ) {
Generated
ByteCode               println ( x )                println ( x ( ) )
                    }                            }
Binary
compatibility
                    foo ( 1 )                    foo ( ( ) => 1 )
Questions?

                   Что изредка может приводить к ошибке (параметр будет
                   вычисляться каждый раз, когда к нему будет
                   производится обращение).




                                                                                  4 / 19
Non local return

Syntactic sugar
For
                   Return statement внутри closure на деле компилируется в
comprehensions
By-name
                   код, который бросает NonLocalReturnControl. В
parameters
Non local return
                   большинстве случаев это удобно, но нужно учитывать
Local functions    следующее
Lazy values
Generated             В критичных по производительности кусках кода этот
ByteCode
Binary
                      exception следует избегать
compatibility
                      Нельзя ловить Throwable в том месте, где этот
Questions?
                      exception бросается
                      В силу синтаксического сахара описанного ранее, все
                      это может происходить неявно (for-comprehensions и
                      by-name parameters)




                                                                        5 / 19
Local functions

Syntactic sugar
For
                   В Java любой вспомогательный код оформляется в виде
comprehensions
By-name
                   private методов на уровне класса. В Scala это можно
parameters
Non local return
                   сделать более структурированным, если использовать
Local functions    локальные методы, хотя на уровне bytecode получается
Lazy values
Generated
                   примерно тоже самое:
ByteCode
Binary
compatibility                                    import scala . runtime . IntRef ;
                                                 public class LocalFunctions {
Questions?          class LocalFunctions {
                                                     p u b l i c void foo () {
                      def foo {
                                                             I n t R e f i $ 1 = new I n t R e f ( 1 ) ;
                        var i = 1
                                                             i n t j$1 = 2;
                        val j = 2
                                                             l o c a l $ 1 ( i$1 , j$1 ) ;
                        def local {
                          i += j
                                                             l o c a l $ 1 ( i$1 , j$1 ) ;
                                                     }
                        }
                                                     p r i v a t e f i n a l void local$1 (
                        local
                                                         IntRef intref , i n t i ) {
                        local
                                                             i n t r e f . e l e m += i ;
                      }
                                                     }
                    }
                                                     p u b l i c L o c a l F u n c t i o n s ( ) {}
                                                 }




                                                                                                       6 / 19
Lazy values

Syntactic sugar
For
                   Это тоже синтаксический сахар, который надо
comprehensions
By-name
                   использовать аккуратно (так как возможны deadlock и
parameters
Non local return
                   проблемы производительности). Независимо от
Local functions    расположения lazy val, компилируется он таким образом
Lazy values
Generated
ByteCode
                                             import scala . runtime . BoxedUnit ;
Binary                                       p u b l i c c l a s s Lazy {
compatibility                                   public int x () {
                                                     i f ( ( b i t m a p $ 0 & 2 ) == 0 )
Questions?                                              synchronized ( this ) {
                                                           i f ( ( b i t m a p $ 0 & 2 ) == 0 ) {
                                                               x = 1;
                                                               bitmap$0 = bitmap$0 | 2;
                    c l a s s Lazy {
                        lazy val x = 1
                                                           }
                                                           BoxedUnit _tmp =
                    }
                                                               BoxedUnit . UNIT ;
                                                        }
                                                        return x ;
                                                    }
                                                p u b l i c L a z y ( ) {}
                                                private int x ;
                                                public v o l a t i l e i n t bitmap$0 ;
                                             }



                                                                                                    7 / 19
Syntactic sugar
Generated
ByteCode
Classes and names
Objects
Traits
Trait subclasses
Linearization
Initialisation order
Binary
                       Generated ByteCode
compatibility

Questions?




                                            8 / 19
Classes and names

Syntactic sugar
                       Для классов ничего магического не происходит.
Generated
ByteCode               Как преобразуются имена. Для большинства символов
Classes and names
Objects                есть его текстовый эквивалент
Traits
Trait subclasses          :   $colon
Linearization
Initialisation order
                          +   $plus
Binary                    ©   $u00A9
compatibility

Questions?             Внутри Scala кода можно использовать оба варианта
                       подобных идентификаторов
                       Подробнее можно изучить преобразования с помощью
                       методов NameTransfomer.encode/decode из
                       scala-compiler.jar.




                                                                           9 / 19
Objects

Syntactic sugar
                       Объект всегда компилируется в два класса.
Generated
ByteCode
Classes and names
                          Object$ содержит в себе статическое поле MODULE$,
Objects                   а также код всех методов
Traits
Trait subclasses          Object содержит в себе все статические методы
Linearization
Initialisation order      объекта, с телом вида Object$.MODULE$.foo()
Binary
compatibility          Важно понимать, что статические методы добавлены для
Questions?             удобства вызова из Java. Тем не менее они добавляются
                       не всегда.
                          В Companion Trait не добавляется ничего.
                          В Companion Class не добавляются методы с таким
                          именем, которое уже есть в этом классе
                          Методы класса java.lang.Object


                                                                         10 / 19
Traits

Syntactic sugar
                       Если trait отличается от обычного интерфейса в Java
Generated
ByteCode               наличием конкретных методов, то к соответствующему
Classes and names
Objects                интерфейсу будет создан класс Trait$class с
Traits
Trait subclasses
                       имплементацией этих методов.
Linearization
Initialisation order
Binary                                                      public abstract class   A$class {
compatibility                                                   public static int   foo ( A $this ,
                                                                                          int x) {
Questions?                                                          return   2;
                        trait A {
                                                                }
                          val x = 1                             public s t a t i c void $init$ (
                                                                  A $this
                            def foo ( x :   Int ) = 2
                                                                ) {
                        }
                                                                    $this .
                                                                      test$A$_setter_$x_$eq (1) ;
                                                                }
                                                            }




                                                                                                      11 / 19
Trait subclasses

Syntactic sugar
                       Если в Java попытаться реализовать Trait, в котором есть
Generated
ByteCode               уже имплементированые методы, то их все равно
Classes and names
Objects                пришлось бы реализовывать. Другой вопрос, что это
Traits
Trait subclasses
                       можно сделать предельно легко:
Linearization
Initialisation order
Binary                 i n t foo ( ) { r e t u r n Trait$class . foo ( t h i s ) ; }
compatibility

Questions?
                       В случае наследников написанных на Scala, то же самое
                       делает компилятор.




                                                                                       12 / 19
Linearization

Syntactic sugar
                       Этот алгоритм требуется компилятору, чтобы определить,
Generated
ByteCode               в каком порядке надо искать методы в базовых классах.
Classes and names
Objects
Traits
Trait subclasses       trait   A extends B
Linearization          trait   B
Initialisation order   class   C extends B
Binary                 class   D extends C with A
compatibility

Questions?
                       Здесь порядок D, A, C, B.
                       Если два метода с одинаковой сигнатурой без
                       модификатора ’override’ приходят в класс наследник из
                       супертрейтов, то ошибки не будет, так как обязательно
                       надо будет переопределить эту сигнатуру. Если же у
                       кого-то есть модификатор ’override’, может случится
                       неявный override согласно правилам линеаризации.

                                                                           13 / 19
Initialisation order

Syntactic sugar
                       Инициализация происходит в порядке, обратном
Generated
ByteCode               линеаризации. Если к переменной обратиться до того, как
Classes and names
Objects                она проинициализирована, можно получить NPE.
Traits
Trait subclasses
                       Есть два способа избавится от подобных проблем:
Linearization
Initialisation order      Использовать lazy val
Binary
compatibility
                          Использовать early definitions
Questions?




                                                                          14 / 19
Syntactic sugar
Generated
ByteCode
Binary
compatibility
Methods
Values
Lazy values

Questions?        Binary compatibility




                                         15 / 19
Methods

Syntactic sugar
                  Здесь все очень похоже на Java. Чаще всего проблем не
Generated
ByteCode          будет.
Binary
compatibility        Добавлять метод можно даже в Trait, но только если
Methods
Values               старые методы не ссылаются на новые, так как
Lazy values
                     имплементации в классы наследники добавлены не
Questions?
                     будут.
                     В класс опасно добавлять методы, имена которых
                     совпадают с именем методов из Companion Object, так
                     как статические реализации будут удалены
                     компилятором, что может вызвать проблемы с кодом
                     написанным не на Scala.




                                                                     16 / 19
Values

Syntactic sugar
                  Если переменная находится в классе или объекте, то
Generated
ByteCode          переменная компилируется в getter, setter (для variables) и
Binary
compatibility
                  field, который инциализируется в конструкторе класса. А
Methods           значит все будет также хорошо как и с методами.
Values
Lazy values       Если переменная находится в Trait, то она компилируется
Questions?        в getter и setter (всегда). Инициализация происходит в
                  методе Trait$class.$init$ через вызов setter.
                      Значит добавлять переменную в трейт нельзя. Так как
                      будет вызван абстрактный setter.
                      По аналогичным причинам нельзя изменять def на val
                      Тем не менее val на def также изменять нельзя, так как
                      тогда в классах наследниках, где как раз и хранится
                      field, переменная не будет проинициализирована.


                                                                         17 / 19
Lazy values

Syntactic sugar
                  В подклассах не генерируется field bitmap, если он есть в
Generated
ByteCode          базовом классе.
Binary
compatibility         Поэтому в этих случаях добавлять lazy value в классы
Methods
Values                нельзя
Lazy values
                      В Trait добавлять можно, если эта переменная не
Questions?
                      будет использована в старом коде
                      Так как компиляция lazy val в Trait от компиляции
                      метода не отличается совсем, то их можно заменять
                      друг на друга, учитывая только, что в наследниках
                      подобная семантика не изменится




                                                                        18 / 19
Syntactic sugar
Generated
ByteCode
Binary
compatibility

Questions?



                  Questions?




                               19 / 19

More Related Content

What's hot

Теории и практики фунционального программирования - GDG D2D
Теории и практики фунционального программирования - GDG D2DТеории и практики фунционального программирования - GDG D2D
Теории и практики фунционального программирования - GDG D2D0xffAA
 
Теории и практики функционального программирования.
Теории и практики функционального программирования.Теории и практики функционального программирования.
Теории и практики функционального программирования.Dev2Dev
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программированияAlex.Kolonitsky
 
Инкапсуляция и полиморфизм в ruby
Инкапсуляция и полиморфизм в rubyИнкапсуляция и полиморфизм в ruby
Инкапсуляция и полиморфизм в rubyEvgeny Smirnov
 
Ruby — Паттерны программирования
Ruby — Паттерны программированияRuby — Паттерны программирования
Ruby — Паттерны программированияEvgeny Smirnov
 
Динамическое программирование на ruby
Динамическое программирование на rubyДинамическое программирование на ruby
Динамическое программирование на rubyEvgeny Smirnov
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.Igor Shkulipa
 
Алгоритмы на ruby: жадные алгоритмы
Алгоритмы на ruby: жадные алгоритмыАлгоритмы на ruby: жадные алгоритмы
Алгоритмы на ruby: жадные алгоритмыEvgeny Smirnov
 
Обработка коллекций наизнанку: как применить много функций к одному аргументу...
Обработка коллекций наизнанку: как применить много функций к одному аргументу...Обработка коллекций наизнанку: как применить много функций к одному аргументу...
Обработка коллекций наизнанку: как применить много функций к одному аргументу...corehard_by
 
Ruby: работа с массивами
Ruby: работа с массивамиRuby: работа с массивами
Ruby: работа с массивамиEvgeny Smirnov
 
Задачи по ООП в ruby
Задачи по ООП в rubyЗадачи по ООП в ruby
Задачи по ООП в rubyEvgeny Smirnov
 
Запись вспомогательный алгоритмов на языка Паскаль
Запись вспомогательный алгоритмов на языка ПаскальЗапись вспомогательный алгоритмов на языка Паскаль
Запись вспомогательный алгоритмов на языка ПаскальAndrey Dolinin
 
Cpp/cli types
Cpp/cli typesCpp/cli types
Cpp/cli typesmcroitor
 
чернякова г.в.
чернякова г.в.чернякова г.в.
чернякова г.в.sharikdp
 
Общие сведения о языке программирования Паскаль
Общие сведения о языке программирования ПаскальОбщие сведения о языке программирования Паскаль
Общие сведения о языке программирования ПаскальAndrey Dolinin
 
Способы записи алгоритмов
Способы записи алгоритмовСпособы записи алгоритмов
Способы записи алгоритмовAndrey Dolinin
 
C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.Igor Shkulipa
 

What's hot (20)

Урок 1. Что такое функциональное программирование
Урок 1. Что такое функциональное программированиеУрок 1. Что такое функциональное программирование
Урок 1. Что такое функциональное программирование
 
Теории и практики фунционального программирования - GDG D2D
Теории и практики фунционального программирования - GDG D2DТеории и практики фунционального программирования - GDG D2D
Теории и практики фунционального программирования - GDG D2D
 
Теории и практики функционального программирования.
Теории и практики функционального программирования.Теории и практики функционального программирования.
Теории и практики функционального программирования.
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программирования
 
Инкапсуляция и полиморфизм в ruby
Инкапсуляция и полиморфизм в rubyИнкапсуляция и полиморфизм в ruby
Инкапсуляция и полиморфизм в ruby
 
Ruby — Паттерны программирования
Ruby — Паттерны программированияRuby — Паттерны программирования
Ruby — Паттерны программирования
 
777
777777
777
 
Динамическое программирование на ruby
Динамическое программирование на rubyДинамическое программирование на ruby
Динамическое программирование на ruby
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.
 
Алгоритмы на ruby: жадные алгоритмы
Алгоритмы на ruby: жадные алгоритмыАлгоритмы на ruby: жадные алгоритмы
Алгоритмы на ruby: жадные алгоритмы
 
Обработка коллекций наизнанку: как применить много функций к одному аргументу...
Обработка коллекций наизнанку: как применить много функций к одному аргументу...Обработка коллекций наизнанку: как применить много функций к одному аргументу...
Обработка коллекций наизнанку: как применить много функций к одному аргументу...
 
Ruby: работа с массивами
Ruby: работа с массивамиRuby: работа с массивами
Ruby: работа с массивами
 
Задачи по ООП в ruby
Задачи по ООП в rubyЗадачи по ООП в ruby
Задачи по ООП в ruby
 
Запись вспомогательный алгоритмов на языка Паскаль
Запись вспомогательный алгоритмов на языка ПаскальЗапись вспомогательный алгоритмов на языка Паскаль
Запись вспомогательный алгоритмов на языка Паскаль
 
Cpp/cli types
Cpp/cli typesCpp/cli types
Cpp/cli types
 
чернякова г.в.
чернякова г.в.чернякова г.в.
чернякова г.в.
 
Общие сведения о языке программирования Паскаль
Общие сведения о языке программирования ПаскальОбщие сведения о языке программирования Паскаль
Общие сведения о языке программирования Паскаль
 
Способы записи алгоритмов
Способы записи алгоритмовСпособы записи алгоритмов
Способы записи алгоритмов
 
C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.
 
Python
PythonPython
Python
 

Viewers also liked

Scala laboratory: Globus. iteration #3
Scala laboratory: Globus. iteration #3Scala laboratory: Globus. iteration #3
Scala laboratory: Globus. iteration #3Vasil Remeniuk
 
Types by Adform Research, Saulius Valatka
Types by Adform Research, Saulius ValatkaTypes by Adform Research, Saulius Valatka
Types by Adform Research, Saulius ValatkaVasil Remeniuk
 
Spark Intro by Adform Research
Spark Intro by Adform ResearchSpark Intro by Adform Research
Spark Intro by Adform ResearchVasil Remeniuk
 
The Kotlin Programming Language, Svetlana Isakova
The Kotlin Programming Language, Svetlana IsakovaThe Kotlin Programming Language, Svetlana Isakova
The Kotlin Programming Language, Svetlana IsakovaVasil Remeniuk
 
Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14Vasil Remeniuk
 
Cake pattern. Presentation by Alex Famin at scalaby#14
Cake pattern. Presentation by Alex Famin at scalaby#14Cake pattern. Presentation by Alex Famin at scalaby#14
Cake pattern. Presentation by Alex Famin at scalaby#14Vasil Remeniuk
 
Testing in Scala by Adform research
Testing in Scala by Adform researchTesting in Scala by Adform research
Testing in Scala by Adform researchVasil Remeniuk
 
scala.reflect, Eugene Burmako
scala.reflect, Eugene Burmakoscala.reflect, Eugene Burmako
scala.reflect, Eugene BurmakoVasil Remeniuk
 
a million bots can't be wrong
a million bots can't be wronga million bots can't be wrong
a million bots can't be wrongVasil Remeniuk
 

Viewers also liked (9)

Scala laboratory: Globus. iteration #3
Scala laboratory: Globus. iteration #3Scala laboratory: Globus. iteration #3
Scala laboratory: Globus. iteration #3
 
Types by Adform Research, Saulius Valatka
Types by Adform Research, Saulius ValatkaTypes by Adform Research, Saulius Valatka
Types by Adform Research, Saulius Valatka
 
Spark Intro by Adform Research
Spark Intro by Adform ResearchSpark Intro by Adform Research
Spark Intro by Adform Research
 
The Kotlin Programming Language, Svetlana Isakova
The Kotlin Programming Language, Svetlana IsakovaThe Kotlin Programming Language, Svetlana Isakova
The Kotlin Programming Language, Svetlana Isakova
 
Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14Работа с Akka Сluster, @afiskon, scalaby#14
Работа с Akka Сluster, @afiskon, scalaby#14
 
Cake pattern. Presentation by Alex Famin at scalaby#14
Cake pattern. Presentation by Alex Famin at scalaby#14Cake pattern. Presentation by Alex Famin at scalaby#14
Cake pattern. Presentation by Alex Famin at scalaby#14
 
Testing in Scala by Adform research
Testing in Scala by Adform researchTesting in Scala by Adform research
Testing in Scala by Adform research
 
scala.reflect, Eugene Burmako
scala.reflect, Eugene Burmakoscala.reflect, Eugene Burmako
scala.reflect, Eugene Burmako
 
a million bots can't be wrong
a million bots can't be wronga million bots can't be wrong
a million bots can't be wrong
 

Similar to Scala Magic, Alexander Podhaliusin

Язык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовЯзык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовAndrew Shitov
 
Михаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияМихаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияYandex
 
Михаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxМихаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxYandex
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013ScalaNsk
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияYandex
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняAlexander Granin
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Stfalcon Meetups
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPython Meetup
 

Similar to Scala Magic, Alexander Podhaliusin (9)

Discovering Lambdas (Speech)
Discovering Lambdas (Speech)Discovering Lambdas (Speech)
Discovering Lambdas (Speech)
 
Язык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовЯзык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистов
 
Михаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияМихаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знания
 
Михаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxМихаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajax
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знания
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
 

More from Vasil Remeniuk

Product Minsk - РТБ и Программатик
Product Minsk - РТБ и ПрограмматикProduct Minsk - РТБ и Программатик
Product Minsk - РТБ и ПрограмматикVasil Remeniuk
 
Types by Adform Research
Types by Adform ResearchTypes by Adform Research
Types by Adform ResearchVasil Remeniuk
 
Scalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovScalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovVasil Remeniuk
 
Scalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovScalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovVasil Remeniuk
 
Spark by Adform Research, Paulius
Spark by Adform Research, PauliusSpark by Adform Research, Paulius
Spark by Adform Research, PauliusVasil Remeniuk
 
Scala Style by Adform Research (Saulius Valatka)
Scala Style by Adform Research (Saulius Valatka)Scala Style by Adform Research (Saulius Valatka)
Scala Style by Adform Research (Saulius Valatka)Vasil Remeniuk
 
Spark intro by Adform Research
Spark intro by Adform ResearchSpark intro by Adform Research
Spark intro by Adform ResearchVasil Remeniuk
 
SBT by Aform Research, Saulius Valatka
SBT by Aform Research, Saulius ValatkaSBT by Aform Research, Saulius Valatka
SBT by Aform Research, Saulius ValatkaVasil Remeniuk
 
Scala laboratory: Globus. iteration #2
Scala laboratory: Globus. iteration #2Scala laboratory: Globus. iteration #2
Scala laboratory: Globus. iteration #2Vasil Remeniuk
 
Testing in Scala. Adform Research
Testing in Scala. Adform ResearchTesting in Scala. Adform Research
Testing in Scala. Adform ResearchVasil Remeniuk
 
Scala laboratory. Globus. iteration #1
Scala laboratory. Globus. iteration #1Scala laboratory. Globus. iteration #1
Scala laboratory. Globus. iteration #1Vasil Remeniuk
 
Cassandra + Spark + Elk
Cassandra + Spark + ElkCassandra + Spark + Elk
Cassandra + Spark + ElkVasil Remeniuk
 
Опыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событияхОпыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событияхVasil Remeniuk
 
Funtional Reactive Programming with Examples in Scala + GWT
Funtional Reactive Programming with Examples in Scala + GWTFuntional Reactive Programming with Examples in Scala + GWT
Funtional Reactive Programming with Examples in Scala + GWTVasil Remeniuk
 
[Не]практичные типы
[Не]практичные типы[Не]практичные типы
[Не]практичные типыVasil Remeniuk
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?Vasil Remeniuk
 
Metaprogramming in Scala 2.10, Eugene Burmako,
Metaprogramming  in Scala 2.10, Eugene Burmako, Metaprogramming  in Scala 2.10, Eugene Burmako,
Metaprogramming in Scala 2.10, Eugene Burmako, Vasil Remeniuk
 
"Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin "Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin Vasil Remeniuk
 

More from Vasil Remeniuk (20)

Product Minsk - РТБ и Программатик
Product Minsk - РТБ и ПрограмматикProduct Minsk - РТБ и Программатик
Product Minsk - РТБ и Программатик
 
Types by Adform Research
Types by Adform ResearchTypes by Adform Research
Types by Adform Research
 
Scalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovScalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex Gryzlov
 
Scalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex GryzlovScalding by Adform Research, Alex Gryzlov
Scalding by Adform Research, Alex Gryzlov
 
Spark by Adform Research, Paulius
Spark by Adform Research, PauliusSpark by Adform Research, Paulius
Spark by Adform Research, Paulius
 
Scala Style by Adform Research (Saulius Valatka)
Scala Style by Adform Research (Saulius Valatka)Scala Style by Adform Research (Saulius Valatka)
Scala Style by Adform Research (Saulius Valatka)
 
Spark intro by Adform Research
Spark intro by Adform ResearchSpark intro by Adform Research
Spark intro by Adform Research
 
SBT by Aform Research, Saulius Valatka
SBT by Aform Research, Saulius ValatkaSBT by Aform Research, Saulius Valatka
SBT by Aform Research, Saulius Valatka
 
Scala laboratory: Globus. iteration #2
Scala laboratory: Globus. iteration #2Scala laboratory: Globus. iteration #2
Scala laboratory: Globus. iteration #2
 
Testing in Scala. Adform Research
Testing in Scala. Adform ResearchTesting in Scala. Adform Research
Testing in Scala. Adform Research
 
Scala laboratory. Globus. iteration #1
Scala laboratory. Globus. iteration #1Scala laboratory. Globus. iteration #1
Scala laboratory. Globus. iteration #1
 
Cassandra + Spark + Elk
Cassandra + Spark + ElkCassandra + Spark + Elk
Cassandra + Spark + Elk
 
Опыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событияхОпыт использования Spark, Основано на реальных событиях
Опыт использования Spark, Основано на реальных событиях
 
ETL со Spark
ETL со SparkETL со Spark
ETL со Spark
 
Funtional Reactive Programming with Examples in Scala + GWT
Funtional Reactive Programming with Examples in Scala + GWTFuntional Reactive Programming with Examples in Scala + GWT
Funtional Reactive Programming with Examples in Scala + GWT
 
Vaadin+Scala
Vaadin+ScalaVaadin+Scala
Vaadin+Scala
 
[Не]практичные типы
[Не]практичные типы[Не]практичные типы
[Не]практичные типы
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
Metaprogramming in Scala 2.10, Eugene Burmako,
Metaprogramming  in Scala 2.10, Eugene Burmako, Metaprogramming  in Scala 2.10, Eugene Burmako,
Metaprogramming in Scala 2.10, Eugene Burmako,
 
"Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin "Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin
 

Scala Magic, Alexander Podhaliusin

  • 2. Syntactic sugar For comprehensions By-name parameters Non local return Local functions Lazy values Generated ByteCode Binary Syntactic sugar compatibility Questions? 2 / 19
  • 3. For comprehensions Syntactic sugar For В Scala for является синтаксическим сахаром, тем не comprehensions By-name менее правила преобразования довольно сложны parameters Non local return Один генератор с ’yield’ тоже, что вызов метода ’map’ Local functions Lazy values Один генератор без ’yield’ тоже, что ’foreach’ Generated Несколько генераторов транслируются во ’flatMap’ ByteCode Binary compatibility Questions? f o r ( i <− 1 t o 5) (1 to 5) . map { i = i > i } yield i i (1 to 5) . f o r e a c h { f o r ( i <− 1 t o println ( i ) 5)   } i = println ( i ) > f o r { i <− 1 t o 5 (1 to 5) . f l a t M a p { j <− 1 t o 5} i = (1 to 5) . map { j = i + j } > > yield i + j } Подробнее можно почитать в спецификации. 3 / 19
  • 4. By-name parameters Syntactic sugar For Возможность в вызов метода передавать выражения comprehensions By-name лениво это другой пример того, где неявно могут быть parameters Non local return зашиты closures. Следующие два примера идентичны: Local functions Lazy values d e f foo ( x : => Int ) { d e f foo ( x : ( ) => Int ) { Generated ByteCode println ( x ) println ( x ( ) ) } } Binary compatibility foo ( 1 ) foo ( ( ) => 1 ) Questions? Что изредка может приводить к ошибке (параметр будет вычисляться каждый раз, когда к нему будет производится обращение). 4 / 19
  • 5. Non local return Syntactic sugar For Return statement внутри closure на деле компилируется в comprehensions By-name код, который бросает NonLocalReturnControl. В parameters Non local return большинстве случаев это удобно, но нужно учитывать Local functions следующее Lazy values Generated В критичных по производительности кусках кода этот ByteCode Binary exception следует избегать compatibility Нельзя ловить Throwable в том месте, где этот Questions? exception бросается В силу синтаксического сахара описанного ранее, все это может происходить неявно (for-comprehensions и by-name parameters) 5 / 19
  • 6. Local functions Syntactic sugar For В Java любой вспомогательный код оформляется в виде comprehensions By-name private методов на уровне класса. В Scala это можно parameters Non local return сделать более структурированным, если использовать Local functions локальные методы, хотя на уровне bytecode получается Lazy values Generated примерно тоже самое: ByteCode Binary compatibility import scala . runtime . IntRef ; public class LocalFunctions { Questions? class LocalFunctions { p u b l i c void foo () { def foo { I n t R e f i $ 1 = new I n t R e f ( 1 ) ; var i = 1 i n t j$1 = 2; val j = 2 l o c a l $ 1 ( i$1 , j$1 ) ; def local { i += j   l o c a l $ 1 ( i$1 , j$1 ) ; } } p r i v a t e f i n a l void local$1 ( local IntRef intref , i n t i ) { local i n t r e f . e l e m += i ; } } } p u b l i c L o c a l F u n c t i o n s ( ) {} } 6 / 19
  • 7. Lazy values Syntactic sugar For Это тоже синтаксический сахар, который надо comprehensions By-name использовать аккуратно (так как возможны deadlock и parameters Non local return проблемы производительности). Независимо от Local functions расположения lazy val, компилируется он таким образом Lazy values Generated ByteCode import scala . runtime . BoxedUnit ; Binary p u b l i c c l a s s Lazy { compatibility public int x () { i f ( ( b i t m a p $ 0 & 2 ) == 0 ) Questions? synchronized ( this ) { i f ( ( b i t m a p $ 0 & 2 ) == 0 ) { x = 1; bitmap$0 = bitmap$0 | 2; c l a s s Lazy { lazy val x = 1   } BoxedUnit _tmp = } BoxedUnit . UNIT ; } return x ; } p u b l i c L a z y ( ) {} private int x ; public v o l a t i l e i n t bitmap$0 ; } 7 / 19
  • 8. Syntactic sugar Generated ByteCode Classes and names Objects Traits Trait subclasses Linearization Initialisation order Binary Generated ByteCode compatibility Questions? 8 / 19
  • 9. Classes and names Syntactic sugar Для классов ничего магического не происходит. Generated ByteCode Как преобразуются имена. Для большинства символов Classes and names Objects есть его текстовый эквивалент Traits Trait subclasses :   $colon Linearization Initialisation order +   $plus Binary ©   $u00A9 compatibility Questions? Внутри Scala кода можно использовать оба варианта подобных идентификаторов Подробнее можно изучить преобразования с помощью методов NameTransfomer.encode/decode из scala-compiler.jar. 9 / 19
  • 10. Objects Syntactic sugar Объект всегда компилируется в два класса. Generated ByteCode Classes and names Object$ содержит в себе статическое поле MODULE$, Objects а также код всех методов Traits Trait subclasses Object содержит в себе все статические методы Linearization Initialisation order объекта, с телом вида Object$.MODULE$.foo() Binary compatibility Важно понимать, что статические методы добавлены для Questions? удобства вызова из Java. Тем не менее они добавляются не всегда. В Companion Trait не добавляется ничего. В Companion Class не добавляются методы с таким именем, которое уже есть в этом классе Методы класса java.lang.Object 10 / 19
  • 11. Traits Syntactic sugar Если trait отличается от обычного интерфейса в Java Generated ByteCode наличием конкретных методов, то к соответствующему Classes and names Objects интерфейсу будет создан класс Trait$class с Traits Trait subclasses имплементацией этих методов. Linearization Initialisation order Binary public abstract class A$class { compatibility public static int foo ( A $this , int x) { Questions? return 2; trait A { } val x = 1   public s t a t i c void $init$ ( A $this def foo ( x : Int ) = 2 ) { } $this . test$A$_setter_$x_$eq (1) ; } } 11 / 19
  • 12. Trait subclasses Syntactic sugar Если в Java попытаться реализовать Trait, в котором есть Generated ByteCode уже имплементированые методы, то их все равно Classes and names Objects пришлось бы реализовывать. Другой вопрос, что это Traits Trait subclasses можно сделать предельно легко: Linearization Initialisation order Binary i n t foo ( ) { r e t u r n Trait$class . foo ( t h i s ) ; } compatibility Questions? В случае наследников написанных на Scala, то же самое делает компилятор. 12 / 19
  • 13. Linearization Syntactic sugar Этот алгоритм требуется компилятору, чтобы определить, Generated ByteCode в каком порядке надо искать методы в базовых классах. Classes and names Objects Traits Trait subclasses trait A extends B Linearization trait B Initialisation order class C extends B Binary class D extends C with A compatibility Questions? Здесь порядок D, A, C, B. Если два метода с одинаковой сигнатурой без модификатора ’override’ приходят в класс наследник из супертрейтов, то ошибки не будет, так как обязательно надо будет переопределить эту сигнатуру. Если же у кого-то есть модификатор ’override’, может случится неявный override согласно правилам линеаризации. 13 / 19
  • 14. Initialisation order Syntactic sugar Инициализация происходит в порядке, обратном Generated ByteCode линеаризации. Если к переменной обратиться до того, как Classes and names Objects она проинициализирована, можно получить NPE. Traits Trait subclasses Есть два способа избавится от подобных проблем: Linearization Initialisation order Использовать lazy val Binary compatibility Использовать early definitions Questions? 14 / 19
  • 16. Methods Syntactic sugar Здесь все очень похоже на Java. Чаще всего проблем не Generated ByteCode будет. Binary compatibility Добавлять метод можно даже в Trait, но только если Methods Values старые методы не ссылаются на новые, так как Lazy values имплементации в классы наследники добавлены не Questions? будут. В класс опасно добавлять методы, имена которых совпадают с именем методов из Companion Object, так как статические реализации будут удалены компилятором, что может вызвать проблемы с кодом написанным не на Scala. 16 / 19
  • 17. Values Syntactic sugar Если переменная находится в классе или объекте, то Generated ByteCode переменная компилируется в getter, setter (для variables) и Binary compatibility field, который инциализируется в конструкторе класса. А Methods значит все будет также хорошо как и с методами. Values Lazy values Если переменная находится в Trait, то она компилируется Questions? в getter и setter (всегда). Инициализация происходит в методе Trait$class.$init$ через вызов setter. Значит добавлять переменную в трейт нельзя. Так как будет вызван абстрактный setter. По аналогичным причинам нельзя изменять def на val Тем не менее val на def также изменять нельзя, так как тогда в классах наследниках, где как раз и хранится field, переменная не будет проинициализирована. 17 / 19
  • 18. Lazy values Syntactic sugar В подклассах не генерируется field bitmap, если он есть в Generated ByteCode базовом классе. Binary compatibility Поэтому в этих случаях добавлять lazy value в классы Methods Values нельзя Lazy values В Trait добавлять можно, если эта переменная не Questions? будет использована в старом коде Так как компиляция lazy val в Trait от компиляции метода не отличается совсем, то их можно заменять друг на друга, учитывая только, что в наследниках подобная семантика не изменится 18 / 19