Метка: Scala

  • Встречи Scala программистов в Москве

    Для меня Scala не “абстрактный сферический конь в вакууме”, а язык, который я использовал в нескольких реальных проектах в течение последних трех лет. Хочу сразу отметить, что мы не использовали никаких скала-фреймворков – лифт, скалаторы и прочее. Во-первых не было необходимости, во-вторых можно без особых усилий писать на scala и использовать только обычные java-фреймворки.

    Кроме программирования на Scala в 2010-2011 я вел курс по выбору в МФТИ “Практикум по программированию на Java и Scala”. В результате у меня наработался некоторый объём дидактического материала.

    В итоге летом 2011 года мы с друзьями решили организовать в Москве независимые регулярные встречи Scala программистов.
    Под “независимыми” имеется в виду – без патронажа каких либо коммерческих организаций жадных до денег или мозгов программистов.
    Регулярные – старались встречаться каждую неделю, но естественно были перерывы.
    Формат встреч самый простой – собираемся и решаем небольшие задачки на Scala.

    Место встречи – различные кофейни и другие либеральные заведения общественного питания, в которых есть wi-fi.
    Как правило встречи проводились после рабочего дня, поэтому кто-то в процессе обучения пил кофе и ел пирожные, кому-то было интересней пиво или сытный ужин.

    Один человек притаскивал ноутбук (как правило это был я со своим 17” HP).
    Выбирали одну задачку на всех, она разбивалась на несколько кусочков.
    Главное условие – каждый должен был написать хотя бы несколько строк кода.
    Если не успеваем решить – переносим на следующую встречу.

    Также кто-то на встречах рассказывал про свой опыт использования Scala у себя на работе или какие-то интересные аспекты языка.
    В качестве источника информации использовали в основном стандартную документацию по API, мои презентации к физтеховским семинарам,
    и книжку Мартина Одерского “Programming in Scala”, которую мне подарил Коля Матюшев (книжка на английском, он ее купил когда работал в Лондоне).

    Некоторые задачки которые мы решали на наших “семинарах”:

    • Рисовалка Мандельброта
    • Разные фракталы на L-System-е
    • Игра жизнь
    • Решалка судоку

    Места в которых проводил занятия (в хронологическом порядке):

    • КофеИн
    • Шоколадница
    • Кофе-Хаус
    • Му-Му

    Думаю станет чуть потеплее и мы продолжим (а может и раньше).
    Кто был на встречах: Валерия Ива Виннер, Серж, Артур, Ник, Миха, Вит.
    Прошу прощения если кого-то забыл. Буду рад новым встречам!

  • Поездка в Санкт-Петербург

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

  • Мои хинты для Netbeans 7

    Недавно нужно было заново установить Netbeans 7.
    Вот некоторые действия, которые всегда приходится делать после установки “коробочной” версии,
    а именно: поддержка Scala, интерфейс на английском и quick file chooser.

    Установка

    Заходим на официальный сайт: netbeans.org
    Нажимаем на [Download FREE] и переходим на ссылку http://netbeans.org/downloads/index.html
    Скачиваем, устанавливаем и запускаем.

    Итак, что приходится делать:

    0. Обновления.

    На всякий случай проверить наличие обновлений:
    Меню → Help → Check for Updates

    1. Русский → English

    Чтобы вернуть обратно английский нужно:
    – Найти файл “netbeans.conf” (для Windows-пользователей: он должен находится где-то здесь – “C:\Program Files\NetBeans 7.0\etc\” )
    – Указать в настройках –locale en:US

    netbeans_default_options="МНОГО_БУКВ   --locale en:US"
    

    UPD: Почистить домашнюю папку “.netbeans/7.x” перед сменой локали, а то “Службы” и некоторые другие сообщения могут остаться на русском. Предварительно сделайте бэкап.

    2. File Chooser

    Сразу же установить плагин Quick File Chooser:
    Меню → Тools → Plugins → Available Plugins
    Это намного более шустрый и удобный (на мой взгляд) диалог для выбора файлов.

    3. Scala

    Ставим plugin для работы со Scala.
    Для версии 2.8.x: http://plugins.netbeans.org/plugin/36598/nbscala-2-8-x
    Подробнее можно прочитать на вики нетбинсов:
    http://wiki.netbeans.org/Scala
    или на портале с плагинами:
    http://plugins.netbeans.org/

  • Scala и пустота

    В Scala есть несколько разных сущностей для обозначения несуществующих, пустых или неопределенных объектов.
    Начнем с самого привычного для Java-программистов случая.

    Null

    Null – это trait. Объект null (с маленькой буквы) — это как раз и есть объект типа Null. Он находится внизу иерархии типов в Scala, в противовес AnyRef.
    Благодаря этому вы всегда можете как-бы “занулить” любую ссылку, т.е. присвоить ссылки значение null:

    scala> var x = "String"
    x: java.lang.String = String
    scala> var i = List(3)
    i: List[Int] = List(3)
    scala> i = null
    i: List[Int] = null
    scala> x = null
    x: java.lang.String = null
    

    Null работает только для ссылочных типов, для более общего случая, есть “ничто (Nothing)” .

    Nothing

    Nothing – это тоже trait. Nothing находится на самом дне иерархии типов, в противовес Any. Соответственно, это более общий тип, чем Null и подходит даже для AnyVal объектов (числа, буквы, правда/ложь и т.д.).

    В отличие от Null, Nothing не может иметь экземпляров (на то оно и ничто).
    Другими словами нет аналога null для Nothing.

    Возникает вопрос, где такое самое “нижнее ничто” может использоваться?
    В документации по API можно найти несколько примеров:

    // пакет scala.sys
    def error(message: String): Nothing = throw new RuntimeException(message)
    

    Этот метод никогда ничего не возвращает, поэтому возвращаемый тип Nothing.

    Unit

    Unitкласс, чем-то похоже на void, который используется в Java. В Scala тип Unit применяется тогда, когда нужно показать, что функция возвращает пустое значение (но все-таки что-то возвращает, хоть и пустое).

    Если открыть документацию, то можно увидеть что:

    class Unit extends Any with AnyVal
    

    Внимание! AnyVal, а не AnyRef. Это значит, что Unit это не ссылочный тип ( в отличие от Null). Можно сказать, что Unit-у как бы “ближе по родству” будут числа, буквы и другие примитивные типы (которые тоже AnyVal).

    В отличие от Nothing, Unit повезло больше. Он может иметь свой объект, правда в единственном экземпляре. Он обозначается двумя круглыми скобками: (). Например:

    scala> val u = ()
    u: Unit = ()
    

    Другими словами Nothing уместен тогда, когда функция в принципе ничего не возвращает, а Unit – это когда возвращает, но оно пустое.
    Это отличие существенно. Например результат вызова функции с Unit может быть присвоено (в Java с void такой фокус не выйдет).

    scala> def foo():Unit = {}
    foo: ()Unit
    scala> val u = foo()
    u: Unit = ()
    

    Nil

    Nilобъект, пустой список (extends List[Nothing]).
    Поскольку Nil – это список, хоть и пустой, у него как у любого списка есть метод :: (два двоеточия), с помощью которого удобно создавать списки:

    scala> var x = 1 :: 2 :: Nil
    x: List[Int] = List(1, 2)
    

    Это возможно благодаря тому, что название метода заканчивается на : (двоеточие), в таком случае метод применяется к правому операнду (работает для операторной нотации вызова метода).

    Другими словами, это аналогично вызову: (Nil.::(2)).::(1)

    None

    None – это такой хитрый объект (extends Option[Nothing]) , который используется в случае, если мы хотим получить что-то, например, из Map, а его там нет.

    Например:

    scala> var m = Map(1->2)
    m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2)
    scala> val n = m.get(100)// ну нет такого элемента
    n: Option[Int] = None
    

    None примечателен тем, что:

    • это объект (т.е. синглтон)
    • это кейс-объект
    • наследуется от Option[Nothing]

    В случае попытки получить значение (вызвав метод n.get()), мы получим исключение:java.util.NoSuchElementException.

    Если у None вызывать метод isEmpty() – мы получим true.

    Поскольку None – объект кейс-класса, то мы можем его “матчить” (сопоставлять по шаблону).

    scala> n match { 
     case Some(x) => println("x:" + x) 
     case None => println("none") 
    }
    

    Если у None вызвать метод toList – мы получим пустой список (т.е. Nil).

    scala> n.toList() == Nil
    res21: Boolean = true
    

    Поскольку None объявлен как extends Option[Nothing], а Nothing – “самое нижнее ничто”, то None может работать с любыми типами (как с ссылочными так и с примитивными).

  • Main args, netbeans

    Пара простых вещей (про аргументы командной строки + Java/Scala и чуть-чуть про NetBeans)

    Самый популярный и набивший оскомину пример HelloWorld встречается, наверное, уже во всех учебниках по программированию:

    // Пример из туториала: http://download.oracle.com/javase/tutorial/getStarted/application/index.html
    class HelloWorldApp {
        public static void main(String[] args) {
            System.out.println("Hello World!"); // Display the string.
        }
    }
    

    Здесь String[] args — аргументы командной строки.
    Например:
    java HelloWorldApp 1 2 означает, что args будет равно {“1”, “2”}.

    Рассмотрим как работать с этими аргументами.
    Если передается всего один аргумент (например, “debug”), то все очень просто — можно подсмотреть пример из туториала: cmdLineArgs.

    В случае, если аргументов много (как в гнусных линуксовых командах), то можно использовать какую-нибудь готовую библиотеку:

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

    В том случае, если аргументы не такие сложные и не слишком простые, а что-то среднее, то тянуть для этих целей дополнительную библиотеку нет никакого смысла. Например, если нужно передать что-то вроде: “-x -size 1024 -v”.
    Обычно это бывает, когда требуется небольшая, почти “одноразовая” программа…

    Многие настолько не любят писать разбор таких аргументов, что лепят все параметры в системные свойства (java … -Dfoo=”some string”), чтобы потом дергать их через System.getProperty().
    Это конечно удобно, но не всегда нормально.

    Проще написать разбор обычными стандартными средствами:

    public class App {
    
        public static void main(String[] args) {
            boolean v = false, x = false;
            int size = 0;     
            for (int i=0;iSnippet: Match Arguments.
    Что-то очень сложное – подключаем сторонние библиотеки для разбора аргументов командной строки (ту же апачевскую или jopt).
    В том случае, если что-то среднее, то можно написать на чистой Scala:

    object App  {
      def main(args:Array[String]) = {
          var v = false; var x = false; var size = 0   
         ("" +: args :+ "") reduceLeft ( (i, j) => {
            i match {
              case "-v"     => v = true
              case "-size"  => size = j.toInt
              case "-x"     => x = true
              case _ =>
            }; j
         })
        println("v =" + v )
        println("x = " + x)
        println("size = " + size)
       }
    }
    

    Пару слов про reduceLeft. По сути этот тот же foldLeft, только начинается с первого элемента коллекции. Подробнее можно почитать в Scala API по работе с коллекциями.

    Про другую известную многим фишку, о которой хотел рассказать — макросы в NetBeans-ах.
    Точнее, про самый популярный макрос - debug-var. Вызывается по нажатию: Ctrl-J D.
    Вообще макросы в нетбинсах есть уже много лет, по-крайне мере, когда я только начинал использовать нетбинс (3.* версии), они уже там были.
    Например, для Scala можно сделать макрос, который будет вставлять в код: println("var=" + var)

    Настроить можно здесь:
    Tools -> Option -> Editor -> Macros

    Про другие полезные макросы можно почитать здесь

  • Немного карри

    Использовать карринг в Scala одно удовольствие.
    Само определение каррирования(или карринга, названо в честь Хаскелла Карри):

    Для функции h типа h : (A × B) → C оператор каррирования Λ выполняет преобразование
    Λ(h) : A → (B → C)

    Отметим, что Λ – это оператор, то есть “функция над функциями”.
    Например берем функцию foo(x,y), каррируем и получаем moo(x)(y) – функцию от x которая возвращает функцию от y. (далее…)

  • Scala. Pattern Matching


    Продолжил работу по созданию учебных материалов по Scala.
    Выкладываю черновую версию одной из глав.

    Сопоставление по образцу (pattern matching). Начало.

    (далее…)

  • Netbeans Scala Maven

    Если вам приходилось работать в связке Netbeans 6.9.1 + Scala + Maven, то вы могли заметить, что компиляция происходит сильно медленнее, чем если бы вы НЕ использовали maven-scala-plugin.
    Дело в том, что по умолчанию компиляция запускается в режиме “компилировать все классы”. Это не очень приятно, учитывая то, что Scala компилятор не очень-то быстрый.
    К счастью, такое поведение можно изменить, указав в настройках для recompileMode значение modified-only (компилировать только измененные). По-умолчанию оно all.
    В некоторых случаях перевод в режим modified-only удобен, например если ваша задача не выпуск финальной версии продукта, а работа над определенным куском кода в режиме “написал, нажал Shift-F6, посмотрел что получилось…”.
    Внимание! Перевод recompileMode в режим modified-only может привести к нежелательным последствиям и побочным эффектам. Как говорится, не уверен – не обгоняй (а уверен – обгоняй).

    Пример возможной (но далеко не оптимальной) модификации pom.xml.

    
        org.scala-tools
        maven-scala-plugin
          
               modified-only
         
    
    
  • Принцип работы FFT и Scala

    Разбор алгоритма быстрого преобразования фурье (он же Fast Fourier transform, он же FFT).

    Целью публикации является отобразить суть алгоритма, а не создание быстрой по скорости работы реализации.
    Т.к. в этой программе я буду интенсивно использовать объекты вместо примитивных типов, а также рекурсию,
    скорость работы будет заведомо уступать многим другим реализациям FFT, которые можно сейчас найти
    в интернете в огромном количестве в открытом доступе.
    (далее…)

  • Поиск. КМП-алгоритм

    Недавно на досуге решил написать алгоритм КМП  (КнутаМорриса — Пратта) для Scala.

    Изначально, мне нужно было решить простенькую задачку – найти последовательность байт в потоке байтов. Сделал на Java. Потом, решил сделать тоже самое на Scala. Занятно, но в стандартной библиотеке коллекций Scala используется именно КМП поиск.

    Вот мой вариант.
    (далее…)