Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Язык программирования Scala / Владимир Успенский (TCS Bank)

956 views

Published on

Язык программирования Scala / Владимир Успенский (TCS Bank)

  1. 1. Язык программирования Scalадля создания успешных Интернет-проектовУспенскийВладимир
  2. 2. О нашем проектеСтарт — сентябрь 2011Запуск — май 2012Итого 9 месяцев▶ Сразу лучший Интернет-банк в России▶ Хорошие отзывы клиентов▶ Бешенное развитие в течение года:функционал, безопасность, интерфейси это не конец...
  3. 3. Общие слова о ScalaОдин из альтернативных языков на JVM,привносит функциональный подходООП и ФП дополняют друг другаООП чище чем в Java:все значения — объекты,все операции — вызов методаФункциональный != Процедурный
  4. 4. BookИтак, мы начинаем проект...BookStoresellAuthorMoney acceptПридумаем модель предметной области:Просто, правда?has
  5. 5. Количество кода, обозримостьcase class Money(amount: Long, currency: Currency)case class Author(name: String)case class Book(name: String, author: Author)trait BookStore {def buy(bookName: String, money: Money): Book}Чтобы иметь интерфейсы под рукой,можно объявить всё в одном файле:Всё ещё просто!
  6. 6. Количество кода, обозримостьWAT?
  7. 7. Вывод типовMap<String, List<String>> booksAuthors =new HashMap<String, List<String>>();List<String> authors = new ArrayList(1);authors.add("Herman Melville");booksAuthors.put("Moby-Dick", authors);for(Map.Entry<String, List<String>> bookAuthors :booksAuthors.entrySet()) {String book = bookAuthors.getKey();String authors = bookAuthors.getValue();...}
  8. 8. Вывод типовval booksAuthors = Map("Moby-Dick" ->List("Herman Melville"))for((book, authors) <- booksAuthors) {...}Ничего лишнего!
  9. 9. Коллекцииval somethingToRead =books.filter(isPhysics).groupBy(_.author).map({case (author, books) =>books.sortBy(rating(author)).head}).headOptionConsole.print(somethingToRead.firstPage)Стандартные методы на все случаи жизни:
  10. 10. Коллекцииval somethingToRead =books.filter(isPhysics).groupBy(_.author).map({case (author, books) =>books.sortBy(rating(author)).head}).headOptionConsole.print(somethingToRead.firstPage)Стандартные методы на все случаи жизни:
  11. 11. Коллекцииval somethingToRead =books.filter(isPhysics).groupBy(_.author).map({case (author, books) =>books.sortBy(rating(author)).head}).headOptionConsole.print(somethingToRead.map(_.firstPage).getOrElse("Nothing is there!"))Стандартные методы на все случаи жизни:
  12. 12. JSONcase class Address(street: String, city: String)case class Person(name: String, address: Address)val json = parse("""{ "name": "joe","address": {"street": "Boulevard","city": "Helsinki"}}""")assert (json.extract[Person] ==Person(joe, Address("Buolevard", "Helsinki"))(Scala 2.10, Json4s)
  13. 13. XMLval xml = <root><tag attr="value">text</tag></root>val xml = XML.loadString("""<root><tag attr="value">text</tag></root>""")XPathassert ((xml "tag").text == "text")assert ((xml "tag" "@attr").text == "value")
  14. 14. Pimp my library!import ru.tcs.db.extensions._val userId = resultSet.getId[User]("user_id")// userId: Id[User]val balance = resultSet.getMoney("balance")// balance: MoneyAmountБерём обычный java.sql.ResultSetRetroactive extension для любого типа!
  15. 15. Абстракция▶ Способность находить и описывать общее, чтобы- экономить время, переиспользуя, или при правках- и недопускать разного поведения и ошибок▶ Обычно применяются: наследование,параметризация, параметризация типа (generics)▶ Замыкания и функции над функциямипозволяют параметризовать код другим кодом,давая доступ к новому механизму абстракции
  16. 16. Функции высшего порядка// где-то в определениии Iterable[T]...def filter(predicate: T => Boolean):Iterable[T]def map[A](transform: T => A): Iterable[A]Операции с коллекциями так удобно использовать,как раз потому, что стандартные функции можнопараметризировать своим поведеднием
  17. 17. Примеси/Mixinsclass Animaltrait Philosophical {def philosophize() {Console.println("It aint easy being " + toString)}}class Frog extends Animal with Philosophical {override def toString = "green"}new Frog().philosophize()// It aint easy being greenПомогают выноситьобщий функциналбез недостатковмножественногонаследования
  18. 18. Higher Kindstrait Factory[T] {def create(): T}Параметр типа первого порядка:trait Functor[H[_]] {def map[A,B](fn: A => B)(fa: H[A]): H[B]}Параметр типа высшего порядка:
  19. 19. Корректность и тотальностьВсё никогда не бывает хорошо"A good programmer is someone who looks both waysbefore crossing a one-way street." ~ Doug LinderТотальность — свойство программы, бытьопределённой для всех входных параметровScala использует типизацию (type-safety) для проверкикорректности при компилляции, где это возможно
  20. 20. Маленький мотивирующий примерBook book = bookShelf.get("Moby-Dick");Reader reader = readersQueue.peek();if(reader.favorite.equals(book.author)) {reader.read(book);}
  21. 21. Маленький мотивирующий примерBook book = bookShelf.get("Moby-Dick");Reader reader = readersQueue.peek();if(reader.favorite.equals(book.author)) {reader.read(book);}Значения может просто не быть!Если значение необязательно,лучше предусмотреть это в модели типов
  22. 22. Маленький мотивирующий примерval book: Option[Book] = bookShelf.get("Moby-Dick")val reader: Option[Reader] = readersQueue.peekif(reader.favorite.equals(book.author)) {reader.read(book)}Теперь программа просто не собраласьРазработчик узнал об ошибках сразу,до передачи в тестирование или переноса в бой
  23. 23. Управление непредвиденнымПри выполнении вычислений возможно:Возможностью таких исходов можно управлятьс помощью типа возвращаемого значения.Такие значения можно создавать и связывать.Тип вместе с операциями называется Монадой.▶ ничего не получить, — Option▶ получить исключение, — Try▶ занимать время, — Future▶ работать с диском — IOetc.
  24. 24. Более строгие ограничения на типы▶ Параметр типа обязательно должен бытьВсегда List[T], но не List▶ Higher KindsНе надо переходить к Object▶ ВариантностьНе обязательно переходить к List[_]
  25. 25. Вариантностьcase class Invariant[T]()case class Covariant[+T]()case class Contravariant[-T]()val in: Invariant[Object] = Invariant[String]val in: Invariant[String] = Invariant[Object]val co: Covariant[Object] = Covariant[String]val co: Covariant[String] = Covariant[Object]val contra: Contravariant[Object] = Contravariant[String]val contra: Contravariant[String] = Contravariant[Object]Scala позволяет указать вариантность для параметров типа:
  26. 26. Immutability▶ Возможность изменения выбирается явно:▶ Коллекции по умолчанию immutableval immutable = ...var mutable = ...List, Set, Map,▶ Immutability — невозможность изменить объектили ссылку после создания.есть также mutable версии
  27. 27. Достоинства Immutability▶ Меньше ошибок из-за переиспользованияпеременных для разных целей▶ Операции проще и однороднее:нет особенностей, связанных с изменением▶ Просто работать в многопоточной среде,нет расходов на синхронизацию,возникающих из-за concurrent mutable state
  28. 28. Адаптация к изменениямКогда, проект запущенКлиенты начали пользоваться и писать отзывыБизнес хочет зарабатывать на продуктеА несколько раз в год, запускаются крупные проектыВам нужно быть очень гибкими!
  29. 29. Адаптация к изменениямЕсли приходится что-то серьёзно менять,когда меньше кода, лучше видны последствия,а, благодаря типам, изменения ещё и проверяютсякомпиллятором — меньше вероятность сломать.Выше уровень абстракциии и однородный код —нет необходимости влезать в низкоуровневые деталиреализации, можно охватить больше случаевменьшими усилиями.
  30. 30. Группировка запросов ипараллельная обработкаЗадача:«Сделать возможность параллельнойобработки запросов, когда все запросыобработаны, нужно собрать результаты»
  31. 31. Группировка запросов ипараллельная обработкаThreadPool?CyclicBarrier?CountDownLatch?Задача:«Сделать возможность параллельнойобработки запросов, когда все запросыобработаны, нужно собрать результаты»Похоже,это сложнаязадача!
  32. 32. Группировка запросов ипараллельная обработкаval responses =requests.par.map(processRequest).seqЗадача:«Сделать возможность параллельнойобработки запросов, когда все запросыобработаны, нужно собрать результаты»
  33. 33. Нужно собирать информациюсо множества бекендовПродуктыCRMОперационныеданныеПредложения
  34. 34. Нужно собирать информациюсо множества бекендовПродуктыCRMОперационныеданныеПредложенияОчень долго!
  35. 35. Нужно собирать информациюсо множества бекендовПродуктыCRMОперационныеданныеПредложенияОтлично!
  36. 36. Нужно собирать информациюсо множества бекендовПродуктыCRMОперационныеданныеПредложенияОтлично!ThreadPool?CyclicBarrier?CountDownLatch?Похоже этосложная задача!Мне нужнонесколько дней!
  37. 37. Нужно собирать информациюсо множества бекендовРаспараллелить долгие вызовы для одного,не самого простого, случая удалось за 30 минутval (operations, offers) = Await.result(future {operationsRepo.readOperations(userId)} zip future {offersRepo.readOffers(userId)}, 60 seconds)
  38. 38. Расширение командыНовые сотрудники втягиваются за пару недель:- всё не так сильно отличается,- меньше кода и неявных контрактовпочти за два года командалюди менялись в процессевыросла почти с нуля,
  39. 39. Недостатки▶ Есть неочевидные местаxНадо читать документацию и писать тесты▶ Длинные цепочки вызовов тяжело отлаживать,что заставляет выносить переменныеи разделять код на небольшие методы
  40. 40. Недостатки▶ Есть неочевидные местаxНадо читать документацию и писать тесты▶ Длинные цепочки вызовов тяжело отлаживать,что заставляет выносить переменныеи разделять код на небольшие методыЧто?тесты и небольшиеметоды? да ладно!
  41. 41. Недостатки▶ Есть неочевидные местаxНадо читать документацию и писать тесты▶ Длинные цепочки вызовов тяжело отлаживать,что заставляет выносить переменныеи разделять код на небольшие методы▶ Ограниченная поддержка генерации кода в IDE,впрочем генерировать код не очень актуально▶ На рынке не так много специалистов по Scala,приходится искать заинтересованных ребят,которые хотят делать что-то новое
  42. 42. ▶ Та же платформа▶ Те же среды разработки▶ Та же релизная политика▶ Доступен код на Java, все библиотеки JVM,старое доброе ООП и императивностьмало того, с этого стоит начатьПерейти простоадминистраторам всё знакомоне нужны новые лицензиитестировщики и администраторы в покоеесли что, всегда есть к чему вернуться,
  43. 43. Итог▶ Проще код▶ Меньше ошибок▶ Меньше времени на типовые вещи▶ Простая работа с потоками▶ Просто поддерживать рост▶ Легко попробовать и перейти
  44. 44. ИтогScala — отличный инструментдля успешного проекта!scala-lang.org/downloads
  45. 45. scala> questions
  46. 46. e-mail: v.uspenskiy@tcsbank.ruskype: tcs_uspenskiy

×